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