add ability to copy providers or all services from satellites to favourites (this...
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 24 Jan 2006 00:29:54 +0000 (00:29 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 24 Jan 2006 00:29:54 +0000 (00:29 +0000)
add ability to remove a complete bouquet
both are just working with enabled multi bouquet mode

lib/dvb/db.cpp
lib/dvb/idvb.h
lib/python/Screens/ChannelSelection.py
lib/python/enigma_python.i
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicefs.cpp
lib/service/servicefs.h

index ad2996f913fa7f1ca984c29494119b260d5eccdc..e0fadc5ea0fb6c277a455a5a2193a6f054744fd1 100644 (file)
@@ -107,6 +107,12 @@ err:
        return -1;
 }
 
        return -1;
 }
 
+RESULT eBouquet::setListName(const std::string &name)
+{
+       m_bouquet_name = name;
+       return 0;
+}
+
 eDVBService::eDVBService()
 {
 }
 eDVBService::eDVBService()
 {
 }
index f18d4f34b81af4e660bd4e9191380ef6f9b9dfa1..c7db9779288cbccec4141ad613768a70027572ba 100644 (file)
@@ -21,11 +21,12 @@ struct eBouquet
        std::string m_filename;  // without path.. just name
        typedef std::list<eServiceReference> list;
        list m_services;
        std::string m_filename;  // without path.. just name
        typedef std::list<eServiceReference> list;
        list m_services;
-// the following four methods are implemented in db.cpp
+// the following five methods are implemented in db.cpp
        RESULT flushChanges();
        RESULT addService(const eServiceReference &);
        RESULT removeService(const eServiceReference &);
        RESULT moveService(const eServiceReference &, unsigned int);
        RESULT flushChanges();
        RESULT addService(const eServiceReference &);
        RESULT removeService(const eServiceReference &);
        RESULT moveService(const eServiceReference &, unsigned int);
