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