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