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