+       RESULT setListName(const std::string &name);
 };
 
                /* these structures have by intention no operator int() defined.
 };
 
                /* these structures have by intention no operator int() defined.
index 59cc6b24989e3289e32da39678ff0445a1dad2c2..43cf66d7af9fa11993cf54dc9ad301addefa063f 100644 (file)
@@ -3,7 +3,7 @@ from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap
 from EpgSelection import EPGSelection
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap
 from EpgSelection import EPGSelection
-from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer
+from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB
 from Components.config import config, configElement, ConfigSubsection, configText, currentConfigSelectionElement
 from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
 from Components.config import config, configElement, ConfigSubsection, configText, currentConfigSelectionElement
 from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
@@ -11,7 +11,9 @@ from Components.NimManager import nimmanager
 from Components.ServiceName import ServiceName
 from Components.Clock import Clock
 from Components.EventInfo import EventInfo
 from Components.ServiceName import ServiceName
 from Components.Clock import Clock
 from Components.EventInfo import EventInfo
+from ServiceReference import ServiceReference
 from re import *
 from re import *
+from os import remove
 
 import xml.dom.minidom
 
 
 import xml.dom.minidom
 
@@ -37,14 +39,20 @@ class ChannelContextMenu(FixedMenu):
                inBouquet = csel.getMutableList() is not None
                haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
 
                inBouquet = csel.getMutableList() is not None
                haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
 
-               if not csel.bouquet_mark_edit and not csel.movemode and not inBouquetRootList:
-                       if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
-                               if haveBouquets:
-                                       menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
-                               else:
-                                       menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
-                       if inBouquet:
-                               menu.append((_("remove service"), self.removeCurrentService))
+               if not csel.bouquet_mark_edit and not csel.movemode:
+                       if not inBouquetRootList:
+                               if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
+                                       if haveBouquets:
+                                               menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
+                                       else:
+                                               menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
+                               elif haveBouquets:
+                                       if not inBouquet and csel.getCurrentSelection().getPath().find("PROVIDERS") == -1:
+                                               menu.append((_("copy to favourites"), csel.copyCurrentToBouquetList))
+                               if inBouquet:
+                                       menu.append((_("remove service"), self.removeCurrentService))
+                       elif haveBouquets:
+                               menu.append((_("remove bouquet"), csel.removeBouquet))
 
                if inBouquet: # current list is editable?
                        if not csel.bouquet_mark_edit:
 
                if inBouquet: # current list is editable?
                        if not csel.bouquet_mark_edit:
@@ -83,6 +91,14 @@ class ChannelContextMenu(FixedMenu):
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
+       def copyCurrentToBouquetList(self):
+               self.csel.copyCurrentToBouquetList()
+               self.close()
+
+       def removeBouquet(self):
+               self.csel.removeBouquet()
+               self.close()
+
        def addCurrentServiceToBouquet(self, dest):
                self.csel.addCurrentServiceToBouquet(dest)
                self.close()
        def addCurrentServiceToBouquet(self, dest):
                self.csel.addCurrentServiceToBouquet(dest)
                self.close()
@@ -159,6 +175,65 @@ class ChannelSelectionEdit:
                        return list.startEdit()
                return None
 
                        return list.startEdit()
                return None
 
+       def buildBouquetID(self, str):
+               tmp = str.lower()
+               name = ''
+               for c in tmp:
+                       if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
+                               name += c
+                       else:
+                               name += '_'
+               return name
+
+       def copyCurrentToBouquetList(self):
+               provider = ServiceReference(self.getCurrentSelection())
+               serviceHandler = eServiceCenter.getInstance()
+               mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
+               if mutableBouquetList:
+                       providerName = provider.getServiceName()
+                       if self.mode == MODE_TV:
+                               str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
+                       else:
+                               str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
+                       new_bouquet_ref = eServiceReference(str)
+                       if not mutableBouquetList.addService(new_bouquet_ref):
+                               mutableBouquetList.flushChanges()
+                               eDVBDB.getInstance().reloadBouquets()
+                               mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
+                               if mutableBouquet:
+                                       mutableBouquet.setListName(providerName)
+                                       list = [ ]
+                                       services = serviceHandler.list(provider.ref)
+                                       if not services is None:
+                                               if not services.getContent(list, True):
+                                                       for service in list:
+                                                               if mutableBouquet.addService(service):
+                                                                       print "add", service.toString(), "to new bouquet failed"
+                                                       mutableBouquet.flushChanges()
+                                               else:
+                                                       print "getContent failed"
+                                       else:
+                                               print "list provider", providerName, "failed"
+                               else:
+                                       print "get mutable list for new created bouquet failed"
+                       else:
+                               print "add", str, "to bouquets failed"
+               else:
+                       print "bouquetlist is not editable"
+
+       def removeBouquet(self):
+               refstr = self.getCurrentSelection().toString()
+               pos = refstr.find('FROM BOUQUET "')
+               if pos != -1:
+                       refstr = refstr[pos+14:]
+                       print refstr
+                       pos = refstr.find('"')
+                       if pos != -1:
+                               filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
+               self.removeCurrentService()
+               remove(filename)
+               eDVBDB.getInstance().reloadBouquets()
+
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
        def startMarkedEdit(self):
                self.mutableList = self.getMutableList()
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
        def startMarkedEdit(self):
                self.mutableList = self.getMutableList()
@@ -279,7 +354,7 @@ class ChannelSelectionBase(Screen):
 
                # this makes it much simple to implement a selectable radio or tv mode :)
                self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17)'
 
                # this makes it much simple to implement a selectable radio or tv mode :)
                self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17)'
-               self.service_types_radio = '1:7:1:0:0:0:0:0:0:0:(type == 2)'
+               self.service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
 
                self["key_red"] = Button(_("All"))
                self["key_green"] = Button(_("Satellites"))
 
                self["key_red"] = Button(_("All"))
                self["key_green"] = Button(_("Satellites"))
index 8029a2651e18b710285b75817bba8b0392d76f09..53238e4a9344fe73ae0a7d576a75cc1b1e78af3d 100644 (file)
@@ -251,4 +251,9 @@ PyObject *New_TestObj()
     TestObj *result = (TestObj *)new TestObj();
     return SWIG_NewPointerObj((void*)(result), SWIGTYPE_p_TestObj, 1);
 }
     TestObj *result = (TestObj *)new TestObj();
     return SWIG_NewPointerObj((void*)(result), SWIGTYPE_p_TestObj, 1);
 }
+PyObject *New_eServiceReference(const eServiceReference &ref)
+{
+    eServiceReference *result = new eServiceReference(ref);
+    return SWIG_NewPointerObj((void*)(result), SWIGTYPE_p_eServiceReference, 1);
+}
 %}
 %}
index 2b42510d61c2f712f4fc62cfeb7ac64154582d98..1f55fe4952ec9c81d5959800f9d3ae099ee0a979 100644 (file)
@@ -2,6 +2,7 @@
 #define __lib_dvb_iservice_h
 
 #include <lib/python/swig.h>
 #define __lib_dvb_iservice_h
 
 #include <lib/python/swig.h>
+#include <lib/python/python.h>
 #include <lib/base/object.h>
 #include <string>
 #include <connection.h>
 #include <lib/base/object.h>
 #include <string>
 #include <connection.h>
@@ -166,6 +167,8 @@ public:
 
 SWIG_ALLOW_OUTPUT_SIMPLE(eServiceReference);
 
 
 SWIG_ALLOW_OUTPUT_SIMPLE(eServiceReference);
 
+extern PyObject *New_eServiceReference(const eServiceReference &ref); // defined in enigma_python.i
+
 typedef long long pts_t;
 
        /* the reason we have the servicereference as additional argument is
 typedef long long pts_t;
 
        /* the reason we have the servicereference as additional argument is
@@ -442,6 +445,8 @@ public:
                /* moves a service in a list, only if list suppports a specific sort method. */
                /* pos is the new, absolute position from 0..size-1 */
        virtual RESULT moveService(eServiceReference &ref, int pos)=0;
                /* moves a service in a list, only if list suppports a specific sort method. */
                /* pos is the new, absolute position from 0..size-1 */
        virtual RESULT moveService(eServiceReference &ref, int pos)=0;
