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