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