[TeleText] update page catching, lcd-fix (subpages), About-Dialog
[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.Pixmap import Pixmap
13 from Components.ServiceEventTracker import ServiceEventTracker
14 from Components.config import config, configfile, getConfigListEntry, ConfigSubsection, ConfigEnableDisable, ConfigSlider, ConfigSelection, ConfigSequence
15 from GlobalActions import globalActionMap
16 from Plugins.Plugin import PluginDescriptor
17 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
18
19 import array
20 import socket
21 import struct
22
23 import NavigationInstance
24
25 from os import unlink
26 from select import POLLIN, POLLPRI, POLLHUP, POLLERR
27
28 from enigma import Teletext as TeletextInterface
29 from enigma import DISABLED, BILINEAR, ANISOTROPIC, SHARP, SHARPER, BLURRY, ANTI_FLUTTER, ANTI_FLUTTER_BLURRY, ANTI_FLUTTER_SHARP
30
31 CMD_CTL_CACHE=1
32 CMD_SHOW_PAGE=2
33 CMD_PAGE_NEXT=3
34 CMD_PAGE_PREV=4
35 CMD_SUBP_NEXT=5
36 CMD_SUBP_PREV=6
37 CMD_COLKEY_RD=7
38 CMD_COLKEY_GN=8
39 CMD_COLKEY_YE=9
40 CMD_COLKEY_BL=10
41 CMD_CATCHPAGE=11
42 CMD_CONCEALED=12
43 CMD_SET_BRIGH=13
44 CMD_SET_CONTR=14
45 CMD_RQ_UPDATE=15
46 CMD_RZAP_PAGE=16
47 CMD_OPAQUE=17
48 CMD_TRANSPARENCY=18
49 CMD_FLOF=19
50 CMD_PAGEINPUT=20
51 CMD_EDGE_CUT=21
52 CMD_TEXTLEVEL=22
53 CMD_REGION=23
54 CMD_VERSION=24
55 CMD_CLOSE_DMN=99
56
57 SPLIT_MODE_PAT = "pat"
58 SPLIT_MODE_TAP = "tap"
59 SPLIT_MODE_TIP = "tip"
60 splittingModeList = [ (SPLIT_MODE_PAT, _("picture and teletext")), (SPLIT_MODE_TAP, _("teletext and picture")), (SPLIT_MODE_TIP, _("teletext in picture")) ]
61 textlevelModeList = [ ("0", "1.0"), ("1", "1.5"), ("2", "2.5"), ("3", "3.5") ]
62 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")) ]
63 filterList = [ ("%d"%DISABLED,_("Disabled")), ("%d"%BILINEAR,_("bilinear")), ("%d"%ANISOTROPIC,_("anisotropic")), ("%d"%SHARP,_("sharp")), ("%d"%SHARPER,_("sharper"))]
64
65 HELP_TEXT_POS          = _("Enter values (left, top, right, bottom) or press TEXT to move and resize the teletext graphically.")
66 HELP_TEXT_TIP_POS      = _("Enter values (left, top, right, bottom) or press TEXT to move and resize the teletext graphically.")
67 HELP_TEXT_SPLITTING    = _("Select splitting mode.")
68 HELP_TEXT_BRIGHTNESS   = _("Select brightness.")
69 HELP_TEXT_CONTRAST     = _("Select contrast.")
70 HELP_TEXT_TRANSPARENCY = _("Select transparency.")
71 HELP_TEXT_EDGE_CUT     = _("Display first and last row.")
72 HELP_TEXT_MESSAGES     = _("Show message if no teletext available or exit silently.")
73 HELP_TEXT_DEBUG        = _("Print debug messages to /tmp/dbttcp.log.")
74 HELP_TEXT_TEXTLEVEL    = _("Select teletext version to use.")
75 HELP_TEXT_REGION       = _("Select your region to use the proper font.")
76 HELP_TEXT_SCALE_FILTER = _("Select your favourite scale filter.")
77 HELP_TEXT_CACHING      = _("If caching is disabled, each teletext page will searched when you entered its number.")
78
79 dsk_size   = getDesktop(0).size()
80 dsk_width  = dsk_size.width()
81 dsk_height = dsk_size.height()
82
83 MIN_W = 400
84 MIN_H = 300
85
86 NAV_MODE_TEXT          = 0
87 NAV_MODE_SIZE_TEXT     = 1
88 NAV_MODE_SIZE_TIP_TEXT = 2
89
90 config.plugins.TeleText = ConfigSubsection()
91 config.plugins.TeleText.scale_filter = ConfigSelection(filterList, default="%d"%BILINEAR)
92 config.plugins.TeleText.scale_filter_zoom = ConfigSelection(filterList, default="%d"%BILINEAR)
93 config.plugins.TeleText.brightness   = ConfigSlider(default=8,  increment=1, limits=(0,15))
94 config.plugins.TeleText.contrast     = ConfigSlider(default=12, increment=1, limits=(0,15))
95 config.plugins.TeleText.transparency = ConfigSlider(default=8,  increment=1, limits=(0,15))
96 config.plugins.TeleText.messages = ConfigEnableDisable(default=True)
97 config.plugins.TeleText.edge_cut = ConfigEnableDisable(default=False)
98 config.plugins.TeleText.splitting_mode = ConfigSelection(splittingModeList, default=SPLIT_MODE_PAT)
99 config.plugins.TeleText.textlevel      = ConfigSelection(textlevelModeList, default="2")
100 config.plugins.TeleText.region   = ConfigSelection(regionList, default="16")
101 config.plugins.TeleText.debug    = ConfigEnableDisable(default=False)
102 config.plugins.TeleText.pos      = ConfigSequence(default=[0, 0, dsk_width, dsk_height], seperator = ",", limits = [(0,dsk_width>>3),(0,dsk_height>>3),(dsk_width-(dsk_width>>3),dsk_width),(dsk_height-(dsk_height>>3),dsk_height)])
103 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)])
104 # state
105 config.plugins.TeleText.textOnly = ConfigEnableDisable(default=True)
106 config.plugins.TeleText.opaque   = ConfigEnableDisable(default=False)
107 config.plugins.TeleText.background_caching = ConfigEnableDisable(default=True)
108
109 # global functions
110
111 def log(message):
112   _log(message)
113   if config.plugins.TeleText.debug.value:
114     _debug(message)
115
116 class TeleText(Screen):
117
118   pageInput   = 0
119   catchPage   = False
120   naviValue   = True
121   infoValue   = False
122   edgeValue   = False
123   opaqueValue = False
124   nav_mode    = NAV_MODE_TEXT
125   zoom        = TeletextInterface.MODE_FULL
126   filter_mode = BILINEAR
127   pid_list = []
128   pid_index = 0
129   pid_count = 0
130   demux  = -1
131   txtpid = -1
132   txtpid_origin = -1
133   cur_page = "100-00/00"
134   daemonVersion = "0.0"
135
136   onChangedEntry = [ ]
137
138   def __init__(self, session):
139     TeleText.skin = """<screen position="0,0" size="%d,%d" title="TeleText" flags="wfNoBorder"/>""" % (dsk_width, dsk_height)
140     Screen.__init__(self, session)
141
142     self.__event_tracker = ServiceEventTracker(screen = self, eventmap={
143       iPlayableService.evStart : self.serviceStarted,
144       iPlayableService.evEnd : self.serviceStopped,
145       iPlayableService.evUpdatedInfo : self.serviceInfoChanged,
146     })
147
148     self["actions"] = NumberActionMap(["OkCancelActions", "TeleTextActions"],
149     {
150       "ok" : self.okPressed,
151       "cancel" : self.cancelPressed,
152       "1" : self.keyNumberGlobal,
153       "2" : self.keyNumberGlobal,
154       "3" : self.keyNumberGlobal,
155       "4" : self.keyNumberGlobal,
156       "5" : self.keyNumberGlobal,
157       "6" : self.keyNumberGlobal,
158       "7" : self.keyNumberGlobal,
159       "8" : self.keyNumberGlobal,
160       "9" : self.keyNumberGlobal,
161       "0" : self.keyNumberGlobal,
162       "prev":   self.prevPressed,
163       "next":   self.nextPressed,
164       "prev_long": self.prevLongPressed,
165       "next_long": self.nextLongPressed,
166       "red":    self.redPressed,
167       "green":  self.greenPressed,
168       "yellow": self.yellowPressed,
169       "blue":   self.bluePressed,
170       "right":  self.rightPressed,
171       "left":   self.leftPressed,
172       "down":   self.downPressed,
173       "up":     self.upPressed,
174       "info":   self.infoPressed,
175       "tv":     self.tvPressed,
176       "radio":  self.radioPressed,
177       "text":   self.textPressed,
178       "menu":   self.menuPressed,
179       "help":   self.helpPressed,
180       "video":  self.videoPressed,
181       "nextBouquet": self.nextBouquetPressed,
182       "prevBouquet": self.prevBouquetPressed,
183       "volUp":       self.volumeUpPressed,
184       "volDown":     self.volumeDownPressed
185     }, -1)
186     self["actions"].setEnabled(True)
187
188     self.helpList.append((self["actions"], "TeleTextActions", [("1", _("enter page number"))]))
189     self.helpList.append((self["actions"], "TeleTextActions", [("2", _("enter page number"))]))
190     self.helpList.append((self["actions"], "TeleTextActions", [("3", _("enter page number"))]))
191     self.helpList.append((self["actions"], "TeleTextActions", [("4", _("enter page number"))]))
192     self.helpList.append((self["actions"], "TeleTextActions", [("5", _("enter page number"))]))
193     self.helpList.append((self["actions"], "TeleTextActions", [("6", _("enter page number"))]))
194     self.helpList.append((self["actions"], "TeleTextActions", [("7", _("enter page number"))]))
195     self.helpList.append((self["actions"], "TeleTextActions", [("8", _("enter page number"))]))
196     self.helpList.append((self["actions"], "TeleTextActions", [("9", _("enter page number / page 100"))]))
197     self.helpList.append((self["actions"], "TeleTextActions", [("prev", _("prev channel / channel list"))]))
198     self.helpList.append((self["actions"], "TeleTextActions", [("0", _("enter page number / rezap"))]))
199     self.helpList.append((self["actions"], "TeleTextActions", [("next", _("next channel / channel list"))]))
200     self.helpList.append((self["actions"], "OkCancelActions", [("cancel", _("exit"))]))
201 #    self.helpList.append((self["actions"], "TeleTextActions", [("volUp",_("increase width"))]))
202 #    self.helpList.append((self["actions"], "TeleTextActions", [("volDown",_("decrease width"))]))
203     self.helpList.append((self["actions"], "TeleTextActions", [("nextBouquet",_("zoom / increase height"))]))
204     self.helpList.append((self["actions"], "TeleTextActions", [("prevBouquet",_("decrease height"))]))
205     self.helpList.append((self["actions"], "TeleTextActions", [("info", _("toggle info"))]))
206     self.helpList.append((self["actions"], "TeleTextActions", [("menu", _("teletext settings"))]))
207     self.helpList.append((self["actions"], "TeleTextActions", [("up", _("next page / catch page / move"))]))
208     self.helpList.append((self["actions"], "TeleTextActions", [("left", _("prev sub page / move"))]))
209     self.helpList.append((self["actions"], "OkCancelActions", [("ok", _("start page catching / select page"))]))
210     self.helpList.append((self["actions"], "TeleTextActions", [("right", _("next sub page / move"))]))
211     self.helpList.append((self["actions"], "TeleTextActions", [("down", _("prev page / catch page / move"))]))
212     self.helpList.append((self["actions"], "TeleTextActions", [("video", _("toggle flof/top"))]))
213     self.helpList.append((self["actions"], "TeleTextActions", [("red", _("red teletext link"))]))
214     self.helpList.append((self["actions"], "TeleTextActions", [("green", _("green teletext link"))]))
215     self.helpList.append((self["actions"], "TeleTextActions", [("yellow", _("yellow teletext link"))]))
216     self.helpList.append((self["actions"], "TeleTextActions", [("blue", _("blue teletext link"))]))
217     self.helpList.append((self["actions"], "TeleTextActions", [("tv", _("split screen"))]))
218     self.helpList.append((self["actions"], "TeleTextActions", [("radio", _("toggle transparency"))]))
219     self.helpList.append((self["actions"], "TeleTextActions", [("text", _("exit"))]))
220
221     self.inMenu = False
222     self.connected = False
223
224     self.ttx = TeletextInterface()
225
226     self.onLayoutFinish.append(self.__layoutFinished)
227     self.onExecBegin.append(self.__execBegin)
228     self.onClose.append(self.__closed)
229
230     self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
231     self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
232     try:
233       unlink('/tmp/dbttcp.socket')
234     except:
235       pass
236     self.socket.bind('/tmp/dbttcp.socket')
237     self.listen_sn = eSocketNotifier(self.socket.fileno(), POLLIN)
238     self.listen_sn.callback.append(self.listen_data_avail)
239     self.socket.listen(1)
240
241   def socketSend(self, buf):
242     log("send %s" % (buf))
243     try:
244       s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
245       s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
246       s.settimeout(5.0)
247       if config.plugins.TeleText.debug.value:
248         log("... connecting")
249       s.connect('/tmp/dbttcd.socket')
250     except socket.error, msg:
251       log("couldn't connect to /tmp/dbttcd.socket")
252       log(msg)
253       return
254
255     try:
256       msg_len = len(buf)
257       totalsent = 0
258       while totalsent < msg_len:
259         if config.plugins.TeleText.debug.value:
260           log("... sending")
261         sent = s.send(buf[totalsent:])
262         if sent == 0:
263           raise RuntimeError("socket connection broken")
264         elif config.plugins.TeleText.debug.value:
265           log("    sent %s bytes" % sent)
266         totalsent = totalsent + sent
267       s.close()
268       s = None
269     except socket.error, msg:
270       log("couldn't send data to /tmp/dbttcd.socket")
271       log(msg)
272
273   def getDaemonVersion(self):
274     x = array.array('B')
275     x.append(CMD_VERSION)
276     self.socketSend(x)
277
278
279   def listen_data_avail(self, what):
280     conn, addr = self.socket.accept()
281     buf = conn.recv(8, socket.MSG_WAITALL)
282     x = array.array('H')
283     x.fromstring(buf)
284     if x[0] == 0:
285       self.catchPage = False
286     elif x[0] == 1:
287       self.ttx.update(0,0,492,250, self.zoom, self.filter_mode)
288       if x[1] == 2303:
289         x[1] = 0x0100
290       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)
291       for i in self.onChangedEntry:
292         i()
293     elif x[0] == 2:
294       self.daemonVersion = "%s.%s" % (x[1], x[2])
295       log("daemon version %s" % self.daemonVersion)
296     conn.close()
297
298   def __execBegin(self):
299     log("execBegin")
300
301     if not (config.plugins.TeleText.background_caching.value or self.inMenu):
302       self.checkServiceInfo(True)
303
304     self.updateLayout()
305
306     # send brightness, contrast and transparency...
307     self.sendSettings()
308
309     renderOffset = self.ttx.getRenderBufferOffset()
310     stride = self.ttx.getRenderBufferStride()
311
312     log("framebuffer offset is %08x stride is %08x" % (renderOffset, stride))
313     x = array.array('B', (CMD_RQ_UPDATE, 1, (renderOffset&0xFF000000)>>24, (renderOffset&0xFF0000)>>16, (renderOffset&0xFF00)>>8, renderOffset&0xFF, (stride&0xFF00) >> 8, stride&0xFF))
314     self.socketSend(x)
315     
316     # get daemon version
317     self.getDaemonVersion()
318
319   def __closed(self):
320     log("__closed")
321     renderOffset = self.ttx.getRenderBufferOffset()
322     stride = self.ttx.getRenderBufferStride()
323     x = array.array('B', (CMD_RQ_UPDATE, 0, (renderOffset&0xFF000000)>>24, (renderOffset&0xFF0000)>>16, (renderOffset&0xFF00)>>8, renderOffset&0xFF, (stride&0xFF00) >> 8, stride&0xFF))
324     self.socketSend(x)
325
326     if not (config.plugins.TeleText.background_caching.value or self.inMenu):
327       self.stopCaching()
328
329   def __layoutFinished(self):
330     log("__layoutFinished")
331     self.ttx.show(self.instance)
332
333   def keyNumberGlobal(self, number):
334     if self.nav_mode != NAV_MODE_TEXT or self.catchPage:
335       return
336     log("%s pressed" % (number))
337     x = array.array('B')
338     if self.pageInput == 0:
339       if number == 0:
340         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
341           self.zoom = TeletextInterface.MODE_UPPER_HALF
342         x.append(CMD_RZAP_PAGE)
343       elif number == 9:
344         x.fromlist([CMD_SHOW_PAGE, 1, 0, 0])
345       else:
346         x.fromlist([CMD_PAGEINPUT, number])
347         self.pageInput = (self.pageInput + 1) % 3
348     else:
349       x.fromlist([CMD_PAGEINPUT, number])
350       self.pageInput = (self.pageInput + 1) % 3
351     self.socketSend(x)
352
353   def upPressed(self):
354     if self.nav_mode == NAV_MODE_TEXT:
355       if self.pageInput != 0:
356         return
357       log("up pressed")
358       if self.catchPage:
359         x = array.array('B', (CMD_CATCHPAGE, 2, 2))
360       else:
361         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
362           self.zoom = TeletextInterface.MODE_UPPER_HALF
363         x = array.array('B')
364         x.append(CMD_PAGE_NEXT)
365       self.socketSend(x)
366     else:
367       if self.nav_pos[1] > 0 and self.nav_pos[3] > self.nav_config.limits[3][0]:
368         self.nav_pos[1] = self.nav_pos[1] - 1
369         self.nav_pos[3] = self.nav_pos[3] - 1
370       self.updateLayout()
371
372   def downPressed(self):
373     if self.nav_mode == NAV_MODE_TEXT:
374       if self.pageInput != 0:
375         return
376       log("down pressed")
377       if self.catchPage:
378         x = array.array('B', (CMD_CATCHPAGE, 2, 3))
379       else:
380         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
381           self.zoom = TeletextInterface.MODE_UPPER_HALF
382         x = array.array('B')
383         x.append(CMD_PAGE_PREV)
384       self.socketSend(x)
385     else:
386       if self.nav_pos[1] < self.nav_config.limits[1][1] and self.nav_pos[3] < dsk_height:
387         self.nav_pos[1] = self.nav_pos[1] + 1
388         self.nav_pos[3] = self.nav_pos[3] + 1
389         self.updateLayout()
390
391   def leftPressed(self):
392     if self.nav_mode == NAV_MODE_TEXT:
393       if self.pageInput != 0:
394         return
395       log("left pressed")
396       if self.catchPage:
397         x = array.array('B', (CMD_CATCHPAGE, 2, 0))
398       else:
399         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
400           self.zoom = TeletextInterface.MODE_UPPER_HALF
401         x = array.array('B')
402         x.append(CMD_SUBP_PREV)
403       self.socketSend(x)
404     else:
405       if self.nav_pos[0] > 0 and self.nav_pos[2] > self.nav_config.limits[2][0]:
406         self.nav_pos[0] = self.nav_pos[0] - 1
407         self.nav_pos[2] = self.nav_pos[2] - 1
408       self.updateLayout()
409
410   def rightPressed(self):
411     if self.nav_mode == NAV_MODE_TEXT:
412       if self.pageInput != 0:
413         return
414       log("right pressed")
415       if self.catchPage:
416         x = array.array('B', (CMD_CATCHPAGE, 2, 1))
417       else:
418         if self.zoom == TeletextInterface.MODE_LOWER_HALF:
419           self.zoom = TeletextInterface.MODE_UPPER_HALF
420         x = array.array('B')
421         x.append(CMD_SUBP_NEXT)
422       self.socketSend(x)
423     else:
424       if self.nav_pos[0] < self.nav_config.limits[0][1] and self.nav_pos[2] < dsk_width:
425         self.nav_pos[0] = self.nav_pos[0] + 1
426         self.nav_pos[2] = self.nav_pos[2] + 1
427         self.updateLayout()
428
429   def nextBouquetPressed(self):
430     log("bouqet+ pressed")
431     if self.nav_mode == NAV_MODE_TEXT:
432       if self.catchPage or self.pageInput != 0:
433         return
434       # zoom teletext
435       if self.zoom == TeletextInterface.MODE_UPPER_HALF:
436         self.zoom = TeletextInterface.MODE_LOWER_HALF
437       elif self.zoom == TeletextInterface.MODE_LOWER_HALF:
438         self.zoom = TeletextInterface.MODE_FULL
439       else:
440         self.zoom = TeletextInterface.MODE_UPPER_HALF
441
442       if self.zoom:
443         self.filter_mode = int(config.plugins.TeleText.scale_filter_zoom.value)
444       else:
445         self.filter_mode = int(config.plugins.TeleText.scale_filter.value)
446     else:
447       # position setup
448       if self.nav_pos[3] < dsk_height:
449         self.nav_pos[3] = self.nav_pos[3] + 1
450       elif self.nav_pos[1] > 0:
451         self.nav_pos[1] = self.nav_pos[1] - 1
452     self.updateLayout()
453
454   def prevBouquetPressed(self):
455     if self.nav_mode == NAV_MODE_TEXT:
456       return
457     log("bouquet- pressed")
458     if self.nav_pos[3] > (self.nav_pos[1] + MIN_H):
459       if self.nav_pos[3] > self.nav_config.limits[3][0]:
460         self.nav_pos[3] = self.nav_pos[3] - 1
461       elif self.nav_pos[1] < self.nav_config.limits[1][1]:
462         self.nav_pos[1] = self.nav_pos[1] + 1
463       self.updateLayout()
464
465   def volumeUpPressed(self):
466     if self.nav_mode == NAV_MODE_TEXT:
467       globalActionMap.action("TeleText", "volumeUp")
468       return
469     log("volume+ pressed")
470     if self.nav_pos[2] < dsk_width:
471       self.nav_pos[2] = self.nav_pos[2] + 1
472     elif self.nav_pos[0] > 0:
473       self.nav_pos[0] = self.nav_pos[0] - 1
474     self.updateLayout()
475
476   def volumeDownPressed(self):
477     if self.nav_mode == NAV_MODE_TEXT:
478       globalActionMap.action("TeleText", "volumeDown")
479       return
480     log("volume- pressed")
481     if self.nav_pos[2] > (self.nav_pos[0] + MIN_W):
482       if self.nav_pos[2] > self.nav_config.limits[2][0]:
483         self.nav_pos[2] = self.nav_pos[2] - 1
484       elif self.nav_pos[0] < self.nav_config.limits[0][1]:
485         self.nav_pos[0] = self.nav_pos[0] + 1
486     self.updateLayout()
487
488   def redPressed(self):
489     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
490       return
491     log("red pressed")
492     x = array.array('B')
493     x.append(CMD_COLKEY_RD)
494     self.socketSend(x)
495
496   def greenPressed(self):
497     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
498       return
499     log("green pressed")
500     x = array.array('B')
501     x.append(CMD_COLKEY_GN)
502     self.socketSend(x)
503
504   def yellowPressed(self):
505     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
506       return
507     log("yellow pressed")
508     x = array.array('B')
509     x.append(CMD_COLKEY_YE)
510     self.socketSend(x)
511
512   def bluePressed(self):
513     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
514       return
515     log("blue pressed")
516     x = array.array('B')
517     x.append(CMD_COLKEY_BL)
518     self.socketSend(x)
519
520   def infoPressed(self):
521     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
522       return
523     log("info pressed")
524     self.infoValue = not self.infoValue
525     for i in self.onChangedEntry:
526       i()
527     x = array.array('B')
528     x.append(CMD_CONCEALED)
529     self.socketSend(x)
530
531   def videoPressed(self):
532     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
533       return
534     log("video pressed")
535     self.naviValue = not self.naviValue
536     for i in self.onChangedEntry:
537       i()
538     x = array.array('B')
539     x.append(CMD_FLOF)
540     self.socketSend(x)
541
542   def tvPressed(self):
543     if self.nav_mode != NAV_MODE_TEXT:
544       return
545     log("tv pressed")
546     if config.plugins.TeleText.textOnly.value:
547       config.plugins.TeleText.textOnly.value = False
548     else:
549       config.plugins.TeleText.textOnly.value = True
550     config.plugins.TeleText.textOnly.save()
551     configfile.save()
552     self.updateLayout()
553
554   def radioPressed(self):
555     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
556       return
557     log("radio pressed")
558     if config.plugins.TeleText.opaque.value:
559       config.plugins.TeleText.opaque.value = False
560     else:
561       config.plugins.TeleText.opaque.value = True
562     config.plugins.TeleText.opaque.save()
563     configfile.save()
564     self.opaqueValue = config.plugins.TeleText.opaque.value
565     x = array.array('B')
566     x.append(CMD_OPAQUE)
567     self.socketSend(x)
568
569   def textPressed(self):
570     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
571       return
572     log("text pressed")
573     self.resetVideo()
574     self.__closed()
575     if self.txtpid != self.txtpid_origin:
576       self.txtpid = self.txtpid_origin
577       self.switchChannel(True)
578     self.close()
579
580   def menuPressed(self):
581     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
582       return
583     log("menu pressed")
584     self.__closed()
585     self.resetVideo()
586     self.inMenu = True
587     self.session.openWithCallback(self.menuResult, TeleTextMenu, parent = self)
588
589   def menuResult(self, result):
590     self.inMenu = False
591     if result is None:
592       config.plugins.TeleText.pos.load()
593       config.plugins.TeleText.tip_pos.load()
594       self.updateLayout()
595       return
596
597     self.nav_text_only = config.plugins.TeleText.textOnly.value
598     self.nav_config   = result
599     self.nav_orig_pos = result.value
600     self.nav_pos      = result.value
601
602     if result == config.plugins.TeleText.pos:
603       self.nav_mode = NAV_MODE_SIZE_TEXT
604       config.plugins.TeleText.textOnly.value = True
605     elif result == config.plugins.TeleText.tip_pos:
606       self.nav_mode = NAV_MODE_SIZE_TIP_TEXT
607       config.plugins.TeleText.textOnly.value = False
608       config.plugins.TeleText.textOnly.value = SPLIT_MODE_TIP
609     self.updateLayout()
610
611   def updateLayout(self):
612     if self.nav_mode == NAV_MODE_TEXT:
613       pos = config.plugins.TeleText.pos.value
614     else:
615       pos = self.nav_pos
616     right  = pos[2]
617     bottom = pos[3]
618     mode = config.plugins.TeleText.splitting_mode.value
619
620     if config.plugins.TeleText.textOnly.value == True:
621       left  = pos[0]
622       width  = right - left
623       top    = pos[1]
624       height = bottom - top
625       self.resetVideo()
626     elif mode == SPLIT_MODE_PAT:
627       left   = dsk_width>>1
628       width  = right - (dsk_width>>1)
629       top    = pos[1]
630       height = bottom - top
631       log("splitting video")
632       l=open("/proc/stb/vmpeg/0/dst_left","w")
633       l.write("%x" % 0)
634       l.close()
635       w=open("/proc/stb/vmpeg/0/dst_width","w")
636       w.write("%x" % 360)
637       w.close()
638     elif mode == SPLIT_MODE_TAP:
639       left   = pos[0]
640       width  = (dsk_width>>1) - left
641       top    = pos[1]
642       height = bottom - top
643       log("splitting video")
644       l=open("/proc/stb/vmpeg/0/dst_left","w")
645       l.write("%x" % 360)
646       l.close()
647       w=open("/proc/stb/vmpeg/0/dst_width","w")
648       w.write("%x" % 360)
649       w.close()
650     elif mode == SPLIT_MODE_TIP:
651       if self.nav_mode == NAV_MODE_TEXT:
652         pos = config.plugins.TeleText.tip_pos.value
653       left   = pos[0]
654       width  = pos[2] - left
655       top    = pos[1]
656       height = pos[3] - top
657       self.resetVideo()
658
659     log("screen rect %s %s %s %s" % (left, top, width, height))
660     self.instance.move(ePoint(left,top))
661     self.instance.resize(eSize(*(width, height)))
662
663     self.ttx.hide()
664     self.ttx.show(self.instance)
665     self.ttx.update(0,0,492,250,self.zoom,self.filter_mode)
666
667   def resetVideo(self):
668     log("reset video")
669     l=open("/proc/stb/vmpeg/0/dst_left","w")
670     l.write("%x" % 0)
671     l.close()
672     w=open("/proc/stb/vmpeg/0/dst_width","w")
673     w.write("%x" % 720)
674     w.close()
675
676   def sendSettings(self, result = True):
677     if result:
678       # region
679       x = array.array('B')
680       x.append(CMD_REGION)
681       x.append(int(config.plugins.TeleText.region.value))
682       self.socketSend(x)
683       # Helligkeit
684       x = array.array('B')
685       x.append(CMD_SET_BRIGH)
686       x.append(config.plugins.TeleText.brightness.value<<4)
687       self.socketSend(x)
688       # Kontrast
689       x = array.array('B')
690       x.append(CMD_SET_CONTR)
691       x.append(config.plugins.TeleText.contrast.value<<4)
692       self.socketSend(x)
693       # Transparenz
694       x = array.array('B')
695       x.append(CMD_TRANSPARENCY)
696       x.append(config.plugins.TeleText.transparency.value<<4)
697       self.socketSend(x)
698       # edge cut
699       if self.edgeValue != config.plugins.TeleText.edge_cut.value:
700         self.edgeValue = config.plugins.TeleText.edge_cut.value
701         x = array.array('B')
702         x.append(CMD_EDGE_CUT)
703         self.socketSend(x)
704       # teletext level
705       x = array.array('B')
706       x.append(CMD_TEXTLEVEL)
707       x.append(int(config.plugins.TeleText.textlevel.value))
708       self.socketSend(x)
709       # opaque
710       if self.opaqueValue != config.plugins.TeleText.opaque.value:
711         self.opaqueValue = config.plugins.TeleText.opaque.value
712         x = array.array('B')
713         x.append(CMD_OPAQUE)
714         self.socketSend(x)
715
716   def prevPressed(self):
717     if self.nav_mode == NAV_MODE_TEXT:
718       log("prev pressed")
719
720       if len(self.pid_list) < 2:
721         return
722
723       new_pid = -1
724       while new_pid == -1:
725         if self.pid_index == 0:
726           self.pid_index = len(self.pid_list) - 1
727         else:
728           self.pid_index = self.pid_index - 1
729         new_pid = self.pid_list[self.pid_index][2]
730
731       self.txtpid = new_pid
732       log("new txtpid: %s" % new_pid)
733       self.switchChannel(True)
734
735   def nextPressed(self):
736     if self.nav_mode == NAV_MODE_TEXT:
737       log("next pressed")
738
739       if len(self.pid_list) < 2:
740         return
741
742       new_pid = -1
743       while new_pid == -1:
744         if self.pid_index == (len(self.pid_list) - 1):
745           self.pid_index = 0
746         else:
747           self.pid_index = self.pid_index + 1
748         new_pid = self.pid_list[self.pid_index][2]
749
750       self.txtpid = new_pid
751       log("new txtpid: %s" % new_pid)
752       self.switchChannel(True)
753
754   def prevLongPressed(self):
755     if self.nav_mode == NAV_MODE_TEXT:
756       log("prev long pressed")
757       if len(self.pid_list) > 0:
758         self.__closed()
759         self.resetVideo()
760         self.session.openWithCallback(self.transponderResult, TeleTextTransponderMenu, self.pid_list, self.pid_index)
761
762   def nextLongPressed(self):
763     if self.nav_mode == NAV_MODE_TEXT:
764       log("next long pressed")
765       self.prevLongPressed()
766
767   def transponderResult(self, result):
768     log("transponder result: %s" % result)
769     if result > -1 and result != self.txtpid:
770       self.txtpid = result
771       log("new txtpid: %s" % result)
772       self.switchChannel(True)
773     self.updateLayout()
774
775   def helpPressed(self):
776     self.__closed()
777     self.resetVideo()
778     self.session.open(HelpMenu, self.helpList)
779
780   def okPressed(self):
781     if self.nav_mode == NAV_MODE_TEXT:
782       if self.pageInput != 0:
783         return
784       log("ok pressed")
785       if self.catchPage:
786         x = array.array('B', (CMD_CATCHPAGE, 3, 1))
787         self.catchPage = False
788       else:
789         x = array.array('B', (CMD_CATCHPAGE, 1, 0))
790         self.catchPage = True
791         self.zoom = TeletextInterface.MODE_FULL
792         self.filter_mode = int(config.plugins.TeleText.scale_filter.value)
793       self.socketSend(x)
794     else:
795       if self.nav_mode == NAV_MODE_SIZE_TEXT:
796         config.plugins.TeleText.pos.value = self.nav_pos
797         config.plugins.TeleText.pos.save()
798       else:
799         config.plugins.TeleText.tip_pos.value = self.nav_pos
800         config.plugins.TeleText.tip_pos.save()
801       config.plugins.TeleText.textOnly.value = self.nav_text_only
802       del self.nav_text_only
803       del self.nav_config
804       del self.nav_orig_pos
805       del self.nav_pos
806       self.nav_mode = NAV_MODE_TEXT
807       self.updateLayout()
808
809   def cancelPressed(self):
810     if self.nav_mode == NAV_MODE_TEXT:
811       if self.pageInput != 0:
812         return
813       log("cancel pressed")
814       if self.catchPage:
815         x = array.array('B', (CMD_CATCHPAGE, 3, 0))
816         self.socketSend(x)
817         self.catchPage = False
818       else:
819         self.resetVideo()
820         self.__closed()
821         if self.txtpid != self.txtpid_origin:
822           self.txtpid = self.txtpid_origin
823           self.switchChannel(True)
824         self.close()
825     else:
826       if self.nav_mode == NAV_MODE_SIZE_TEXT:
827         config.plugins.TeleText.pos.cancel()
828       else:
829         config.plugins.TeleText.tip_pos.cancel()
830       config.plugins.TeleText.textOnly.value = self.nav_text_only
831       del self.nav_text_only
832       del self.nav_config
833       del self.nav_orig_pos
834       del self.nav_pos
835       self.nav_mode = NAV_MODE_TEXT
836       self.updateLayout()
837
838   def serviceStarted(self):
839     log("service started")
840
841   def serviceStopped(self):
842     log("service stopped")
843     self.stopCaching()
844
845   def stopCaching(self):
846     x = array.array('B', (CMD_CTL_CACHE, 0, 0, 0))
847     self.socketSend(x)
848
849   def serviceInfoChanged(self):
850     log("serviceInfoChanged")
851     self.checkServiceInfo(config.plugins.TeleText.background_caching.value or self.inMenu or self.execing)
852
853   def checkServiceInfo(self, do_send = True):
854     service = self.session.nav.getCurrentService()
855     info = service and service.info()
856     self.txtpid_origin = info and info.getInfo(iServiceInformation.sTXTPID)
857     self.txtpid = self.txtpid_origin
858
859     stream = service and service.stream()
860     demux = stream and stream.getStreamingData()
861     self.demux = demux and demux.get("demux", -1)
862
863     log("TXT PID %s DEMUX %s" % (self.txtpid, self.demux))
864     self.switchChannel(do_send)
865
866     # read all txtpids and channels from transponder
867     cur_ref = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
868     if cur_ref is None:
869       self.channel_and_txt_pid = []
870       self.pid_index = 0
871     else:
872       pos = service_types_tv.rfind(':')
873       refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' % (service_types_tv[:pos+1],
874           cur_ref.getUnsignedData(4), # NAMESPACE
875           cur_ref.getUnsignedData(2), # TSID
876           cur_ref.getUnsignedData(3), # ONID
877           service_types_tv[pos+1:])
878       ref = eServiceReference(refstr)
879       self.pid_list = self.ttx.getTextPidsAndName(ref)
880
881     i = 0
882     available = 0
883     for x in self.pid_list:
884       if x[2] != -1:
885         available = available + 1
886       if x[2] == self.txtpid:
887         self.pid_index = i
888       i = i + 1
889     self.pid_count = available
890
891     log("transponder: %s" % self.pid_list)
892
893   def switchChannel(self, do_send = True):
894     if self.demux > -1 and self.txtpid > -1 and do_send:
895       x = array.array('B', (CMD_CTL_CACHE, (self.txtpid & 0xFF00) >> 8, (self.txtpid & 0xFF), self.demux))
896       self.socketSend(x)
897
898   def showMessages(self):
899     return config.plugins.TeleText.messages.value
900
901   # ---- for summary (lcd) ----
902
903   def createSummary(self):
904     return TeleTextSummary
905
906   def getCurrentPage(self):
907     return self.cur_page
908
909   def getAvailableTxtPidCount(self):
910     return self.pid_count
911
912   def naviEnabled(self):
913     return self.naviValue
914
915   def infoEnabled(self):
916     return self.infoValue
917
918 # ----------------------------------------
919
920 class TeleTextSummary(Screen):
921
922   def __init__(self, session, parent):
923     onPic  = resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/lcd_on.png")
924     offPic = resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/lcd_off.png")
925
926     TeleTextSummary.skin = ("""<screen name="TeleTextSummary" position="0,0" size="132,64" id="1">
927       <widget name="page"     position="0,0"   size="132,20" font="Regular;20" valign="center" halign="center" zPosition="1"/>
928
929       <widget name="navi_off" position="12,28"  size="20,20" pixmap="%s" zPosition="1"/>
930       <widget name="info_off" position="100,28" size="20,20" pixmap="%s" zPosition="1"/>
931       <widget name="navi_on"  position="12,28"  size="20,20" pixmap="%s" zPosition="2"/>
932       <widget name="info_on"  position="100,28" size="20,20" pixmap="%s" zPosition="2"/>
933       <widget name="tp_count" position="44,28"  size="44,20" font="Regular;16" valign="center" halign="center" zPosition="1"/>
934
935       <widget name="navi_txt" position="0,50"  size="44,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
936       <widget name="tp_txt"   position="44,50" size="44,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
937       <widget name="info_txt" position="88,50" size="44,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
938     </screen>""" % (offPic, offPic, onPic, onPic),
939     """<screen name="TeleTextSummary" position="0,0" size="96,64" id="2">
940       <widget name="page"     position="0,0"   size="96,20" font="Regular;20" valign="center" halign="center" zPosition="1"/>
941
942       <widget name="navi_off" position="6,28"  size="20,20" pixmap="%s" zPosition="1"/>
943       <widget name="info_off" position="70,28" size="20,20" pixmap="%s" zPosition="1"/>
944       <widget name="navi_on"  position="6,28"  size="20,20" pixmap="%s" zPosition="2"/>
945       <widget name="info_on"  position="70,28" size="20,20" pixmap="%s" zPosition="2"/>
946       <widget name="tp_count" position="32,28" size="32,20" font="Regular;16" valign="center" halign="center" zPosition="1"/>
947
948       <widget name="navi_txt" position="0,50"  size="32,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
949       <widget name="tp_txt"   position="36,50" size="32,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
950       <widget name="info_txt" position="64,50" size="32,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
951     </screen>""" % (offPic, offPic, onPic, onPic))
952
953     Screen.__init__(self, session, parent = parent)
954     self["page"] = Label("")
955     self["navi_txt"] = Label("NAVI")
956     self["tp_txt"] = Label("TPT")
957     self["tp_count"] = Label("<1>")
958     self["info_txt"] = Label("INFO")
959     self["navi_off"] = Pixmap()
960     self["info_off"] = Pixmap()
961     self["navi_on"]  = Pixmap()
962     self["info_on"]  = Pixmap()
963     self.onShow.append(self.addWatcher)
964     self.onHide.append(self.removeWatcher)
965
966   def addWatcher(self):
967     self.parent.onChangedEntry.append(self.selectionChanged)
968     self.selectionChanged()
969
970   def removeWatcher(self):
971     self.parent.onChangedEntry.remove(self.selectionChanged)
972
973   def selectionChanged(self):
974     self["tp_count"].setText("< %s >"%self.parent.getAvailableTxtPidCount())
975     self["page"].setText(self.parent.getCurrentPage())
976     if self.parent.naviEnabled():
977       self["navi_off"].hide()
978       self["navi_on"].show()
979     else:
980       self["navi_on"].hide()
981       self["navi_off"].show()
982
983     if self.parent.infoEnabled():
984       self["info_off"].hide()
985       self["info_on"].show()
986     else:
987       self["info_on"].hide()
988       self["info_off"].show()
989
990 # ----------------------------------------
991
992 class TeleTextTransponderMenu(Screen):
993
994   ch_list = []
995   ch_index = 0
996
997   cur_service = ""
998   new_service = ""
999
1000   onChangedEntry = [ ]
1001
1002   def __init__(self, session, list, index):
1003     log("[transponder] __init__")
1004
1005     self.ch_list = list
1006     self.ch_index = index
1007     self.cur_service = self.ch_list[self.ch_index][1]
1008
1009     width = 420
1010     height = 75
1011     left = (dsk_width - width)>>1
1012     top = (dsk_height - height)>>1
1013     log("[transponder] screen rect %s %s %s %s" % (left, top, width, height))
1014     TeleTextTransponderMenu.skin = """<screen position="%d,%d" size="%d,%d" title="%s">
1015         <widget name="prev"    position="0,5"   size="35,25"  zPosition="4" pixmap="%s" alphatest="on"/>
1016         <widget name="channel" position="40,7"  size="325,20" zPosition="5" valign="center" halign="left"  font="Regular;21" transparent="1" foregroundColor="white"/>
1017         <widget name="zapped"  position="365,7" size="20,20"  zPosition="5" valign="center" halign="right" font="Regular;21" transparent="1" foregroundColor="#888888"/>
1018         <widget name="next"    position="385,5" size="35,25"  zPosition="4" pixmap="%s" alphatest="on"/>
1019
1020         <ePixmap pixmap="skin_default/div-h.png" position="0,32" zPosition="1" size="420,2" />
1021
1022         <ePixmap pixmap="skin_default/buttons/red.png"    position="0,35"   zPosition="0" size="140,40" transparent="1" alphatest="on" />
1023         <ePixmap pixmap="skin_default/buttons/green.png"  position="280,35" zPosition="0" size="140,40" transparent="1" alphatest="on" />
1024         <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" />
1025         <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" />
1026       </screen>""" % (left, top, width, height, _("Select teletext"), resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/key_lt.png"), resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/key_gt.png"))
1027     Screen.__init__(self, session)
1028
1029     self["actions"] = ActionMap(["OkCancelActions", "TeleTextActions"],
1030     {
1031       "ok"     : self.okPressed,
1032       "cancel" : self.cancelPressed,
1033       "red"    : self.cancelPressed,
1034       "green"  : self.okPressed,
1035       "left"   : self.prevPressed,
1036       "right"  : self.nextPressed,
1037       "prev"   : self.prevPressed,
1038       "next"   : self.nextPressed,
1039       "prev_long": self.prevPressed,
1040       "next_long": self.nextPressed
1041     }, -2)
1042     self["actions"].setEnabled(True)
1043
1044     self["key_r"] = Label(_("Cancel"))
1045     self["key_g"] = Label(_("OK"))
1046
1047     self["channel"] = Label("")
1048     self["prev"] = Pixmap()
1049     self["next"] = Pixmap()
1050     self["zapped"] = Label("*")
1051     self["zapped"].hide()
1052     if len(self.ch_list) == 1:
1053       self["prev"].hide()
1054       self["next"].hide()
1055     else:
1056       self["prev"].show()
1057       self["next"].show()
1058     self.updateLayout()
1059
1060   def updateLayout(self):
1061     if self.ch_list[self.ch_index][2] == -1:
1062       self["zapped"].show()
1063       self["key_g"].setText("")
1064     else:
1065       self["zapped"].hide()
1066       self["key_g"].setText(_("OK"))
1067     self.new_service = self.ch_list[self.ch_index][1]
1068     self["channel"].setText(self.new_service)
1069     for i in self.onChangedEntry:
1070       i()
1071
1072   def prevPressed(self):
1073     log("[transponder] prev pressed")
1074     if self.ch_index == 0:
1075       self.ch_index = len(self.ch_list) - 1
1076     else:
1077       self.ch_index = self.ch_index - 1
1078     self.updateLayout()
1079
1080   def nextPressed(self):
1081     log("[transponder] next pressed")
1082     if self.ch_index == (len(self.ch_list) - 1):
1083       self.ch_index = 0
1084     else:
1085       self.ch_index = self.ch_index + 1
1086     self.updateLayout()
1087
1088   def okPressed(self):
1089     log("[transponder] ok pressed")
1090     if self.ch_list[self.ch_index][2] > -1:
1091       self.close(self.ch_list[self.ch_index][2])
1092
1093   def cancelPressed(self):
1094     log("[transponder] cancel pressed")
1095     self.close(-1)
1096
1097   # ---- for summary (lcd) ----
1098
1099   def createSummary(self):
1100     return TeleTextTransponderSummary
1101
1102   def getCurrentService(self):
1103     return self.cur_service
1104
1105   def getNewService(self):
1106     return self.new_service
1107
1108 # ----------------------------------------
1109
1110 class TeleTextTransponderSummary(Screen):
1111
1112   def __init__(self, session, parent):
1113
1114     TeleTextTransponderSummary.skin = ("""<screen name="TeleTextTransponderSummary" position="0,0" size="132,64" id="1">
1115       <widget name="c_service" position="0,5"   size="100,20" font="Regular;20" halign="left"/>
1116       <ePixmap pixmap="skin_default/div-h.png" position="46,32" size="40,2" zPosition="1"/>
1117       <widget name="n_service" position="32,39" size="100,20" font="Regular;20" halign="right"/>
1118     </screen>""",
1119     """<screen name="TeleTextTransponderSummary" position="0,0" size="96,64" id="2">
1120       <widget name="c_service" position="0,5"   size="90,20" font="Regular;20" halign="left"/>
1121       <ePixmap pixmap="skin_default/div-h.png" position="28,32" size="40,2" zPosition="1"/>
1122       <widget name="n_service" position="6,39" size="90,20" font="Regular;20" halign="right"/>
1123     </screen>""")
1124
1125     Screen.__init__(self, session, parent = parent)
1126     self["c_service"] = Label(self.parent.getCurrentService())
1127     self["n_service"] = Label(self.parent.getNewService())
1128     self.onShow.append(self.addWatcher)
1129     self.onHide.append(self.removeWatcher)
1130
1131   def addWatcher(self):
1132     self.parent.onChangedEntry.append(self.selectionChanged)
1133     self.selectionChanged()
1134
1135   def removeWatcher(self):
1136     self.parent.onChangedEntry.remove(self.selectionChanged)
1137
1138   def selectionChanged(self):
1139     self["n_service"].setText(self.parent.getNewService())
1140
1141 # ----------------------------------------
1142
1143 class TeleTextMenu(ConfigListScreen, Screen):
1144
1145   onChangedEntry = [ ]
1146   isInitialized = False
1147   parent = None
1148
1149   def __init__(self, session, parent):
1150     width = 492
1151     height = 480
1152     left = (dsk_width - width)>>1
1153     top = (dsk_height - height)>>1
1154     log("[menu] screen rect %s %s %s %s" % (left, top, width, height))
1155     TeleTextMenu.skin = """<screen position="%d,%d" size="%d,%d" title="%s">
1156         <widget name="config" position="0,0"   size="492,355" scrollbarMode="showOnDemand" zPosition="1"/>
1157         <ePixmap pixmap="skin_default/div-h.png" position="0,358" zPosition="1" size="492,2" />
1158         <widget name="label"  position="0,360" size="492,70" font="Regular;16" zPosition="1" halign="left" valign="top"/>
1159         <ePixmap pixmap="skin_default/div-h.png" position="0,435" zPosition="1" size="492,2" />
1160         <ePixmap pixmap="skin_default/buttons/red.png"    position="0,440"   zPosition="0" size="140,40" transparent="1" alphatest="on" />
1161         <ePixmap pixmap="skin_default/buttons/green.png"  position="176,440" zPosition="0" size="140,40" transparent="1" alphatest="on" />
1162         <ePixmap pixmap="skin_default/buttons/yellow.png" position="352,440" zPosition="0" size="140,40" transparent="1" alphatest="on" />
1163         <widget name="key_r" position="0,440"   size="140,40" zPosition="5" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1164         <widget name="key_g" position="176,440" size="140,40" zPosition="5" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1165         <widget name="key_y" position="352,440" size="140,40" zPosition="5" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1166       </screen>""" % (left, top, width, height, _("TeleText settings"))
1167
1168     Screen.__init__(self, session, parent)
1169
1170     # create config list
1171     self.list = []
1172     ConfigListScreen.__init__(self, self.list)
1173     self.createConfigList()
1174
1175     self["actions"] = ActionMap(["OkCancelActions", "TeleTextActions"],
1176     {
1177       "ok"     : self.okPressed,
1178       "cancel" : self.cancelPressed,
1179       "red"    : self.cancelPressed,
1180       "green"  : self.okPressed,
1181       "yellow" : self.resetPressed,
1182       "menu"   : self.cancelPressed,
1183       "text"   : self.textPressed,
1184       "info"   : self.infoPressed
1185     }, -2)
1186     self["actions"].setEnabled(True)
1187
1188     self["label"] = Label("Info")
1189     self["key_r"] = Label(_("Cancel"))
1190     self["key_y"] = Label(_("Default"))
1191     self["key_g"] = Label(_("OK"))
1192     self.onLayoutFinish.append(self.__layoutFinished)
1193
1194   def __layoutFinished(self):
1195     self.isInitialized = True
1196     if not self.selectionChanged in self["config"].onSelectionChanged:
1197       self["config"].onSelectionChanged.append(self.selectionChanged)
1198     self.selectionChanged()
1199
1200   def selectionChanged(self):
1201     configele = self["config"].getCurrent()[1]
1202     if configele == config.plugins.TeleText.pos:
1203       self["label"].setText(HELP_TEXT_POS)
1204     elif configele == config.plugins.TeleText.brightness:
1205       self["label"].setText(HELP_TEXT_BRIGHTNESS)
1206     elif configele == config.plugins.TeleText.contrast:
1207       self["label"].setText(HELP_TEXT_CONTRAST)
1208     elif configele == config.plugins.TeleText.transparency:
1209       self["label"].setText(HELP_TEXT_TRANSPARENCY)
1210     elif configele == config.plugins.TeleText.splitting_mode:
1211       self["label"].setText(HELP_TEXT_SPLITTING)
1212     elif configele == config.plugins.TeleText.tip_pos:
1213       self["label"].setText(HELP_TEXT_TIP_POS)
1214     elif configele == config.plugins.TeleText.messages:
1215       self["label"].setText(HELP_TEXT_MESSAGES)
1216     elif configele == config.plugins.TeleText.debug:
1217       self["label"].setText(HELP_TEXT_DEBUG)
1218     elif configele == config.plugins.TeleText.edge_cut:
1219       self["label"].setText(HELP_TEXT_EDGE_CUT)
1220     elif configele == config.plugins.TeleText.textlevel:
1221       self["label"].setText(HELP_TEXT_TEXTLEVEL)
1222     elif configele == config.plugins.TeleText.region:
1223       self["label"].setText(HELP_TEXT_REGION)
1224     elif configele == config.plugins.TeleText.scale_filter:
1225       self["label"].setText(HELP_TEXT_SCALE_FILTER)
1226     elif configele == config.plugins.TeleText.scale_filter_zoom:
1227       self["label"].setText(HELP_TEXT_SCALE_FILTER)
1228     elif configele == config.plugins.TeleText.background_caching:
1229       self["label"].setText(HELP_TEXT_CACHING)
1230
1231   def createConfig(self, configele):
1232     if not self.isInitialized:
1233       return
1234     self.createConfigList()
1235
1236   def createConfigList(self):
1237     self.isInitialized = False
1238
1239     # remove notifiers
1240     for x in self["config"].list:
1241       x[1].clearNotifiers()
1242
1243     self.list = [
1244       getConfigListEntry(_("Scale filter"),      config.plugins.TeleText.scale_filter),
1245       getConfigListEntry(_("Scale filter zoom"), config.plugins.TeleText.scale_filter_zoom),
1246       getConfigListEntry(_("Brightness"),        config.plugins.TeleText.brightness),
1247       getConfigListEntry(_("Contrast"),          config.plugins.TeleText.contrast),
1248       getConfigListEntry(_("Transparency"),      config.plugins.TeleText.transparency),
1249       getConfigListEntry(_("Text level"),        config.plugins.TeleText.textlevel),
1250       getConfigListEntry(_("Region"),            config.plugins.TeleText.region),
1251       getConfigListEntry(_("Position and size"), config.plugins.TeleText.pos),
1252       getConfigListEntry(_("Display edges"),     config.plugins.TeleText.edge_cut),
1253       getConfigListEntry(_("Splitting mode"),    config.plugins.TeleText.splitting_mode)
1254     ]
1255     if config.plugins.TeleText.splitting_mode.value == SPLIT_MODE_TIP:
1256       self.list.append(getConfigListEntry("... %s" % _("Position and size"),   config.plugins.TeleText.tip_pos))
1257     self.list.append(getConfigListEntry(_("Background caching"),config.plugins.TeleText.background_caching))
1258     self.list.append(getConfigListEntry(_("Message"), config.plugins.TeleText.messages))
1259     self.list.append(getConfigListEntry(_("Debug"),   config.plugins.TeleText.debug))
1260
1261     self["config"].list = self.list
1262
1263     # add notifiers (lcd, info)
1264     for x in self["config"].list:
1265       x[1].addNotifier(self.changedEntry)
1266     # add notifiers (menu)
1267     config.plugins.TeleText.splitting_mode.addNotifier(self.createConfig)
1268
1269     self.isInitialized = True
1270
1271   def resetPressed(self):
1272     log("[menu] reset pressed")
1273     config.plugins.TeleText.scale_filter.setValue("%d"%BILINEAR)
1274     config.plugins.TeleText.scale_filter_zoom.setValue("%d"%BILINEAR)
1275     config.plugins.TeleText.brightness.setValue(8)
1276     config.plugins.TeleText.contrast.setValue(12)
1277     config.plugins.TeleText.transparency.setValue(8)
1278     config.plugins.TeleText.messages.setValue(True)
1279     config.plugins.TeleText.edge_cut.setValue(False)
1280     config.plugins.TeleText.splitting_mode.setValue(SPLIT_MODE_PAT)
1281     config.plugins.TeleText.textlevel.setValue("2")
1282     config.plugins.TeleText.region.setValue("16")
1283     config.plugins.TeleText.debug.setValue(False)
1284     config.plugins.TeleText.pos.setValue([0, 0, dsk_width, dsk_height])
1285     config.plugins.TeleText.tip_pos.setValue([(dsk_width>>1)+(dsk_width>>2), (dsk_height>>1)+(dsk_height>>2), dsk_width, dsk_height])
1286     config.plugins.TeleText.background_caching.setValue(True)
1287     self["config"].selectionChanged()
1288
1289   def infoPressed(self):
1290     log("[menu] info pressed")
1291     self.session.open(MessageBox, "Daemon Version: %s" % self.parent.daemonVersion, MessageBox.TYPE_INFO, timeout = 15)
1292
1293   def textPressed(self):
1294     log("[menu] text pressed")
1295     if self["config"].getCurrent()[1] == config.plugins.TeleText.pos:
1296       self.close(config.plugins.TeleText.pos)
1297     elif self["config"].getCurrent()[1] == config.plugins.TeleText.tip_pos:
1298       self.close(config.plugins.TeleText.tip_pos)
1299
1300   def okPressed(self):
1301     log("[menu] ok pressed")
1302     self.checkPositionValues(config.plugins.TeleText.pos)
1303     self.checkPositionValues(config.plugins.TeleText.tip_pos)
1304     for x in self["config"].list:
1305       x[1].save()
1306     configfile.save()
1307     self.close(None)
1308
1309   def checkPositionValues(self, configele):
1310     pos = configele.value
1311     log("... old pos: %s %s %s %s" % (pos[0], pos[1], pos[2], pos[3]))
1312     update = False
1313     if pos[0] > pos[2]:
1314       i = pos[0]
1315       pos[0] = pos[2]
1316       pos[2] = i
1317       update = True
1318     if pos[1] > pos[3]:
1319       i = pos[1]
1320       pos[1] = pos[3]
1321       pos[3] = i
1322       update = True
1323     if (pos[2] - pos[0]) < MIN_W:
1324       pos[2] = pos[0] + MIN_W
1325       update = True
1326     if (pos[3] - pos[1]) < MIN_H:
1327       pos[3] = pos[1] + MIN_H
1328       update = True
1329     if pos[2] > dsk_width:
1330       pos[0] = pos[0] + dsk_width - pos[2]
1331       pos[2] = dsk_width
1332       update = True
1333     if pos[3] > dsk_height:
1334       pos[1] = pos[1] + dsk_height - pos[3]
1335       pos[3] = dsk_height
1336       update = True
1337     log("... new pos: %s %s %s %s" % (pos[0], pos[1], pos[2], pos[3]))
1338
1339     if update:
1340       configele.setValue(pos)
1341
1342   def cancelPressed(self):
1343     log("[menu] cancel pressed")
1344     confirm = False
1345     for x in self["config"].list:
1346       confirm = confirm or x[1].isChanged()
1347     if confirm:
1348       self.session.openWithCallback(self.DiscardConfirm, MessageBox, _("Discard changes?"))
1349     else:
1350       self.close(None)
1351
1352   def DiscardConfirm(self, result):
1353     if result:
1354       for x in self["config"].list:
1355         if x[1].isChanged():
1356           x[1].cancel()
1357       self.close(None)
1358
1359   # ---- for summary (lcd) ----
1360
1361   def changedEntry(self, element=None):
1362     for x in self.onChangedEntry:
1363       x()
1364
1365   def getCurrentEntry(self):
1366     return self["config"].getCurrent()[0]
1367
1368   def getCurrentValue(self):
1369     return str(self["config"].getCurrent()[1].getText())
1370
1371   def createSummary(self):
1372     return TeleTextMenuSummary
1373
1374 # ----------------------------------------
1375
1376 class TeleTextMenuSummary(Screen):
1377   skin = ("""<screen name="TeleTextMenuSummary" position="0,0" size="132,64" id="1">
1378       <widget name="SetupTitle" position="6,4"  size="120,20" font="Regular;20" halign="center"/>
1379       <widget name="SetupEntry" position="6,30" size="120,12" font="Regular;12" halign="left"/>
1380       <widget name="SetupValue" position="6,48" size="120,12" font="Regular;12" halign="right"/>
1381     </screen>""",
1382     """<screen name="TeleTextMenuSummary" position="0,0" size="96,64" id="2">
1383       <widget name="SetupTitle" position="3,4"  size="90,20" font="Regular;20" halign="center"/>
1384       <widget name="SetupEntry" position="3,30" size="90,12" font="Regular;12" halign="left"/>
1385       <widget name="SetupValue" position="3,48" size="90,12" font="Regular;12" halign="right"/>
1386     </screen>""")
1387
1388   def __init__(self, session, parent):
1389     Screen.__init__(self, session, parent = parent)
1390     self["SetupTitle"] = Label(_("TeleText settings"))
1391     self["SetupEntry"] = Label("")
1392     self["SetupValue"] = Label("")
1393     self.onShow.append(self.addWatcher)
1394     self.onHide.append(self.removeWatcher)
1395
1396   def addWatcher(self):
1397     self.parent.onChangedEntry.append(self.selectionChanged)
1398     self.parent["config"].onSelectionChanged.append(self.selectionChanged)
1399     self.selectionChanged()
1400
1401   def removeWatcher(self):
1402     self.parent.onChangedEntry.remove(self.selectionChanged)
1403     self.parent["config"].onSelectionChanged.remove(self.selectionChanged)
1404
1405   def selectionChanged(self):
1406     self["SetupEntry"].text = self.parent.getCurrentEntry()
1407     self["SetupValue"].text = self.parent.getCurrentValue()
1408
1409 # ----------------------------------------
1410
1411 def sessionstart(reason, session):
1412   log("----- sessionstart(%s) -----" % session)
1413   # Plugin initialisieren
1414   global ttx_screen
1415   global my_session
1416   ttx_screen = session.instantiateDialog(TeleText)
1417   my_session = session
1418
1419 def autostart(reason, **kwargs):
1420   log("autostart(%s, %s)" % (reason, kwargs))
1421   if reason == 0:
1422     pass
1423   elif reason == 1:
1424     pass
1425
1426 def mainText(session, **kwargs):
1427   global ttx_screen
1428   log("mainText")
1429   if ttx_screen.txtpid != -1:
1430     session.execDialog(ttx_screen)
1431   else:
1432     if ttx_screen.showMessages():
1433       session.open(MessageBox, _("No teletext available."), MessageBox.TYPE_INFO, timeout = 3)
1434     else:
1435       session.openWithCallback(selectText, TeleTextTransponderMenu, ttx_screen.pid_list, ttx_screen.pid_index)
1436
1437 def selectText(result):
1438   global my_session
1439   global ttx_screen
1440   if result > -1:
1441     ttx_screen.txtpid = result
1442     ttx_screen.txtpid_origin = result
1443     ttx_screen.switchChannel(True)
1444     my_session.execDialog(ttx_screen)
1445
1446 def mainMenu(session, **kwargs):
1447   global ttx_screen
1448   log("mainMenu")
1449   session.open(TeleTextMenu)
1450
1451 def Plugins(**kwargs):
1452   log("plugins")
1453   return [
1454     PluginDescriptor(name="TeleText", description="teletext", where = PluginDescriptor.WHERE_TELETEXT, fnc=mainText),
1455     PluginDescriptor(needsRestart = False, where = PluginDescriptor.WHERE_SESSIONSTART, fnc=sessionstart),
1456     PluginDescriptor(needsRestart = False, where = PluginDescriptor.WHERE_AUTOSTART, fnc=autostart)
1457     ]
1458
1459 # EOF