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