From: Andreas Monzner Date: Thu, 20 Jul 2006 18:17:12 +0000 (+0000) Subject: add support for markers in bouquets X-Git-Tag: 2.6.0~3145 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/b32851030de5d3706883afa87598cba8a8226f5d add support for markers in bouquets < > are usable to jump from marker to marker --- diff --git a/data/keymap.xml b/data/keymap.xml index bf5e4244..0a10b532 100644 --- a/data/keymap.xml +++ b/data/keymap.xml @@ -259,6 +259,8 @@ + + diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index eb0721b6..eb62f1fb 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -12,13 +12,19 @@ DEFINE_REF(eDVBService); -RESULT eBouquet::addService(const eServiceReference &ref) +RESULT eBouquet::addService(const eServiceReference &ref, eServiceReference before) { list::iterator it = std::find(m_services.begin(), m_services.end(), ref); if ( it != m_services.end() ) return -1; - m_services.push_back(ref); + if (before.valid()) + { + it = std::find(m_services.begin(), m_services.end(), before); + m_services.insert(it, ref); + } + else + m_services.push_back(ref); return 0; } diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index 5c427e7a..46d3e5d6 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -34,7 +34,7 @@ struct eBouquet list m_services; // the following five methods are implemented in db.cpp RESULT flushChanges(); - RESULT addService(const eServiceReference &); + RESULT addService(const eServiceReference &, eServiceReference before=eServiceReference()); RESULT removeService(const eServiceReference &); RESULT moveService(const eServiceReference &, unsigned int); RESULT setListName(const std::string &name); diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 8525ade3..d255b8e0 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -19,6 +19,10 @@ class ServiceList(HTMLComponent, GUIComponent): if pic: self.l.setPixmap(self.l.picFolder, pic) + pic = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "marker-fs8.png")) + if pic: + self.l.setPixmap(self.l.picMarker, pic) + pic = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "ico_dvb_s-fs8.png")) if pic: self.l.setPixmap(self.l.picDVB_S, pic) @@ -66,6 +70,14 @@ class ServiceList(HTMLComponent, GUIComponent): self.instance.moveSelectionTo(index) print "Moving to character " + str(char) + def moveToNextMarker(self): + idx = self.l.getNextMarkerPos() + self.instance.moveSelectionTo(idx) + + def moveToPrevMarker(self): + idx = self.l.getPrevMarkerPos() + self.instance.moveSelectionTo(idx) + def moveToIndex(self, index): self.instance.moveSelectionTo(index) @@ -107,8 +119,11 @@ class ServiceList(HTMLComponent, GUIComponent): if not justSet: self.l.sort() - def addService(self, service): - self.l.addService(service) + def removeCurrent(self): + self.l.removeCurrent() + + def addService(self, service, beforeCurrent=False): + self.l.addService(service, beforeCurrent) def finishFill(self): self.l.FillFinished() diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index 84e99516..90c12a5d 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -86,18 +86,17 @@ class ChannelContextMenu(Screen): if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1: menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags)) if inBouquet: - menu.append((_("remove service"), self.removeCurrentService)) + menu.append((_("remove entry"), self.removeCurrentService)) if current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1: menu.append((_("remove new found flag"), self.removeNewFoundFlag)) - - if haveBouquets: - menu.append((_("add bouquet..."), self.showBouquetInputBox)) - if inBouquetRootList: - menu.append((_("remove bouquet"), self.removeBouquet)) + else: + menu.append((_("add bouquet"), self.showBouquetInputBox)) + menu.append((_("remove entry"), self.removeBouquet)) if inBouquet: # current list is editable? if not csel.bouquet_mark_edit: if not csel.movemode: + menu.append((_("add marker"), self.showMarkerInputBox)) menu.append((_("enable move mode"), self.toggleMoveMode)) if not inBouquetRootList: if haveBouquets: @@ -128,7 +127,8 @@ class ChannelContextMenu(Screen): def bouquetInputCallback(self, bouquet): if bouquet is not None: - self.csel.addBouquet(bouquet, None, True) + self.csel.addBouquet(bouquet, None) + self.close() def addServiceToBouquetSelected(self): bouquets = self.csel.getBouquetList() @@ -156,6 +156,14 @@ class ChannelContextMenu(Screen): self.csel.removeBouquet() self.close() + def showMarkerInputBox(self): + self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT) + + def markerInputCallback(self, marker): + if marker is not None: + self.csel.addMarker(marker) + self.close() + def addCurrentServiceToBouquet(self, dest): self.csel.addCurrentServiceToBouquet(dest) if self.bsel is not None: @@ -263,7 +271,25 @@ class ChannelSelectionEdit: name += '_' return name - def addBouquet(self, bName, services, refresh=False): + def addMarker(self, name): + current = self.servicelist.getCurrent() + mutableList = self.getMutableList() + cnt = 0 + while mutableList: + str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name) + ref = eServiceReference(str) + if current and current.valid(): + if not mutableList.addService(ref, current): + self.servicelist.addService(ref, True) + mutableList.flushChanges() + break + elif not mutableList.addService(ref): + self.servicelist.addService(ref, True) + mutableList.flushChanges() + break + cnt+=1 + + def addBouquet(self, bName, services): serviceHandler = eServiceCenter.getInstance() mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit() if mutableBouquetList: @@ -285,9 +311,11 @@ class ChannelSelectionEdit: for service in services: if mutableBouquet.addService(service): print "add", service.toString(), "to new bouquet failed" + else: + current = self.servicelist.getCurrent() + if current and current.toString() == self.bouquet_rootstr: + self.servicelist.addService(service, True) mutableBouquet.flushChanges() - if refresh: - self.setRoot(self.getRoot()) else: print "get mutable list for new created bouquet failed" else: @@ -316,7 +344,6 @@ class ChannelSelectionEdit: remove(filename) except OSError: print "error during remove of", filename - eDVBDB.getInstance().reloadBouquets() # multiple marked entry stuff ( edit mode, later multiepg selection ) def startMarkedEdit(self): @@ -384,7 +411,7 @@ class ChannelSelectionEdit: if not mutableList.removeService(ref): self.bouquetNumOffsetCache = { } mutableList.flushChanges() #FIXME dont flush on each single removed service - self.setRoot(self.getRoot()) + self.servicelist.removeCurrent() def addCurrentServiceToBouquet(self, dest): mutableList = self.getMutableList(dest) @@ -472,6 +499,8 @@ class ChannelSelectionBase(Screen): "showSatellites": self.showSatellites, "nextBouquet": self.nextBouquet, "prevBouquet": self.prevBouquet, + "nextMarker": self.nextMarker, + "prevMarker": self.prevMarker, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, @@ -834,6 +863,12 @@ class ChannelSelectionBase(Screen): else: self.showAllServices() + def nextMarker(self): + self.servicelist.moveToNextMarker() + + def prevMarker(self): + self.servicelist.moveToPrevMarker() + HISTORYSIZE = 20 #config for lastservice @@ -930,7 +965,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect self.enterPath(ref) elif self.bouquet_mark_edit: self.doMark() - else: + elif not (ref.flags & 64): # no marker self.zap() self.close(ref) @@ -1156,7 +1191,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS self.enterPath(ref) elif self.bouquet_mark_edit: self.doMark() - else: + elif not (ref.flags & 64): # no marker playingref = self.session.nav.getCurrentlyPlayingServiceReference() if playingref is None or playingref != ref: self.session.nav.playService(ref) @@ -1194,7 +1229,7 @@ class SimpleChannelSelection(ChannelSelectionBase): ref = self.getCurrentSelection() if (ref.flags & 7) == 7: self.enterPath(ref) - else: + elif not (ref.flags & 64): ref = self.getCurrentSelection() self.close(ref) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 4f0e76b1..4c06661a 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -299,16 +299,39 @@ class InfoBarChannelSelection: self.session.execDialog(self.servicelist) def zapUp(self): - if currentConfigSelectionElement(config.usage.quickzap_bouquet_change) == "yes": - if self.servicelist.inBouquet() and self.servicelist.atBegin(): - self.servicelist.prevBouquet() - self.servicelist.moveUp() + if self.servicelist.inBouquet(): + prev = self.servicelist.getCurrentSelection() + if prev: + prev = prev.toString() + while True: + if currentConfigSelectionElement(config.usage.quickzap_bouquet_change) == "yes": + if self.servicelist.atBegin(): + self.servicelist.prevBouquet() + self.servicelist.moveUp() + cur = self.servicelist.getCurrentSelection() + if not cur or (not (cur.flags & 64)) or cur.toString() == prev: + break + else: + self.servicelist.moveUp() self.servicelist.zap() self.doShow() def zapDown(self): - if currentConfigSelectionElement(config.usage.quickzap_bouquet_change) == "yes" and self.servicelist.inBouquet() and self.servicelist.atEnd(): - self.servicelist.nextBouquet() + if self.servicelist.inBouquet(): + prev = self.servicelist.getCurrentSelection() + if prev: + prev = prev.toString() + while True: + if currentConfigSelectionElement(config.usage.quickzap_bouquet_change) == "yes": + if self.servicelist.atEnd(): + self.servicelist.nextBouquet() + else: + self.servicelist.moveDown() + else: + self.servicelist.moveDown() + cur = self.servicelist.getCurrentSelection() + if not cur or (not (cur.flags & 64)) or cur.toString() == prev: + break else: self.servicelist.moveDown() self.servicelist.zap() diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 7dba7321..2c395a9c 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -38,7 +38,8 @@ public: flagDirectory=isDirectory|mustDescent|canDescent, shouldSort=8, // should be ASCII-sorted according to service_name. great for directories. hasSortKey=16, // has a sort key in data[3]. not having a sort key implies 0. - sort1=32 // sort key is 1 instead of 0 + sort1=32, // sort key is 1 instead of 0 + isMarker=64 // Marker }; int flags; // flags will NOT be compared. @@ -540,7 +541,7 @@ public: /* flush changes */ virtual RESULT flushChanges()=0; /* adds a service to a list */ - virtual RESULT addService(eServiceReference &ref)=0; + virtual RESULT addService(eServiceReference &ref, eServiceReference before=eServiceReference())=0; /* removes a service from a list */ virtual RESULT removeService(eServiceReference &ref)=0; /* moves a service in a list, only if list suppports a specific sort method. */ diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 284776fd..33afaffe 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -5,9 +5,29 @@ #include #include -void eListboxServiceContent::addService(const eServiceReference &service) +void eListboxServiceContent::addService(const eServiceReference &service, bool beforeCurrent) { - m_list.push_back(service); + if (beforeCurrent && m_size) + { + m_list.insert(m_cursor, service); + ++m_size; + --m_cursor; + } + else + m_list.push_back(service); +} + +void eListboxServiceContent::removeCurrent() +{ + if (m_size && m_listbox) + { + if (m_cursor_number == m_size-1) + m_list.erase(m_cursor--); + else + m_list.erase(m_cursor++); + --m_size; + m_listbox->entryRemoved(m_cursor_number); + } } void eListboxServiceContent::FillFinished() @@ -87,6 +107,38 @@ int eListboxServiceContent::getNextBeginningWithChar(char c) return 0; } +int eListboxServiceContent::getPrevMarkerPos() +{ + if (!m_listbox) + return 0; + list::iterator i(m_cursor); + int index = m_cursor_number; + while (index) + { + --i; + --index; + if (i->flags & eServiceReference::isMarker) + break; + } + return index; +} + +int eListboxServiceContent::getNextMarkerPos() +{ + if (!m_listbox) + return 0; + list::iterator i(m_cursor); + int index = m_cursor_number; + while (index < (m_size-1)) + { + ++i; + ++index; + if (i->flags & eServiceReference::isMarker) + break; + } + return index; +} + void eListboxServiceContent::initMarked() { m_marked.clear(); @@ -377,7 +429,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (m_is_playable_ignore.valid() && service_info && !service_info->isPlayable(*m_cursor, m_is_playable_ignore)) painter.setForegroundColor(gRGB(0xbbbbbb)); - int xoffset=0; // used as offset when painting the folder symbol + int xoffset=0; // used as offset when painting the folder/marker symbol for (int e = 0; e < celElements; ++e) { @@ -394,8 +446,21 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { case celServiceNumber: { + if (m_cursor->flags & eServiceReference::isMarker) + continue; char bla[10]; - sprintf(bla, "%d", m_numberoffset + m_cursor_number + 1); + /* how we can do this better? :) */ + int markers_before=0; + { + list::iterator tmp=m_cursor; + while(tmp != m_list.begin()) + { + --tmp; + if (tmp->flags & eServiceReference::isMarker) + ++markers_before; + } + } + sprintf(bla, "%d", m_numberoffset + m_cursor_number + 1 - markers_before); text = bla; flags|=gPainter::RT_HALIGN_RIGHT; break; @@ -455,17 +520,23 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.renderPara(para, offset+ePoint(xoffs, yoffs)); } - else if (e == celServiceTypePixmap || e == celFolderPixmap) + else if (e == celServiceTypePixmap || e == celFolderPixmap || e == celMarkerPixmap) { int orbpos = m_cursor->getUnsignedData(4) >> 16; ePtr &pixmap = (e == celFolderPixmap) ? m_pixmaps[picFolder] : + (e == celMarkerPixmap) ? m_pixmaps[picMarker] : (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; if (pixmap) { eSize pixmap_size = pixmap->size(); - eRect area = m_element_position[e == celFolderPixmap ? celServiceName : celServiceInfo]; + int p = celServiceInfo; + if (e == celFolderPixmap) + p = celServiceName; + else if (e == celMarkerPixmap) + p = celServiceNumber; + eRect area = m_element_position[p]; int correction = (area.height() - pixmap_size.height()) / 2; if (m_cursor->flags & eServiceReference::flagDirectory) @@ -474,6 +545,11 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const continue; xoffset = pixmap_size.width() + 8; } + else if (m_cursor->flags & eServiceReference::isMarker) + { + if (e != celMarkerPixmap) + continue; + } else { if (e != celServiceTypePixmap) diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index d26ee545..59d4d920 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -11,7 +11,8 @@ class eListboxServiceContent: public virtual iListboxContent public: eListboxServiceContent(); - void addService(const eServiceReference &ref); + void addService(const eServiceReference &ref, bool beforeCurrent=false); + void removeCurrent(); void FillFinished(); void setIgnoreService( const eServiceReference &service ); @@ -19,7 +20,9 @@ public: void getCurrent(eServiceReference &ref); int getNextBeginningWithChar(char c); - + int getPrevMarkerPos(); + int getNextMarkerPos(); + /* support for marked services */ void initMarked(); void addMarked(const eServiceReference &ref); @@ -43,6 +46,7 @@ public: /* only in complex mode: */ enum { celServiceNumber, + celMarkerPixmap, celFolderPixmap, celServiceName, celServiceTypePixmap, @@ -55,6 +59,7 @@ public: picDVB_T, picDVB_C, picFolder, + picMarker, picElements }; diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 10de6213..d789da69 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -506,11 +506,11 @@ RESULT eDVBServiceList::startEdit(ePtr &res) return -1; } -RESULT eDVBServiceList::addService(eServiceReference &ref) +RESULT eDVBServiceList::addService(eServiceReference &ref, eServiceReference before) { if (!m_bouquet) return -1; - return m_bouquet->addService(ref); + return m_bouquet->addService(ref, before); } RESULT eDVBServiceList::removeService(eServiceReference &ref) diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h index 8026d655..5d3d0085 100644 --- a/lib/service/servicedvb.h +++ b/lib/service/servicedvb.h @@ -41,7 +41,7 @@ public: RESULT startEdit(ePtr &); RESULT flushChanges(); - RESULT addService(eServiceReference &ref); + RESULT addService(eServiceReference &ref, eServiceReference before); RESULT removeService(eServiceReference &ref); RESULT moveService(eServiceReference &ref, int pos); RESULT setListName(const std::string &name);