new E2-Plugin: PiPServiceRelation
[enigma2-plugins.git] / pipservicerelation / src / plugin.py
1 # -*- coding: utf-8 -*-
2 #
3 #  PipServiceRelation E2
4 #
5 #  Coded by Dr.Best (c) 2011
6 #  Support: www.dreambox-tools.info
7 #
8 #  This plugin is licensed under the Creative Commons 
9 #  Attribution-NonCommercial-ShareAlike 3.0 Unported 
10 #  License. To view a copy of this license, visit
11 #  http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
12 #  Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
13 #
14 #  Alternatively, this plugin may be distributed and executed on hardware which
15 #  is licensed by Dream Multimedia GmbH.
16
17 #  This plugin is NOT free software. It is open source, you are allowed to
18 #  modify it (if you keep the license), but it may not be commercially 
19 #  distributed other than under the conditions noted above.
20 #
21 from Plugins.Plugin import PluginDescriptor
22 from Screens.PictureInPicture import PictureInPicture
23 from Screens.Screen import Screen
24 from Screens.MessageBox import MessageBox
25 from Screens.ChannelSelection import SimpleChannelSelection
26 from enigma import eServiceCenter, getBestPlayableServiceReference, eServiceReference, eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_VALIGN_CENTER
27 from Components.MenuList import MenuList
28 from Components.Sources.StaticText import StaticText
29 from Components.ActionMap import ActionMap
30 from ServiceReference import ServiceReference
31 from Tools.BoundFunction import boundFunction
32 from Components.ConfigList import ConfigListScreen
33 from Components.config import getConfigListEntry, config, ConfigDirectory, NoSave
34
35 from os import path as os_path
36 from pickle import load as pickle_load, dump as pickle_dump
37 from enigma import eEnv
38
39 basePictureInPicture__init__ = None
40 CONFIG_FILE = eEnv.resolve('${libdir}/enigma2/python/Plugins/SystemPlugins/PiPServiceRelation/psr_config')
41
42 def getRelationDict():
43         if os_path.exists(CONFIG_FILE):
44                 pkl_file = open(CONFIG_FILE, 'rb')
45                 if pkl_file:
46                         volumedict = pickle_load(pkl_file)
47                         pkl_file.close()
48                         return volumedict
49         return {}
50
51 def saveRelationDict(dict):
52         pkl_file = open(CONFIG_FILE, 'wb')
53         if pkl_file:
54                 pickle_dump(dict, pkl_file)
55                 pkl_file.close()
56
57 def autostart_PictureInPicture(session, **kwargs):
58         init_pipservicerelation()
59
60 def setup(session,**kwargs):
61         session.open(PipServiceRelationSetup)
62
63
64 class PipServiceRelationSetup(Screen):
65         skin = """
66                 <screen position="center,center" size="655,400">
67                         <widget render="Label" source="name" position="5,0" size="320,50" font="Regular;20" halign="left"/>
68                         <widget render="Label" source="relationname" position="330,0" size="320,50" font="Regular;20" halign="left"/>
69                         <widget name="entrylist" position="0,50" size="655,300" scrollbarMode="showOnDemand"/>
70                         <widget render="Label" source="key_red" position="0,350" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
71                         <widget source="key_green" render="Label" position="140,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
72                         <widget render="Label" source="key_yellow" position="280,350" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="yellow" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
73                         <widget render="Label" source="key_blue" position="420,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
74                         <ePixmap position="0,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
75                         <ePixmap position="140,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
76                         <ePixmap position="280,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
77                         <ePixmap position="420,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
78                 </screen>"""
79
80         def __init__(self, session):
81                 Screen.__init__(self, session)
82                 self.title = _("PipServiceRelation - Config")
83                 self["name"] = StaticText(_("Service"))
84                 self["relationname"] = StaticText(_("Related PiP Service"))
85                 self["key_red"] = StaticText(_("Delete"))
86                 self["key_green"] = StaticText(_("Close"))
87                 self["key_yellow"] = StaticText(_("Add"))
88                 self["key_blue"] = StaticText(_("Edit"))
89                 self["entrylist"] = PipServiceRelationEntryList([])
90                 self["actions"] = ActionMap(["WizardActions","MenuActions","ShortcutActions"],
91                         {
92                          "ok"   :       self.keyBlue,
93                          "back" :       self.keyClose,
94                          "red"  :       self.keyDelete,
95                          "green":       self.keyClose,
96                          "yellow":      self.keyYellow,
97                          "blue":        self.keyBlue,
98                          }, -1)
99                 self["entrylist"].setConfig(getRelationDict())
100                 self.updateList()
101
102         def updateList(self):
103                 self["entrylist"].buildList()
104
105         def keyClose(self):
106                 self.close()
107
108         def keyBlue(self):
109                 try:sel = self["entrylist"].l.getCurrentSelection()[0]
110                 except: sel = None
111                 if sel is None:
112                         return
113                 self.session.openWithCallback(self.updateList,PipServiceRelationEntryConfigScreen,sel, self["entrylist"].configPSR)
114
115         def keyYellow(self):
116                 self.session.openWithCallback(self.updateList,PipServiceRelationEntryConfigScreen,None, self["entrylist"].configPSR)
117
118         def keyDelete(self):
119                 try:sel = self["entrylist"].l.getCurrentSelection()[0]
120                 except: sel = None
121                 if sel is None:
122                         return
123                 self.session.openWithCallback(self.deleteConfirm, MessageBox, _("Do you really want to delete this entry?"))
124
125         def deleteConfirm(self, result):
126                 if not result:
127                         return
128                 sel = self["entrylist"].l.getCurrentSelection()[0]
129                 del self["entrylist"].configPSR[sel[0]]
130                 self.updateList()
131
132 class PipServiceRelationEntryList(MenuList):
133         def __init__(self, list, enableWrapAround = True):
134                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
135                 self.l.setFont(0, gFont("Regular", 20))
136                 self.l.setFont(1, gFont("Regular", 18))
137                 self.configPSR = None
138
139         def postWidgetCreate(self, instance):
140                 MenuList.postWidgetCreate(self, instance)
141                 instance.setItemHeight(20)
142
143         def getCurrentIndex(self):
144                 return self.instance.getCurrentIndex()
145                 
146         def setConfig(self, configPSR):
147                 self.configPSR = configPSR
148                 
149         def buildList(self):
150                 list = []
151                 for c in self.configPSR.items():
152                         res = [
153                                 c,
154                                 (eListboxPythonMultiContent.TYPE_TEXT, 5, 0, 320, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, ServiceReference(eServiceReference(c[0])).getServiceName()),
155                                 (eListboxPythonMultiContent.TYPE_TEXT, 330, 0,320, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, ServiceReference(eServiceReference(c[1])).getServiceName()),
156                         ]
157                         list.append(res)
158                 self.list = list
159                 self.l.setList(list)
160                 self.moveToIndex(0)
161
162
163 class PipServiceRelationEntryConfigScreen(ConfigListScreen, Screen):
164         skin = """
165                 <screen name="PipServiceRelationEntryConfigScreen" position="center,center" size="550,400">
166                         <widget name="config" position="20,10" size="520,330" scrollbarMode="showOnDemand" />
167                         <ePixmap position="0,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
168                         <ePixmap position="140,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
169                         <ePixmap position="280,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
170                         <ePixmap position="420,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
171
172                         <widget source="key_red" render="Label" position="0,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
173                         <widget source="key_green" render="Label" position="140,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
174                 </screen>"""
175
176         def __init__(self, session, entry, configPSR):  
177                 self.session = session
178                 Screen.__init__(self, session)
179                 self.title = _("PipServiceRelation - Entry Config")
180                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
181                 {
182                         "green": self.keySave,
183                         "red": self.keyCancel,
184                         "cancel": self.keyCancel,
185                         "ok": self.keySelect,
186                 }, -2)
187                 self["key_red"] = StaticText(_("Cancel"))
188                 self["key_green"] = StaticText(_("OK"))
189                 self.configPSR = configPSR
190                 self.entry = entry
191                 if entry is None:
192                         self.currentKey = None
193                         self.ref1 =  NoSave(ConfigDirectory(default = _("Press OK to select a service")))
194                         self.ref2 =  NoSave(ConfigDirectory(default = _("Press OK to select a related PiP service")))
195                 else:
196                         self.currentKey = entry[0]
197                         self.ref1 =  NoSave(ConfigDirectory(default = ServiceReference(eServiceReference(entry[0])).getServiceName()))
198                         self.ref2 =  NoSave(ConfigDirectory(default = ServiceReference(eServiceReference(entry[1])).getServiceName()))
199                 self.list = [ ]
200                 self.serviceref1 =  getConfigListEntry(_("Service"), self.ref1)
201                 self.serviceref2 =  getConfigListEntry(_("Related Pip Service"), self.ref2)
202                 self.list.append(self.serviceref1)
203                 self.list.append(self.serviceref2)
204                 ConfigListScreen.__init__(self, self.list, session)
205                 
206         def keySelect(self):
207                 cur = self["config"].getCurrent()
208                 if cur == self.serviceref1:
209                         index = 1
210                         descr = _("Channel Selection")
211                 else:
212                         index = 2
213                         if self.entry and self.entry[0]:
214                                 sname = ServiceReference(eServiceReference(self.entry[0])).getServiceName()
215                         else:
216                                 sname = ""
217                         descr = _("Related PiP service for %s") % sname
218                 self.session.openWithCallback(boundFunction(self.channelSelected,index), SimpleChannelSelection, descr)
219                         
220         def channelSelected(self, index, ref = None):
221                 if ref:
222                         if self.entry:
223                                 val1 = self.entry[0]
224                                 val2 = self.entry[1]
225                         else:
226                                 val1 = val2 = None
227                         if index == 1:
228                                 self.entry = (ref.toString(), val2)
229                                 self.ref1.value = ServiceReference(ref).getServiceName()
230                         else:
231                                 self.entry = (val1, ref.toString())
232                                 self.ref2.value = ServiceReference(ref).getServiceName()
233
234         def keySave(self):
235                 if self.entry and self.entry[0] and self.entry[1]:
236                         if self.currentKey is not None:
237                                 del self.configPSR[self.currentKey]
238                         self.configPSR[self.entry[0]] = self.entry[1]
239                         saveRelationDict(self.configPSR)
240                 self.close()
241
242         def keyCancel(self):
243                 ConfigListScreen.cancelConfirm(self, True)
244
245 def init_pipservicerelation():
246         global basePictureInPicture__init__, basePictureInPicture_playService
247         if basePictureInPicture__init__ is None:
248                 basePictureInPicture__init__ = PictureInPicture.__init__
249         PictureInPicture.__init__ = PictureInPicture__init__
250         PictureInPicture.playService = playService
251
252
253 def PictureInPicture__init__(self, session):
254         basePictureInPicture__init__(self, session)
255         self.pipServiceRelation = getRelationDict()
256
257 def playService(self, service):
258         current_service = service
259         n_service = self.pipServiceRelation.get(service.toString(),None)
260         if n_service is not None:
261                 service = eServiceReference(n_service)
262         if service and (service.flags & eServiceReference.isGroup):
263                 ref = getBestPlayableServiceReference(service, eServiceReference())
264         else:
265                 ref = service
266         if ref:
267                 self.pipservice = eServiceCenter.getInstance().play(ref)
268                 if self.pipservice and not self.pipservice.setTarget(1):
269                         self.pipservice.start()
270                         self.currentService = current_service
271                         return True
272                 else:
273                         self.pipservice = None
274         return False
275
276 def Plugins(**kwargs):
277         list = []
278         list.append(PluginDescriptor(name="Setup PiPServiceRelation", description=_("setup for PiPServiceRelation"), where = [PluginDescriptor.WHERE_PLUGINMENU], fnc=setup))
279         list.append(PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, fnc = autostart_PictureInPicture))
280         return list
281