[browser] fix bug.
[vuplus_dvbapp] / lib / python / Plugins / Extensions / HbbTV / plugin.py
1 from Plugins.Plugin import PluginDescriptor
2
3 from Screens.Screen import Screen
4 from Screens.InfoBar import InfoBar
5 from Screens.ChoiceBox import ChoiceBox
6 from Screens.MessageBox import MessageBox
7 from Screens.InfoBarGenerics import InfoBarNotifications
8 from Screens.VirtualKeyBoard import VirtualKeyBoard
9 from Screens.HelpMenu import HelpableScreen
10 from Screens.ChannelSelection import service_types_tv
11
12 from Components.Language import language
13 from Components.PluginComponent import plugins
14 from Components.Button import Button
15 from Components.Sources.StaticText import StaticText
16 from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
17 from Components.ServiceEventTracker import ServiceEventTracker
18 from Components.MenuList import MenuList
19 from Components.Label import Label, MultiColorLabel
20 from Components.ConfigList import ConfigListScreen
21 from Components.VolumeControl import VolumeControl
22 from Components.Pixmap import Pixmap
23 from Components.config import config, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile, getCharValue
24
25 from enigma import eTimer, eConsoleAppContainer, getDesktop, eServiceReference, iPlayableService, iServiceInformation, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, getPrevAsciiCode, eRCInput, fbClass, eServiceCenter
26
27 from bookmark import BookmarkManager, BookmarkData, CategoryData
28
29 import os, struct, threading, stat, select, time, socket, select
30
31 from __init__ import _
32
33 strIsEmpty = lambda x: x is None or len(x) == 0
34
35 HBBTVAPP_PATH = "/usr/local/hbb-browser"
36 COMMAND_PATH = '/tmp/.sock.hbbtv.cmd'
37
38 _g_helper = None
39
40 class GlobalValues:
41         command_util   = None
42         command_server = None
43
44         before_service = None
45
46         channel_info_sid   = None
47         channel_info_onid  = None
48         channel_info_tsid  = None
49         channel_info_name  = None
50         channel_info_orgid = None
51
52         hbbtv_handelr = None
53
54         packet_m  = 0xBBADBEE
55         packet_h  = '!IIII'
56         packet_hl = struct.calcsize(packet_h)
57
58         need_restart = False
59         plugin_browser = None
60 __gval__ = GlobalValues()
61
62 def setPluginBrowser(browser=None):
63         global __gval__
64         __gval__.plugin_browser = browser
65 def getPluginBrowser():
66         global __gval__
67         return __gval__.plugin_browser
68
69 def getPacketHeaders():
70         global __gval__
71         return (__gval__.packet_m, __gval__.packet_h, __gval__.packet_hl)
72
73 def setChannelInfo(sid, onid, tsid, name, orgid):
74         if sid is None:   sid   = 0;
75         if onid is None:  onid  = 0;
76         if tsid is None:  tsid  = 0;
77         if name is None:  name  = "";
78         if orgid is None: orgid = 0;
79         global __gval__
80         __gval__.channel_info_sid   = sid
81         __gval__.channel_info_onid  = onid
82         __gval__.channel_info_tsid  = tsid
83         __gval__.channel_info_name  = name
84         __gval__.channel_info_orgid = orgid
85         print "Set Channel Info >> sid : %X, onid : %X, tsid : %X, name : %s, orgid : %d " % (sid, onid, tsid, name, orgid)
86 def getChannelInfos():
87         global __gval__
88         print "Get Channel Info >> sid : %X, onid : %X, tsid : %X, name : %s, orgid : %d " % (__gval__.channel_info_sid, 
89                 __gval__.channel_info_onid, __gval__.channel_info_tsid, __gval__.channel_info_name, __gval__.channel_info_orgid)
90         return (__gval__.channel_info_sid, 
91                 __gval__.channel_info_onid, 
92                 __gval__.channel_info_tsid, 
93                 __gval__.channel_info_name, 
94                 __gval__.channel_info_orgid)
95
96 def isNeedRestart():
97         global __gval__
98         print "Need Restart(GET) : ", __gval__.need_restart
99         return __gval__.need_restart
100 def setNeedRestart(n):
101         global __gval__
102         __gval__.need_restart = n
103         print "Need Restart(SET) : ", __gval__.need_restart
104
105 def getCommandUtil():
106         global __gval__
107         return __gval__.command_util
108 def getCommandServer():
109         global __gval__
110         return __gval__.command_server
111
112 def setBeforeService(s):
113         global __gval__
114         __gval__.before_service = s
115 def getBeforeService():
116         global __gval__
117         return __gval__.before_service
118
119 def _unpack(packed_data):
120         (mg, h, hlen) = getPacketHeaders()
121
122         if strIsEmpty(packed_data):
123                 return None
124         (m, o, l, s) = struct.unpack(h, packed_data[:hlen])
125         if m != mg:
126                 return None
127         d = 0
128         if l > 0:
129                 d = packed_data[hlen:hlen+l]
130         return (o,d,s)
131
132 def _pack(opcode, params=None, reserved=0):
133         (m, h, hlen) = getPacketHeaders()
134         if strIsEmpty(params):
135                 params = ''
136         packed_data = struct.pack(h, m, opcode, len(params), reserved)
137         return packed_data + params
138
139 class MMSStreamURL:
140         headers = [
141                    'GET %s HTTP/1.0'
142                   ,'Accept: */* '
143                   ,'User-Agent: NSPlayer/7.10.0.3059 '
144                   ,'Host: %s '
145                   ,'Connection: Close '
146                   ]
147
148         def __init__(self):
149                 self.sendmsg = ''
150                 for m in self.headers:
151                         self.sendmsg += m + '\n'
152                 self.sendmsg += '\n\n'
153
154         def request(self, host, port=80, location='/'):
155                 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
156                 sock.connect((host, port))
157                 sock.send(self.sendmsg%(location, host))
158                 print "Request."
159                 print self.sendmsg%(location, host)
160                 fullydata = ''
161                 while 1:
162                         res = sock.recv(1024)
163                         if res == '': break
164                         fullydata += res
165                 sock.close()
166                 return fullydata
167
168         def parse(self, data):
169                 for d in data.splitlines():
170                         if d.startswith('Location: '):
171                                 return d[9:]
172                 return None
173
174         def getLocationData(self, url):
175                 url_list,host,location = None,None,None
176                 try:
177                         url = url[url.find(':')+3:]
178                         url_list = url.split('/')
179                         host = url_list[0]
180                         location = url[len(url_list[0]):]
181                 except Exception, err_msg:
182                         print err_msg
183                         return None
184                 html = self.request(host=host, location=location)
185                 return self.parse(html)
186
187 class OpCodeSet:
188         def __init__(self):
189                 self._opcode_ = {
190                          "OP_UNKNOWN"                   : 0x0000
191                         ,"OP_HBBTV_EXIT"                : 0x0001
192                         ,"OP_HBBTV_OPEN_URL"            : 0x0002
193                         ,"OP_HBBTV_LOAD_AIT"            : 0x0003
194                         ,"OP_HBBTV_UNLOAD_AIT"          : 0x0004
195                         ,"OP_HBBTV_FULLSCREEN"          : 0x0005
196                         ,"OP_HBBTV_TITLE"               : 0x0006
197                         ,"OP_HBBTV_RETRY_OPEN_URL"      : 0x0009
198                         ,"OP_HBBTV_CHANGE_CHANNEL"      : 0x000A
199                         ,"OP_OIPF_GET_CHANNEL_INFO_URL" : 0x0101
200                         ,"OP_OIPF_GET_CHANNEL_INFO_AIT" : 0x0102
201                         ,"OP_OIPF_GET_CHANNEL_INFO_LIST": 0x0103
202                         ,"OP_VOD_URI"                   : 0x0201
203                         ,"OP_VOD_PLAY"                  : 0x0202
204                         ,"OP_VOD_STOP"                  : 0x0203
205                         ,"OP_VOD_PAUSE"                 : 0x0204
206                         ,"OP_VOD_STATUS"                : 0x0205
207                         ,"OP_VOD_FORBIDDEN"             : 0x0206
208                         ,"OP_VOD_STOPED"                : 0x0207
209                         ,"OP_VOD_SPEED_CTRL"            : 0x0208
210                         ,"OP_VOD_SEEK_CTRL"             : 0x0209
211                         ,"OP_BROWSER_OPEN_URL"          : 0x0301
212                         ,"OP_BROWSER_VKBD_REQ"          : 0x0309
213                         ,"OP_BROWSER_VKBD_RES"          : 0x030A
214                         ,"OP_BROWSER_VKBD_PASTE_REQ"    : 0x030B
215                         ,"OP_BROWSER_VKBD_PASTE_KEY"    : 0x030C
216                         ,"OP_BROWSER_VKBD_PASTE_MOUSE"  : 0x030D
217                         ,"OP_BROWSER_MENU_REQ"          : 0x030E
218                         ,"OP_BROWSER_MENU_RES"          : 0x030F
219                         ,"OP_DVBAPP_VOL_UP"             : 0x0401
220                         ,"OP_DVBAPP_VOL_DOWN"           : 0x0402
221                         ,"OP_SYSTEM_OUT_OF_MEMORY"      : 0x0501
222                         ,"OP_SYSTEM_NOTIFY_MY_PID"      : 0x0502
223                 }
224                 self._opstr_ = {
225                          0x0000 : "OP_UNKNOWN"
226                         ,0x0001 : "OP_HBBTV_EXIT"
227                         ,0x0002 : "OP_HBBTV_OPEN_URL"
228                         ,0x0003 : "OP_HBBTV_LOAD_AIT"
229                         ,0x0004 : "OP_HBBTV_UNLOAD_AIT"
230                         ,0x0005 : "OP_HBBTV_FULLSCREEN"
231                         ,0x0006 : "OP_HBBTV_TITLE"
232                         ,0x0009 : "OP_HBBTV_RETRY_OPEN_URL"
233                         ,0x000A : "OP_HBBTV_CHANGE_CHANNEL"
234                         ,0x0101 : "OP_OIPF_GET_CHANNEL_INFO_URL"
235                         ,0x0102 : "OP_OIPF_GET_CHANNEL_INFO_AIT"
236                         ,0x0103 : "OP_OIPF_GET_CHANNEL_INFO_LIST"
237                         ,0x0201 : "OP_VOD_URI"
238                         ,0x0202 : "OP_VOD_PLAY"
239                         ,0x0203 : "OP_VOD_STOP"
240                         ,0x0204 : "OP_VOD_PAUSE"
241                         ,0x0205 : "OP_VOD_STATUS"
242                         ,0x0206 : "OP_VOD_FORBIDDEN"
243                         ,0x0207 : "OP_VOD_STOPED"
244                         ,0x0208 : "OP_VOD_SPEED_CTRL"
245                         ,0x0209 : "OP_VOD_SEEK_CTRL"
246                         ,0x0301 : "OP_BROWSER_OPEN_URL"
247                         ,0x0309 : "OP_BROWSER_VKBD_REQ"
248                         ,0x030A : "OP_BROWSER_VKBD_RES"
249                         ,0x030B : "OP_BROWSER_VKBD_PASTE_REQ"
250                         ,0x030C : "OP_BROWSER_VKBD_PASTE_KEY"
251                         ,0x030D : "OP_BROWSER_VKBD_PASTE_MOUSE"
252                         ,0x030E : "OP_BROWSER_MENU_REQ"
253                         ,0x030F : "OP_BROWSER_MENU_RES"
254                         ,0x0401 : "OP_DVBAPP_VOL_UP"
255                         ,0x0402 : "OP_DVBAPP_VOL_DOWN"
256                         ,0x0501 : "OP_SYSTEM_OUT_OF_MEMORY"
257                         ,0x0502 : "OP_SYSTEM_NOTIFY_MY_PID"
258                 }
259
260         def get(self, opstr):
261                 try:
262                         return self._opcode_[opstr]
263                 except: pass
264                 return self._opcode_["OP_UNKNOWN"]
265
266         def what(self, opcode):
267                 try:
268                         return self._opstr_[opcode]
269                 except: pass
270                 return self._opstr_["0x0000"]
271
272 class SocketParams:
273         def __init__(self):
274                 self.protocol = None
275                 self.type     = None
276                 self.addr     = None
277                 self.buf_size = 4096
278                 self.handler  = None
279                 self.timeout  = 5
280                 self.destroy  = None
281
282 class StreamServer:
283         def __init__(self, params):
284                 self._protocol = params.protocol
285                 self._type     = params.type
286                 self._addr     = params.addr
287                 self._buf_size = params.buf_size
288                 self._handler  = params.handler
289                 self._timeout  = params.timeout
290                 self._destroy  = params.destroy
291
292                 self._terminated = False
293                 self._server_thread = None
294
295                 self.onHbbTVCloseCB = []
296                 self.onSetPageTitleCB = []
297
298         def __del__(self):
299                 if self._destroy is not None:
300                         self._destroy(self._addr)
301
302         def stop(self):
303                 self._terminated = True
304                 if self._server_thread is not None:
305                         self._server_thread.join()
306                         self._server_thread = None
307
308         def start(self):
309                 self._socket = socket.socket(self._protocol, self._type)
310                 self._socket.settimeout(self._timeout)
311                 self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
312                 self._socket.bind(self._addr)
313                 self._socket.listen(True)
314
315                 self._server_thread = threading.Thread(target=self._listen)
316                 self._server_thread.start()
317
318         def _listen(self):
319                 select_list = [self._socket]
320                 def _accept():
321                         try:
322                                 conn, addr = self._socket.accept()
323                                 self._client(conn, addr)
324                         except Exception, ErrMsg:
325                                 print "ServerSocket Error >>", ErrMsg
326                                 pass
327
328                 while not self._terminated:
329                         readable, writable, errored = select.select(select_list, [], [], self._timeout)
330                         for s in readable:
331                                 if s is self._socket:
332                                         _accept()
333
334         def _client(self, conn, addr):
335                 try:
336                         send_data     = ''
337                         received_data = conn.recv(self._buf_size)
338                         if self._handler is not None and not strIsEmpty(received_data):
339                                 send_data = self._handler.doHandle(received_data, self.onHbbTVCloseCB, self.onSetPageTitleCB)
340                         self._send(conn, send_data)
341                 except Exception, ErrMsg: 
342                         try: conn.close()
343                         except:pass
344                         if self._handler is not None:
345                                 self._handler.printError(ErrMsg)
346         def _send(self, conn, data) :
347                 conn.send(data)
348                 conn.close()
349
350 class ServerFactory:
351         def doListenUnixTCP(self, name, handler):
352                 def destroy(name):
353                         import os
354                         try:
355                                 if os.path.exists(name):
356                                         os.unlink(name)
357                                         print "Removed ", name
358                         except: pass
359                 destroy(name)
360
361                 params = SocketParams()
362                 params.protocol = socket.AF_UNIX
363                 params.type     = socket.SOCK_STREAM
364                 params.addr     = name
365                 params.handler  = handler
366                 params.destroy  = destroy
367
368                 streamServer = StreamServer(params)
369                 streamServer.start()
370                 return streamServer
371
372         def doListenInetTCP(self, ip, port, handler):
373                 print "Not implemented yet!!"
374         def doListenUnixDGRAM(self, name, handler):
375                 print "Not implemented yet!!"
376         def doListenInetDGRAM(self, ip, port, handler):
377                 print "Not implemented yet!!"
378
379 class Handler:
380         def doUnpack(self, data):
381                 return _unpack(data)
382
383         def doPack(self, opcode, params, reserved=0):
384                 return _pack(opcode, params, reserved)
385
386         def doHandle(self, data, onCloseCB):
387                 opcode, params = 0x0, 'Invalid Request!!'
388                 return _pack(opcode, params)
389
390         def printError(self, reason):
391                 print reason
392
393 class BrowserCommandUtil(OpCodeSet):
394         def __init__(self):
395                 self._fd = None
396                 OpCodeSet.__init__(self)
397
398         def isConnected(self):
399                 if self._fd is None:
400                         return False
401                 return True
402
403         def doConnect(self, filename):
404                 if not os.path.exists(filename):
405                         print "File not exists :", filename
406                         return False
407                 try:
408                         self._fd = os.open(filename, os.O_WRONLY|os.O_NONBLOCK)
409                         if self._fd is None:
410                                 print "Fail to open file :", filename
411                                 return False
412                 except Exception, ErrMsg:
413                         print ErrMsg
414                         self._fd = None
415                         return False
416                 return True
417
418         def doDisconnect(self):
419                 if self._fd is None:
420                         return
421                 os.close(self._fd)
422                 self._fd = None
423
424         def doSend(self, command, params=None, reserved=0):
425                 if self._fd is None:
426                         print "No found pipe!!"
427                         return False
428                 data = ''
429                 try:
430                         data = _pack(self.get(command), params, reserved)
431                         if data is None:
432                                 return False
433                         os.write(self._fd, data)
434                         print "Send OK!! :", command
435                 except: return False
436                 return True
437
438         def sendCommand(self, command, params=None, reserved=0):
439                 if not self.isConnected():
440                         global COMMAND_PATH
441                         self.doConnect(COMMAND_PATH)
442                 result = self.doSend(command, params, reserved)
443                 self.doDisconnect()
444                 return result
445
446 class HandlerHbbTV(Handler):
447         _vod_service = None
448         def __init__(self, session):
449                 self._session = session
450                 self.opcode = OpCodeSet()
451                 self.handle_map = {
452                          0x0001 : self._cb_handleCloseHbbTVBrowser
453                         ,0x0006 : self._cb_handleSetPageTitle
454                         ,0x0009 : self._cb_handleHbbTVRetryOpen
455                         ,0x000A : self._cb_handleHbbTVChangeChannel
456                         ,0x0101 : self._cb_handleGetChannelInfoForUrl
457                         ,0x0102 : self._cb_handleGetChannelInfoForAIT
458                         ,0x0103 : self._cb_handleGetChannelInfoList
459                         ,0x0201 : self._cb_handleVODPlayerURI
460                         ,0x0202 : self._cb_handleVODPlayerPlay
461                         ,0x0203 : self._cb_handleVODPlayerStop
462                         ,0x0204 : self._cb_handleVODPlayerPlayPause
463                         ,0x0401 : self._cb_handleDVBAppVolUp
464                         ,0x0402 : self._cb_handleDVBAppVolDown
465                         ,0x0208 : self._cb_handleVODSpeedCtrl
466                         ,0x0209 : self._cb_handleVODSeekCtrl
467                         ,0x0501 : self._cb_handleSystemOutOfMemory
468                         ,0x0502 : self._cb_handleSystemNotufyMyPID
469                         ,0x0309 : self._cb_handleShowVirtualKeyboard
470                         ,0x030B : self._cb_handlePasteVirtualKeyboard
471                         ,0x030E : self._cb_handleBrowserMenuReq
472                 }
473                 self._on_close_cb = None
474                 self._on_set_title_cb = None
475
476                 self._vod_uri = None
477
478                 self._retry_open_url = None
479                 self._timer_retry_open = eTimer()
480                 self._timer_paste_vkbd = eTimer()
481                 self._curren_title = None
482
483         def _handle_dump(self, handle, opcode, data=None):
484                 if True: return
485                 print str(handle)
486                 try:
487                         print "    - opcode : ", self.opcode.what(opcode)
488                 except: pass
489                 print "    - data   : ", data
490
491         def doHandle(self, data, onCloseCB, onSetPageTitleCB):
492                 opcode, params, reserved = None, None, 0
493                 self._on_close_cb = onCloseCB
494                 self._on_set_title_cb = onSetPageTitleCB
495                 try:
496                         datas  = self.doUnpack(data)
497                 except Exception, ErrMsg:
498                         print "Unpacking packet ERR :", ErrMsg
499                         params = 'fail to unpack packet!!'
500                         opcode = self.opcode.get("OP_UNKNOWN")
501                         return self.doPack(opcode, params)
502                 else:
503                         opcode = datas[0]
504                         params = datas[1]
505                 self.opcode.what(opcode)
506
507                 try:
508                         #print self.handle_map[opcode]
509                         (reserved, params) = self.handle_map[opcode](opcode, params)
510                 except Exception, ErrMsg:
511                         print "Handling packet ERR :", ErrMsg
512                         params = 'fail to handle packet!!'
513                         opcode = self.opcode.get("OP_UNKNOWN")
514                         return self.doPack(opcode, params)
515                 self._on_close_cb = None
516                 self._on_set_title_cb = None
517                 return self.doPack(opcode, params, reserved)
518
519         def _cb_handleHbbTVChangeChannel(self, opcode, data):
520                 self._handle_dump(self._cb_handleHbbTVChangeChannel, opcode, data)
521                 global _g_helper
522                 if _g_helper is None: 
523                         return (0, "NOK")
524                 dataItems = data.split(":")
525                 sid  = dataItems[0]
526                 tsid = dataItems[1]
527                 if not _g_helper.doChangeChannel(sid, tsid):
528                         return (0, "NOK")
529                 return (0, "OK")
530
531         def _cb_handleBrowserMenuReq(self, opcode, data):
532                 self._handle_dump(self._cb_handleBrowserMenuReq, opcode, data)
533                 fbClass.getInstance().unlock()
534                 eRCInput.getInstance().unlock()
535                 browser = getPluginBrowser()
536                 if browser is not None:
537                         browser.setCurrentPageUrl(data, self._curren_title)
538                 return (0, "OK")
539
540         def _cb_handlePasteVirtualKeyboard(self, opcode, data):
541                 self._handle_dump(self._cb_handlePasteVirtualKeyboard, opcode, data)
542                 def _cb_PasteRefocusVirtualKeyboard():
543                         self._timer_paste_vkbd.stop()
544                         command_util = getCommandUtil()
545                         command_util.sendCommand('OP_BROWSER_VKBD_PASTE_MOUSE')
546                         try:
547                                 self._timer_paste_vkbd.callback.remove(_cb_PasteMouseVirtualKeyboard)
548                         except: pass
549                 def _cb_PasteKeyVirtualKeyboard():
550                         self._timer_paste_vkbd.stop()
551                         command_util = getCommandUtil()
552                         command_util.sendCommand('OP_BROWSER_VKBD_PASTE_KEY')
553                         try:
554                                 self._timer_paste_vkbd.callback.remove(_cb_PasteKeyVirtualKeyboard)
555                         except: pass
556                         self._timer_paste_vkbd.callback.append(_cb_PasteRefocusVirtualKeyboard)
557                         self._timer_paste_vkbd.start(100)
558                 def _cb_PasteMouseVirtualKeyboard():
559                         self._timer_paste_vkbd.stop()
560                         command_util = getCommandUtil()
561                         command_util.sendCommand('OP_BROWSER_VKBD_PASTE_MOUSE')
562                         #time.sleep(1)
563                         #command_util.sendCommand('OP_BROWSER_VKBD_PASTE_MOUSE')
564                         try:
565                                 self._timer_paste_vkbd.callback.remove(_cb_PasteMouseVirtualKeyboard)
566                         except: pass
567                         #self._timer_paste_vkbd.callback.append(_cb_PasteKeyVirtualKeyboard)
568                         #self._timer_paste_vkbd.start(1000)
569                 self._timer_paste_vkbd.callback.append(_cb_PasteMouseVirtualKeyboard)
570                 self._timer_paste_vkbd.start(50)
571                 return (0, "OK")
572
573         def _cb_virtualKeyboardClosed(self, data=None):
574                 fbClass.getInstance().lock()
575                 eRCInput.getInstance().lock()
576                 command_util = getCommandUtil()
577                 command_util.sendCommand('OP_BROWSER_VKBD_RES', data)
578         def _cb_handleShowVirtualKeyboard(self, opcode, data):
579                 self._handle_dump(self._cb_handleShowVirtualKeyboard, opcode, data)
580                 fbClass.getInstance().unlock()
581                 eRCInput.getInstance().unlock()
582                 if data == 0 or strIsEmpty(data):
583                         data = ""
584                 self._session.openWithCallback(self._cb_virtualKeyboardClosed, VirtualKeyBoard, title=("Please enter URL here"), text=data)
585                 return (0, "OK")
586
587         def _cb_handleVODSeekCtrl(self, opcode, data):
588                 self._handle_dump(self._cb_handleVODSeekCtrl, opcode, data)
589                 headLen = struct.calcsize('!I')
590                 unpackedData = struct.unpack('!I', data[:headLen])
591                 seekTime = unpackedData[0]
592                 service = self._session.nav.getCurrentService()
593                 seekable = service.seek()
594                 if seekable is None or not seekable.isCurrentlySeekable():
595                         raise Exception("This stream is not support manual seek.")
596                 pts = seekTime
597                 seekable.seekRelative(pts<0 and -1 or 1, abs(pts))
598                 return (0, "OK")
599
600         def _cb_handleHbbTVRetryOpen(self, opcode, data):
601                 def _cb_HbbTVRetryOpenURL():
602                         self._timer_retry_open.stop()
603                         if self._retry_open_url is not None:
604                                 command_util = getCommandUtil()
605                                 command_util.sendCommand('OP_HBBTV_RETRY_OPEN_URL', params=self._retry_open_url)
606                         self._retry_open_url = None
607                         try:
608                                 self._timer_retry_open.callback.remove(_cb_HbbTVRetryOpenURL)
609                         except: pass
610                 self._handle_dump(self._cb_handleHbbTVRetryOpen, opcode, data)
611                 headLen = struct.calcsize('!I')
612                 unpackedData = struct.unpack('!I', data[:headLen])
613                 delayTime = unpackedData[0]
614                 restartUrl = data[headLen:]
615
616                 self._retry_open_url = restartUrl.strip()
617                 self._timer_retry_open.callback.append(_cb_HbbTVRetryOpenURL)
618                 self._timer_retry_open.start(delayTime*1000)
619                 return (0, "OK")
620
621         def _cb_handleSystemNotufyMyPID(self, opcode, data):
622                 self._handle_dump(self._cb_handleSystemNotufyMyPID, opcode, data)
623                 return (0, "OK")
624
625         def _cb_handleSystemOutOfMemory(self, opcode, data):
626                 self._handle_dump(self._cb_handleSystemOutOfMemory, opcode, data)
627                 setNeedRestart(True)
628                 return (0, "OK")
629
630         def _cb_handleVODSpeedCtrl(self, opcode, data):
631                 self._handle_dump(self._cb_handleVODSpeedCtrl, opcode, data)
632                 headLen = struct.calcsize('!I')
633                 unpackedData = struct.unpack('!I', data[:headLen])
634                 playSpeed = unpackedData[0]
635                 service = self._session.nav.getCurrentService()
636                 pauseable = service.pause()
637                 if playSpeed > 2:
638                         playSpeed = 2
639                 if pauseable.setFastForward(playSpeed) == -1:
640                         pauseable.setFastForward(1)
641                         raise Exception("This stream is not support trick play.")
642                 return (0, "OK")
643
644         def _cb_handleDVBAppVolUp(self, opcode, data):
645                 self._handle_dump(self._cb_handleDVBAppVolUp, opcode, data)
646                 vcm = VolumeControl.instance
647                 vcm.volUp()
648                 return (0, "OK")
649
650         def _cb_handleDVBAppVolDown(self, opcode, data):
651                 self._handle_dump(self._cb_handleDVBAppVolDown, opcode, data)
652                 vcm = VolumeControl.instance
653                 vcm.volDown()
654                 return (0, "OK")
655
656         def _cb_handleGetChannelInfoForUrl(self, opcode, data):
657                 self._handle_dump(self._cb_handleGetChannelInfoForUrl, opcode, data)
658                 (sid, onid, tsid, name, orgid) = getChannelInfos()
659                 namelen = len(name)
660                 return (0, struct.pack('!IIII', sid, onid, tsid, namelen) + name)
661
662         def _cb_handleGetChannelInfoForAIT(self, opcode, data):
663                 self._handle_dump(self._cb_handleGetChannelInfoForAIT, opcode, data)
664                 (sid, onid, tsid, name, orgid) = getChannelInfos()
665                 namelen = len(name)
666                 return (0, struct.pack('!IIIII', orgid, sid, onid, tsid, namelen) + name)
667
668         def _cb_handleGetChannelInfoList(self, opcode, data):
669                 self._handle_dump(self._cb_handleGetChannelInfoList, opcode, data)
670                 (sid, onid, tsid, name, orgid) = getChannelInfos()
671                 namelen = len(name)
672                 channel_list_size = 1
673                 return (channel_list_size, struct.pack('!IIII', sid, onid, tsid, namelen) + name)
674
675         def _cb_handleSetPageTitle(self, opcode, data):
676                 self._handle_dump(self._cb_handleCloseHbbTVBrowser, opcode, data)
677                 if data.startswith('file://') or data.startswith('http://'):
678                         return "OK"
679                 if self._on_set_title_cb is not None:
680                         for x in self._on_set_title_cb:
681                                 try:
682                                         x(data)
683                                         self._curren_title = data
684                                 except Exception, ErrMsg:
685                                         if x in self._on_set_title_cb:
686                                                 self._on_set_title_cb.remove(x)
687                 return (0, "OK")
688
689         def _cb_handleCloseHbbTVBrowser(self, opcode, data):
690                 self._timer_retry_open.stop()
691                 try:
692                         self._timer_retry_open.callback.remove(_cb_HbbTVRetryOpenURL)
693                 except: pass
694                 self._handle_dump(self._cb_handleCloseHbbTVBrowser, opcode, data)
695
696                 if self._on_close_cb:
697                         for x in self._on_close_cb:
698                                 try:
699                                         x()
700                                 except Exception, ErrMsg:
701                                         if x in self._on_close_cb:
702                                                 self._on_close_cb.remove(x)
703
704                 command_util = getCommandUtil()
705                 command_util.sendCommand('OP_HBBTV_FULLSCREEN', None)
706
707                 before_service = getBeforeService()
708                 if before_service is not None:
709                         self._session.nav.playService(before_service)
710                         self._vod_uri = None
711                 return (0, "OK")
712
713         def _cb_handleVODPlayerURI(self, opcode, data):
714                 self._vod_uri = None
715                 hl = struct.calcsize('!II')
716                 datas = struct.unpack('!II', data[:hl])
717                 uriLength = datas[1]
718                 vodUri = data[hl:hl+uriLength]
719                 self._handle_dump(self._cb_handleVODPlayerURI, opcode, vodUri)
720                 self._vod_uri = vodUri
721                 return (0, "OK")
722
723         def doStop(self, restoreBeforeService=True, needStop=True):
724                 if needStop == True:
725                         self._session.nav.stopService()
726                 if self._vod_service is not None and restoreBeforeService:
727                         before_service = getBeforeService()
728                         self._session.nav.playService(before_service)
729                         self._vod_uri = None
730                 self._vod_service = None
731
732         def getUrl(self):
733                 return self._vod_uri
734
735         def doRetryOpen(self, url):
736                 if url is None:
737                         return False
738                 for ii in range(5):
739                         self._vod_service = None
740                         try:
741                                 print "Try to open vod [%d] : %s" % (ii, url)
742                                 self._vod_service = eServiceReference(4097, 0, url)
743                                 self._session.nav.playService(self._vod_service)
744                                 if self._vod_service is not None:
745                                         return True
746                         except Exception, ErrMsg: 
747                                 print "OpenVOD ERR :", ErrMsg
748                         time.sleep(1)
749                 return False
750
751         def _cb_handleVODPlayerPlay(self, opcode, data):
752                 self._handle_dump(self._cb_handleVODPlayerPlay, opcode, data)
753                 self.doStop(restoreBeforeService=False)
754                 if self.doRetryOpen(url=self._vod_uri) == False:
755                         self.doStop()
756                 return (0, "OK")
757
758         def _cb_handleVODPlayerStop(self, opcode, data):
759                 self._handle_dump(self._cb_handleVODPlayerStop, opcode, data)
760                 self.doStop()   
761                 return (0, "OK")
762
763         def _cb_handleVODPlayerPlayPause(self, opcode, data):
764                 self._handle_dump(self._cb_handleVODPlayerPlayPause, opcode, data)
765                 service = self._session.nav.getCurrentService()
766                 try:
767                         pauseFlag = data[0]
768                         servicePause = service.pause()
769                         if pauseFlag == 'U':
770                                 servicePause.unpause()
771                         elif pauseFlag == 'P':
772                                 servicePause.pause()
773                 except Exception, ErrMsg:
774                         print "onPause ERR :", ErrMsg
775                 return (0, "OK")
776
777 from libshm import SimpleSharedMemory
778 _g_ssm_ = None
779 class HbbTVWindow(Screen, InfoBarNotifications):
780         skin =  """
781                 <screen name="HbbTVWindow" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="HbbTV Plugin">
782                 </screen>
783                 """
784         def __init__(self, session, url=None, cbf=None, useAIT=False, profile=0):
785                 self._session = session
786                 fbClass.getInstance().lock()
787                 eRCInput.getInstance().lock()
788
789                 Screen.__init__(self, session)
790                 InfoBarNotifications.__init__(self)
791                 self.__event_tracker = ServiceEventTracker(screen = self, eventmap = {
792                         iPlayableService.evUser+20: self._serviceForbiden,
793                         iPlayableService.evStart: self._serviceStarted,
794                         iPlayableService.evEOF: self._serviceEOF,
795                 })
796
797                 self._url = url
798                 self._use_ait = useAIT
799                 self._profile = profile
800                 self._cb_closed_func = cbf
801                 self.onLayoutFinish.append(self._layoutFinished)
802
803                 command_server = getCommandServer()
804                 if self._cb_set_page_title not in command_server.onSetPageTitleCB:
805                         command_server.onSetPageTitleCB.append(self._cb_set_page_title)
806
807                 if self._cb_close_window not in command_server.onHbbTVCloseCB:
808                         command_server.onHbbTVCloseCB.append(self._cb_close_window)
809
810                 self._closeTimer = eTimer()
811                 self._closeTimer.callback.append(self._do_close)
812
813                 self._currentServicePositionTimer = eTimer()
814                 self._currentServicePositionTimer.callback.append(self._cb_currentServicePosition)
815                 self._vodLength = 0
816
817                 global _g_ssm_
818                 self._ssm = _g_ssm_
819                 self._vod_length = 0
820
821         def getVodPlayTime(self):
822                 try:
823                         service = self._session.nav.getCurrentService()
824                         seek = service and service.seek()
825                         l = seek.getLength()
826                         p = seek.getPlayPosition()
827                         #return (p[1]/90000, l[1]/90000)
828                         return (p[1], l[1])
829                 except: pass
830                 return (-1,-1)
831
832         def _cb_currentServicePosition(self):
833                 def getTimeString(t):
834                         t = time.localtime(t/90000)
835                         return "%2d:%02d:%02d" % (t.tm_hour, t.tm_min, t.tm_sec)
836                 position,length = 0,0
837                 try:
838                         (position,length) = self.getVodPlayTime()
839                         self._vod_length = length
840                         if position == -1 and length == -1:
841                                 raise Exception("Can't get play status")
842                         #print getTimeString(position), "/", getTimeString(length)
843                         self._ssm.setStatus(position, length, 1)
844                 except Exception, ErrMsg:
845                         print ErrMsg
846                         self._serviceEOF()
847
848         def _serviceStarted(self):
849                 try:
850                         self._ssm.setStatus(0, 0, 0)
851                         self._currentServicePositionTimer.start(1000)
852                 except Exception, ErrMsg:
853                         print ErrMsg
854
855         def _serviceEOF(self):
856                 self._currentServicePositionTimer.stop()
857
858         def _layoutFinished(self):
859                 self.setTitle(_('HbbTV Plugin'))
860                 command_util = getCommandUtil()
861                 profile = self._profile
862                 (sid, onid, tsid, name, orgid) = getChannelInfos()
863                 params  = struct.pack('!IIIIII', orgid, profile, sid, onid, tsid, len(name)) + name
864                 if self._use_ait:
865                         command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
866                         time.sleep(1)
867                         command_util.sendCommand('OP_HBBTV_LOAD_AIT', params, 1)
868                         return
869                 command_util.sendCommand('OP_HBBTV_LOAD_AIT', params)
870                 time.sleep(1)
871                 command_util.sendCommand('OP_HBBTV_OPEN_URL', self._url)
872
873         def _cb_close_window(self):
874                 self._closeTimer.start(1000)
875
876         def _do_close(self):
877                 self._closeTimer.stop()
878                 command_server = getCommandServer()
879                 try:
880                         if self._cb_set_page_title in command_server.onSetPageTitleCB:
881                                 command_server.onSetPageTitleCB.remove(self._cb_set_page_title)
882                 except Exception, ErrMsg: pass
883                 try:
884                         if self._cb_close_window in command_server.onHbbTVCloseCB:
885                                         command_server.onHbbTVCloseCB.remove(self._cb_close_window)
886                 except Exception, ErrMsg: pass
887                 try:
888                         if self._cb_closed_func is not None:
889                                 self._cb_closed_func()
890                 except: pass
891                 fbClass.getInstance().unlock()
892                 eRCInput.getInstance().unlock()
893                 self.close()
894
895         def _serviceForbiden(self):
896                 global __gval__
897                 real_url = MMSStreamURL().getLocationData(__gval__.hbbtv_handelr.getUrl())
898                 print "Received URI :\n", real_url
899
900                 if real_url is not None:
901                         __gval__.hbbtv_handelr.doRetryOpen(real_url.strip())
902
903         def _cb_set_page_title(self, title=None):
904                 print "page title :",title
905                 if title is None:
906                         return
907                 self.setTitle(title)
908
909 class HbbTVHelper(Screen):
910         skin =  """<screen name="HbbTVHelper" position="0,0" size="0,0" backgroundColor="transparent" flags="wfNoBorder" title=" "></screen>"""
911         def __init__(self, session):
912                 global __gval__
913                 __gval__.hbbtv_handelr = HandlerHbbTV(session)
914                 __gval__.command_server = ServerFactory().doListenUnixTCP('/tmp/.sock.hbbtv.url', __gval__.hbbtv_handelr)
915
916                 self._urls = None
917                 #self._stop_opera()
918                 #self._start_opera()
919                 self._restart_opera()
920
921                 Screen.__init__(self, session)
922                 self._session = session
923                 self._timer_infobar = eTimer()
924                 self._timer_infobar.callback.append(self._cb_registrate_infobar)
925                 self._timer_infobar.start(1000)
926
927                 self._excuted_browser = False
928                 self._profile = 0
929
930                 __gval__.command_util = BrowserCommandUtil()
931
932                 global _g_ssm_
933                 if _g_ssm_ is None:
934                         _g_ssm_ = SimpleSharedMemory()
935                         _g_ssm_.doConnect()
936
937         def _cb_registrate_infobar(self):
938                 if InfoBar.instance:
939                         self._timer_infobar.stop()
940                         if self._cb_ready_for_ait not in InfoBar.instance.onReadyForAIT:
941                                 InfoBar.instance.onReadyForAIT.append(self._cb_ready_for_ait)
942                         if self._cb_hbbtv_activated not in InfoBar.instance.onHBBTVActivation:
943                                 InfoBar.instance.onHBBTVActivation.append(self._cb_hbbtv_activated)
944
945         def _cb_ready_for_ait(self, orgId=0):
946                 if orgId == 0:
947                         if not self._excuted_browser:
948                                 command_util = getCommandUtil()
949                                 command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
950                         return
951                 setChannelInfo(None, None, None, None, None)
952
953                 service = self._session.nav.getCurrentService()
954                 info = service and service.info()
955                 if info is not None:
956                         sid  = info.getInfo(iServiceInformation.sSID)
957                         onid = info.getInfo(iServiceInformation.sONID)
958                         tsid = info.getInfo(iServiceInformation.sTSID)
959                         name = info.getName()
960                         if name is None:
961                                 name = ""
962                         orgid   = 0
963                         namelen = len(name)
964                         for x in info.getInfoObject(iServiceInformation.sHBBTVUrl):
965                                 if x[0] in (1, -1) :
966                                         orgid = x[3]
967                                         break
968                         setChannelInfo(sid, onid, tsid, name, orgid)
969
970         def _cb_hbbtv_activated(self, title=None, url=None):
971                 if not self._is_browser_running():
972                         message = _("HbbTV Browser was not running.\nPlease running browser before start HbbTV Application.")
973                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
974                         return
975                 service = self._session.nav.getCurrentlyPlayingServiceReference()
976                 setBeforeService(service)
977                 self._start_hbbtv_application(title, url)
978
979         def _start_hbbtv_application(self, title, url):
980                 use_ait = False
981                 tmp_url = self.getStartHbbTVUrl()
982                 if url is None:
983                         url = tmp_url
984                 if strIsEmpty(url):
985                         print "can't get url of hbbtv!!"
986                         return
987                 print "success to get url of hbbtv!! >>", url
988                 if self._excuted_browser:
989                         print "already excuted opera browser!!"
990                         return
991
992                 if isNeedRestart():
993                         self._restart_opera()
994                         time.sleep(2)
995                         setNeedRestart(False)
996
997                 for x in self._urls:
998                         control_code = x[0]
999                         tmp_url = x[2]
1000                         if tmp_url == url and control_code == 1:
1001                                 use_ait = True
1002                 self._excuted_browser = True
1003                 self._session.open(HbbTVWindow, url, self._cb_closed_browser, use_ait, self._profile)
1004
1005         def _cb_closed_browser(self):
1006                 self._excuted_browser = False
1007
1008         def _start_opera(self):
1009                 if not self._is_browser_running():
1010                         global HBBTVAPP_PATH
1011                         start_command = '%s/launcher start'%(HBBTVAPP_PATH)
1012                         os.system(start_command)
1013
1014         def _stop_opera(self):
1015                 global HBBTVAPP_PATH
1016                 try:    os.system('%s/launcher stop'%(HBBTVAPP_PATH))
1017                 except: pass
1018
1019         def _restart_opera(self):
1020                 global HBBTVAPP_PATH
1021                 try:    os.system('%s/launcher restart'%(HBBTVAPP_PATH))
1022                 except: pass
1023
1024         def getStartHbbTVUrl(self):
1025                 url, self._urls, self._profile = None, None, 0
1026                 service = self._session.nav.getCurrentService()
1027                 info = service and service.info()
1028                 if not info: return None
1029                 self._urls = info.getInfoObject(iServiceInformation.sHBBTVUrl)
1030                 for u in self._urls:
1031                         if u[0] in (1, -1): # 0:control code, 1:name, 2:url, 3:orgid, 4:appid, 5:profile code
1032                                 url = u[2]
1033                                 self._profile = u[5]
1034                 if url is None:
1035                         url = info.getInfoString(iServiceInformation.sHBBTVUrl)
1036                 return url
1037
1038         def showApplicationSelectionBox(self):
1039                 applications = []
1040
1041                 if self.getStartHbbTVUrl():
1042                         for x in self._urls:
1043                                 applications.append((x[1], x))
1044                 else: applications.append((_("No detected HbbTV applications."), None))
1045                 self._session.openWithCallback(self._application_selected, ChoiceBox, title=_("Please choose an HbbTV application."), list=applications)
1046
1047         def _application_selected(self, selected):
1048                 try:
1049                         if selected[1] is None: return
1050                         self._cb_hbbtv_activated(selected[1][1], selected[1][2])
1051                 except Exception, ErrMsg: print ErrMsg
1052
1053         def showBrowserConfigBox(self):
1054                 start_stop_mode = []
1055                 if self._is_browser_running():
1056                         start_stop_mode.append((_('Stop'),'Stop'))
1057                 else:   start_stop_mode.append((_('Start'),'Start'))
1058                 self._session.openWithCallback(self._browser_config_selected, ChoiceBox, title=_("Please choose one."), list=start_stop_mode)
1059
1060         def _browser_config_selected(self, selected):
1061                 if selected is None:
1062                         return
1063                 try:
1064                         mode = selected[1]
1065                         if mode == 'Start':
1066                                 if not self._is_browser_running():
1067                                         self._start_opera()
1068                         elif mode == 'Stop':
1069                                 self._stop_opera()
1070                 except Exception, ErrMsg: print "Config ERR :", ErrMsg
1071
1072         def _is_browser_running(self):
1073                 try:
1074                         global HBBTVAPP_PATH
1075                         ret = os.popen('%s/launcher check'%(HBBTVAPP_PATH)).read()
1076                         return ret.strip() != "0"
1077                 except Exception, ErrMsg:
1078                         print "Check Browser Running ERR :", ErrMsg
1079                 return False
1080
1081         def doChangeChannel(self, _sid, _tsid):
1082                 root = eServiceReference(service_types_tv)
1083                 if root is None:
1084                         return False
1085                 serviceList = eServiceCenter.getInstance().list(root)
1086                 if serviceList is None:
1087                         return False    
1088                 while True:
1089                         service = serviceList.getNext()
1090                         if service is None or not service.valid():
1091                                 break
1092
1093                         #1:0:19:2840:3FB:1:C00000:0:0:0:
1094                         serviceRef = service.toString()
1095                         if strIsEmpty(serviceRef):
1096                                 continue
1097                         serviceRefItems = serviceRef.split(":")
1098                         if len(serviceRefItems) < 5:
1099                                 continue
1100
1101                         sid  = serviceRefItems[3]
1102                         tsid = serviceRefItems[4]
1103                         if sid == _sid and tsid == _tsid:
1104                                 self._session.nav.playService(eServiceReference(serviceRef))
1105                                 service = self._session.nav.getCurrentlyPlayingServiceReference()
1106                                 setBeforeService(service)
1107                                 return True
1108                 return False
1109
1110 class OperaBrowserSetting:
1111         def __init__(self):
1112                 self._settingFileName = '/usr/local/hbb-browser/home/setting.ini'
1113                 self._start = None
1114                 self._type  = None
1115                 self._read()
1116         def _read(self):
1117                 f = open(self._settingFileName)
1118                 for line in f.readlines():
1119                         if line.startswith('start='):
1120                                 tmp = line[6:len(line)-1].split()
1121                                 self._start = tmp[0]
1122                                 if len(tmp) > 1:
1123                                         self._type = int(tmp[1])
1124                                 else:   self._type = 0
1125                 f.close()
1126         def _write(self):
1127                 tmpstr = []
1128                 tmpstr.append('start=%s %d\n' % (self._start, self._type))
1129                 f = open(self._settingFileName, 'w')
1130                 f.writelines(tmpstr)
1131                 f.close()
1132         def setData(self, start, types=0):
1133                 self._start = start
1134                 self._type = types
1135                 self._write()
1136         def getData(self):
1137                 return {
1138                         'start':self._start,
1139                         'type':self._type,
1140                 }
1141
1142 class OperaBrowserPreferenceWindow(ConfigListScreen, Screen):
1143         skin=   """
1144                 <screen position="center,center" size="600,350" title="Preference">
1145                         <widget name="url" position="5,0" size="590,100" valign="center" font="Regular;20" />
1146                         <widget name="config" position="0,100" size="600,200" scrollbarMode="showOnDemand" />
1147
1148                         <ePixmap pixmap="skin_default/buttons/red.png" position="310,310" size="140,40" alphatest="on" />
1149                         <ePixmap pixmap="skin_default/buttons/green.png" position="150,310" size="140,40" alphatest="on" />
1150
1151                         <widget source="key_red" render="Label" position="310,310" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
1152                         <widget source="key_green" render="Label" position="150,310" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
1153                 </screen>
1154                 """
1155         def __init__(self, session, currentUrl): 
1156                 self.session = session
1157                 Screen.__init__(self, session)
1158
1159                 self.menulist = []
1160                 ConfigListScreen.__init__(self, self.menulist)
1161
1162                 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ], {
1163                         "red"    : self.keyRed,
1164                         "green"  : self.keyGreen,
1165                         "ok"     : self.keyOK,
1166                         "cancel" : self.keyRed
1167                 }, -2)
1168                 self["key_red"]   = StaticText(_("Cancel"))
1169                 self["key_green"] = StaticText(_("Save"))
1170                 self["url"]       = Label()
1171
1172                 self._currentPageUrl = currentUrl
1173                 if self._currentPageUrl is None:
1174                         self._currentPageUrl = ''
1175                 self._startPageUrl   = None
1176
1177                 self.makeMenuEntry()
1178                 self.onLayoutFinish.append(self.layoutFinished)
1179
1180         def layoutFinished(self):
1181                 self.setTitle(_('Preference'))
1182                 try:
1183                         d = OperaBrowserSetting().getData()
1184                         self._startPageUrl = d['start']
1185                         #d['type']
1186                 except: self._startPageUrl = 'http://vuplus.com'
1187                 self.updateStartPageUrl()
1188
1189         def updateStartPageUrl(self):
1190                 if self.menuItemStartpage.value == "startpage":
1191                         self["url"].setText(self._startPageUrl)
1192                 elif self.menuItemStartpage.value == "current":
1193                         self["url"].setText(self._currentPageUrl)
1194                 elif self.menuItemStartpage.value == "direct":
1195                         self["url"].setText('')
1196
1197         def keyGreen(self):
1198                 url = self["url"].getText()
1199                 if strIsEmpty(url):
1200                         self.session.open(MessageBox, _('Invalid URL!!(Empty)\nPlease, Input to the URL.'), type = MessageBox.TYPE_INFO)
1201                         return
1202                 mode = 0
1203                 if url.find('/usr/local/manual') > 0:
1204                         mode = 1
1205                 OperaBrowserSetting().setData(url, mode)
1206                 self.close()
1207
1208         def keyRed(self):
1209                 self.close()
1210
1211         def keyOK(self):
1212                 def _cb_directInputUrl(data):
1213                         if strIsEmpty(data):
1214                                 return
1215                         self["url"].setText(data)
1216                 if self.menuItemStartpage.value == "direct":
1217                         self.session.openWithCallback(_cb_directInputUrl, VirtualKeyBoard, title=(_("Please enter URL here")), text='http://')
1218
1219         def keyLeft(self):
1220                 ConfigListScreen.keyLeft(self)
1221                 self.updateStartPageUrl()
1222
1223         def keyRight(self):
1224                 ConfigListScreen.keyRight(self)
1225                 self.updateStartPageUrl()
1226
1227         def makeMenuEntry(self):
1228                 l = []
1229                 l.append(("startpage", _("Start Page")))
1230                 if not strIsEmpty(self._currentPageUrl):
1231                         l.append(("current", _("Current Page")))
1232                 l.append(("direct", _("Direct Input")))
1233                 self.menuItemStartpage  = ConfigSelection(default="startpage", choices = l)
1234                 self.menuEntryStartpage = getConfigListEntry(_("Startpage"), self.menuItemStartpage)
1235                 self.resetMenuList()
1236
1237         def resetMenuList(self):
1238                 self.menulist = []
1239                 self.menulist.append(self.menuEntryStartpage)
1240
1241                 self["config"].list = self.menulist
1242                 self["config"].l.setList(self.menulist)
1243
1244 class BookmarkEditWindow(ConfigListScreen, Screen):
1245         CATEGORY,BOOKMARK = 0,1
1246         skin=   """
1247                 <screen position="center,center" size="600,140" title="Bookmark Edit">
1248                         <widget name="config" position="0,0" size="600,100" scrollbarMode="showOnDemand" />
1249
1250                         <ePixmap pixmap="skin_default/buttons/red.png" position="310,100" size="140,40" alphatest="on" />
1251                         <ePixmap pixmap="skin_default/buttons/green.png" position="150,100" size="140,40" alphatest="on" />
1252
1253                         <widget source="key_red" render="Label" position="310,100" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
1254                         <widget source="key_green" render="Label" position="150,100" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
1255
1256                         <widget name="VKeyIcon" pixmap="skin_default/buttons/key_text.png" position="0,100" zPosition="10" size="35,25" transparent="1" alphatest="on" />
1257
1258                 </screen>
1259                 """
1260         def __init__(self, session, _mode, _type, _data, _bm):
1261                 self.mMode = _mode
1262                 self.mType = _type
1263                 self.mData = _data
1264                 self.mSession = session
1265                 self.mBookmarkManager = _bm
1266
1267                 if _data is not None:
1268                         print _data.mId
1269
1270                 Screen.__init__(self, session)
1271
1272                 self.menulist = []
1273                 ConfigListScreen.__init__(self, self.menulist)
1274
1275                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions",], {
1276                         "ok"     : self.keyGreen,
1277                         "green"  : self.keyGreen,
1278                         "red"    : self.keyRed,
1279                         "cancel" : self.keyRed,
1280                 }, -2)
1281
1282                 self["VKeyIcon"]  = Pixmap()
1283                 self["key_red"]   = StaticText(_("Cancel"))
1284                 self["key_green"] = StaticText(_("Save"))
1285
1286                 self.menuItemTitle = None
1287                 self.menuItemUrl   = None
1288                 self.menuItemName  = None
1289
1290                 self.menuEntryName = None
1291                 self.menuEntryTitle = None
1292                 self.menuEntryUrl = None
1293
1294                 self.makeConfigList()
1295                 self.onLayoutFinish.append(self.layoutFinished)
1296
1297         def layoutFinished(self):
1298                 self.setTitle(_('Bookmark') + ' ' + self.mMode)
1299
1300         def selectedItem(self):
1301                 currentPosition = self["config"].getCurrent()
1302                 if self.mType == BookmarkEditWindow.CATEGORY:
1303                         return (_("Name"), self.menuItemName)
1304                 else:
1305                         if currentPosition == self.menuEntryTitle:
1306                                 return (_("Title"), self.menuItemTitle)
1307                         elif currentPosition == self.menuEntryUrl:
1308                                 return (_("Url"), self.menuItemUrl)
1309                 return None
1310
1311         def showMessageBox(self, text):
1312                 msg = _("Invalid ") + text + _("!!(Empty)\nPlease, Input to the ") + text + "."
1313                 self.mSession.openWithCallback(self.showVKeyWindow, MessageBox, msg, MessageBox.TYPE_INFO)
1314                 return False
1315
1316         def showVKeyWindow(self, data=None):
1317                 itemTitle = ""
1318                 itemValue = ""
1319                 selected = self.selectedItem()
1320                 if selected is not None:
1321                         itemValue = selected[1].value
1322                         if strIsEmpty(itemValue):
1323                                 itemValue = ""
1324                         itemTitle = selected[0]
1325
1326                 self.session.openWithCallback(self.cbVKeyWindow, VirtualKeyBoard, title=itemTitle, text=itemValue)
1327
1328         def cbVKeyWindow(self, data=None):
1329                 if data is not None:
1330                         selected = self.selectedItem()
1331                         if selected is not None:
1332                                 selected[1].setValue(data)
1333
1334         def saveData(self):
1335                 if self.mType == BookmarkEditWindow.CATEGORY:
1336                         if self.mMode == _('Add'):
1337                                 categoryName = self.menuItemName.value
1338                                 if strIsEmpty(categoryName):
1339                                         return self.showMessageBox(_("Category Name"))
1340                                 self.mBookmarkManager.addCategory(categoryName)
1341                         else:
1342                                 if strIsEmpty(self.menuItemName.value):
1343                                         return self.showMessageBox(_("Category Name"))
1344                                 self.mData.mName = self.menuItemName.value
1345                                 self.mBookmarkManager.updateCategory(self.mData)
1346                 else:
1347                         if self.mMode == _('Add'):
1348                                 bookmarkTitle = self.menuItemTitle.value
1349                                 bookmarkUrl   = self.menuItemUrl.value
1350                                 if strIsEmpty(bookmarkTitle):
1351                                         self["config"].setCurrentIndex(0)
1352                                         return self.showMessageBox(_("Bookmark Title"))
1353                                 if strIsEmpty(bookmarkUrl):
1354                                         self["config"].setCurrentIndex(1)
1355                                         return self.showMessageBox(_("Bookmark URL"))
1356                                 self.mBookmarkManager.addBookmark(bookmarkTitle, bookmarkUrl, self.mData.mParent, 0)
1357                         else:
1358                                 if strIsEmpty(self.menuItemTitle.value):
1359                                         self["config"].setCurrentIndex(0)
1360                                         return self.showMessageBox(_("Bookmark Title"))
1361                                 if strIsEmpty(self.menuItemUrl.value):
1362                                         self["config"].setCurrentIndex(1)
1363                                         return self.showMessageBox(_("Bookmark URL"))
1364                                 self.mData.mTitle = self.menuItemTitle.value
1365                                 self.mData.mUrl   = self.menuItemUrl.value
1366                                 self.mBookmarkManager.updateBookmark(self.mData)
1367                 return True
1368
1369         def keyGreen(self):
1370                 if not self.saveData():
1371                         return
1372                 self.close(True)
1373         def keyRed(self):
1374                 self.close(False)
1375         def keyLeft(self):
1376                 ConfigListScreen.keyLeft(self)
1377         def keyRight(self):
1378                 ConfigListScreen.keyRight(self)
1379         def makeConfigList(self):
1380                 self.menulist = []
1381
1382                 if self.mType == BookmarkEditWindow.CATEGORY:
1383                         self.menuItemName = ConfigText(default=self.mData.mName, visible_width=65, fixed_size=False)
1384
1385                         self.menuEntryName  = getConfigListEntry(_("Name"), self.menuItemName)
1386
1387                         self.menulist.append(self.menuEntryName)
1388                 else:
1389                         self.menuItemTitle = ConfigText(default=self.mData.mTitle, visible_width=65, fixed_size=False)
1390                         self.menuItemUrl   = ConfigText(default=self.mData.mUrl, visible_width=65, fixed_size=False)
1391
1392                         self.menuEntryTitle = getConfigListEntry(_("Title"), self.menuItemTitle)
1393                         self.menuEntryUrl   = getConfigListEntry(_("Url"), self.menuItemUrl)
1394
1395                         self.menulist.append(self.menuEntryTitle)
1396                         self.menulist.append(self.menuEntryUrl)
1397                         
1398                 self["config"].list = self.menulist
1399                 self["config"].l.setList(self.menulist)
1400
1401 class OperaBrowserBookmarkWindow(Screen):
1402         skin =  """
1403                 <screen name="HbbTVBrowserBookmarkWindow" position="center,center" size="600,400" title="Bookmark" >
1404                         <widget name="bookmarklist" position="0,0" size="600,200" zPosition="10" scrollbarMode="showOnDemand" />
1405
1406                         <ePixmap pixmap="skin_default/buttons/key_0.png" position="556,330" size="35,30" alphatest="on" />
1407                         <widget source="key_0" render="Label" position="258,330" zPosition="1" size="300,30" font="Regular;20" halign="right" valign="center"/>
1408
1409                         <ePixmap pixmap="skin_default/buttons/red.png" position="5,360" size="140,40" alphatest="on" />
1410                         <ePixmap pixmap="skin_default/buttons/green.png" position="155,360" size="140,40" alphatest="on" />
1411                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,360" size="140,40" alphatest="on" />
1412                         <ePixmap pixmap="skin_default/buttons/blue.png" position="450,360" size="140,40" alphatest="on" />
1413
1414                         <widget source="key_red" render="Label" position="5,360" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
1415                         <widget source="key_green" render="Label" position="155,360" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
1416                         <widget source="key_yellow" render="Label" position="305,360" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
1417                         <widget source="key_blue" render="Label" position="450,360" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1" />
1418                 </screen>
1419                 """
1420
1421         def __init__(self, _session, _url=None, _title=None):
1422                 self.mUrl   = _url
1423                 self.mTitle = _title
1424                 self.mBookmarkManager = BookmarkManager.getInstance()
1425                 self.mSession = _session
1426                 Screen.__init__(self, _session)
1427                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions","ColorActions", "NumberActions"], {
1428                                 "ok"    : self.keyOK,
1429                                 "cancel": self.keyCancel,
1430                                 "red"   : self.keyRed,
1431                                 "green" : self.keyGreen,
1432                                 "yellow": self.keyYellow,
1433                                 "blue"  : self.keyBlue,
1434                                 "0"     : self.keyNumber,
1435                         },-2)
1436
1437                 self["key_red"]    = StaticText(_("Exit"))
1438                 self["key_green"]  = StaticText(_("Add"))
1439                 self["key_yellow"] = StaticText(_("Edit"))
1440                 self["key_blue"]   = StaticText(_("Delete"))
1441                 self["key_0"]      = StaticText(_("Set as Startpage"))
1442
1443                 self.mBookmarkList = self.setBookmarkList()
1444                 self["bookmarklist"] = MenuList(self.mBookmarkList)
1445
1446                 self.onLayoutFinish.append(self.layoutFinished)
1447
1448         def layoutFinished(self):
1449                 self.setTitle(_('Bookmark'))
1450
1451         def setBookmarkList(self):
1452                 l = []
1453                 #self.mBookmarkManager.dump()
1454                 cd = self.mBookmarkManager.getBookmarkRoot()
1455                 for ck in cd.iterkeys():
1456                         l.append(('# ' + cd[ck].mName, cd[ck]))
1457                         bd = cd[ck].mBookmarks
1458                         for bk in bd.iterkeys():
1459                                 l.append(('    - ' + bd[bk].mTitle, bd[bk]))
1460                 return l
1461         def updateBookmarkList(self):
1462                 self.mBookmarkList = self.setBookmarkList()
1463                 self["bookmarklist"].setList(self.mBookmarkList)
1464         def cbEditWindow(self, ret=False):
1465                 if not ret: 
1466                         return
1467                 self.updateBookmarkList()
1468         def getParentCategory(self):
1469                 idx = self["bookmarklist"].getSelectedIndex()
1470                 try:
1471                         while idx >= 0:
1472                                 data = self.mBookmarkList[idx][0].strip()
1473                                 if data[0] == '#':
1474                                         return self.mBookmarkList[idx][1]
1475                                 idx -= 1
1476                 except: pass
1477                 return None
1478         def isCategoryItem(self):
1479                 try:
1480                         head = self["bookmarklist"].getCurrent()[0].strip()
1481                         if head[0] == '#':
1482                                 return True
1483                 except: pass
1484                 return False
1485         def keyNumber(self):
1486                 data = self["bookmarklist"].getCurrent()[1]
1487                 if strIsEmpty(data.mUrl):
1488                         msg = _("Invalid URL. Please check again!!")
1489                         self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
1490                         return
1491                 def cbSetStartpage(ret=None):
1492                         if ret is None: return
1493                         if ret:
1494                                 data = self["bookmarklist"].getCurrent()[1]
1495                                 OperaBrowserSetting().setData(data.mUrl, data.mType)
1496                 msg = _("Do you want to set selected url to the Startpage?")
1497                 self.mSession.openWithCallback(cbSetStartpage, MessageBox, msg, MessageBox.TYPE_YESNO, default=True)
1498
1499         def keyGreen(self):
1500                 def cbGreen(data):
1501                         if data is None:
1502                                 return
1503                         if data[1] == 1:
1504                                 parent = self.getParentCategory()
1505                                 if parent is None:
1506                                         return
1507                                 if strIsEmpty(self.mTitle):
1508                                         return
1509                                 retAdd = self.mBookmarkManager.addBookmark(self.mTitle, self.mUrl, parent.mId, 0)
1510                                 if not retAdd:
1511                                         msg = _("Current page is already exist.")
1512                                         self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
1513                                 self.cbEditWindow(True)
1514                         elif data[1] == 2:
1515                                 parent = self.getParentCategory()
1516                                 if parent is None:
1517                                         return
1518                                 b = BookmarkData(0, '', '', parent.mId, 0)
1519                                 self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, _('Add'), BookmarkEditWindow.BOOKMARK, b, self.mBookmarkManager)
1520                         elif data[1] == 3:
1521                                 c = CategoryData(0, '')
1522                                 self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, _('Add'), BookmarkEditWindow.CATEGORY, c, self.mBookmarkManager)
1523                 if strIsEmpty(self.mUrl):
1524                         l = [(_('Direct Input(Bookmark)'),2,), (_('Direct Input(Category)'),3,)]
1525                 else:   l = [(_('Currentpage(Bookmark)'),1,), (_('Direct Input(Bookmark)'),2,), (_('Direct Input(Category)'),3,)]
1526                 self.mSession.openWithCallback(cbGreen, ChoiceBox, title=_("Please choose."), list=l)
1527         def keyYellow(self):
1528                 data = self["bookmarklist"].getCurrent()[1]
1529                 if self.isCategoryItem():
1530                         self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, _('Edit'), BookmarkEditWindow.CATEGORY, data, self.mBookmarkManager)
1531                 else:   self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, _('Edit'), BookmarkEditWindow.BOOKMARK, data, self.mBookmarkManager)
1532         def keyBlue(self):
1533                 def cbBlue(ret=None):
1534                         if not ret: return
1535                         data = self["bookmarklist"].getCurrent()[1]
1536                         if self.isCategoryItem():
1537                                 self.mBookmarkManager.deleteCategory(data.mId)
1538                         else:   self.mBookmarkManager.deleteBookmark(data.mId)
1539                         self.updateBookmarkList()
1540                 if self.isCategoryItem():
1541                         msg = _("Do you want to delete the category and the bookmarks?")
1542                 else:   msg = _("Do you want to delete the bookmark?")
1543                 self.mSession.openWithCallback(cbBlue, MessageBox, msg, MessageBox.TYPE_YESNO, default=True)
1544         def keyOK(self):
1545                 if self.isCategoryItem(): return
1546
1547                 data = self["bookmarklist"].getCurrent()[1]
1548                 url = data.mUrl.strip()
1549                 if len(url) == 0:
1550                         self.session.open(MessageBox, _("Can't open selected bookmark.\n   - URL data is empty!!"), type = MessageBox.TYPE_INFO)
1551                         return
1552                 mode = data.mType
1553                 if mode:
1554                         lang = language.getLanguage()
1555                         if lang == 'ru_RU' and os.path.exists('/usr/local/manual/ru_RU'):
1556                                 url = '/usr/local/manual/ru_RU/main.html'
1557                         elif lang == 'de_DE' and os.path.exists('/usr/local/manual/de_DE'):
1558                                 url = '/usr/local/manual/de_DE/main.html'
1559                 self.close((url, mode))
1560         def keyRed(self):
1561                 self.keyCancel()
1562         def keyCancel(self):
1563                 self.close()
1564
1565 class BrowserHelpWindow(Screen, HelpableScreen):
1566         MODE_GLOBAL,MODE_KEYBOARD,MODE_MOUSE = 1,2,3
1567         skin =  """
1568                 <screen name="BrowserHelpWindow" position="center,center" size="600,40" title="Browser Help" >
1569                         <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
1570                         <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
1571                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
1572                         <ePixmap pixmap="skin_default/buttons/blue.png" position="450,0" size="140,40" alphatest="on" />
1573
1574                         <widget source="key_red" render="Label" position="5,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
1575                         <widget source="key_green" render="Label" position="155,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
1576                         <widget source="key_yellow" render="Label" position="305,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
1577                         <widget source="key_blue" render="Label" position="450,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1" />
1578                 </screen>
1579                 """
1580         def __init__(self, session):
1581                 Screen.__init__(self, session)
1582                 HelpableScreen.__init__(self)
1583
1584                 self["key_red"]    = StaticText(_("Exit"))
1585                 self["key_green"]  = StaticText(_("Global"))
1586                 self["key_yellow"] = StaticText(_("Mouse"))
1587                 self["key_blue"]   = StaticText(_("Keyboard"))
1588
1589                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions","ColorActions"], {
1590                                 "ok"    : self.keyRed,
1591                                 "cancel": self.keyRed,
1592                                 "red"   : self.keyRed,
1593                                 "green" : self.keyGreen,
1594                                 "yellow": self.keyYellow,
1595                                 "blue"  : self.keyBlue,
1596                         },-2)
1597
1598                 self.showHelpTimer = eTimer()
1599                 self.showHelpTimer.callback.append(self.cbShowHelpTimerClosed)
1600                 self.showHelpTimer.start(500)
1601
1602                 self.onLayoutFinish.append(self.layoutFinished)
1603
1604         def layoutFinished(self):
1605                 self.setTitle(_('Browser Help'))
1606
1607         def cbShowHelpTimerClosed(self):
1608                 self.showHelpTimer.stop()
1609                 self.setHelpModeActions(self.MODE_GLOBAL)
1610
1611         def setHelpModeActions(self, _mode=0):
1612                 self.helpList = []
1613                 if _mode == self.MODE_GLOBAL:
1614                         self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
1615                                 "cancel" : (self.keyPass, _("Exit the Opera browser.")),
1616                         })
1617                         self["MenuActions"] = HelpableActionMap(self, "MenuActions", {
1618                                 "menu" : (self.keyPass, _("Show the Menu window.")),
1619                         })
1620                         self["ColorActions"] = HelpableActionMap(self, "ColorActions", {
1621                                 "green"  : (self.keyPass, _("Enter Key")),
1622                                 "yellow" : (self.keyPass, _("Show the Virtual keyboard window.")),
1623                                 "blue"   : (self.keyPass, _("Backspace Key")),
1624                         })
1625                         self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
1626                                 "info" : (self.keyPass, _("Switch to keyboard/mouse mode.")),
1627                         })
1628
1629                 elif _mode == self.MODE_MOUSE:
1630                         self["DirectionActions"] = HelpableActionMap(self, "DirectionActions", {
1631                                 "up"    : (self.keyPass, _("It will move the mouse pointer up.")),
1632                                 "down"  : (self.keyPass, _("It will move the mouse pointer down.")),
1633                                 "left"  : (self.keyPass, _("It will move the mouse pointer left.")),
1634                                 "right" : (self.keyPass, _("It will move the mouse pointer right.")),
1635                         })
1636                         self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
1637                                 "ok" : (self.keyPass, _("Left Mouse Button")),
1638                         })
1639                         self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
1640                                 "nextBouquet" : (self.keyPass, _("Right Mouse Button")),
1641                                 "nextService" : (self.keyPass, _("Left Key")),
1642                                 "prevService" : (self.keyPass, _("Right Key")),
1643                         })
1644                 elif _mode == self.MODE_KEYBOARD:
1645                         self["DirectionActions"] = HelpableActionMap(self, "DirectionActions", {
1646                                 "up"    : (self.keyPass, _("Up Key")),
1647                                 "down"  : (self.keyPass, _("Down Key")),
1648                                 "left"  : (self.keyPass, _("Left Key")),
1649                                 "right" : (self.keyPass, _("Right Key")),
1650                         })
1651                         self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
1652                                 "ok" : (self.keyPass, _("Enter Key")),
1653                         })
1654                         self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
1655                                 "nextBouquet" : (self.keyPass, _("PageUp Key")),
1656                                 "prevBouquet" : (self.keyPass, _("PageDown Key")),
1657                                 "nextService" : (self.keyPass, _("Go to previous page.")),
1658                                 "prevService" : (self.keyPass, _("Go to next page.")),
1659                         })
1660
1661                 if _mode > 0:
1662                         self.showHelp()
1663
1664         def keyPass(self):
1665                 pass
1666
1667         def keyRed(self):
1668                 self.close()
1669         def keyGreen(self):
1670                 self.setHelpModeActions(self.MODE_GLOBAL)
1671         def keyYellow(self):
1672                 self.setHelpModeActions(self.MODE_MOUSE)
1673         def keyBlue(self):
1674                 self.setHelpModeActions(self.MODE_KEYBOARD)
1675
1676 class OperaBrowser(Screen):
1677         MENUBAR_ITEM_WIDTH  = 150
1678         MENUBAR_ITEM_HEIGHT = 30
1679         SUBMENULIST_WIDTH   = 200
1680         SUBMENULIST_HEIGHT  = 25
1681         SUBMENULIST_NEXT    = 2
1682
1683         skin =  """
1684                 <screen name="Opera Browser" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="Opera Browser">
1685                         <widget name="topArea" zPosition="-1" position="0,0" size="1280,60" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
1686                         <widget name="menuitemFile" position="30,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
1687                         <widget name="menuitemTool" position="180,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
1688                         <widget name="menuitemHelp" position="330,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
1689                         <widget name="menulist" position="50,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
1690                         <widget name="submenulist" position="%d,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
1691                         <widget name="bottomArea" position="0,640" size="1280,80" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
1692                 </screen>
1693                 """ % (MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH, SUBMENULIST_WIDTH+50+SUBMENULIST_NEXT, MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH)# modify menu
1694
1695         MENUITEMS_LIST =[[(_('Open Startpage'), None), (_('Open URL'), None), (_('Start/Stop'),None), (_('Exit'), None)],
1696                          [(_('Bookmark'), None), (_('Preference'), None)],
1697                          [(_('About'), None), (_('Help'), None)]]
1698         def __init__(self, session, url=None):
1699                 Screen.__init__(self, session)
1700                 self["actions"] = ActionMap(["DirectionActions", "MenuActions", "OkCancelActions"], {
1701                          "cancel"      : self.keyCancel
1702                         ,"ok"          : self.keyOK
1703                         ,"left"        : self.keyLeft
1704                         ,"right"       : self.keyRight
1705                         ,"up"          : self.keyUp
1706                         ,"down"        : self.keyDown
1707                         ,"menu"        : self.keyMenu
1708                 }, -2)
1709
1710                 self._terminatedBrowser = True
1711                 self._enableKeyEvent = True
1712                 self._currentPageUrl = None
1713                 self._currentPageTitle = None
1714                 self.menubarCurrentIndex = 0
1715                 self.lvMenuItems = []
1716                 self.lvSubMenuItems = []
1717
1718                 self["topArea"]    = Label()
1719                 self["bottomArea"] = Label()
1720
1721                 self["menuitemFile"] = MultiColorLabel()# modify menu
1722                 self["menuitemTool"] = MultiColorLabel()
1723                 self["menuitemHelp"] = MultiColorLabel()
1724
1725                 self["menulist"] = MenuList(self.setListOnView())
1726                 self["submenulist"] = MenuList(self.setSubListOnView())
1727
1728                 self.toggleMainScreenFlag = True
1729                 self.toggleListViewFlag = False
1730                 self.toggleSubListViewFlag = False
1731                 self.currentListView = self["menulist"]
1732
1733                 self.onLayoutFinish.append(self.layoutFinished)
1734
1735                 self._onCloseTimer = eTimer()
1736                 self._onCloseTimer.callback.append(self._cb_onClose)
1737
1738                 self.paramUrl = url
1739
1740         def enableRCMouse(self, mode): #mode=[0|1]|[False|True]
1741                 rcmouse_path = "/proc/stb/fp/mouse"
1742                 if os.path.exists(rcmouse_path):
1743                         os.system("echo %d > %s" % (mode, rcmouse_path))
1744
1745         def layoutFinished(self):
1746                 self["menuitemFile"].setText(_("File"))# modify menu
1747                 self["menuitemTool"].setText(_("Tools"))
1748                 self["menuitemHelp"].setText(_("Help"))
1749
1750                 self["menulist"].hide()
1751                 self["submenulist"].hide()
1752
1753                 self["bottomArea"].setText(_("Opera Web Browser Plugin v1.0"))
1754                 self.setTitle(_("BrowserMain"))
1755                 self.selectMenuitem()
1756
1757                 if self.paramUrl is not None:
1758                         self.keyMenu()
1759                         self.cbUrlText(self.paramUrl, 1)
1760
1761         def selectMenuitem(self):
1762                 tmp = [self["menuitemFile"], self["menuitemTool"], self["menuitemHelp"]]# modify menu
1763                 self["menuitemFile"].setForegroundColorNum(0)
1764                 self["menuitemTool"].setForegroundColorNum(0)
1765                 self["menuitemHelp"].setForegroundColorNum(0)
1766                 tmp[self.menubarCurrentIndex].setForegroundColorNum(1)
1767
1768         def popupCloseAll(self):
1769                 self.keyLeft()
1770                 self.keyLeft()
1771                 self.keyUp()
1772                 self.keyCancel()
1773
1774         def setListOnView(self):
1775                 l = self.MENUITEMS_LIST[self.menubarCurrentIndex]
1776                 if not self._terminatedBrowser and self.menubarCurrentIndex == 0: # running
1777                         l = [(_('Return'), None)]
1778                 self.lvMenuItems = l #self.MENUITEMS_LIST[self.menubarCurrentIndex]     
1779                 return self.lvMenuItems
1780
1781         def setSubListOnView(self):
1782                 self.lvSubMenuItems = []
1783                 xl = self["menulist"].getCurrent()[1]
1784                 if xl is None: return []
1785                 for x in xl:
1786                         self.lvSubMenuItems.append((x,None))
1787                 return self.lvSubMenuItems
1788
1789         def toggleMainScreen(self):
1790                 if not self.toggleMainScreenFlag:
1791                         self.show()
1792                 else:   self.hide()
1793                 self.toggleMainScreenFlag = not self.toggleMainScreenFlag
1794
1795         def toggleListView(self):
1796                 if not self.toggleListViewFlag:
1797                         self["menulist"].show()
1798                 else:   self["menulist"].hide()
1799                 self.toggleListViewFlag = not self.toggleListViewFlag
1800
1801         def toggleSubListView(self):
1802                 if not self.toggleSubListViewFlag:
1803                         self["submenulist"].show()
1804                 else:   self["submenulist"].hide()
1805                 self.toggleSubListViewFlag = not self.toggleSubListViewFlag
1806
1807         def setCurrentListView(self, listViewIdx):
1808                 if listViewIdx == 0:
1809                         self.currentListView = None
1810                 elif listViewIdx == 1:
1811                         self.currentListView = self["menulist"]
1812                 elif listViewIdx == 2:
1813                         self.currentListView = self["submenulist"]
1814
1815         def _cb_onClose(self):
1816                 self._onCloseTimer.stop()
1817                 command_server = getCommandServer()
1818                 try:
1819                         if self._on_close_window in command_server.onHbbTVCloseCB:
1820                                         command_server.onHbbTVCloseCB.remove(self._on_close_window)
1821                 except Exception, ErrMsg: pass
1822                 try:
1823                         if self._on_setPageTitle in command_server.onSetPageTitleCB:
1824                                 command_server.onSetPageTitleCB.remove(self._on_setPageTitle)
1825                 except Exception, ErrMsg: pass
1826                 self._on_setPageTitle(_('Opera Browser'))
1827                 self.enableRCMouse(False)
1828                 self.toggleMainScreen()
1829                 fbClass.getInstance().unlock()
1830                 eRCInput.getInstance().unlock()
1831                 self._terminatedBrowser = True
1832                 self._enableKeyEvent = True
1833                 #if not self.toggleListViewFlag:
1834                 #       self.keyDown()
1835                 self._currentPageUrl = ''
1836                 if self.paramUrl is not None:
1837                         self.keyCancel()
1838                 else:
1839                         self.keyRight()
1840                         self.keyLeft()
1841
1842         def _on_setPageTitle(self, title=None):
1843                 print "Title :",title
1844                 if title is None:
1845                         return
1846                 self.setTitle(title)
1847
1848         def cbUrlText(self, data=None, mode=0):
1849                 print "Inputed Url :", data, mode
1850                 if strIsEmpty(data):
1851                         return
1852                 #self.hideSubmenu()
1853                 command_server = getCommandServer()
1854                 if self._on_setPageTitle not in command_server.onSetPageTitleCB:
1855                                 command_server.onSetPageTitleCB.append(self._on_setPageTitle)
1856                 if self._on_close_window not in command_server.onHbbTVCloseCB:
1857                         command_server.onHbbTVCloseCB.append(self._on_close_window)
1858                 self.toggleMainScreen()
1859                 self.enableRCMouse(True)
1860                 fbClass.getInstance().lock()
1861                 eRCInput.getInstance().lock()
1862                 command_util = getCommandUtil()
1863                 command_util.sendCommand('OP_BROWSER_OPEN_URL', data, mode)
1864                 self._terminatedBrowser = False
1865                 self._enableKeyEvent = False
1866
1867         def _on_close_window(self):
1868                 self._onCloseTimer.start(1000)
1869
1870         def _cb_bookmarkWindowClosed(self, data=None):
1871                 if data is None:
1872                         return
1873                 (url, mode) = data
1874                 self.cbUrlText(url, mode)
1875
1876         def _cmd_on_OpenUrl(self):
1877                 global _g_helper
1878                 if not _g_helper._is_browser_running():
1879                         message = _("Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu.")
1880                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
1881                         return
1882                 self.session.openWithCallback(self.cbUrlText, VirtualKeyBoard, title=(_("Please enter URL here")), text='http://')
1883         def _cmd_on_About(self):
1884                 self.session.open(MessageBox, _('Opera Web Browser Plugin v1.0'), type = MessageBox.TYPE_INFO)
1885         def _cmd_on_Exit(self):
1886                 self.close()
1887         def _cmd_on_StartStop(self):
1888                 global _g_helper
1889                 if _g_helper is None: 
1890                         return
1891                 _g_helper.showBrowserConfigBox()
1892         def _cmd_on_Bookmark(self):
1893                 url = self._currentPageUrl
1894                 if url is None:
1895                         url = ''
1896                 title = self._currentPageTitle
1897                 if title is None:
1898                         title = ''
1899                 self.session.openWithCallback(self._cb_bookmarkWindowClosed, OperaBrowserBookmarkWindow, url, title)
1900         def _cmd_on_Preference(self):
1901                 url = self._currentPageUrl
1902                 if url is None:
1903                         url = ''
1904                 self.session.open(OperaBrowserPreferenceWindow, url)
1905         def _cmd_on_OpenStartpage(self):
1906                 global _g_helper
1907                 if not _g_helper._is_browser_running():
1908                         message = _("Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu.")
1909                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
1910                         return
1911                 mode = 0
1912                 start = 'http://vuplus.com'
1913                 try:
1914                         d = OperaBrowserSetting().getData()
1915                         start = d['start']
1916                         mode = d['type']
1917                 except: pass
1918                 self.cbUrlText(start, mode)
1919         def _cmd_on_ReturnToBrowser(self):
1920                 self.keyCancel()
1921
1922         def _cmd_on_Help(self):
1923                 self.session.open(BrowserHelpWindow)
1924
1925         def doCommand(self, command):
1926                 # modify menu
1927                 cmd_map = {}
1928                 cmd_map[_('Exit')] = self._cmd_on_Exit
1929                 cmd_map[_('Help')] = self._cmd_on_Help
1930                 cmd_map[_('About')] = self._cmd_on_About
1931                 cmd_map[_('Open URL')] = self._cmd_on_OpenUrl
1932                 cmd_map[_('Start/Stop')] = self._cmd_on_StartStop
1933                 cmd_map[_('Bookmark')] = self._cmd_on_Bookmark
1934                 cmd_map[_('Preference')] = self._cmd_on_Preference
1935                 cmd_map[_('Return')] = self._cmd_on_ReturnToBrowser
1936                 cmd_map[_('Open Startpage')] = self._cmd_on_OpenStartpage
1937                 try:
1938                         cmd_map[command]()
1939                 except Exception, ErrMsg: print ErrMsg
1940
1941         def keyOK(self):
1942                 if not self.toggleListViewFlag:
1943                         self.keyDown()
1944                         return
1945                 if self.currentListView.getCurrent()[1] is None:
1946                         self.doCommand(self.currentListView.getCurrent()[0])
1947                         #self.session.open(MessageBox, _(self.currentListView.getCurrent()[0]), type = MessageBox.TYPE_INFO)
1948                         return
1949                 self.keyRight()
1950
1951         def updateSelectedMenuitem(self, status):
1952                 if self.menubarCurrentIndex == 0 and status < 0:
1953                         self.menubarCurrentIndex = 2 # modify menu
1954                 elif self.menubarCurrentIndex == 2 and status > 0: # modify menu
1955                         self.menubarCurrentIndex = 0
1956                 else:   self.menubarCurrentIndex += status
1957                 self.selectMenuitem()
1958
1959         def keyLeft(self):
1960                 if not self.toggleMainScreenFlag:
1961                         return
1962                 if not self.toggleListViewFlag:
1963                         self.updateSelectedMenuitem(-1)
1964                         return
1965                 if self.toggleSubListViewFlag:
1966                         self.setCurrentListView(1)
1967                         self.toggleSubListView()
1968                         return
1969                 #if self.currentListView.getSelectedIndex():
1970                 self.currentListView.pageUp()
1971                 self.keyUp()
1972                 self.keyLeft()
1973                 self.keyDown()
1974
1975         def keyRight(self):
1976                 if not self.toggleMainScreenFlag:
1977                         return
1978                 if not self.toggleListViewFlag:
1979                         self.updateSelectedMenuitem(1)
1980                         return
1981                 if self.currentListView is None:
1982                         return
1983                 if self.currentListView.getCurrent()[1] is not None:
1984                         parentSelectedIndex = self.currentListView.getSelectedIndex()
1985                         self.setCurrentListView(2)
1986                         self.currentListView.setList(self.setSubListOnView())
1987                         self.currentListView.resize(self.SUBMENULIST_WIDTH, self.SUBMENULIST_HEIGHT*len(self.lvSubMenuItems)+5)
1988                         self.currentListView.move(self.MENUBAR_ITEM_WIDTH*self.menubarCurrentIndex + self.SUBMENULIST_WIDTH+self.SUBMENULIST_NEXT + 50,self.MENUBAR_ITEM_HEIGHT+30+(parentSelectedIndex*self.SUBMENULIST_HEIGHT))
1989                         self.toggleSubListView()
1990                         return
1991                 self.currentListView.pageUp()
1992                 self.keyUp()
1993                 self.keyRight()
1994                 self.keyDown()
1995
1996         def keyDown(self):
1997                 if not self.toggleMainScreenFlag:
1998                         return
1999                 if self.currentListView is None:
2000                         return
2001                 if not self.toggleListViewFlag:
2002                         self.currentListView.setList(self.setListOnView())
2003                         self.currentListView.resize(self.SUBMENULIST_WIDTH, self.SUBMENULIST_HEIGHT*len(self.lvMenuItems)+5)
2004                         self.currentListView.move(self.MENUBAR_ITEM_WIDTH*self.menubarCurrentIndex+1+ 50,self.MENUBAR_ITEM_HEIGHT+30)
2005                         self.toggleListView()
2006                         return
2007                 self.currentListView.down()
2008
2009         def keyUp(self):
2010                 if not self.toggleMainScreenFlag:
2011                         return
2012                 if self.currentListView is None:
2013                         return
2014                 if self.currentListView == self["menulist"]:
2015                         if self.currentListView.getSelectedIndex() == 0:
2016                                 self.toggleListView()
2017                                 return
2018                 self.currentListView.up()
2019
2020         def keyCancel(self):
2021                 if not self._terminatedBrowser:
2022                         #self._session.openWithCallback(self._cb_virtualKeyboardClosed, VirtualKeyBoard, title=("Please enter URL here"), text="")
2023                         fbClass.getInstance().lock()
2024                         eRCInput.getInstance().lock()
2025                         if self.toggleListViewFlag:
2026                                 self.toggleMainScreen()
2027                         self._currentPageUrl   = None
2028                         self._currentPageTitle = None
2029                         command_util = getCommandUtil()
2030                         command_util.sendCommand('OP_BROWSER_MENU_RES')
2031                         return
2032                 self.close()
2033
2034         def keyMenu(self):
2035                 self.toggleMainScreen()
2036
2037         def setCurrentPageUrl(self, url, title=None):
2038                 self._currentPageUrl = url
2039                 if title is None:
2040                         idx = len(url)
2041                         if idx > 10: idx = 10
2042                         title = url[:idx]
2043                 self._currentPageTitle = title
2044                 print self._currentPageUrl
2045                 self.toggleMainScreen()
2046                 self.hideSubmenu()
2047                 self.keyDown()
2048
2049         def hideSubmenu(self):
2050                 self.currentListView.pageUp()
2051                 self.keyUp()
2052
2053 def auto_start_main(reason, **kwargs):
2054         if reason:
2055                 command_server = getCommandServer()
2056                 command_server.stop()
2057
2058 from  Screens.HelpMenu import HelpableScreen
2059 def session_start_main(session, reason, **kwargs):
2060         fbClass.getInstance().unlock()
2061         eRCInput.getInstance().unlock()
2062         global _g_helper
2063         _g_helper = session.open(HbbTVHelper)
2064
2065         HelpableScreen.__init__ = HelpableScreen__init__
2066         HelpableScreen.session = session
2067
2068 def HelpableScreen__init__(self):
2069         if isinstance(self, HelpableScreen):
2070                 HelpableScreen.showManual = showManual
2071
2072                 self["helpActions"] = ActionMap(["HelpbuttonActions"], {
2073                         "help_b" : self.showHelp,
2074                         "help_l" : self.showManual, 
2075                 }, -2)
2076
2077 _g_clearBrowserDataTimer = eTimer()
2078 def showManual(self):
2079         if not os.path.exists('/usr/local/manual'):
2080                 return
2081
2082         url = 'file:///usr/local/manual/main.html'
2083         lang = language.getLanguage()
2084         if lang == 'ru_RU' and os.path.exists('/usr/local/manual/ru_RU'):
2085                 url = 'file:///usr/local/manual/ru_RU/main.html'
2086         elif lang == 'de_DE' and os.path.exists('/usr/local/manual/de_DE'):
2087                 url = 'file:///usr/local/manual/de_DE/main.html'
2088
2089         def _do_clean():
2090                 _g_clearBrowserDataTimer.stop()
2091                 try:    _g_clearBrowserDataTimer.callback.remove(_do_clean)
2092                 except: pass
2093                 setPluginBrowser(None)
2094         def clearBrowserData():
2095                 _g_clearBrowserDataTimer.callback.append(_do_clean)
2096                 _g_clearBrowserDataTimer.start(50)
2097         setPluginBrowser(self.session.openWithCallback(clearBrowserData, OperaBrowser, url))
2098
2099 def plugin_start_main(session, **kwargs):
2100         #session.open(OperaBrowser)
2101         def _do_clean():
2102                 _g_clearBrowserDataTimer.stop()
2103                 try:    _g_clearBrowserDataTimer.callback.remove(_do_clean)
2104                 except: pass
2105                 setPluginBrowser(None)
2106         def clearBrowserData():
2107                 _g_clearBrowserDataTimer.callback.append(_do_clean)
2108                 _g_clearBrowserDataTimer.start(50)
2109         setPluginBrowser(session.openWithCallback(clearBrowserData, OperaBrowser))
2110
2111 def plugin_extension_start_application(session, **kwargs):
2112         global _g_helper
2113         if _g_helper is None: 
2114                 return
2115         _g_helper.showApplicationSelectionBox()
2116
2117 def plugin_extension_browser_config(session, **kwargs):
2118         global _g_helper
2119         if _g_helper is None: 
2120                 return
2121         _g_helper.showBrowserConfigBox()
2122
2123 def Plugins(path, **kwargs):
2124         l = []
2125         l.append(PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=auto_start_main))
2126         l.append(PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10))
2127         l.append(PluginDescriptor(name=_("HbbTV Applications"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_start_application))
2128         l.append(PluginDescriptor(name=_("Browser Start/Stop"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_browser_config))
2129         l.append(PluginDescriptor(name=_("Opera Web Browser"), description=_("start opera web browser"), where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=True, fnc=plugin_start_main))
2130
2131         return l
2132