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