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