Teletext: added summary screen id=3
[enigma2-plugins.git] / teletext / src / plugin.py
1 from __init__ import _debug , _log
2
3 from enigma import iServiceInformation, iPlayableService, eSocketNotifier, getDesktop, ePoint, eSize, eServiceReference, eVideoWidget, getDesktop, gRGB
4
5 from Screens.ChannelSelection import service_types_tv
6 from Screens.HelpMenu import HelpMenu
7 from Screens.MessageBox import MessageBox
8 from Screens.Screen import Screen
9 from Components.ActionMap import ActionMap, NumberActionMap
10 from Components.ConfigList import ConfigListScreen
11 from Components.Label import Label
12 from Components.MenuList import MenuList
13 from Components.Pixmap import Pixmap
14 from Components.ServiceEventTracker import ServiceEventTracker
15 from Components.config import config, configfile, getConfigListEntry, ConfigSubsection, ConfigOnOff, ConfigSlider, ConfigSelection, ConfigSequence
16 from GlobalActions import globalActionMap
17 from Plugins.Plugin import PluginDescriptor
18 from Plugins.SystemPlugins.Toolkit.NTIVirtualKeyBoard import NTIVirtualKeyBoard
19 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
20
21 import array
22 import socket
23 from struct import pack
24 from twisted.python.sendmsg import SCM_RIGHTS, send1msg
25
26 import NavigationInstance
27
28 from os import unlink
29 from select import POLLIN
30
31 from enigma import Teletext as TeletextInterface
32 from enigma import DISABLED, BILINEAR, ANISOTROPIC, SHARP, SHARPER
33
34 from ConfigParser import ConfigParser
35
36 PLUGIN_VERSION="20190312"
37
38 CMD_CTL_CACHE=1
39 CMD_SHOW_PAGE=2
40 CMD_PAGE_NEXT=3
41 CMD_PAGE_PREV=4
42 CMD_SUBP_NEXT=5
43 CMD_SUBP_PREV=6
44 CMD_COLKEY_RD=7
45 CMD_COLKEY_GN=8
46 CMD_COLKEY_YE=9
47 CMD_COLKEY_BL=10
48 CMD_CATCHPAGE=11
49 CMD_CONCEALED=12
50 CMD_SET_BRIGH=13
51 CMD_SET_CONTR=14
52 CMD_RQ_UPDATE=15
53 CMD_RZAP_PAGE=16
54 CMD_OPAQUE=17
55 CMD_TRANSPARENCY=18
56 CMD_FLOF=19
57 CMD_PAGEINPUT=20
58 CMD_EDGE_CUT=21
59 CMD_TEXTLEVEL=22
60 CMD_REGION=23
61 CMD_VERSION=24
62 CMD_CLOSE_DMN=99
63
64 SPLIT_MODE_PAT = "pat"
65 SPLIT_MODE_TAP = "tap"
66 SPLIT_MODE_TIP = "tip"
67 splittingModeList = [ (SPLIT_MODE_PAT, _("picture and teletext")), (SPLIT_MODE_TAP, _("teletext and picture")), (SPLIT_MODE_TIP, _("teletext in picture")) ]
68 textlevelModeList = [ ("0", "1.0"), ("1", "1.5"), ("2", "2.5"), ("3", "3.5") ]
69 regionList = [ ("0", _("Western and Central Europe")), ("8", _("Eastern Europe")), ("16", _("Western Europe and Turkey")), ("24", _("Central and Southeast Europe")), ("32", _("Cyrillic")), ("48", _("Turkish / Greek")), ("64", _("Arabic")), ("80", _("Hebrew / Arabic")) ]
70 filterList = [ ("%d"%DISABLED,_("Disabled")), ("%d"%BILINEAR,_("bilinear")), ("%d"%ANISOTROPIC,_("anisotropic")), ("%d"%SHARP,_("sharp")), ("%d"%SHARPER,_("sharper"))]
71
72 HELP_TEXT_POS          = _("Enter values (left, top, right, bottom) or press TEXT to move and resize the teletext graphically.")
73 HELP_TEXT_TIP_POS      = _("Enter values (left, top, right, bottom) or press TEXT to move and resize the teletext graphically.")
74 HELP_TEXT_SPLITTING    = _("Select splitting mode.")
75 HELP_TEXT_BRIGHTNESS   = _("Select brightness.")
76 HELP_TEXT_CONTRAST     = _("Select contrast.")
77 HELP_TEXT_TRANSPARENCY = _("Select transparency.")
78 HELP_TEXT_EDGE_CUT     = _("Display first and last row.")
79 HELP_TEXT_DEBUG        = _("Print debug messages to /tmp/dbttcp.log.")
80 HELP_TEXT_TEXTLEVEL    = _("Select teletext version to use.")
81 HELP_TEXT_REGION       = _("Select your region to use the proper font.")
82 HELP_TEXT_SCALE_FILTER = _("Select your favourite scale filter.")
83 HELP_TEXT_CACHING      = _("If caching is disabled, each teletext page will searched when you entered its number.")
84
85 dsk_size   = getDesktop(0).size()
86 dsk_width  = dsk_size.width()
87 dsk_height = dsk_size.height()
88
89 MIN_W = 400
90 MIN_H = 300
91
92 NAV_MODE_TEXT          = 0
93 NAV_MODE_SIZE_TEXT     = 1
94 NAV_MODE_SIZE_TIP_TEXT = 2
95
96 # i.d.R. bezeichnet man 90% der vollen Aufloesung als "Title-Safe-Area" --> Default
97
98 DEF_TOP    = dsk_height / 20
99 DEF_LEFT   = dsk_width / 20
100 DEF_RIGHT  = dsk_width - DEF_LEFT
101 DEF_BOTTOM = dsk_height - DEF_TOP
102
103 config.plugins.TeleText = ConfigSubsection()
104 config.plugins.TeleText.scale_filter = ConfigSelection(filterList, default="%d"%BILINEAR)
105 config.plugins.TeleText.scale_filter_zoom = ConfigSelection(filterList, default="%d"%BILINEAR)
106 config.plugins.TeleText.brightness   = ConfigSlider(default=8,  increment=1, limits=(0,15))
107 config.plugins.TeleText.contrast     = ConfigSlider(default=12, increment=1, limits=(0,15))
108 config.plugins.TeleText.transparency = ConfigSlider(default=8,  increment=1, limits=(0,15))
109 config.plugins.TeleText.edge_cut = ConfigOnOff(default=False)
110 config.plugins.TeleText.splitting_mode = ConfigSelection(splittingModeList, default=SPLIT_MODE_PAT)
111 config.plugins.TeleText.textlevel      = ConfigSelection(textlevelModeList, default="2")
112 config.plugins.TeleText.region   = ConfigSelection(regionList, default="16")
113 config.plugins.TeleText.debug    = ConfigOnOff(default=False)
114 config.plugins.TeleText.pos      = ConfigSequence(default=[DEF_LEFT, DEF_TOP, DEF_RIGHT, DEF_BOTTOM], seperator = ",", limits = [(0,dsk_width>>3),(0,dsk_height>>3),(dsk_width-(dsk_width>>3),dsk_width),(dsk_height-(dsk_height>>3),dsk_height)])
115 config.plugins.TeleText.tip_pos  = ConfigSequence(default=[(dsk_width>>1)+(dsk_width>>2), (dsk_height>>1)+(dsk_height>>2), dsk_width, dsk_height], seperator = ",", limits = [(0,dsk_width-MIN_W),(0,dsk_height-MIN_H),(MIN_W,dsk_width),(MIN_H,dsk_height)])
116 # state
117 config.plugins.TeleText.textOnly = ConfigOnOff(default=True)
118 config.plugins.TeleText.opaque   = ConfigOnOff(default=False)
119 config.plugins.TeleText.background_caching = ConfigOnOff(default=True)
120
121 # global functions
122
123 def log(message):
124   _log(message)
125   if config.plugins.TeleText.debug.value:
126     _debug(message)
127
128 # ----------------------------------------
129
130 class TeleText(Screen):
131
132   pageInput   = 0
133   catchPage   = False
134   naviValue   = True
135   infoValue   = False
136   edgeValue   = False
137   opaqueValue = False
138   nav_mode    = NAV_MODE_TEXT
139   zoom        = TeletextInterface.MODE_FULL
140   filter_mode = BILINEAR
141   pid_list = []
142   pid_index = 0
143   pid_count = 0
144   demux  = -1
145   txtpid = -1
146   txtpid_origin = -1
147   cur_page = "100-00/00"
148   daemonVersion = "0.0"
149   favorites = None
150   read_data = False
151
152   onChangedEntry = [ ]
153
154   def __init__(self, session):
155     TeleText.skin = """<screen position="0,0" size="%d,%d" title="TeleText" backgroundColor="#FF000000" flags="wfNoBorder"/>""" % (dsk_width, dsk_height)
156     Screen.__init__(self, session)
157
158     self.__event_tracker = ServiceEventTracker(screen = self, eventmap={
159       iPlayableService.evStart : self.serviceStarted,
160       iPlayableService.evEnd : self.serviceStopped,
161       iPlayableService.evUpdatedInfo : self.serviceInfoChanged,
162     })
163
164     self["actions"] = NumberActionMap(["OkCancelActions", "TeleTextActions"],
165     {
166       "ok" : self.okPressed,
167       "cancel" : self.cancelPressed,
168       "1" : self.keyNumberGlobal,
169       "2" : self.keyNumberGlobal,
170       "3" : self.keyNumberGlobal,
171       "4" : self.keyNumberGlobal,
172       "5" : self.keyNumberGlobal,
173       "6" : self.keyNumberGlobal,
174       "7" : self.keyNumberGlobal,
175       "8" : self.keyNumberGlobal,
176       "9" : self.keyNumberGlobal,
177       "0" : self.keyNumberGlobal,
178       "prev":   self.prevPressed,
179       "next":   self.nextPressed,
180       "prev_long": self.prevLongPressed,
181       "next_long": self.nextLongPressed,
182       "red":    self.redPressed,
183       "green":  self.greenPressed,
184       "yellow": self.yellowPressed,
185       "blue":   self.bluePressed,
186       "right":  self.rightPressed,
187       "left":   self.leftPressed,
188       "down":   self.downPressed,
189       "up":     self.upPressed,
190       "info":   self.infoPressed,
191       "tv":     self.tvPressed,
192       "radio":  self.radioPressed,
193       "text":   self.textPressed,
194       "menu":   self.menuPressed,
195       "help":   self.helpPressed,
196       "video":  self.videoPressed,
197       "nextBouquet": self.nextBouquetPressed,
198       "prevBouquet": self.prevBouquetPressed,
199       "volUp":       self.volumeUpPressed,
200       "volDown":     self.volumeDownPressed
201     }, -1)
202     self["actions"].setEnabled(True)
203
204     self.helpList.append((self["actions"], "TeleTextActions", [("1", _("enter page number"))]))
205     self.helpList.append((self["actions"], "TeleTextActions", [("2", _("enter page number"))]))
206     self.helpList.append((self["actions"], "TeleTextActions", [("3", _("enter page number"))]))
207     self.helpList.append((self["actions"], "TeleTextActions", [("4", _("enter page number"))]))
208     self.helpList.append((self["actions"], "TeleTextActions", [("5", _("enter page number"))]))
209     self.helpList.append((self["actions"], "TeleTextActions", [("6", _("enter page number"))]))
210     self.helpList.append((self["actions"], "TeleTextActions", [("7", _("enter page number"))]))
211     self.helpList.append((self["actions"], "TeleTextActions", [("8", _("enter page number"))]))
212     self.helpList.append((self["actions"], "TeleTextActions", [("9", _("enter page number / page 100"))]))
213     self.helpList.append((self["actions"], "TeleTextActions", [("prev", _("prev channel / channel list"))]))
214     self.helpList.append((self["actions"], "TeleTextActions", [("0", _("enter page number / rezap"))]))
215     self.helpList.append((self["actions"], "TeleTextActions", [("next", _("next channel / channel list"))]))
216     self.helpList.append((self["actions"], "OkCancelActions", [("cancel", _("exit"))]))
217 #    self.helpList.append((self["actions"], "TeleTextActions", [("volUp",_("increase width"))]))
218 #    self.helpList.append((self["actions"], "TeleTextActions", [("volDown",_("decrease width"))]))
219     self.helpList.append((self["actions"], "TeleTextActions", [("nextBouquet",_("zoom / increase height"))]))
220     self.helpList.append((self["actions"], "TeleTextActions", [("prevBouquet",_("favorites / decrease height"))]))
221     self.helpList.append((self["actions"], "TeleTextActions", [("info", _("toggle info"))]))
222     self.helpList.append((self["actions"], "TeleTextActions", [("menu", _("teletext settings"))]))
223     self.helpList.append((self["actions"], "TeleTextActions", [("up", _("next page / catch page / move"))]))
224     self.helpList.append((self["actions"], "TeleTextActions", [("left", _("prev sub page / move"))]))
225     self.helpList.append((self["actions"], "OkCancelActions", [("ok", _("start page catching / select page"))]))
226     self.helpList.append((self["actions"], "TeleTextActions", [("right", _("next sub page / move"))]))
227     self.helpList.append((self["actions"], "TeleTextActions", [("down", _("prev page / catch page / move"))]))
228     self.helpList.append((self["actions"], "TeleTextActions", [("video", _("toggle flof/top"))]))
229     self.helpList.append((self["actions"], "TeleTextActions", [("red", _("red teletext link"))]))
230     self.helpList.append((self["actions"], "TeleTextActions", [("green", _("green teletext link"))]))
231     self.helpList.append((self["actions"], "TeleTextActions", [("yellow", _("yellow teletext link"))]))
232     self.helpList.append((self["actions"], "TeleTextActions", [("blue", _("blue teletext link"))]))
233     self.helpList.append((self["actions"], "TeleTextActions", [("tv", _("split screen"))]))
234     self.helpList.append((self["actions"], "TeleTextActions", [("radio", _("toggle transparency"))]))
235     self.helpList.append((self["actions"], "TeleTextActions", [("text", _("exit"))]))
236
237     self.inMenu = False
238     self.connected = False
239
240     self.favorites = TeleTextFavorites()
241
242     self.ttx = TeletextInterface()
243
244     self.onLayoutFinish.append(self.__layoutFinished)
245     self.onExecBegin.append(self.__execBegin)
246     self.onClose.append(self.__closed)
247
248     self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
249     self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
250     try:
251       unlink('/tmp/dbttcp.socket')
252     except:
253       pass
254     self.socket.bind('/tmp/dbttcp.socket')
255     self.listen_sn = eSocketNotifier(self.socket.fileno(), POLLIN)
256     self.listen_sn_conn = self.listen_sn.activated.connect(self.listen_data_avail)
257     self.socket.listen(1)
258
259   def socketSend(self, buf, fd = None):
260     log("send %s" % (buf))
261     try:
262       s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
263       s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
264       s.settimeout(5.0)
265       if config.plugins.TeleText.debug.value:
266         log("... connecting")
267       s.connect('/tmp/dbttcd.socket')
268     except socket.error, msg:
269       log("couldn't connect to /tmp/dbttcd.socket")
270       log(msg)
271       return
272
273     try:
274       msg_len = len(buf)
275       totalsent = 0
276       while totalsent < msg_len:
277         if config.plugins.TeleText.debug.value:
278           log("... sending")
279         if fd is not None and totalsent == 0:
280           sent = send1msg(s.fileno(), buf.tostring(), 0, [(socket.SOL_SOCKET, SCM_RIGHTS, pack("i", fd))])
281         else:
282           sent = s.send(buf[totalsent:])
283         if sent == 0:
284           raise RuntimeError("socket connection broken")
285         elif config.plugins.TeleText.debug.value:
286           log("    sent %s bytes" % sent)
287         totalsent = totalsent + sent
288       s.close()
289       s = None
290     except socket.error, msg:
291       log("couldn't send data to /tmp/dbttcd.socket")
292       log(msg)
293
294   def getDaemonVersion(self):
295     x = array.array('B')
296     x.append(CMD_VERSION)
297     self.socketSend(x)
298
299
300   def listen_data_avail(self, what):
301     conn, addr = self.socket.accept()
302     buf = conn.recv(8, socket.MSG_WAITALL)
303     x = array.array('H')
304     x.fromstring(buf)
305     if x[0] == 0:
306       self.catchPage = False
307     elif x[0] == 1:
308       self.ttx.update(0,0,492,250, self.zoom, self.filter_mode)
309       if x[1] == 2303:
310         x[1] = 0x0100
311       self.cur_page = "%s%s%s-%s%s/%s%s" % ((x[1]&0x0F00)>>8, (x[1]&0xF0)>>4, x[1]&0x0F, x[2]>>4, x[2]&0x0F, x[3]>>4, x[3]&0x0F)
312       for i in self.onChangedEntry:
313         i()
314     elif x[0] == 2:
315       self.daemonVersion = "%s.%s" % (x[1], x[2])
316       log("daemon version %s" % self.daemonVersion)
317     conn.close()
318
319   def __execBegin(self):
320     log("execBegin")
321
322     if not (config.plugins.TeleText.background_caching.value or self.inMenu):
323       self.checkServiceInfo(True)
324
325     self.updateLayout()
326
327     # send brightness, contrast and transparency...
328     self.sendSettings()
329
330     renderOffset = self.ttx.getRenderBufferOffset()
331     stride = self.ttx.getRenderBufferStride()
332     fd = self.ttx.getRenderBufferFD()
333
334     log("framebuffer offset is %08x stride is %08x" % (renderOffset, stride))
335     x = array.array('B', (CMD_RQ_UPDATE, 1, (renderOffset&0xFF000000)>>24, (renderOffset&0xFF0000)>>16, (renderOffset&0xFF00)>>8, renderOffset&0xFF, (stride&0xFF00) >> 8, stride&0xFF))
336     self.socketSend(x, fd)
337
338     # get daemon version
339     self.getDaemonVersion()
340
341   def __closed(self):
342     log("__closed")
343     self.pig.hide()
344     renderOffset = self.ttx.getRenderBufferOffset()
345     stride = self.ttx.getRenderBufferStride()
346     x = array.array('B', (CMD_RQ_UPDATE, 0, (renderOffset&0xFF000000)>>24, (renderOffset&0xFF0000)>>16, (renderOffset&0xFF00)>>8, renderOffset&0xFF, (stride&0xFF00) >> 8, stride&0xFF))
347     self.socketSend(x)
348
349     if not (config.plugins.TeleText.background_caching.value or self.inMenu):
350       self.stopCaching()
351
352   def __layoutFinished(self):
353     log("__layoutFinished")
354     desk = getDesktop(0)
355     self.pig = eVideoWidget(self.instance)
356     self.pig.setBackgroundColor(gRGB(0xFF000000))
357     self.pig.setDecoder(0)
358     self.pig.setFBSize(desk.size())
359     self.pig.hide()
360     self.ttx.show(self.instance)
361
362   def keyNumberGlobal(self, number):
363     if self.nav_mode != NAV_MODE_TEXT or self.catchPage:
364       return
365     log("%s pressed" % (number))
366     x = array.array('B')
367     if self.pageInput == 0:
368       if number == 0:
369         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
370           self.zoom = TeletextInterface.MODE_UPPER_HALF
371         x.append(CMD_RZAP_PAGE)
372       elif number == 9:
373         page = self.fav_list[self.fav_index]
374         if self.fav_index == len(self.fav_list)-1:
375           self.fav_index = 0
376         else:
377           self.fav_index = self.fav_index + 1
378         x.fromlist([CMD_SHOW_PAGE, page/100, (((page%100)/10)<<4) + (page%10), 0])
379       else:
380         x.fromlist([CMD_PAGEINPUT, number])
381         self.pageInput = (self.pageInput + 1) % 3
382     else:
383       x.fromlist([CMD_PAGEINPUT, number])
384       self.pageInput = (self.pageInput + 1) % 3
385     self.socketSend(x)
386
387   def upPressed(self):
388     if self.nav_mode == NAV_MODE_TEXT:
389       if self.pageInput != 0:
390         return
391       log("up pressed")
392       if self.catchPage:
393         x = array.array('B', (CMD_CATCHPAGE, 2, 2))
394       else:
395         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
396           self.zoom = TeletextInterface.MODE_UPPER_HALF
397         x = array.array('B')
398         x.append(CMD_PAGE_NEXT)
399       self.socketSend(x)
400     else:
401       if self.nav_pos[1] > 0 and self.nav_pos[3] > self.nav_config.limits[3][0]:
402         self.nav_pos[1] = self.nav_pos[1] - 1
403         self.nav_pos[3] = self.nav_pos[3] - 1
404       self.updateLayout()
405
406   def downPressed(self):
407     if self.nav_mode == NAV_MODE_TEXT:
408       if self.pageInput != 0:
409         return
410       log("down pressed")
411       if self.catchPage:
412         x = array.array('B', (CMD_CATCHPAGE, 2, 3))
413       else:
414         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
415           self.zoom = TeletextInterface.MODE_UPPER_HALF
416         x = array.array('B')
417         x.append(CMD_PAGE_PREV)
418       self.socketSend(x)
419     else:
420       if self.nav_pos[1] < self.nav_config.limits[1][1] and self.nav_pos[3] < dsk_height:
421         self.nav_pos[1] = self.nav_pos[1] + 1
422         self.nav_pos[3] = self.nav_pos[3] + 1
423         self.updateLayout()
424
425   def leftPressed(self):
426     if self.nav_mode == NAV_MODE_TEXT:
427       if self.pageInput != 0:
428         return
429       log("left pressed")
430       if self.catchPage:
431         x = array.array('B', (CMD_CATCHPAGE, 2, 0))
432       else:
433         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
434           self.zoom = TeletextInterface.MODE_UPPER_HALF
435         x = array.array('B')
436         x.append(CMD_SUBP_PREV)
437       self.socketSend(x)
438     else:
439       if self.nav_pos[0] > 0 and self.nav_pos[2] > self.nav_config.limits[2][0]:
440         self.nav_pos[0] = self.nav_pos[0] - 1
441         self.nav_pos[2] = self.nav_pos[2] - 1
442       self.updateLayout()
443
444   def rightPressed(self):
445     if self.nav_mode == NAV_MODE_TEXT:
446       if self.pageInput != 0:
447         return
448       log("right pressed")
449       if self.catchPage:
450         x = array.array('B', (CMD_CATCHPAGE, 2, 1))
451       else:
452         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
453           self.zoom = TeletextInterface.MODE_UPPER_HALF
454         x = array.array('B')
455         x.append(CMD_SUBP_NEXT)
456       self.socketSend(x)
457     else:
458       if self.nav_pos[0] < self.nav_config.limits[0][1] and self.nav_pos[2] < dsk_width:
459         self.nav_pos[0] = self.nav_pos[0] + 1
460         self.nav_pos[2] = self.nav_pos[2] + 1
461         self.updateLayout()
462
463   def nextBouquetPressed(self):
464     log("bouqet+ pressed")
465     if self.nav_mode == NAV_MODE_TEXT:
466       if self.catchPage or self.pageInput != 0:
467         return
468       # zoom teletext
469       if self.zoom == TeletextInterface.MODE_UPPER_HALF:
470         self.zoom = TeletextInterface.MODE_LOWER_HALF
471       elif self.zoom == TeletextInterface.MODE_LOWER_HALF:
472         self.zoom = TeletextInterface.MODE_FULL
473       else:
474         self.zoom = TeletextInterface.MODE_UPPER_HALF
475
476       if self.zoom:
477         self.filter_mode = int(config.plugins.TeleText.scale_filter_zoom.value)
478       else:
479         self.filter_mode = int(config.plugins.TeleText.scale_filter.value)
480     else:
481       # position setup
482       if self.nav_pos[3] < dsk_height:
483         self.nav_pos[3] = self.nav_pos[3] + 1
484       elif self.nav_pos[1] > 0:
485         self.nav_pos[1] = self.nav_pos[1] - 1
486     self.updateLayout()
487
488   def prevBouquetPressed(self):
489     log("bouqet- pressed")
490     if self.nav_mode == NAV_MODE_TEXT:
491       if self.catchPage or self.pageInput != 0:
492         return
493       # open favorites
494       if len(self.pid_list) > 0:
495         self.inMenu = True
496         self.session.openWithCallback(self.favoritesResult, TeleTextFavoritesMenu, parent = self, service = self.pid_list[self.pid_index], page = self.cur_page.split("-",1)[0], favorites = self.favorites)
497     else:
498       # position setup
499       if self.nav_pos[3] > (self.nav_pos[1] + MIN_H):
500         if self.nav_pos[3] > self.nav_config.limits[3][0]:
501           self.nav_pos[3] = self.nav_pos[3] - 1
502         elif self.nav_pos[1] < self.nav_config.limits[1][1]:
503           self.nav_pos[1] = self.nav_pos[1] + 1
504         self.updateLayout()
505
506   def volumeUpPressed(self):
507     if self.nav_mode == NAV_MODE_TEXT:
508       globalActionMap.action("TeleText", "volumeUp")
509       return
510     log("volume+ pressed")
511     if self.nav_pos[2] < dsk_width:
512       self.nav_pos[2] = self.nav_pos[2] + 1
513     elif self.nav_pos[0] > 0:
514       self.nav_pos[0] = self.nav_pos[0] - 1
515     self.updateLayout()
516
517   def volumeDownPressed(self):
518     if self.nav_mode == NAV_MODE_TEXT:
519       globalActionMap.action("TeleText", "volumeDown")
520       return
521     log("volume- pressed")
522     if self.nav_pos[2] > (self.nav_pos[0] + MIN_W):
523       if self.nav_pos[2] > self.nav_config.limits[2][0]:
524         self.nav_pos[2] = self.nav_pos[2] - 1
525       elif self.nav_pos[0] < self.nav_config.limits[0][1]:
526         self.nav_pos[0] = self.nav_pos[0] + 1
527     self.updateLayout()
528
529   def redPressed(self):
530     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
531       return
532     log("red pressed")
533     x = array.array('B')
534     x.append(CMD_COLKEY_RD)
535     self.socketSend(x)
536
537   def greenPressed(self):
538     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
539       return
540     log("green pressed")
541     x = array.array('B')
542     x.append(CMD_COLKEY_GN)
543     self.socketSend(x)
544
545   def yellowPressed(self):
546     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
547       return
548     log("yellow pressed")
549     x = array.array('B')
550     x.append(CMD_COLKEY_YE)
551     self.socketSend(x)
552
553   def bluePressed(self):
554     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
555       return
556     log("blue pressed")
557     x = array.array('B')
558     x.append(CMD_COLKEY_BL)
559     self.socketSend(x)
560
561   def infoPressed(self):
562     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
563       return
564     log("info pressed")
565     self.infoValue = not self.infoValue
566     for i in self.onChangedEntry:
567       i()
568     x = array.array('B')
569     x.append(CMD_CONCEALED)
570     self.socketSend(x)
571
572   def videoPressed(self):
573     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
574       return
575     log("video pressed")
576     self.naviValue = not self.naviValue
577     for i in self.onChangedEntry:
578       i()
579     x = array.array('B')
580     x.append(CMD_FLOF)
581     self.socketSend(x)
582
583   def tvPressed(self):
584     if self.nav_mode != NAV_MODE_TEXT:
585       return
586     log("tv pressed")
587     if config.plugins.TeleText.textOnly.value:
588       config.plugins.TeleText.textOnly.value = False
589     else:
590       config.plugins.TeleText.textOnly.value = True
591     config.plugins.TeleText.textOnly.save()
592     configfile.save()
593     self.updateLayout()
594
595   def radioPressed(self):
596     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
597       return
598     log("radio pressed")
599     if config.plugins.TeleText.opaque.value:
600       config.plugins.TeleText.opaque.value = False
601     else:
602       config.plugins.TeleText.opaque.value = True
603     config.plugins.TeleText.opaque.save()
604     configfile.save()
605     self.opaqueValue = config.plugins.TeleText.opaque.value
606     x = array.array('B')
607     x.append(CMD_OPAQUE)
608     self.socketSend(x)
609
610   def textPressed(self):
611     if self.nav_mode != NAV_MODE_TEXT or self.catchPage:
612       return
613     log("text pressed")
614     if self.pageInput != 0:
615       self.pageInput = 0
616       x = array.array('B')
617       x.fromlist([CMD_PAGEINPUT, 0x0a])
618       self.socketSend(x)
619     self.resetVideo()
620     self.__closed()
621     if self.txtpid != self.txtpid_origin:
622       self.txtpid = self.txtpid_origin
623       self.switchChannel(True)
624       self.readFavorites()
625     self.close()
626
627   def menuPressed(self):
628     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
629       return
630     log("menu pressed")
631     self.__closed()
632     self.resetVideo()
633     self.inMenu = True
634     self.session.openWithCallback(self.menuResult, TeleTextMenu, parent = self)
635
636   def menuResult(self, result):
637     self.inMenu = False
638     if result is None:
639       config.plugins.TeleText.pos.load()
640       config.plugins.TeleText.tip_pos.load()
641       self.updateLayout()
642       return
643
644     self.nav_text_only = config.plugins.TeleText.textOnly.value
645     self.nav_config   = result
646     self.nav_orig_pos = result.value
647     self.nav_pos      = result.value
648
649     if result == config.plugins.TeleText.pos:
650       self.nav_mode = NAV_MODE_SIZE_TEXT
651       config.plugins.TeleText.textOnly.value = True
652     elif result == config.plugins.TeleText.tip_pos:
653       self.nav_mode = NAV_MODE_SIZE_TIP_TEXT
654       config.plugins.TeleText.textOnly.value = False
655       config.plugins.TeleText.textOnly.value = SPLIT_MODE_TIP
656     self.updateLayout()
657
658   def favoritesResult(self, result):
659     # read favorites
660     self.readFavorites()
661
662     self.inMenu = False
663     self.updateLayout()
664     if result is None:
665       return
666
667     # open favorite page
668     x = array.array('B')
669     x.fromlist([CMD_SHOW_PAGE, result/100, (((result%100)/10)<<4) + (result%10), 0])
670     self.socketSend(x)
671
672   def updateLayout(self):
673     if self.nav_mode == NAV_MODE_TEXT:
674       pos = config.plugins.TeleText.pos.value
675     else:
676       pos = self.nav_pos
677     right  = pos[2]
678     bottom = pos[3]
679     mode = config.plugins.TeleText.splitting_mode.value
680
681     if config.plugins.TeleText.textOnly.value == True:
682       left  = pos[0]
683       width  = right - left
684       top    = pos[1]
685       height = bottom - top
686       self.resetVideo()
687     elif mode == SPLIT_MODE_PAT:
688       left   = dsk_width>>1
689       width  = dsk_width>>1
690       top    = 0
691       height = dsk_height
692       log("splitting video")
693       self.pig.move(ePoint(0,0))
694       size = self.instance.size()
695       self.pig.resize(eSize(size.width()/2*100/108, size.height()*100/108))
696       self.pig.show()
697     elif mode == SPLIT_MODE_TAP:
698       left   = 0
699       width  = (dsk_width>>1) - left
700       top    = 0
701       height = dsk_height
702       log("splitting video")
703       size = self.instance.size()
704       self.pig.move(ePoint(size.width()/2*104/100,0))
705       self.pig.resize(eSize(size.width()/2*100/108, size.height()*100/108))
706       self.pig.show()
707     elif mode == SPLIT_MODE_TIP:
708       if self.nav_mode == NAV_MODE_TEXT:
709         pos = config.plugins.TeleText.tip_pos.value
710       left   = pos[0]
711       width  = pos[2] - left
712       top    = pos[1]
713       height = pos[3] - top
714       self.resetVideo()
715
716     log("screen rect %s %s %s %s" % (left, top, width, height))
717
718     self.ttx.hide()
719     self.ttx.show(self.instance, ePoint(left, top), eSize(width, height))
720     self.ttx.update(0,0,492,250,self.zoom,self.filter_mode)
721
722   def resetVideo(self):
723     log("reset video")
724     self.pig.hide()
725
726   def sendSettings(self, result = True):
727     if result:
728       # region
729       x = array.array('B')
730       x.append(CMD_REGION)
731       x.append(int(config.plugins.TeleText.region.value))
732       self.socketSend(x)
733       # Helligkeit
734       x = array.array('B')
735       x.append(CMD_SET_BRIGH)
736       x.append(config.plugins.TeleText.brightness.value<<4)
737       self.socketSend(x)
738       # Kontrast
739       x = array.array('B')
740       x.append(CMD_SET_CONTR)
741       x.append(config.plugins.TeleText.contrast.value<<4)
742       self.socketSend(x)
743       # Transparenz
744       x = array.array('B')
745       x.append(CMD_TRANSPARENCY)
746       x.append(config.plugins.TeleText.transparency.value<<4)
747       self.socketSend(x)
748       # edge cut
749       if self.edgeValue != config.plugins.TeleText.edge_cut.value:
750         self.edgeValue = config.plugins.TeleText.edge_cut.value
751         x = array.array('B')
752         x.append(CMD_EDGE_CUT)
753         self.socketSend(x)
754       # teletext level
755       x = array.array('B')
756       x.append(CMD_TEXTLEVEL)
757       x.append(int(config.plugins.TeleText.textlevel.value))
758       self.socketSend(x)
759       # opaque
760       if self.opaqueValue != config.plugins.TeleText.opaque.value:
761         self.opaqueValue = config.plugins.TeleText.opaque.value
762         x = array.array('B')
763         x.append(CMD_OPAQUE)
764         self.socketSend(x)
765
766   def prevPressed(self):
767     if self.nav_mode == NAV_MODE_TEXT:
768       log("prev pressed")
769
770       if len(self.pid_list) < 2:
771         return
772
773       new_pid = -1
774       while new_pid == -1:
775         if self.pid_index == 0:
776           self.pid_index = len(self.pid_list) - 1
777         else:
778           self.pid_index = self.pid_index - 1
779         new_pid = self.pid_list[self.pid_index][2]
780
781       self.txtpid = new_pid
782       log("new txtpid: %s" % new_pid)
783       self.switchChannel(True)
784       self.readFavorites()
785
786   def nextPressed(self):
787     if self.nav_mode == NAV_MODE_TEXT:
788       log("next pressed")
789
790       if len(self.pid_list) < 2:
791         return
792
793       new_pid = -1
794       while new_pid == -1:
795         if self.pid_index == (len(self.pid_list) - 1):
796           self.pid_index = 0
797         else:
798           self.pid_index = self.pid_index + 1
799         new_pid = self.pid_list[self.pid_index][2]
800
801       self.txtpid = new_pid
802       log("new txtpid: %s" % new_pid)
803       self.switchChannel(True)
804       self.readFavorites()
805
806   def prevLongPressed(self):
807     if self.nav_mode == NAV_MODE_TEXT:
808       log("prev long pressed")
809       if len(self.pid_list) > 0:
810         self.__closed()
811         self.resetVideo()
812         self.session.openWithCallback(self.transponderResult, TeleTextTransponderMenu, self.pid_list, self.pid_index)
813
814   def nextLongPressed(self):
815     if self.nav_mode == NAV_MODE_TEXT:
816       log("next long pressed")
817       self.prevLongPressed()
818
819   def transponderResult(self, result):
820     log("transponder result: %s" % result)
821     if result > -1 and result != self.txtpid:
822       self.txtpid = result
823       log("new txtpid: %s" % result)
824       self.switchChannel(True)
825       self.readFavorites()
826     self.updateLayout()
827
828   def helpPressed(self):
829     self.__closed()
830     self.resetVideo()
831     self.session.open(HelpMenu, self.helpList)
832
833   def okPressed(self):
834     if self.nav_mode == NAV_MODE_TEXT:
835       if self.pageInput != 0:
836         return
837       log("ok pressed")
838       if self.catchPage:
839         x = array.array('B', (CMD_CATCHPAGE, 3, 1))
840         self.catchPage = False
841       else:
842         x = array.array('B', (CMD_CATCHPAGE, 1, 0))
843         self.catchPage = True
844         self.zoom = TeletextInterface.MODE_FULL
845         self.filter_mode = int(config.plugins.TeleText.scale_filter.value)
846       self.socketSend(x)
847     else:
848       if self.nav_mode == NAV_MODE_SIZE_TEXT:
849         config.plugins.TeleText.pos.value = self.nav_pos
850         config.plugins.TeleText.pos.save()
851       else:
852         config.plugins.TeleText.tip_pos.value = self.nav_pos
853         config.plugins.TeleText.tip_pos.save()
854       config.plugins.TeleText.textOnly.value = self.nav_text_only
855       del self.nav_text_only
856       del self.nav_config
857       del self.nav_orig_pos
858       del self.nav_pos
859       self.nav_mode = NAV_MODE_TEXT
860       self.updateLayout()
861
862   def cancelPressed(self):
863     if self.nav_mode == NAV_MODE_TEXT:
864       log("cancel pressed")
865       if self.pageInput != 0:
866         self.pageInput = 0
867         x = array.array('B')
868         x.fromlist([CMD_PAGEINPUT, 0x0a])
869         self.socketSend(x)
870       elif self.catchPage:
871         x = array.array('B', (CMD_CATCHPAGE, 3, 0))
872         self.socketSend(x)
873         self.catchPage = False
874       else:
875         self.resetVideo()
876         self.__closed()
877         if self.txtpid != self.txtpid_origin:
878           self.txtpid = self.txtpid_origin
879           self.switchChannel(True)
880           self.readFavorites()
881         self.close()
882     else:
883       if self.nav_mode == NAV_MODE_SIZE_TEXT:
884         config.plugins.TeleText.pos.cancel()
885       else:
886         config.plugins.TeleText.tip_pos.cancel()
887       config.plugins.TeleText.textOnly.value = self.nav_text_only
888       del self.nav_text_only
889       del self.nav_config
890       del self.nav_orig_pos
891       del self.nav_pos
892       self.nav_mode = NAV_MODE_TEXT
893       self.updateLayout()
894
895   def serviceStarted(self):
896     ref = self.session.nav.getCurrentServiceReference()
897     if ref.valid() and ref.type == ref.idDVB:
898         log("service started")
899
900   def serviceStopped(self):
901     log("service stopped")
902     self.stopCaching()
903
904   def stopCaching(self):
905     x = array.array('B', (CMD_CTL_CACHE, 0, 0, 0))
906     self.socketSend(x)
907
908   def serviceInfoChanged(self):
909     ref = self.session.nav.getCurrentServiceReference()
910     if ref.valid() and ref.type == ref.idDVB:
911         log("serviceInfoChanged")
912         self.checkServiceInfo(config.plugins.TeleText.background_caching.value or self.inMenu or self.execing)
913
914   def checkServiceInfo(self, do_send = True):
915     service = self.session.nav.getCurrentService()
916     info = service and service.info()
917     self.txtpid_origin = info and info.getInfo(iServiceInformation.sTXTPID)
918     self.txtpid = self.txtpid_origin
919
920     stream = service and service.stream()
921     demux = stream and stream.getStreamingData()
922     self.demux = demux and demux.get("demux", -1)
923     log("TXT PID %s DEMUX %s" % (self.txtpid, self.demux))
924
925     self.read_data = True
926     self.switchChannel(do_send)
927
928   def switchChannel(self, do_send = True):
929     if self.demux > -1 and self.txtpid > -1 and do_send:
930       x = array.array('B', (CMD_CTL_CACHE, (self.txtpid & 0xFF00) >> 8, (self.txtpid & 0xFF), self.demux))
931       self.socketSend(x)
932
933   def readTxtPids(self):
934     log("reading data(%s)" % self.read_data)
935     if self.read_data == False:
936       return
937
938     # read all txtpids and channels from transponder
939     cur_ref = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
940     self.pid_index = 0
941     if cur_ref is None:
942       self.pid_list = []
943     else:
944       pos = service_types_tv.rfind(':')
945       refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' % (service_types_tv[:pos+1],
946           cur_ref.getUnsignedData(4), # NAMESPACE
947           cur_ref.getUnsignedData(2), # TSID
948           cur_ref.getUnsignedData(3), # ONID
949           service_types_tv[pos+1:])
950       ref = eServiceReference(refstr)
951       self.pid_list = self.ttx.getTextPidsAndName(ref)
952     log("transponder: %s" % self.pid_list)
953
954     i = 0
955     available = 0
956     for x in self.pid_list:
957       if x[2] != -1:
958         available = available + 1
959       if x[2] == self.txtpid:
960         self.pid_index = i
961       i = i + 1
962     self.pid_count = available
963
964     self.read_data = False
965
966     # read favorites
967     self.readFavorites()
968
969   def readFavorites(self):
970     self.fav_index = 0
971     self.fav_list = []
972     hasStart = False
973     log("pid_list: %s" % self.pid_list)
974     log("pid_index: %s" % self.pid_index)
975     if len(self.pid_list) > 0:
976       service = self.pid_list[self.pid_index]
977       log("get favorites of service %s [%s]"%(service[1], service[0]))
978       for i in range(10):
979         text = self.favorites.getFavorite(service[0], i)
980         if text is not None:
981           page = int(text[0])
982           self.fav_list.append(page)
983           if page == 100:
984             hasStart = True
985     if hasStart == False:
986       self.fav_list.append(100)
987     log("favorites: %s" % self.fav_list)
988
989   # ---- for summary (lcd) ----
990
991   def createSummary(self):
992     return TeleTextSummary
993
994   def getCurrentPage(self):
995     return self.cur_page
996
997   def getAvailableTxtPidCount(self):
998     return self.pid_count
999
1000   def naviEnabled(self):
1001     return self.naviValue
1002
1003   def infoEnabled(self):
1004     return self.infoValue
1005
1006 # ----------------------------------------
1007
1008 class TeleTextSummary(Screen):
1009
1010   def __init__(self, session, parent):
1011     onPic  = resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/lcd_on.png")
1012     offPic = resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/lcd_off.png")
1013
1014     TeleTextSummary.skin = ("""<screen name="TeleTextSummary" position="0,0" size="132,64" id="1">
1015       <widget name="page"     position="0,0"   size="132,20" font="Regular;20" valign="center" halign="center" zPosition="1"/>
1016       <widget name="navi_off" position="12,28"  size="20,20" pixmap="%s" zPosition="1"/>
1017       <widget name="info_off" position="100,28" size="20,20" pixmap="%s" zPosition="1"/>
1018       <widget name="navi_on"  position="12,28"  size="20,20" pixmap="%s" zPosition="2"/>
1019       <widget name="info_on"  position="100,28" size="20,20" pixmap="%s" zPosition="2"/>
1020       <widget name="tp_count" position="44,28"  size="44,20" font="Regular;16" valign="center" halign="center" zPosition="1"/>
1021       <widget name="navi_txt" position="0,50"  size="44,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
1022       <widget name="tp_txt"   position="44,50" size="44,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
1023       <widget name="info_txt" position="88,50" size="44,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
1024     </screen>""" % (offPic, offPic, onPic, onPic),
1025     """<screen name="TeleTextSummary" position="0,0" size="96,64" id="2">
1026       <widget name="page"     position="0,0"   size="96,20" font="Regular;20" valign="center" halign="center" zPosition="1"/>
1027       <widget name="navi_off" position="6,28"  size="20,20" pixmap="%s" zPosition="1"/>
1028       <widget name="info_off" position="70,28" size="20,20" pixmap="%s" zPosition="1"/>
1029       <widget name="navi_on"  position="6,28"  size="20,20" pixmap="%s" zPosition="2"/>
1030       <widget name="info_on"  position="70,28" size="20,20" pixmap="%s" zPosition="2"/>
1031       <widget name="tp_count" position="32,28" size="32,20" font="Regular;16" valign="center" halign="center" zPosition="1"/>
1032       <widget name="navi_txt" position="0,50"  size="32,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
1033       <widget name="tp_txt"   position="36,50" size="32,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
1034       <widget name="info_txt" position="64,50" size="32,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
1035     </screen>""" % (offPic, offPic, onPic, onPic),
1036     """<screen name="TeleTextSummary" position="0,0" size="400,240" id="3">
1037       <widget name="page" font="Display;60" foregroundColor="#faff00" halign="center" position="10,5" size="380,65" valign="center" zPosition="1" />
1038       <widget name="navi_off" pixmap="%s" position="50,95"  size="40,40" zPosition="1" />
1039       <widget name="info_off" pixmap="%s" position="310,95" size="40,40" zPosition="1" />
1040       <widget name="navi_on"  pixmap="%s" position="50,95"  size="40,40" zPosition="2" />
1041       <widget name="info_on"  pixmap="%s" position="310,95" size="40,40" zPosition="2" />
1042       <widget name="tp_count" font="Display;50" halign="center" position="120,90" size="170,52" />
1043       <widget name="navi_txt" font="Display;40" halign="center" position="10,180" size="120,42" />
1044       <widget name="tp_txt"   font="Display;40" halign="center" position="145,180" size="120,42" />
1045       <widget name="info_txt" font="Display;40" halign="center" position="270,180" size="120,42" />
1046     </screen>""" % (offPic, offPic, onPic, onPic))
1047
1048     Screen.__init__(self, session, parent = parent)
1049     self["page"] = Label("")
1050     self["navi_txt"] = Label("NAVI")
1051     self["tp_txt"] = Label("TPT")
1052     self["tp_count"] = Label("<1>")
1053     self["info_txt"] = Label("INFO")
1054     self["navi_off"] = Pixmap()
1055     self["info_off"] = Pixmap()
1056     self["navi_on"]  = Pixmap()
1057     self["info_on"]  = Pixmap()
1058     self.onShow.append(self.addWatcher)
1059     self.onHide.append(self.removeWatcher)
1060
1061   def addWatcher(self):
1062     self.parent.onChangedEntry.append(self.selectionChanged)
1063     self.selectionChanged()
1064
1065   def removeWatcher(self):
1066     self.parent.onChangedEntry.remove(self.selectionChanged)
1067
1068   def selectionChanged(self):
1069     self["tp_count"].setText("< %s >"%self.parent.getAvailableTxtPidCount())
1070     self["page"].setText(self.parent.getCurrentPage())
1071     if self.parent.naviEnabled():
1072       self["navi_off"].hide()
1073       self["navi_on"].show()
1074     else:
1075       self["navi_on"].hide()
1076       self["navi_off"].show()
1077
1078     if self.parent.infoEnabled():
1079       self["info_off"].hide()
1080       self["info_on"].show()
1081     else:
1082       self["info_on"].hide()
1083       self["info_off"].show()
1084
1085 # ----------------------------------------
1086
1087 class TeleTextTransponderMenu(Screen):
1088
1089   ch_list = []
1090   ch_index = 0
1091
1092   cur_service = ""
1093   new_service = ""
1094
1095   onChangedEntry = [ ]
1096
1097   def __init__(self, session, list, index):
1098     log("[transponder] __init__")
1099
1100     self.ch_list = list
1101     self.ch_index = index
1102     self.cur_service = self.ch_list[self.ch_index][1]
1103
1104     width = 620
1105     height = 90
1106     left = (dsk_width - width)>>1
1107     top = (dsk_height - height)>>1
1108     log("[transponder] screen rect %s %s %s %s" % (left, top, width, height))
1109     TeleTextTransponderMenu.skin = """<screen position="%d,%d" size="%d,%d" title="%s">
1110         <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40" alphatest="on" />
1111         <ePixmap pixmap="skin_default/buttons/green.png" position="410,5" size="200,40" alphatest="on" />
1112         <widget name="key_r" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1113         <widget name="key_g" position="410,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1114         <eLabel position="10,50" size="600,1" backgroundColor="grey"/>
1115         <widget name="prev" position="10,60" size="50,25" pixmap="skin_default/icons/left.png" alphatest="on"/>
1116         <widget name="channel" position="70,62" size="450,20" valign="center" halign="left" font="Regular;21"/>
1117         <widget name="zapped" position="530,62" size="20,20" valign="center" halign="right" font="Regular;21"/>
1118         <widget name="next" position="560,60" size="50,25" pixmap="skin_default/icons/right.png" alphatest="on"/>
1119       </screen>""" % (left, top, width, height, _("Select teletext"))
1120     Screen.__init__(self, session)
1121
1122     self["actions"] = ActionMap(["OkCancelActions", "TeleTextActions"],
1123     {
1124       "ok"     : self.okPressed,
1125       "cancel" : self.cancelPressed,
1126       "red"    : self.cancelPressed,
1127       "green"  : self.okPressed,
1128       "left"   : self.prevPressed,
1129       "right"  : self.nextPressed,
1130       "prev"   : self.prevPressed,
1131       "next"   : self.nextPressed,
1132       "prev_long": self.prevPressed,
1133       "next_long": self.nextPressed
1134     }, -2)
1135     self["actions"].setEnabled(True)
1136
1137     self["key_r"] = Label(_("Cancel"))
1138     self["key_g"] = Label(_("OK"))
1139
1140     self["channel"] = Label("")
1141     self["prev"] = Pixmap()
1142     self["next"] = Pixmap()
1143     self["zapped"] = Label("*")
1144     self["zapped"].hide()
1145     if len(self.ch_list) == 1:
1146       self["prev"].hide()
1147       self["next"].hide()
1148     else:
1149       self["prev"].show()
1150       self["next"].show()
1151     self.updateLayout()
1152
1153   def updateLayout(self):
1154     if self.ch_list[self.ch_index][2] == -1:
1155       self["zapped"].show()
1156       self["key_g"].setText("")
1157     else:
1158       self["zapped"].hide()
1159       self["key_g"].setText(_("OK"))
1160     self.new_service = self.ch_list[self.ch_index][1]
1161     self["channel"].setText(self.new_service)
1162     for i in self.onChangedEntry:
1163       i()
1164
1165   def prevPressed(self):
1166     log("[transponder] prev pressed")
1167     if self.ch_index == 0:
1168       self.ch_index = len(self.ch_list) - 1
1169     else:
1170       self.ch_index = self.ch_index - 1
1171     self.updateLayout()
1172
1173   def nextPressed(self):
1174     log("[transponder] next pressed")
1175     if self.ch_index == (len(self.ch_list) - 1):
1176       self.ch_index = 0
1177     else:
1178       self.ch_index = self.ch_index + 1
1179     self.updateLayout()
1180
1181   def okPressed(self):
1182     log("[transponder] ok pressed")
1183     if self.ch_list[self.ch_index][2] > -1:
1184       self.close(self.ch_list[self.ch_index][2])
1185
1186   def cancelPressed(self):
1187     log("[transponder] cancel pressed")
1188     self.close(-1)
1189
1190   # ---- for summary (lcd) ----
1191
1192   def createSummary(self):
1193     return TeleTextTransponderSummary
1194
1195   def getCurrentService(self):
1196     return self.cur_service
1197
1198   def getNewService(self):
1199     return self.new_service
1200
1201 # ----------------------------------------
1202
1203 class TeleTextTransponderSummary(Screen):
1204
1205   def __init__(self, session, parent):
1206
1207     TeleTextTransponderSummary.skin = ("""<screen name="TeleTextTransponderSummary" position="0,0" size="132,64" id="1">
1208       <widget name="c_service" position="0,5"   size="100,20" font="Regular;20" halign="left"/>
1209       <ePixmap pixmap="skin_default/div-h.png" position="46,32" size="40,2" zPosition="1"/>
1210       <widget name="n_service" position="32,39" size="100,20" font="Regular;20" halign="right"/>
1211     </screen>""",
1212     """<screen name="TeleTextTransponderSummary" position="0,0" size="96,64" id="2">
1213       <widget name="c_service" position="0,5"   size="90,20" font="Regular;20" halign="left"/>
1214       <ePixmap pixmap="skin_default/div-h.png" position="28,32" size="40,2" zPosition="1"/>
1215       <widget name="n_service" position="6,39" size="90,20" font="Regular;20" halign="right"/>
1216     </screen>""")
1217
1218     Screen.__init__(self, session, parent = parent)
1219     self["c_service"] = Label(self.parent.getCurrentService())
1220     self["n_service"] = Label(self.parent.getNewService())
1221     self.onShow.append(self.addWatcher)
1222     self.onHide.append(self.removeWatcher)
1223
1224   def addWatcher(self):
1225     self.parent.onChangedEntry.append(self.selectionChanged)
1226     self.selectionChanged()
1227
1228   def removeWatcher(self):
1229     self.parent.onChangedEntry.remove(self.selectionChanged)
1230
1231   def selectionChanged(self):
1232     self["n_service"].setText(self.parent.getNewService())
1233
1234 # ----------------------------------------
1235
1236 class TeleTextMenu(ConfigListScreen, Screen):
1237
1238   onChangedEntry = [ ]
1239   isInitialized = False
1240   parent = None
1241
1242   def __init__(self, session, parent):
1243     width = 820
1244     height = 480
1245     left = (dsk_width - width)>>1
1246     top = (dsk_height - height)>>1
1247     log("[menu] screen rect %s %s %s %s" % (left, top, width, height))
1248     TeleTextMenu.skin = """<screen position="%d,%d" size="%d,%d" title="%s">
1249         <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40" alphatest="on" />
1250                 <ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40" alphatest="on" />
1251                 <ePixmap pixmap="skin_default/buttons/yellow.png" position="410,5" size="200,40" alphatest="on" />
1252                 <widget name="key_r" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1253                 <widget name="key_g" position="210,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1254                 <widget name="key_y" position="410,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1255                 <ePixmap pixmap="skin_default/icons/info.png" position="740,14" size="70,30" alphatest="on"/>
1256                 <eLabel position="10,50" size="800,1" backgroundColor="grey" />
1257                 <widget name="config" position="10,60" size="800,330" enableWrapAround="1" scrollbarMode="showOnDemand" />
1258                 <eLabel position="10,400" size="800,1" backgroundColor="grey" />
1259                 <widget name="label" position="10,415" size="800,50" font="Regular;21" valign="center" halign="center" />
1260       </screen>""" % (left, top, width, height, _("TeleText settings"))
1261
1262     Screen.__init__(self, session, parent)
1263
1264     # create config list
1265     self.list = []
1266     ConfigListScreen.__init__(self, self.list)
1267     self.createConfigList()
1268
1269     self["actions"] = ActionMap(["OkCancelActions", "TeleTextActions"],
1270     {
1271       "ok"     : self.okPressed,
1272       "cancel" : self.cancelPressed,
1273       "red"    : self.cancelPressed,
1274       "green"  : self.okPressed,
1275       "yellow" : self.resetPressed,
1276       "menu"   : self.cancelPressed,
1277       "text"   : self.textPressed,
1278       "info"   : self.infoPressed
1279     }, -2)
1280     self["actions"].setEnabled(True)
1281
1282     self["label"] = Label("Info")
1283     self["key_r"] = Label(_("Cancel"))
1284     self["key_y"] = Label(_("Default"))
1285     self["key_g"] = Label(_("OK"))
1286     self.onLayoutFinish.append(self.__layoutFinished)
1287
1288   def __layoutFinished(self):
1289     self.isInitialized = True
1290     if not self.selectionChanged in self["config"].onSelectionChanged:
1291       self["config"].onSelectionChanged.append(self.selectionChanged)
1292     self.selectionChanged()
1293
1294   def selectionChanged(self):
1295     configele = self["config"].getCurrent()[1]
1296     if configele == config.plugins.TeleText.pos:
1297       self["label"].setText(HELP_TEXT_POS)
1298     elif configele == config.plugins.TeleText.brightness:
1299       self["label"].setText(HELP_TEXT_BRIGHTNESS)
1300     elif configele == config.plugins.TeleText.contrast:
1301       self["label"].setText(HELP_TEXT_CONTRAST)
1302     elif configele == config.plugins.TeleText.transparency:
1303       self["label"].setText(HELP_TEXT_TRANSPARENCY)
1304     elif configele == config.plugins.TeleText.splitting_mode:
1305       self["label"].setText(HELP_TEXT_SPLITTING)
1306     elif configele == config.plugins.TeleText.tip_pos:
1307       self["label"].setText(HELP_TEXT_TIP_POS)
1308     elif configele == config.plugins.TeleText.debug:
1309       self["label"].setText(HELP_TEXT_DEBUG)
1310     elif configele == config.plugins.TeleText.edge_cut:
1311       self["label"].setText(HELP_TEXT_EDGE_CUT)
1312     elif configele == config.plugins.TeleText.textlevel:
1313       self["label"].setText(HELP_TEXT_TEXTLEVEL)
1314     elif configele == config.plugins.TeleText.region:
1315       self["label"].setText(HELP_TEXT_REGION)
1316     elif configele == config.plugins.TeleText.scale_filter:
1317       self["label"].setText(HELP_TEXT_SCALE_FILTER)
1318     elif configele == config.plugins.TeleText.scale_filter_zoom:
1319       self["label"].setText(HELP_TEXT_SCALE_FILTER)
1320     elif configele == config.plugins.TeleText.background_caching:
1321       self["label"].setText(HELP_TEXT_CACHING)
1322
1323   def createConfig(self, configele):
1324     if not self.isInitialized:
1325       return
1326     self.createConfigList()
1327
1328   def createConfigList(self):
1329     self.isInitialized = False
1330
1331     # remove notifiers
1332     for x in self["config"].list:
1333       x[1].clearNotifiers()
1334
1335     self.list = [
1336       getConfigListEntry(_("Scale filter"),      config.plugins.TeleText.scale_filter),
1337       getConfigListEntry(_("Scale filter zoom"), config.plugins.TeleText.scale_filter_zoom),
1338       getConfigListEntry(_("Brightness"),        config.plugins.TeleText.brightness),
1339       getConfigListEntry(_("Contrast"),          config.plugins.TeleText.contrast),
1340       getConfigListEntry(_("Transparency"),      config.plugins.TeleText.transparency),
1341       getConfigListEntry(_("Text level"),        config.plugins.TeleText.textlevel),
1342       getConfigListEntry(_("Region"),            config.plugins.TeleText.region),
1343       getConfigListEntry(_("Position and size"), config.plugins.TeleText.pos),
1344       getConfigListEntry(_("Display edges"),     config.plugins.TeleText.edge_cut),
1345       getConfigListEntry(_("Splitting mode"),    config.plugins.TeleText.splitting_mode)
1346     ]
1347     if config.plugins.TeleText.splitting_mode.value == SPLIT_MODE_TIP:
1348       self.list.append(getConfigListEntry("... %s" % _("Position and size"),   config.plugins.TeleText.tip_pos))
1349     self.list.append(getConfigListEntry(_("Background caching"),config.plugins.TeleText.background_caching))
1350     self.list.append(getConfigListEntry(_("Debug"),   config.plugins.TeleText.debug))
1351
1352     self["config"].list = self.list
1353
1354     # add notifiers (lcd, info)
1355     for x in self["config"].list:
1356       x[1].addNotifier(self.changedEntry)
1357     # add notifiers (menu)
1358     config.plugins.TeleText.splitting_mode.addNotifier(self.createConfig)
1359
1360     self.isInitialized = True
1361
1362   def resetPressed(self):
1363     log("[menu] reset pressed")
1364     config.plugins.TeleText.scale_filter.setValue("%d"%BILINEAR)
1365     config.plugins.TeleText.scale_filter_zoom.setValue("%d"%BILINEAR)
1366     config.plugins.TeleText.brightness.setValue(8)
1367     config.plugins.TeleText.contrast.setValue(12)
1368     config.plugins.TeleText.transparency.setValue(8)
1369     config.plugins.TeleText.edge_cut.setValue(False)
1370     config.plugins.TeleText.splitting_mode.setValue(SPLIT_MODE_PAT)
1371     config.plugins.TeleText.textlevel.setValue("2")
1372     config.plugins.TeleText.region.setValue("16")
1373     config.plugins.TeleText.debug.setValue(False)
1374     config.plugins.TeleText.pos.setValue([DEF_LEFT, DEF_TOP, DEF_RIGHT, DEF_BOTTOM])
1375     config.plugins.TeleText.tip_pos.setValue([(dsk_width>>1)+(dsk_width>>2), (dsk_height>>1)+(dsk_height>>2), dsk_width, dsk_height])
1376     config.plugins.TeleText.background_caching.setValue(True)
1377     self["config"].selectionChanged()
1378
1379   def infoPressed(self):
1380     log("[menu] info pressed")
1381     self.session.open(TeleTextAboutScreen, self.parent.daemonVersion)
1382
1383   def textPressed(self):
1384     log("[menu] text pressed")
1385     if self["config"].getCurrent()[1] == config.plugins.TeleText.pos:
1386       self.close(config.plugins.TeleText.pos)
1387     elif self["config"].getCurrent()[1] == config.plugins.TeleText.tip_pos:
1388       self.close(config.plugins.TeleText.tip_pos)
1389
1390   def okPressed(self):
1391     log("[menu] ok pressed")
1392     self.checkPositionValues(config.plugins.TeleText.pos)
1393     self.checkPositionValues(config.plugins.TeleText.tip_pos)
1394     for x in self["config"].list:
1395       x[1].save()
1396     configfile.save()
1397     self.close(None)
1398
1399   def checkPositionValues(self, configele):
1400     pos = configele.value
1401     log("... old pos: %s %s %s %s" % (pos[0], pos[1], pos[2], pos[3]))
1402     update = False
1403     if pos[0] > pos[2]:
1404       i = pos[0]
1405       pos[0] = pos[2]
1406       pos[2] = i
1407       update = True
1408     if pos[1] > pos[3]:
1409       i = pos[1]
1410       pos[1] = pos[3]
1411       pos[3] = i
1412       update = True
1413     if (pos[2] - pos[0]) < MIN_W:
1414       pos[2] = pos[0] + MIN_W
1415       update = True
1416     if (pos[3] - pos[1]) < MIN_H:
1417       pos[3] = pos[1] + MIN_H
1418       update = True
1419     if pos[2] > dsk_width:
1420       pos[0] = pos[0] + dsk_width - pos[2]
1421       pos[2] = dsk_width
1422       update = True
1423     if pos[3] > dsk_height:
1424       pos[1] = pos[1] + dsk_height - pos[3]
1425       pos[3] = dsk_height
1426       update = True
1427     log("... new pos: %s %s %s %s" % (pos[0], pos[1], pos[2], pos[3]))
1428
1429     if update:
1430       configele.setValue(pos)
1431
1432   def cancelPressed(self):
1433     log("[menu] cancel pressed")
1434     confirm = False
1435     for x in self["config"].list:
1436       confirm = confirm or x[1].isChanged()
1437     if confirm:
1438       self.session.openWithCallback(self.DiscardConfirm, MessageBox, _("Discard changes?"))
1439     else:
1440       self.close(None)
1441
1442   def DiscardConfirm(self, result):
1443     if result:
1444       for x in self["config"].list:
1445         if x[1].isChanged():
1446           x[1].cancel()
1447       self.close(None)
1448
1449   # ---- for summary (lcd) ----
1450
1451   def changedEntry(self, element=None):
1452     for x in self.onChangedEntry:
1453       x()
1454
1455   def getCurrentEntry(self):
1456     return self["config"].getCurrent()[0]
1457
1458   def getCurrentValue(self):
1459     return str(self["config"].getCurrent()[1].getText())
1460
1461   def createSummary(self):
1462     return TeleTextMenuSummary
1463
1464 # ----------------------------------------
1465
1466 class TeleTextMenuSummary(Screen):
1467
1468   skin = ("""<screen name="TeleTextMenuSummary" position="0,0" size="132,64" id="1">
1469       <widget name="SetupTitle" position="6,4"  size="120,20" font="Regular;20" halign="center"/>
1470       <widget name="SetupEntry" position="6,30" size="120,12" font="Regular;12" halign="left"/>
1471       <widget name="SetupValue" position="6,48" size="120,12" font="Regular;12" halign="right"/>
1472     </screen>""",
1473     """<screen name="TeleTextMenuSummary" position="0,0" size="96,64" id="2">
1474       <widget name="SetupTitle" position="3,4"  size="90,20" font="Regular;20" halign="center"/>
1475       <widget name="SetupEntry" position="3,30" size="90,12" font="Regular;12" halign="left"/>
1476       <widget name="SetupValue" position="3,48" size="90,12" font="Regular;12" halign="right"/>
1477     </screen>""")
1478
1479   def __init__(self, session, parent):
1480     Screen.__init__(self, session, parent = parent)
1481     self["SetupTitle"] = Label(_("TeleText settings"))
1482     self["SetupEntry"] = Label("")
1483     self["SetupValue"] = Label("")
1484     self.onShow.append(self.addWatcher)
1485     self.onHide.append(self.removeWatcher)
1486
1487   def addWatcher(self):
1488     self.parent.onChangedEntry.append(self.selectionChanged)
1489     self.parent["config"].onSelectionChanged.append(self.selectionChanged)
1490     self.selectionChanged()
1491
1492   def removeWatcher(self):
1493     self.parent.onChangedEntry.remove(self.selectionChanged)
1494     self.parent["config"].onSelectionChanged.remove(self.selectionChanged)
1495
1496   def selectionChanged(self):
1497     self["SetupEntry"].text = self.parent.getCurrentEntry()
1498     self["SetupValue"].text = self.parent.getCurrentValue()
1499
1500 # ----------------------------------------
1501
1502 class TeleTextAboutScreen(Screen):
1503
1504   daemonVersion = "0.1"
1505
1506   def __init__(self, session, dVersion):
1507     self.daemonVersion = dVersion
1508
1509     width = 720
1510     height = 480
1511     left = (dsk_width - width)>>1
1512     top = (dsk_height - height)>>1
1513     log("[about] screen rect %s %s %s %s" % (left, top, width, height))
1514     TeleTextAboutScreen.skin = """<screen position="%d,%d" size="%d,%d" flags="wfNoBorder">
1515         <widget name="pic"    position="0,0"    size="720,480" zPosition="1" pixmap="%s" alphatest="on"/>
1516         <widget name="text"   position="24,32"  size="672,72"  zPosition="2" font="Console;72" halign="center" backgroundColor="#0000ff"  foregroundColor="white" />
1517         <widget name="daemon" position="24,128" size="672,48"  zPosition="2" font="Console;40" halign="left"   backgroundColor="white" foregroundColor="black" />
1518         <widget name="plugin" position="24,400" size="672,48"  zPosition="2" font="Console;40" halign="right"  backgroundColor="white" foregroundColor="black" />
1519       </screen>""" % (left, top, width, height, resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/teletext.png"))
1520
1521     Screen.__init__(self, session)
1522
1523     self["actions"] = ActionMap(["OkCancelActions"],
1524     {
1525       "ok"     : self.okPressed,
1526       "cancel" : self.cancelPressed
1527     }, -2)
1528     self["actions"].setEnabled(True)
1529
1530     self["pic"] = Pixmap()
1531     self["text"] = Label("TeleText")
1532     self["daemon"] = Label("Daemon v%s" % self.daemonVersion)
1533     self["plugin"] = Label("Plugin v%s" % PLUGIN_VERSION)
1534
1535   def okPressed(self):
1536     log("[about] ok pressed")
1537     self.close(None)
1538
1539   def cancelPressed(self):
1540     log("[about] cancel pressed")
1541     self.close(None)
1542
1543   # ---- for summary (lcd) ----
1544
1545   def getDaemonVersion(self):
1546     return self.daemonVersion
1547
1548   def createSummary(self):
1549     return TeleTextAboutSummary
1550
1551 # ----------------------------------------
1552
1553 class TeleTextAboutSummary(Screen):
1554
1555   skin = ("""<screen name="TeleTextAboutSummary" position="0,0" size="132,64" id="1">
1556       <widget name="title"  position="6,4"  size="120,24" font="Regular;20" halign="center"/>
1557       <widget name="daemon" position="6,30" size="120,16" font="Regular;12" halign="left"/>
1558       <widget name="plugin" position="6,48" size="120,16" font="Regular;12" halign="left"/>
1559     </screen>""",
1560     """<screen name="TeleTextAboutSummary" position="0,0" size="96,64" id="2">
1561       <widget name="title"  position="3,4"  size="90,20" font="Regular;20" halign="center"/>
1562       <widget name="daemon" position="3,30" size="90,16" font="Regular;12" halign="left"/>
1563       <widget name="plugin" position="3,48" size="90,16" font="Regular;12" halign="left"/>
1564     </screen>""")
1565
1566   def __init__(self, session, parent):
1567     Screen.__init__(self, session, parent = parent)
1568     self["title"] = Label("TeleText")
1569     self["daemon"] = Label("Daemon v%s" % parent.getDaemonVersion())
1570     self["plugin"] = Label("Plugin v%s" % PLUGIN_VERSION)
1571
1572 # ----------------------------------------
1573
1574 class TeleTextFavorites():
1575
1576   configFile = "/etc/enigma2/teletext.fav"
1577
1578   def __init__(self):
1579     log("[favorites] reading")
1580     self.parser = ConfigParser()
1581     self.parser.read(self.configFile)
1582
1583   def write(self):
1584     log("[favorites] writing")
1585     fp = open(self.configFile,"w")
1586     self.parser.write(fp)
1587     fp.close()
1588
1589   def getFavorite(self, service, index):
1590     index = str(index)
1591     if self.parser.has_option(service, index) is False:
1592       return None
1593     return self.parser.get(service, index).split(";",1)
1594
1595   def getFavorites(self, service):
1596     result = []
1597     if self.parser.has_section(service) is True:
1598       for x in self.parser.options(service):
1599         result.append(self.getFavorite(service, x))
1600     return result
1601
1602   def setFavorite(self, service, index, page, text):
1603     index = str(index)
1604     page = str(page)
1605     if self.parser.has_section(service) is False:
1606       self.parser.add_section(service)
1607     self.parser.set(service, index, "%s;%s" % (page, text))
1608
1609   def removeFavorite(self, service, index):
1610     index = str(index)
1611     self.parser.remove_option(service, index)
1612     if len(self.parser.options(service)) == 0:
1613       self.parser.remove_section(service)
1614
1615   def removeService(self, service):
1616     self.parser.remove_section(service)
1617
1618 # ----------------------------------------
1619
1620 class TeleTextFavoritesMenu(Screen):
1621
1622   onChangedEntry = [ ]
1623
1624   def __init__(self, session, parent, service, page, favorites):
1625     width = 820
1626     height = 480
1627     left = (dsk_width - width)>>1
1628     top = (dsk_height - height)>>1
1629     log("[fav-menu] screen rect %s %s %s %s" % (left, top, width, height))
1630     TeleTextFavoritesMenu.skin = """<screen position="%d,%d" size="%d,%d" title="%s [%s]">
1631         <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40" alphatest="on" />
1632         <ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40" alphatest="on" />
1633         <ePixmap pixmap="skin_default/buttons/yellow.png" position="410,5" size="200,40" alphatest="on" />
1634         <ePixmap pixmap="skin_default/buttons/blue.png" position="610,5" size="200,40" alphatest="on" />
1635         <widget name="key_r" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1636         <widget name="key_g" position="210,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1637         <widget name="key_y" position="410,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1638         <widget name="key_b" position="610,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
1639         <eLabel position="10,50" size="800,1" backgroundColor="grey" />
1640         <widget name="fav_list" position="63,60" size="754,330" enableWrapAround="1" scrollbarMode="showOnDemand" />
1641         <ePixmap pixmap="skin_default/buttons/key_1.png" position="10,63" size="50,25" alphatest="on"/>
1642         <ePixmap pixmap="skin_default/buttons/key_2.png" position="10,93" size="50,25" alphatest="on"/>
1643         <ePixmap pixmap="skin_default/buttons/key_3.png" position="10,123" size="50,25" alphatest="on"/>
1644         <ePixmap pixmap="skin_default/buttons/key_4.png" position="10,153" size="50,25" alphatest="on"/>
1645         <ePixmap pixmap="skin_default/buttons/key_5.png" position="10,183" size="50,25" alphatest="on"/>
1646         <ePixmap pixmap="skin_default/buttons/key_6.png" position="10,213" size="50,25" alphatest="on"/>
1647         <ePixmap pixmap="skin_default/buttons/key_7.png" position="10,243" size="50,25" alphatest="on"/>
1648         <ePixmap pixmap="skin_default/buttons/key_8.png" position="10,273" size="50,25" alphatest="on"/>
1649         <ePixmap pixmap="skin_default/buttons/key_9.png" position="10,303" size="50,25" alphatest="on"/>
1650         <ePixmap pixmap="skin_default/buttons/key_0.png" position="10,333" size="50,25" alphatest="on"/>
1651       </screen>""" % (left, top, width, height, _("TeleText favorites"), service[1])
1652
1653     self.service = service[0]
1654     self.page = page
1655     self.favorites = favorites
1656
1657     Screen.__init__(self, session, parent)
1658     self["fav_list"] = MenuList([], enableWrapAround = True)
1659     self["fav_list"].onSelectionChanged.append(self.updateLayout)
1660
1661     self["actions"] = NumberActionMap(["OkCancelActions", "TeleTextActions"],
1662     {
1663       "1"      : self.keyNumberGlobal,
1664       "2"      : self.keyNumberGlobal,
1665       "3"      : self.keyNumberGlobal,
1666       "4"      : self.keyNumberGlobal,
1667       "5"      : self.keyNumberGlobal,
1668       "6"      : self.keyNumberGlobal,
1669       "7"      : self.keyNumberGlobal,
1670       "8"      : self.keyNumberGlobal,
1671       "9"      : self.keyNumberGlobal,
1672       "0"      : self.keyNumberGlobal,
1673       "ok"     : self.okPressed,
1674       "cancel" : self.cancelPressed,
1675       "red"    : self.redPressed,
1676       "green"  : self.okPressed,
1677       "yellow" : self.yellowPressed,
1678       "blue"   : self.bluePressed
1679     }, -2)
1680     self["actions"].setEnabled(True)
1681
1682     self["key_r"] = Label("")
1683     self["key_g"] = Label("")
1684     self["key_y"] = Label("")
1685     self["key_b"] = Label(_("Clear all"))
1686
1687     self.updateList()
1688     self.updateLayout()
1689
1690   def keyNumberGlobal(self, number):
1691     log("[favorites] %s pressed" % number)
1692     if number == 0:
1693       index = 9
1694     else:
1695       index = number - 1
1696
1697     if self.pages[index] != -1:
1698       self.close(self.pages[index])
1699
1700   def updateList(self):
1701     list = []
1702     self.pages = []
1703
1704     while len(list) < 10:
1705       text = self.favorites.getFavorite(self.service, len(list))
1706       if text is None:
1707         self.pages.append(-1)
1708         list.append(_("<empty>"))
1709       else:
1710         self.pages.append(int(text[0]))
1711         list.append("[%s] %s" % (text[0], text[1]))
1712     self["fav_list"].setList(list)
1713
1714   def updateLayout(self):
1715     value = self["fav_list"].getCurrent()
1716     self.sel_page = self.pages[self["fav_list"].getSelectedIndex()]
1717     if value == _("<empty>"):
1718       self["key_r"].setText("")
1719       self["key_g"].setText("")
1720       self["key_y"].setText(_("Add"))
1721     else:
1722       self["key_r"].setText(_("Delete"))
1723       self["key_g"].setText(_("Select"))
1724       self["key_y"].setText(_("Edit"))
1725
1726     for i in self.onChangedEntry:
1727       i()
1728
1729   def okPressed(self):
1730     if self.sel_page != -1:
1731       log("[favorites] ok pressed")
1732       self.close(self.sel_page)
1733
1734   def cancelPressed(self):
1735     log("[fav-menu] cancel pressed")
1736     self.close(None)
1737
1738   def yellowPressed(self):
1739     log("[fav-menu] yellow pressed")
1740     page = self.sel_page
1741     if page == -1:
1742       page = self.page
1743     value = self["fav_list"].getCurrent()
1744     if value == _("<empty>"):
1745       value = ""
1746     else:
1747       value = value.split(None,1)[1]
1748     self.session.openWithCallback(
1749       self.addFavorite,
1750       NTIVirtualKeyBoard,
1751       title = _("Enter text for page %s")%page,
1752       text = value
1753     )
1754
1755   def addFavorite(self, text):
1756     if text:
1757       page = self.sel_page
1758       if page == -1:
1759         page = self.page
1760       self.favorites.setFavorite(self.service, self["fav_list"].getSelectedIndex(), page, text)
1761       self.favorites.write()
1762     self.updateList()
1763     self.updateLayout()
1764
1765   def redPressed(self):
1766     log("[fav-menu] red pressed")
1767     if self.sel_page != -1:
1768       self.session.openWithCallback(self.deleteFavorite, MessageBox, _("Delete favorite?"))
1769
1770   def deleteFavorite(self, result):
1771     if result:
1772       self.favorites.removeFavorite(self.service, self["fav_list"].getSelectedIndex())
1773       self.favorites.write()
1774       self.updateList()
1775       self.updateLayout()
1776
1777   def bluePressed(self):
1778     log("[fav-menu] blue pressed")
1779     self.session.openWithCallback(self.cleanupService, MessageBox, _("Delete all favorites?"))
1780
1781   def cleanupService(self, result):
1782     if result:
1783       self.favorites.removeService(self.service)
1784       self.favorites.write()
1785       self.updateList()
1786       self.updateLayout()
1787
1788   # ---- for summary (lcd) ----
1789
1790   def getCurrentPage(self):
1791     page = self.sel_page
1792     if page == -1:
1793       page = ""
1794     return str(page)
1795
1796   def getCurrentValue(self):
1797     return self["fav_list"].getCurrent()
1798
1799   def createSummary(self):
1800     return TeleTextFavoritesSummary
1801
1802 # ----------------------------------------
1803
1804 class TeleTextFavoritesSummary(Screen):
1805
1806   skin = ("""<screen name="TeleTextFavoritesSummary" position="0,0" size="132,64" id="1">
1807       <widget name="title"  position="6,4"  size="120,24" font="Regular;20" halign="center"/>
1808       <widget name="page"   position="6,30" size="120,16" font="Regular;12" halign="left"/>
1809       <widget name="text"   position="6,48" size="120,16" font="Regular;12" halign="left"/>
1810     </screen>""",
1811     """<screen name="TeleTextFavoritesSummary" position="0,0" size="96,64" id="2">
1812       <widget name="title"  position="3,4"  size="90,20" font="Regular;20" halign="center"/>
1813       <widget name="page"   position="3,30" size="90,16" font="Regular;12" halign="left"/>
1814       <widget name="text"   position="3,48" size="90,16" font="Regular;12" halign="left"/>
1815     </screen>""")
1816
1817   def __init__(self, session, parent):
1818     Screen.__init__(self, session, parent = parent)
1819     self["title"] = Label(_("TeleText favorites"))
1820     self["page"]  = Label()
1821     self["text"]  = Label()
1822
1823     self.onShow.append(self.addWatcher)
1824     self.onHide.append(self.removeWatcher)
1825
1826   def addWatcher(self):
1827     self.parent.onChangedEntry.append(self.selectionChanged)
1828     self.selectionChanged()
1829
1830   def removeWatcher(self):
1831     self.parent.onChangedEntry.remove(self.selectionChanged)
1832
1833   def selectionChanged(self):
1834     self["page"].setText(self.parent.getCurrentPage())
1835     self["text"].setText(self.parent.getCurrentValue())
1836
1837 # ----------------------------------------
1838
1839 def sessionstart(reason, session):
1840   log("----- sessionstart(%s) -----" % session)
1841   # Plugin initialisieren
1842   global ttx_screen
1843   global my_session
1844   ttx_screen = session.instantiateDialog(TeleText)
1845   my_session = session
1846
1847 def autostart(reason, **kwargs):
1848   log("autostart(%s, %s)" % (reason, kwargs))
1849   if reason == 0:
1850     pass
1851   elif reason == 1:
1852     pass
1853
1854 def mainText(session, **kwargs):
1855   global ttx_screen
1856   log("mainText")
1857   ttx_screen.readTxtPids()
1858   if ttx_screen.txtpid != -1:
1859     session.execDialog(ttx_screen)
1860   else:
1861     if len(ttx_screen.pid_list) > 0:
1862       session.openWithCallback(selectText, TeleTextTransponderMenu, ttx_screen.pid_list, ttx_screen.pid_index)
1863     else:
1864       session.open(MessageBox, _("No teletext available."), MessageBox.TYPE_INFO, timeout = 3)
1865
1866 def selectText(result):
1867   global my_session
1868   global ttx_screen
1869   if result > -1:
1870     ttx_screen.txtpid = result
1871     ttx_screen.txtpid_origin = result
1872     ttx_screen.switchChannel(True)
1873     ttx_screen.readFavorites()
1874     my_session.execDialog(ttx_screen)
1875
1876 def mainMenu(session, **kwargs):
1877   log("mainMenu")
1878   session.open(TeleTextMenu)
1879
1880 def Plugins(**kwargs):
1881   log("plugins")
1882   return [
1883     PluginDescriptor(name="TeleText", description="teletext", where = PluginDescriptor.WHERE_TELETEXT, fnc=mainText),
1884     PluginDescriptor(needsRestart = False, where = PluginDescriptor.WHERE_SESSIONSTART, fnc=sessionstart),
1885     PluginDescriptor(needsRestart = False, where = PluginDescriptor.WHERE_AUTOSTART, fnc=autostart)
1886     ]
1887
1888 # EOF