[browser] add exception handling.
[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.session = 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.makeConfigList()
1219                 self.onLayoutFinish.append(self.layoutFinished)
1220
1221         def layoutFinished(self):
1222                 self.setTitle('Bookmark ' + self.mMode)
1223         def saveData(self):
1224                 if self.mType == BookmarkEditWindow.CATEGORY:
1225                         if self.mMode == 'Add':
1226                                 categoryName = self.menuItemName.value
1227                                 if strIsEmpty(categoryName):
1228                                         msg = "Invalid Category Name!!(Empty)\nPlease, Input to the Category Name."
1229                                         self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
1230                                         return False
1231                                 self.mBookmarkManager.addCategory(categoryName)
1232                         else:
1233                                 if strIsEmpty(self.menuItemName.value):
1234                                         msg = "Invalid Category Name!!(Empty)\nPlease, Input to the Category Name."
1235                                         self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
1236                                         return False
1237                                 self.mData.mName = self.menuItemName.value
1238                                 self.mBookmarkManager.updateCategory(self.mData)
1239                 else:
1240                         if self.mMode == 'Add':
1241                                 bookmarkTitle = self.menuItemTitle.value
1242                                 bookmarkUrl   = self.menuItemUrl.value
1243                                 if strIsEmpty(bookmarkTitle):
1244                                         msg = "Invalid Bookmark Title!!(Empty)\nPlease input to the Bookmark Title."
1245                                         self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
1246                                         return False
1247                                 self.mBookmarkManager.addBookmark(bookmarkTitle, bookmarkUrl, self.mData.mParent)
1248                         else:
1249                                 if strIsEmpty(self.menuItemTitle.value):
1250                                         msg = "Invalid Bookmark Title!!(Empty)\nPlease input to the Bookmark Title."
1251                                         self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
1252                                         return False
1253                                 self.mData.mTitle = self.menuItemTitle.value
1254                                 self.mData.mUrl   = self.menuItemUrl.value
1255                                 self.mBookmarkManager.updateBookmark(self.mData)
1256                 return True
1257         def keyGreen(self):
1258                 if not self.saveData():
1259                         return
1260                 self.close(True)
1261         def keyRed(self):
1262                 self.close(False)
1263         def keyLeft(self):
1264                 ConfigListScreen.keyLeft(self)
1265         def keyRight(self):
1266                 ConfigListScreen.keyRight(self)
1267         def makeConfigList(self):
1268                 self.menulist = []
1269
1270                 if self.mType == BookmarkEditWindow.CATEGORY:
1271                         self.menuItemName = ConfigText(default=self.mData.mName, visible_width=65, fixed_size=False)
1272                         menuEntryName  = getConfigListEntry(_("Name"), self.menuItemName)
1273                         self.menulist.append(menuEntryName)
1274                 else:
1275                         self.menuItemTitle = ConfigText(default=self.mData.mTitle, visible_width=65, fixed_size=False)
1276                         self.menuItemUrl   = ConfigText(default=self.mData.mUrl, visible_width=65, fixed_size=False)
1277                         menuEntryTitle = getConfigListEntry(_("Title"), self.menuItemTitle)
1278                         menuEntryUrl   = getConfigListEntry(_("Url"), self.menuItemUrl)
1279                         self.menulist.append(menuEntryTitle)
1280                         self.menulist.append(menuEntryUrl)
1281                         
1282                 self["config"].list = self.menulist
1283                 self["config"].l.setList(self.menulist)
1284
1285 class OperaBrowserBookmarkWindow(Screen):
1286         skin =  """
1287                 <screen name="HbbTVBrowserBookmarkWindow" position="center,center" size="600,400" title="Bookmark" >
1288                         <widget name="bookmarklist" position="0,0" size="600,200" zPosition="10" scrollbarMode="showOnDemand" />
1289
1290                         <ePixmap pixmap="skin_default/buttons/key_0.png" position="556,330" size="35,30" alphatest="on" />
1291                         <widget source="key_0" render="Label" position="258,330" zPosition="1" size="300,30" font="Regular;20" halign="right" valign="center"/>
1292
1293                         <ePixmap pixmap="skin_default/buttons/red.png" position="5,360" size="140,40" alphatest="on" />
1294                         <ePixmap pixmap="skin_default/buttons/green.png" position="155,360" size="140,40" alphatest="on" />
1295                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,360" size="140,40" alphatest="on" />
1296                         <ePixmap pixmap="skin_default/buttons/blue.png" position="450,360" size="140,40" alphatest="on" />
1297
1298                         <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" />
1299                         <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" />
1300                         <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" />
1301                         <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" />
1302                 </screen>
1303                 """
1304
1305         def __init__(self, _session, _url=None, _title=None):
1306                 self.mUrl   = _url
1307                 self.mTitle = _title
1308                 self.mBookmarkManager = BookmarkManager.getInstance()
1309                 self.mSession = _session
1310                 Screen.__init__(self, _session)
1311                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions","ColorActions", "NumberActions"], {
1312                                 "ok"    : self.keyOK,
1313                                 "cancel": self.keyCancel,
1314                                 "red"   : self.keyRed,
1315                                 "green" : self.keyGreen,
1316                                 "yellow": self.keyYellow,
1317                                 "blue"  : self.keyBlue,
1318                                 "0"     : self.keyNumber,
1319                         },-2)
1320
1321                 self["key_red"]    = StaticText(_("Exit"))
1322                 self["key_green"]  = StaticText(_("Add"))
1323                 self["key_yellow"] = StaticText(_("Edit"))
1324                 self["key_blue"]   = StaticText(_("Delete"))
1325                 self["key_0"]      = StaticText(_("Set as Startpage"))
1326
1327                 self.mBookmarkList = self.setBookmarkList()
1328                 self["bookmarklist"] = MenuList(self.mBookmarkList)
1329
1330         def setBookmarkList(self):
1331                 l = []
1332                 #self.mBookmarkManager.dump()
1333                 cd = self.mBookmarkManager.getBookmarkRoot()
1334                 for ck in cd.iterkeys():
1335                         l.append(('# ' + cd[ck].mName, cd[ck]))
1336                         bd = cd[ck].mBookmarks
1337                         for bk in bd.iterkeys():
1338                                 l.append(('    - ' + bd[bk].mTitle, bd[bk]))
1339                 return l
1340         def updateBookmarkList(self):
1341                 self.mBookmarkList = self.setBookmarkList()
1342                 self["bookmarklist"].setList(self.mBookmarkList)
1343         def cbEditWindow(self, ret=False):
1344                 if not ret: 
1345                         return
1346                 self.updateBookmarkList()
1347         def getParentCategory(self):
1348                 idx = self["bookmarklist"].getSelectedIndex()
1349                 try:
1350                         while idx >= 0:
1351                                 data = self.mBookmarkList[idx][0].strip()
1352                                 if data[0] == '#':
1353                                         return self.mBookmarkList[idx][1]
1354                                 idx -= 1
1355                 except: pass
1356                 return None
1357         def isCategoryItem(self):
1358                 try:
1359                         head = self["bookmarklist"].getCurrent()[0].strip()
1360                         if head[0] == '#':
1361                                 return True
1362                 except: pass
1363                 return False
1364         def keyNumber(self):
1365                 data = self["bookmarklist"].getCurrent()[1]
1366                 if strIsEmpty(data.mUrl):
1367                         msg = "Invalid URL. Please check again!!"
1368                         self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
1369                         return
1370                 def cbSetStartpage(ret=None):
1371                         if ret is None: return
1372                         if ret:
1373                                 data = self["bookmarklist"].getCurrent()[1]
1374                                 OperaBrowserSetting().setData(data.mUrl)
1375                 msg = "Do you want to set selected url to the Startpage?"
1376                 self.mSession.openWithCallback(cbSetStartpage, MessageBox, msg, MessageBox.TYPE_YESNO, default=True)
1377
1378         def keyGreen(self):
1379                 def cbGreen(data):
1380                         if data is None:
1381                                 return
1382                         if data[1] == 1:
1383                                 parent = self.getParentCategory()
1384                                 if parent is None:
1385                                         return
1386                                 if strIsEmpty(self.mTitle):
1387                                         return
1388                                 retAdd = self.mBookmarkManager.addBookmark(self.mTitle, self.mUrl, parent.mId)
1389                                 if not retAdd:
1390                                         msg = "Current page is already exist."
1391                                         self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
1392                                 self.cbEditWindow(True)
1393                         elif data[1] == 2:
1394                                 parent = self.getParentCategory()
1395                                 if parent is None:
1396                                         return
1397                                 b = BookmarkData(0, '', '', parent.mId)
1398                                 self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Add', BookmarkEditWindow.BOOKMARK, b, self.mBookmarkManager)
1399                         elif data[1] == 3:
1400                                 c = CategoryData(0, '')
1401                                 self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Add', BookmarkEditWindow.CATEGORY, c, self.mBookmarkManager)
1402                 if strIsEmpty(self.mUrl):
1403                         l = [('Direct Input(Bookmark)',2,), ('Direct Input(Category)',3,)]
1404                 else:   l = [('Currentpage(Bookmark)',1,), ('Direct Input(Bookmark)',2,), ('Direct Input(Category)',3,)]
1405                 self.mSession.openWithCallback(cbGreen, ChoiceBox, title=_("Please choose."), list=l)
1406         def keyYellow(self):
1407                 data = self["bookmarklist"].getCurrent()[1]
1408                 if self.isCategoryItem():
1409                         self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Edit', BookmarkEditWindow.CATEGORY, data, self.mBookmarkManager)
1410                 else:   self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Edit', BookmarkEditWindow.BOOKMARK, data, self.mBookmarkManager)
1411         def keyBlue(self):
1412                 def cbBlue(ret=None):
1413                         if not ret: return
1414                         data = self["bookmarklist"].getCurrent()[1]
1415                         if self.isCategoryItem():
1416                                 self.mBookmarkManager.deleteCategory(data.mId)
1417                         else:   self.mBookmarkManager.deleteBookmark(data.mId)
1418                         self.updateBookmarkList()
1419                 if self.isCategoryItem():
1420                         msg = "Do you want to delete the category and the bookmarks?"
1421                 else:   msg = "Do you want to delete the bookmark?"
1422                 self.mSession.openWithCallback(cbBlue, MessageBox, msg, MessageBox.TYPE_YESNO, default=True)
1423         def keyOK(self):
1424                 if self.isCategoryItem(): return
1425
1426                 data = self["bookmarklist"].getCurrent()[1]
1427                 url = data.mUrl.strip()
1428                 if len(url) == 0:
1429                         self.session.open(MessageBox, "Can't open selected bookmark.\n   - URL data is empty!!", type = MessageBox.TYPE_INFO)
1430                         return
1431                 self.close(url)
1432         def keyRed(self):
1433                 self.keyCancel()
1434         def keyCancel(self):
1435                 self.close()
1436
1437
1438 class BrowserHelpWindow(Screen, HelpableScreen):
1439         MODE_GLOBAL,MODE_KEYBOARD,MODE_MOUSE = 1,2,3
1440         skin =  """
1441                 <screen name="BrowserHelpWindow" position="center,center" size="600,40" title="Browser Help" >
1442                         <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
1443                         <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
1444                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
1445                         <ePixmap pixmap="skin_default/buttons/blue.png" position="450,0" size="140,40" alphatest="on" />
1446
1447                         <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" />
1448                         <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" />
1449                         <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" />
1450                         <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" />
1451                 </screen>
1452                 """
1453         def __init__(self, session):
1454                 Screen.__init__(self, session)
1455                 HelpableScreen.__init__(self)
1456
1457                 self["key_red"]    = StaticText(_("Exit"))
1458                 self["key_green"]  = StaticText(_("Global"))
1459                 self["key_yellow"] = StaticText(_("Mouse"))
1460                 self["key_blue"]   = StaticText(_("Keyboard"))
1461
1462                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions","ColorActions"], {
1463                                 "ok"    : self.keyRed,
1464                                 "cancel": self.keyRed,
1465                                 "red"   : self.keyRed,
1466                                 "green" : self.keyGreen,
1467                                 "yellow": self.keyYellow,
1468                                 "blue"  : self.keyBlue,
1469                         },-2)
1470
1471                 self.showHelpTimer = eTimer()
1472                 self.showHelpTimer.callback.append(self.cbShowHelpTimerClosed)
1473                 self.showHelpTimer.start(500)
1474
1475         def cbShowHelpTimerClosed(self):
1476                 self.showHelpTimer.stop()
1477                 self.setHelpModeActions(self.MODE_GLOBAL)
1478
1479         def setHelpModeActions(self, _mode=0):
1480                 self.helpList = []
1481                 if _mode == self.MODE_GLOBAL:
1482                         self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
1483                                 "cancel" : (self.keyPass, _("Exit the Opera browser.")),
1484                         })
1485                         self["MenuActions"] = HelpableActionMap(self, "MenuActions", {
1486                                 "menu" : (self.keyPass, _("Show the Menu window.")),
1487                         })
1488                         self["ColorActions"] = HelpableActionMap(self, "ColorActions", {
1489                                 "green"  : (self.keyPass, _("Enter Key")),
1490                                 "yellow" : (self.keyPass, _("Show the Virtual keyboard window.")),
1491                                 "blue"   : (self.keyPass, _("Backspace Key")),
1492                         })
1493                         self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
1494                                 "info" : (self.keyPass, _("Switch to keyboard/mouse mode.")),
1495                         })
1496
1497                 elif _mode == self.MODE_MOUSE:
1498                         self["DirectionActions"] = HelpableActionMap(self, "DirectionActions", {
1499                                 "up"    : (self.keyPass, _("It will move the mouse pointer up.")),
1500                                 "down"  : (self.keyPass, _("It will move the mouse pointer down.")),
1501                                 "left"  : (self.keyPass, _("It will move the mouse pointer left.")),
1502                                 "right" : (self.keyPass, _("It will move the mouse pointer right.")),
1503                         })
1504                         self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
1505                                 "ok" : (self.keyPass, _("Left Mouse Button")),
1506                         })
1507                         self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
1508                                 "nextBouquet" : (self.keyPass, _("Right Mouse Button")),
1509                                 "nextService" : (self.keyPass, _("Left Key")),
1510                                 "prevService" : (self.keyPass, _("Right Key")),
1511                         })
1512                 elif _mode == self.MODE_KEYBOARD:
1513                         self["DirectionActions"] = HelpableActionMap(self, "DirectionActions", {
1514                                 "up"    : (self.keyPass, _("Up Key")),
1515                                 "down"  : (self.keyPass, _("Down Key")),
1516                                 "left"  : (self.keyPass, _("Left Key")),
1517                                 "right" : (self.keyPass, _("Right Key")),
1518                         })
1519                         self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
1520                                 "ok" : (self.keyPass, _("Enter Key")),
1521                         })
1522                         self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
1523                                 "nextBouquet" : (self.keyPass, _("PageUp Key")),
1524                                 "prevBouquet" : (self.keyPass, _("PageDown Key")),
1525                                 "nextService" : (self.keyPass, _("Go to previous page.")),
1526                                 "prevService" : (self.keyPass, _("Go to next page.")),
1527                         })
1528
1529                 if _mode > 0:
1530                         self.showHelp()
1531
1532         def keyPass(self):
1533                 pass
1534
1535         def keyRed(self):
1536                 self.close()
1537         def keyGreen(self):
1538                 self.setHelpModeActions(self.MODE_GLOBAL)
1539         def keyYellow(self):
1540                 self.setHelpModeActions(self.MODE_MOUSE)
1541         def keyBlue(self):
1542                 self.setHelpModeActions(self.MODE_KEYBOARD)
1543
1544 _g_helper = None
1545 class OperaBrowser(Screen):
1546         MENUBAR_ITEM_WIDTH  = 150
1547         MENUBAR_ITEM_HEIGHT = 30
1548         SUBMENULIST_WIDTH   = 200
1549         SUBMENULIST_HEIGHT  = 25
1550         SUBMENULIST_NEXT    = 2
1551
1552         skin =  """
1553                 <screen name="Opera Browser" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="Opera Browser">
1554                         <widget name="topArea" zPosition="-1" position="0,0" size="1280,60" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
1555                         <widget name="menuitemFile" position="30,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
1556                         <widget name="menuitemTool" position="180,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
1557                         <widget name="menuitemHelp" position="330,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
1558                         <widget name="menulist" position="50,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
1559                         <widget name="submenulist" position="%d,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
1560                         <widget name="bottomArea" position="0,640" size="1280,80" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
1561                 </screen>
1562                 """ % (MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH, SUBMENULIST_WIDTH+50+SUBMENULIST_NEXT, MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH)# modify menu
1563
1564         MENUITEMS_LIST =[[('Open Startpage', None), ('Open URL', None), ('Start/Stop',None), ('Exit', None)],
1565                          [('Bookmark', None), ('Preference', None)],
1566                          [('About', None), ('Help', None)]]
1567         def __init__(self, session):
1568                 Screen.__init__(self, session)
1569                 self["actions"] = ActionMap(["DirectionActions", "MenuActions", "OkCancelActions"], {
1570                          "cancel"      : self.keyCancel
1571                         ,"ok"          : self.keyOK
1572                         ,"left"        : self.keyLeft
1573                         ,"right"       : self.keyRight
1574                         ,"up"          : self.keyUp
1575                         ,"down"        : self.keyDown
1576                         ,"menu"        : self.keyMenu
1577                 }, -2)
1578
1579                 self._terminatedBrowser = True
1580                 self._enableKeyEvent = True
1581                 self._currentPageUrl = None
1582                 self._currentPageTitle = None
1583                 self.menubarCurrentIndex = 0
1584                 self.lvMenuItems = []
1585                 self.lvSubMenuItems = []
1586
1587                 self["topArea"]    = Label()
1588                 self["bottomArea"] = Label()
1589
1590                 self["menuitemFile"] = MultiColorLabel()# modify menu
1591                 self["menuitemTool"] = MultiColorLabel()
1592                 self["menuitemHelp"] = MultiColorLabel()
1593
1594                 self["menulist"] = MenuList(self.setListOnView())
1595                 self["submenulist"] = MenuList(self.setSubListOnView())
1596
1597                 self.toggleMainScreenFlag = True
1598                 self.toggleListViewFlag = False
1599                 self.toggleSubListViewFlag = False
1600                 self.currentListView = self["menulist"]
1601
1602                 self.onLayoutFinish.append(self.layoutFinished)
1603
1604                 self._onCloseTimer = eTimer()
1605                 self._onCloseTimer.callback.append(self._cb_onClose)
1606
1607         def enableRCMouse(self, mode): #mode=[0|1]|[False|True]
1608                 rcmouse_path = "/proc/stb/fp/mouse"
1609                 if os.path.exists(rcmouse_path):
1610                         os.system("echo %d > %s" % (mode, rcmouse_path))
1611
1612         def layoutFinished(self):
1613                 self["menuitemFile"].setText("File")# modify menu
1614                 self["menuitemTool"].setText("Tools")
1615                 self["menuitemHelp"].setText("Help")
1616
1617                 self["menulist"].hide()
1618                 self["submenulist"].hide()
1619
1620                 self["bottomArea"].setText("Opera Web Browser Plugin v1.0")
1621                 self.setTitle("BrowserMain")
1622                 self.selectMenuitem()
1623
1624         def selectMenuitem(self):
1625                 tmp = [self["menuitemFile"], self["menuitemTool"], self["menuitemHelp"]]# modify menu
1626                 self["menuitemFile"].setForegroundColorNum(0)
1627                 self["menuitemTool"].setForegroundColorNum(0)
1628                 self["menuitemHelp"].setForegroundColorNum(0)
1629                 tmp[self.menubarCurrentIndex].setForegroundColorNum(1)
1630
1631         def popupCloseAll(self):
1632                 self.keyLeft()
1633                 self.keyLeft()
1634                 self.keyUp()
1635                 self.keyCancel()
1636
1637         def setListOnView(self):
1638                 l = self.MENUITEMS_LIST[self.menubarCurrentIndex]
1639                 if not self._terminatedBrowser and self.menubarCurrentIndex == 0: # running
1640                         l = [('Return', None)]
1641                 self.lvMenuItems = l #self.MENUITEMS_LIST[self.menubarCurrentIndex]     
1642                 return self.lvMenuItems
1643
1644         def setSubListOnView(self):
1645                 self.lvSubMenuItems = []
1646                 xl = self["menulist"].getCurrent()[1]
1647                 if xl is None: return []
1648                 for x in xl:
1649                         self.lvSubMenuItems.append((x,None))
1650                 return self.lvSubMenuItems
1651
1652         def toggleMainScreen(self):
1653                 if not self.toggleMainScreenFlag:
1654                         self.show()
1655                 else:   self.hide()
1656                 self.toggleMainScreenFlag = not self.toggleMainScreenFlag
1657
1658         def toggleListView(self):
1659                 if not self.toggleListViewFlag:
1660                         self["menulist"].show()
1661                 else:   self["menulist"].hide()
1662                 self.toggleListViewFlag = not self.toggleListViewFlag
1663
1664         def toggleSubListView(self):
1665                 if not self.toggleSubListViewFlag:
1666                         self["submenulist"].show()
1667                 else:   self["submenulist"].hide()
1668                 self.toggleSubListViewFlag = not self.toggleSubListViewFlag
1669
1670         def setCurrentListView(self, listViewIdx):
1671                 if listViewIdx == 0:
1672                         self.currentListView = None
1673                 elif listViewIdx == 1:
1674                         self.currentListView = self["menulist"]
1675                 elif listViewIdx == 2:
1676                         self.currentListView = self["submenulist"]
1677
1678         def _cb_onClose(self):
1679                 self._onCloseTimer.stop()
1680                 command_server = getCommandServer()
1681                 try:
1682                         if self._on_close_window in command_server.onHbbTVCloseCB:
1683                                         command_server.onHbbTVCloseCB.remove(self._on_close_window)
1684                 except Exception, ErrMsg: pass
1685                 try:
1686                         if self._on_setPageTitle in command_server.onSetPageTitleCB:
1687                                 command_server.onSetPageTitleCB.remove(self._on_setPageTitle)
1688                 except Exception, ErrMsg: pass
1689                 self._on_setPageTitle('Opera Browser')
1690                 self.enableRCMouse(False)
1691                 self.toggleMainScreen()
1692                 eRCInput.getInstance().unlock()
1693                 self._terminatedBrowser = True
1694                 self._enableKeyEvent = True
1695                 #if not self.toggleListViewFlag:
1696                 #       self.keyDown()
1697                 self.keyRight()
1698                 self.keyLeft()
1699
1700         def _on_setPageTitle(self, title=None):
1701                 print "Title :",title
1702                 if title is None:
1703                         return
1704                 self.setTitle(title)
1705
1706         def cbUrlText(self, data=None):
1707                 print "Inputed Url :", data
1708                 if strIsEmpty(data):
1709                         return
1710                 #self.hideSubmenu()
1711                 command_server = getCommandServer()
1712                 if self._on_setPageTitle not in command_server.onSetPageTitleCB:
1713                                 command_server.onSetPageTitleCB.append(self._on_setPageTitle)
1714                 if self._on_close_window not in command_server.onHbbTVCloseCB:
1715                         command_server.onHbbTVCloseCB.append(self._on_close_window)
1716                 self.toggleMainScreen()
1717                 self.enableRCMouse(True)
1718                 eRCInput.getInstance().lock()
1719                 command_util = getCommandUtil()
1720                 command_util.sendCommand('OP_BROWSER_OPEN_URL', data)
1721                 self._terminatedBrowser = False
1722                 self._enableKeyEvent = False
1723
1724         def _on_close_window(self):
1725                 self._onCloseTimer.start(1000)
1726
1727         def _cb_bookmarkWindowClosed(self, data=None):
1728                 if data is None:
1729                         return
1730                 self.cbUrlText(data)
1731
1732         def _cmd_on_OpenUrl(self):
1733                 global _g_helper
1734                 if not _g_helper._is_browser_running():
1735                         message = "Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu."
1736                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
1737                         return
1738                 self.session.openWithCallback(self.cbUrlText, VirtualKeyBoard, title=("Please enter URL here"), text='http://')
1739         def _cmd_on_About(self):
1740                 self.session.open(MessageBox, 'Opera Web Browser Plugin v1.0', type = MessageBox.TYPE_INFO)
1741         def _cmd_on_Exit(self):
1742                 self.close()
1743         def _cmd_on_StartStop(self):
1744                 global _g_helper
1745                 if _g_helper is None: 
1746                         return
1747                 _g_helper.showBrowserConfigBox()
1748         def _cmd_on_Bookmark(self):
1749                 url = self._currentPageUrl
1750                 if url is None:
1751                         url = ''
1752                 title = self._currentPageTitle
1753                 if title is None:
1754                         title = ''
1755                 self.session.openWithCallback(self._cb_bookmarkWindowClosed, OperaBrowserBookmarkWindow, url, title)
1756         def _cmd_on_Preference(self):
1757                 url = self._currentPageUrl
1758                 if url is None:
1759                         url = ''
1760                 self.session.open(OperaBrowserPreferenceWindow, url)
1761         def _cmd_on_OpenStartpage(self):
1762                 global _g_helper
1763                 if not _g_helper._is_browser_running():
1764                         message = "Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu."
1765                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
1766                         return
1767                 start = 'http://vuplus.com'
1768                 try:
1769                         start = OperaBrowserSetting().getData()['start']
1770                 except: pass
1771                 self.cbUrlText(start)
1772         def _cmd_on_ReturnToBrowser(self):
1773                 self.keyCancel()
1774
1775         def _cmd_on_Help(self):
1776                 self.session.open(BrowserHelpWindow)
1777
1778         def doCommand(self, command):
1779                 cmd_map = {# modify menu
1780                          'Exit'         :self._cmd_on_Exit
1781                         ,'Help'         :self._cmd_on_Help
1782                         ,'About'        :self._cmd_on_About
1783                         ,'Open URL'     :self._cmd_on_OpenUrl
1784                         ,'Start/Stop'   :self._cmd_on_StartStop
1785                         ,'Bookmark'     :self._cmd_on_Bookmark
1786                         ,'Preference'   :self._cmd_on_Preference
1787                         ,'Return'       :self._cmd_on_ReturnToBrowser
1788                         ,'Open Startpage' :self._cmd_on_OpenStartpage
1789                 }
1790                 try:
1791                         cmd_map[command]()
1792                 except Exception, ErrMsg: print ErrMsg
1793
1794         def keyOK(self):
1795                 if not self.toggleListViewFlag:
1796                         self.keyDown()
1797                         return
1798                 if self.currentListView.getCurrent()[1] is None:
1799                         self.doCommand(self.currentListView.getCurrent()[0])
1800                         #self.session.open(MessageBox, _(self.currentListView.getCurrent()[0]), type = MessageBox.TYPE_INFO)
1801                         return
1802                 self.keyRight()
1803
1804         def updateSelectedMenuitem(self, status):
1805                 if self.menubarCurrentIndex == 0 and status < 0:
1806                         self.menubarCurrentIndex = 2 # modify menu
1807                 elif self.menubarCurrentIndex == 2 and status > 0: # modify menu
1808                         self.menubarCurrentIndex = 0
1809                 else:   self.menubarCurrentIndex += status
1810                 self.selectMenuitem()
1811
1812         def keyLeft(self):
1813                 if not self.toggleMainScreenFlag:
1814                         return
1815                 if not self.toggleListViewFlag:
1816                         self.updateSelectedMenuitem(-1)
1817                         return
1818                 if self.toggleSubListViewFlag:
1819                         self.setCurrentListView(1)
1820                         self.toggleSubListView()
1821                         return
1822                 #if self.currentListView.getSelectedIndex():
1823                 self.currentListView.pageUp()
1824                 self.keyUp()
1825                 self.keyLeft()
1826                 self.keyDown()
1827
1828         def keyRight(self):
1829                 if not self.toggleMainScreenFlag:
1830                         return
1831                 if not self.toggleListViewFlag:
1832                         self.updateSelectedMenuitem(1)
1833                         return
1834                 if self.currentListView is None:
1835                         return
1836                 if self.currentListView.getCurrent()[1] is not None:
1837                         parentSelectedIndex = self.currentListView.getSelectedIndex()
1838                         self.setCurrentListView(2)
1839                         self.currentListView.setList(self.setSubListOnView())
1840                         self.currentListView.resize(self.SUBMENULIST_WIDTH, self.SUBMENULIST_HEIGHT*len(self.lvSubMenuItems)+5)
1841                         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))
1842                         self.toggleSubListView()
1843                         return
1844                 self.currentListView.pageUp()
1845                 self.keyUp()
1846                 self.keyRight()
1847                 self.keyDown()
1848
1849         def keyDown(self):
1850                 if not self.toggleMainScreenFlag:
1851                         return
1852                 if self.currentListView is None:
1853                         return
1854                 if not self.toggleListViewFlag:
1855                         self.currentListView.setList(self.setListOnView())
1856                         self.currentListView.resize(self.SUBMENULIST_WIDTH, self.SUBMENULIST_HEIGHT*len(self.lvMenuItems)+5)
1857                         self.currentListView.move(self.MENUBAR_ITEM_WIDTH*self.menubarCurrentIndex+1+ 50,self.MENUBAR_ITEM_HEIGHT+30)
1858                         self.toggleListView()
1859                         return
1860                 self.currentListView.down()
1861
1862         def keyUp(self):
1863                 if not self.toggleMainScreenFlag:
1864                         return
1865                 if self.currentListView is None:
1866                         return
1867                 if self.currentListView == self["menulist"]:
1868                         if self.currentListView.getSelectedIndex() == 0:
1869                                 self.toggleListView()
1870                                 return
1871                 self.currentListView.up()
1872
1873         def keyCancel(self):
1874                 if not self._terminatedBrowser:
1875                         #self._session.openWithCallback(self._cb_virtualKeyboardClosed, VirtualKeyBoard, title=("Please enter URL here"), text="")
1876                         eRCInput.getInstance().lock()
1877                         if self.toggleListViewFlag:
1878                                 self.toggleMainScreen()
1879                         self._currentPageUrl   = None
1880                         self._currentPageTitle = None
1881                         command_util = getCommandUtil()
1882                         command_util.sendCommand('OP_BROWSER_MENU_RES')
1883                         return
1884                 self.close()
1885
1886         def keyMenu(self):
1887                 self.toggleMainScreen()
1888
1889         def setCurrentPageUrl(self, url, title=None):
1890                 self._currentPageUrl = url
1891                 if title is None:
1892                         idx = len(url)
1893                         if idx > 10: idx = 10
1894                         title = url[:idx]
1895                 self._currentPageTitle = title
1896                 print self._currentPageUrl
1897                 self.toggleMainScreen()
1898                 self.hideSubmenu()
1899                 self.keyDown()
1900
1901         def hideSubmenu(self):
1902                 self.currentListView.pageUp()
1903                 self.keyUp()
1904
1905
1906
1907 def auto_start_main(reason, **kwargs):
1908         if reason:
1909                 command_server = getCommandServer()
1910                 command_server.stop()
1911
1912 def session_start_main(session, reason, **kwargs):
1913         eRCInput.getInstance().unlock()
1914         global _g_helper
1915         _g_helper = session.open(HbbTVHelper)
1916
1917 _g_clearBrowserDataTimer = eTimer()
1918 def plugin_start_main(session, **kwargs):
1919         #session.open(OperaBrowser)
1920         def _do_clean():
1921                 _g_clearBrowserDataTimer.stop()
1922                 try:    _g_clearBrowserDataTimer.callback.remove(_do_clean)
1923                 except: pass
1924                 setPluginBrowser(None)
1925         def clearBrowserData():
1926                 _g_clearBrowserDataTimer.callback.append(_do_clean)
1927                 _g_clearBrowserDataTimer.start(50)
1928         setPluginBrowser(session.openWithCallback(clearBrowserData, OperaBrowser))
1929
1930 def plugin_extension_start_application(session, **kwargs):
1931         global _g_helper
1932         if _g_helper is None: 
1933                 return
1934         _g_helper.showApplicationSelectionBox()
1935
1936 def plugin_extension_browser_config(session, **kwargs):
1937         global _g_helper
1938         if _g_helper is None: 
1939                 return
1940         _g_helper.showBrowserConfigBox()
1941
1942 def Plugins(path, **kwargs):
1943         return  [
1944                 PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=auto_start_main),
1945                 PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10),
1946                 PluginDescriptor(name="HbbTV Applications", where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_start_application),
1947                 PluginDescriptor(name="Browser Start/Stop", where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_browser_config),
1948                 PluginDescriptor(name="Opera Web Browser", description="start opera web browser", where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=True, fnc=plugin_start_main),
1949                 ]
1950