+               /* set name of list, for bouquets this is the visible bouquet name */
+       virtual RESULT setListName(const std::string &name)=0;
 };
 
 TEMPLATE_TYPEDEF(ePtr<iMutableServiceList>, iMutableServiceListPtr);
 };
 
 TEMPLATE_TYPEDEF(ePtr<iMutableServiceList>, iMutableServiceListPtr);
@@ -454,8 +459,9 @@ class iListableService: public iObject
 #endif
 public:
                /* legacy interface: get a list */
 #endif
 public:
                /* legacy interface: get a list */
-       virtual RESULT getContent(std::list<eServiceReference> &list)=0;
-       
+       virtual RESULT getContent(std::list<eServiceReference> &list, bool sorted=false)=0;
+       virtual RESULT getContent(PyObject *list, bool sorted=false)=0;
+
                /* new, shiny interface: streaming. */
        virtual SWIG_VOID(RESULT) getNext(eServiceReference &SWIG_OUTPUT)=0;
        
                /* new, shiny interface: streaming. */
        virtual SWIG_VOID(RESULT) getNext(eServiceReference &SWIG_OUTPUT)=0;
        
index 61221ecb7ac39de62cd687a376175a67363612be..827b7f362702ec89f734852ded841dd453c0ad4b 100644 (file)
@@ -13,6 +13,7 @@
 #include <lib/service/servicedvbrecord.h>
 #include <lib/dvb/metaparser.h>
 #include <lib/dvb/tstools.h>
 #include <lib/service/servicedvbrecord.h>
 #include <lib/dvb/metaparser.h>
 #include <lib/dvb/tstools.h>
+#include <lib/python/python.h>
 
 class eStaticServiceDVBInformation: public iStaticServiceInformation
 {
 
 class eStaticServiceDVBInformation: public iStaticServiceInformation
 {
@@ -305,7 +306,32 @@ RESULT eDVBServiceList::startQuery()
        return 0;
 }
 
        return 0;
 }
 
-RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list)
+RESULT eDVBServiceList::getContent(PyObject *list, bool sorted)
+{
+       eServiceReferenceDVB ref;
+
+       if (!m_query || !list || !PyList_Check(list))
+               return -1;
+
+       std::list<eServiceReferenceDVB> tmplist;
+
+       while (!m_query->getNextResult(ref))
+               tmplist.push_back(ref);
+
+       if (sorted)
+               tmplist.sort(iListableServiceCompare(this));
+
+       for (std::list<eServiceReferenceDVB>::iterator it(tmplist.begin());
+               it != tmplist.end(); ++it)
+       {
+               PyObject *refobj = New_eServiceReference(*it);
+               PyList_Append(list, refobj);
+               Py_DECREF(refobj);
+       }
+       return 0;
+}
+
+RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
 {
        eServiceReferenceDVB ref;
        
 {
        eServiceReferenceDVB ref;
        
@@ -314,6 +340,10 @@ RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list)
        
        while (!m_query->getNextResult(ref))
                list.push_back(ref);
        
        while (!m_query->getNextResult(ref))
                list.push_back(ref);
+
+       if (sorted)
+               list.sort(iListableServiceCompare(this));
+
        return 0;
 }
 
        return 0;
 }
 
