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