@@ -379,6 +409,13 @@ RESULT eDVBServiceList::flushChanges()
        return m_bouquet->flushChanges();
 }
 
        return m_bouquet->flushChanges();
 }
 
+RESULT eDVBServiceList::setListName(const std::string &name)
+{
+       if (!m_bouquet)
+               return -1;
+       return m_bouquet->setListName(name);
+}
+
 RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
 {
        ePtr<eDVBService> service;
 RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
 {
        ePtr<eDVBService> service;
index 61baf6a2d270dd003d491e74cac1d34b011c1b4d..ba4f2fb52cedda4ca395e725986c747218ff84c5 100644 (file)
@@ -32,7 +32,8 @@ class eDVBServiceList: public iListableService, public iMutableServiceList
 DECLARE_REF(eDVBServiceList);
 public:
        virtual ~eDVBServiceList();
 DECLARE_REF(eDVBServiceList);
 public:
        virtual ~eDVBServiceList();
-       RESULT getContent(std::list<eServiceReference> &list);
+       RESULT getContent(std::list<eServiceReference> &list, bool sorted=false);
+       RESULT getContent(PyObject *list, bool sorted=false);
        RESULT getNext(eServiceReference &ptr);
        int compareLessEqual(const eServiceReference &a, const eServiceReference &b);
        
        RESULT getNext(eServiceReference &ptr);
        int compareLessEqual(const eServiceReference &a, const eServiceReference &b);
        
@@ -41,6 +42,7 @@ public:
        RESULT addService(eServiceReference &ref);
        RESULT removeService(eServiceReference &ref);
        RESULT moveService(eServiceReference &ref, int pos);
        RESULT addService(eServiceReference &ref);
        RESULT removeService(eServiceReference &ref);
        RESULT moveService(eServiceReference &ref, int pos);
+       RESULT setListName(const std::string &name);
 private:
        RESULT startQuery();
        eServiceReference m_parent;
 private:
        RESULT startQuery();
        eServiceReference m_parent;
index a22b88d33f5785a8a94259eceaa6cec8375120ef..8254e63b672ee732ec523562e62ccd9b906cc99d 100644 (file)
@@ -96,7 +96,7 @@ eServiceFS::~eServiceFS()
 {
 }
 
 {
 }
 
-RESULT eServiceFS::getContent(std::list<eServiceReference> &list)
+RESULT eServiceFS::getContent(std::list<eServiceReference> &list, bool sorted)
 {
        DIR *d=opendir(path.c_str());
        if (!d)
 {
        DIR *d=opendir(path.c_str());
        if (!d)
@@ -141,6 +141,33 @@ RESULT eServiceFS::getContent(std::list<eServiceReference> &list)
                }
        }
        closedir(d);
                }
        }
        closedir(d);
+
+       if (sorted)
+               list.sort(iListableServiceCompare(this));
+
+       return 0;
+}
+
+RESULT eServiceFS::getContent(PyObject *list, bool sorted)
+{
+       if (!list || !PyList_Check(list))
+               return -1;
+
+       std::list<eServiceReference> tmplist;
+
+       getContent(tmplist, sorted);
+
+       if (sorted)
+               tmplist.sort(iListableServiceCompare(this));
+
+       for (std::list<eServiceReference>::iterator it(tmplist.begin());
+               it != tmplist.end(); ++it)
+       {
+               PyObject *refobj = New_eServiceReference(*it);
+               PyList_Append(list, refobj);
+               Py_DECREF(refobj);
+       }
+
        return 0;
 }
 
        return 0;
 }
 
index 46e8b890df61c1deeb4fac81158cbb3f7c03ccce..4257f2acb578ede214398d4b81e0cfea6045bca2 100644 (file)
@@ -34,7 +34,8 @@ private:
 public:
        virtual ~eServiceFS();
        
 public:
        virtual ~eServiceFS();
        
-       RESULT getContent(std::list<eServiceReference> &list);
+       RESULT getContent(std::list<eServiceReference> &list, bool sorted=false);
+       RESULT getContent(PyObject *list, bool sorted=false);
        RESULT getNext(eServiceReference &ptr);
        int compareLessEqual(const eServiceReference &, const eServiceReference &);
        RESULT startEdit(ePtr<iMutableServiceList> &);
        RESULT getNext(eServiceReference &ptr);
        int compareLessEqual(const eServiceReference &, const eServiceReference &);
        RESULT startEdit(ePtr<iMutableServiceList> &);