[hbbtv] add channel change on hbbtv epg.
[vuplus_dvbapp] / lib / python / Plugins / Extensions / HbbTV / plugin.py
index 9ae4d2e..8b6fa06 100644 (file)
@@ -6,19 +6,24 @@ from Screens.ChoiceBox import ChoiceBox
 from Screens.MessageBox import MessageBox
 from Screens.InfoBarGenerics import InfoBarNotifications
 from Screens.VirtualKeyBoard import VirtualKeyBoard
 from Screens.MessageBox import MessageBox
 from Screens.InfoBarGenerics import InfoBarNotifications
 from Screens.VirtualKeyBoard import VirtualKeyBoard
+from Screens.HelpMenu import HelpableScreen
+from Screens.ChannelSelection import service_types_tv
 
 from Components.PluginComponent import plugins
 from Components.Button import Button
 
 from Components.PluginComponent import plugins
 from Components.Button import Button
-from Components.Label import Label
 from Components.Sources.StaticText import StaticText
 from Components.Sources.StaticText import StaticText
-from Components.ActionMap import NumberActionMap, ActionMap
+from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.MenuList import MenuList
 from Components.Label import Label, MultiColorLabel
 from Components.ConfigList import ConfigListScreen
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.MenuList import MenuList
 from Components.Label import Label, MultiColorLabel
 from Components.ConfigList import ConfigListScreen
+from Components.VolumeControl import VolumeControl
+from Components.Pixmap import Pixmap
 from Components.config import config, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile, getCharValue
 
 from Components.config import config, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile, getCharValue
 
-from enigma import eTimer, eConsoleAppContainer, getDesktop, eServiceReference, iPlayableService, iServiceInformation, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, getPrevAsciiCode, eRCInput, fbClass
+from enigma import eTimer, eConsoleAppContainer, getDesktop, eServiceReference, iPlayableService, iServiceInformation, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, getPrevAsciiCode, eRCInput, fbClass, eServiceCenter
+
+from bookmark import BookmarkManager, BookmarkData, CategoryData
 
 import os, struct, threading, stat, select, time, socket, select
 
 
 import os, struct, threading, stat, select, time, socket, select
 
@@ -27,6 +32,8 @@ strIsEmpty = lambda x: x is None or len(x) == 0
 HBBTVAPP_PATH = "/usr/local/hbb-browser"
 COMMAND_PATH = '/tmp/.sock.hbbtv.cmd'
 
 HBBTVAPP_PATH = "/usr/local/hbb-browser"
 COMMAND_PATH = '/tmp/.sock.hbbtv.cmd'
 
+_g_helper = None
+
 class GlobalValues:
        command_util   = None
        command_server = None
 class GlobalValues:
        command_util   = None
        command_server = None
@@ -44,8 +51,18 @@ class GlobalValues:
        packet_m  = 0xBBADBEE
        packet_h  = '!IIII'
        packet_hl = struct.calcsize(packet_h)
        packet_m  = 0xBBADBEE
        packet_h  = '!IIII'
        packet_hl = struct.calcsize(packet_h)
+
+       need_restart = False
+       plugin_browser = None
 __gval__ = GlobalValues()
 
 __gval__ = GlobalValues()
 
+def setPluginBrowser(browser=None):
+       global __gval__
+       __gval__.plugin_browser = browser
+def getPluginBrowser():
+       global __gval__
+       return __gval__.plugin_browser
+
 def getPacketHeaders():
        global __gval__
        return (__gval__.packet_m, __gval__.packet_h, __gval__.packet_hl)
 def getPacketHeaders():
        global __gval__
        return (__gval__.packet_m, __gval__.packet_h, __gval__.packet_hl)
@@ -73,6 +90,15 @@ def getChannelInfos():
                __gval__.channel_info_name, 
                __gval__.channel_info_orgid)
 
                __gval__.channel_info_name, 
                __gval__.channel_info_orgid)
 
+def isNeedRestart():
+       global __gval__
+       print "Need Restart(GET) : ", __gval__.need_restart
+       return __gval__.need_restart
+def setNeedRestart(n):
+       global __gval__
+       __gval__.need_restart = n
+       print "Need Restart(SET) : ", __gval__.need_restart
+
 def getCommandUtil():
        global __gval__
        return __gval__.command_util
 def getCommandUtil():
        global __gval__
        return __gval__.command_util
@@ -126,7 +152,7 @@ class MMSStreamURL:
                sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                sock.connect((host, port))
                sock.send(self.sendmsg%(location, host))
                sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                sock.connect((host, port))
                sock.send(self.sendmsg%(location, host))
-               print "Send Data : "
+               print "Request."
                print self.sendmsg%(location, host)
                fullydata = ''
                while 1:
                print self.sendmsg%(location, host)
                fullydata = ''
                while 1:
@@ -165,6 +191,8 @@ class OpCodeSet:
                        ,"OP_HBBTV_UNLOAD_AIT"          : 0x0004
                        ,"OP_HBBTV_FULLSCREEN"          : 0x0005
                        ,"OP_HBBTV_TITLE"               : 0x0006
                        ,"OP_HBBTV_UNLOAD_AIT"          : 0x0004
                        ,"OP_HBBTV_FULLSCREEN"          : 0x0005
                        ,"OP_HBBTV_TITLE"               : 0x0006
+                       ,"OP_HBBTV_RETRY_OPEN_URL"      : 0x0009
+                       ,"OP_HBBTV_CHANGE_CHANNEL"      : 0x000A
                        ,"OP_OIPF_GET_CHANNEL_INFO_URL" : 0x0101
                        ,"OP_OIPF_GET_CHANNEL_INFO_AIT" : 0x0102
                        ,"OP_OIPF_GET_CHANNEL_INFO_LIST": 0x0103
                        ,"OP_OIPF_GET_CHANNEL_INFO_URL" : 0x0101
                        ,"OP_OIPF_GET_CHANNEL_INFO_AIT" : 0x0102
                        ,"OP_OIPF_GET_CHANNEL_INFO_LIST": 0x0103
@@ -174,7 +202,21 @@ class OpCodeSet:
                        ,"OP_VOD_PAUSE"                 : 0x0204
                        ,"OP_VOD_STATUS"                : 0x0205
                        ,"OP_VOD_FORBIDDEN"             : 0x0206
                        ,"OP_VOD_PAUSE"                 : 0x0204
                        ,"OP_VOD_STATUS"                : 0x0205
                        ,"OP_VOD_FORBIDDEN"             : 0x0206
+                       ,"OP_VOD_STOPED"                : 0x0207
+                       ,"OP_VOD_SPEED_CTRL"            : 0x0208
+                       ,"OP_VOD_SEEK_CTRL"             : 0x0209
                        ,"OP_BROWSER_OPEN_URL"          : 0x0301
                        ,"OP_BROWSER_OPEN_URL"          : 0x0301
+                       ,"OP_BROWSER_VKBD_REQ"          : 0x0309
+                       ,"OP_BROWSER_VKBD_RES"          : 0x030A
+                       ,"OP_BROWSER_VKBD_PASTE_REQ"    : 0x030B
+                       ,"OP_BROWSER_VKBD_PASTE_KEY"    : 0x030C
+                       ,"OP_BROWSER_VKBD_PASTE_MOUSE"  : 0x030D
+                       ,"OP_BROWSER_MENU_REQ"          : 0x030E
+                       ,"OP_BROWSER_MENU_RES"          : 0x030F
+                       ,"OP_DVBAPP_VOL_UP"             : 0x0401
+                       ,"OP_DVBAPP_VOL_DOWN"           : 0x0402
+                       ,"OP_SYSTEM_OUT_OF_MEMORY"      : 0x0501
+                       ,"OP_SYSTEM_NOTIFY_MY_PID"      : 0x0502
                }
                self._opstr_ = {
                         0x0000 : "OP_UNKNOWN"
                }
                self._opstr_ = {
                         0x0000 : "OP_UNKNOWN"
@@ -184,6 +226,8 @@ class OpCodeSet:
                        ,0x0004 : "OP_HBBTV_UNLOAD_AIT"
                        ,0x0005 : "OP_HBBTV_FULLSCREEN"
                        ,0x0006 : "OP_HBBTV_TITLE"
                        ,0x0004 : "OP_HBBTV_UNLOAD_AIT"
                        ,0x0005 : "OP_HBBTV_FULLSCREEN"
                        ,0x0006 : "OP_HBBTV_TITLE"
+                       ,0x0009 : "OP_HBBTV_RETRY_OPEN_URL"
+                       ,0x000A : "OP_HBBTV_CHANGE_CHANNEL"
                        ,0x0101 : "OP_OIPF_GET_CHANNEL_INFO_URL"
                        ,0x0102 : "OP_OIPF_GET_CHANNEL_INFO_AIT"
                        ,0x0103 : "OP_OIPF_GET_CHANNEL_INFO_LIST"
                        ,0x0101 : "OP_OIPF_GET_CHANNEL_INFO_URL"
                        ,0x0102 : "OP_OIPF_GET_CHANNEL_INFO_AIT"
                        ,0x0103 : "OP_OIPF_GET_CHANNEL_INFO_LIST"
@@ -193,7 +237,21 @@ class OpCodeSet:
                        ,0x0204 : "OP_VOD_PAUSE"
                        ,0x0205 : "OP_VOD_STATUS"
                        ,0x0206 : "OP_VOD_FORBIDDEN"
                        ,0x0204 : "OP_VOD_PAUSE"
                        ,0x0205 : "OP_VOD_STATUS"
                        ,0x0206 : "OP_VOD_FORBIDDEN"
+                       ,0x0207 : "OP_VOD_STOPED"
+                       ,0x0208 : "OP_VOD_SPEED_CTRL"
+                       ,0x0209 : "OP_VOD_SEEK_CTRL"
                        ,0x0301 : "OP_BROWSER_OPEN_URL"
                        ,0x0301 : "OP_BROWSER_OPEN_URL"
+                       ,0x0309 : "OP_BROWSER_VKBD_REQ"
+                       ,0x030A : "OP_BROWSER_VKBD_RES"
+                       ,0x030B : "OP_BROWSER_VKBD_PASTE_REQ"
+                       ,0x030C : "OP_BROWSER_VKBD_PASTE_KEY"
+                       ,0x030D : "OP_BROWSER_VKBD_PASTE_MOUSE"
+                       ,0x030E : "OP_BROWSER_MENU_REQ"
+                       ,0x030F : "OP_BROWSER_MENU_RES"
+                       ,0x0401 : "OP_DVBAPP_VOL_UP"
+                       ,0x0402 : "OP_DVBAPP_VOL_DOWN"
+                       ,0x0501 : "OP_SYSTEM_OUT_OF_MEMORY"
+                       ,0x0502 : "OP_SYSTEM_NOTIFY_MY_PID"
                }
 
        def get(self, opstr):
                }
 
        def get(self, opstr):
@@ -306,11 +364,11 @@ class ServerFactory:
                return streamServer
 
        def doListenInetTCP(self, ip, port, handler):
                return streamServer
 
        def doListenInetTCP(self, ip, port, handler):
-               print "not implemented yet!!"
+               print "Not implemented yet!!"
        def doListenUnixDGRAM(self, name, handler):
        def doListenUnixDGRAM(self, name, handler):
-               print "not implemented yet!!"
+               print "Not implemented yet!!"
        def doListenInetDGRAM(self, ip, port, handler):
        def doListenInetDGRAM(self, ip, port, handler):
-               print "not implemented yet!!"
+               print "Not implemented yet!!"
 
 class Handler:
        def doUnpack(self, data):
 
 class Handler:
        def doUnpack(self, data):
@@ -338,18 +396,17 @@ class BrowserCommandUtil(OpCodeSet):
 
        def doConnect(self, filename):
                if not os.path.exists(filename):
 
        def doConnect(self, filename):
                if not os.path.exists(filename):
-                       print "file not exists :", filename
+                       print "File not exists :", filename
                        return False
                try:
                        self._fd = os.open(filename, os.O_WRONLY|os.O_NONBLOCK)
                        if self._fd is None:
                        return False
                try:
                        self._fd = os.open(filename, os.O_WRONLY|os.O_NONBLOCK)
                        if self._fd is None:
-                               print "fail to open file :", filename
+                               print "Fail to open file :", filename
                                return False
                except Exception, ErrMsg:
                        print ErrMsg
                        self._fd = None
                        return False
                                return False
                except Exception, ErrMsg:
                        print ErrMsg
                        self._fd = None
                        return False
-               print "connected!! to ", filename
                return True
 
        def doDisconnect(self):
                return True
 
        def doDisconnect(self):
@@ -360,7 +417,7 @@ class BrowserCommandUtil(OpCodeSet):
 
        def doSend(self, command, params=None, reserved=0):
                if self._fd is None:
 
        def doSend(self, command, params=None, reserved=0):
                if self._fd is None:
-                       print "connected pipe was not exists!!"
+                       print "No found pipe!!"
                        return False
                data = ''
                try:
                        return False
                data = ''
                try:
@@ -388,6 +445,8 @@ class HandlerHbbTV(Handler):
                self.handle_map = {
                         0x0001 : self._cb_handleCloseHbbTVBrowser
                        ,0x0006 : self._cb_handleSetPageTitle
                self.handle_map = {
                         0x0001 : self._cb_handleCloseHbbTVBrowser
                        ,0x0006 : self._cb_handleSetPageTitle
+                       ,0x0009 : self._cb_handleHbbTVRetryOpen
+                       ,0x000A : self._cb_handleHbbTVChangeChannel
                        ,0x0101 : self._cb_handleGetChannelInfoForUrl
                        ,0x0102 : self._cb_handleGetChannelInfoForAIT
                        ,0x0103 : self._cb_handleGetChannelInfoList
                        ,0x0101 : self._cb_handleGetChannelInfoForUrl
                        ,0x0102 : self._cb_handleGetChannelInfoForAIT
                        ,0x0103 : self._cb_handleGetChannelInfoList
@@ -395,12 +454,26 @@ class HandlerHbbTV(Handler):
                        ,0x0202 : self._cb_handleVODPlayerPlay
                        ,0x0203 : self._cb_handleVODPlayerStop
                        ,0x0204 : self._cb_handleVODPlayerPlayPause
                        ,0x0202 : self._cb_handleVODPlayerPlay
                        ,0x0203 : self._cb_handleVODPlayerStop
                        ,0x0204 : self._cb_handleVODPlayerPlayPause
+                       ,0x0401 : self._cb_handleDVBAppVolUp
+                       ,0x0402 : self._cb_handleDVBAppVolDown
+                       ,0x0208 : self._cb_handleVODSpeedCtrl
+                       ,0x0209 : self._cb_handleVODSeekCtrl
+                       ,0x0501 : self._cb_handleSystemOutOfMemory
+                       ,0x0502 : self._cb_handleSystemNotufyMyPID
+                       ,0x0309 : self._cb_handleShowVirtualKeyboard
+                       ,0x030B : self._cb_handlePasteVirtualKeyboard
+                       ,0x030E : self._cb_handleBrowserMenuReq
                }
                self._on_close_cb = None
                self._on_set_title_cb = None
 
                self._vod_uri = None
 
                }
                self._on_close_cb = None
                self._on_set_title_cb = None
 
                self._vod_uri = None
 
+               self._retry_open_url = None
+               self._timer_retry_open = eTimer()
+               self._timer_paste_vkbd = eTimer()
+               self._curren_title = None
+
        def _handle_dump(self, handle, opcode, data=None):
                if True: return
                print str(handle)
        def _handle_dump(self, handle, opcode, data=None):
                if True: return
                print str(handle)
@@ -437,6 +510,145 @@ class HandlerHbbTV(Handler):
                self._on_set_title_cb = None
                return self.doPack(opcode, params, reserved)
 
                self._on_set_title_cb = None
                return self.doPack(opcode, params, reserved)
 
+       def _cb_handleHbbTVChangeChannel(self, opcode, data):
+               self._handle_dump(self._cb_handleHbbTVChangeChannel, opcode, data)
+               global _g_helper
+               if _g_helper is None: 
+                       return (0, "NOK")
+               dataItems = data.split(":")
+               sid  = dataItems[0]
+               tsid = dataItems[1]
+               if not _g_helper.doChangeChannel(sid, tsid):
+                       return (0, "NOK")
+
+
+               return (0, "OK")
+
+       def _cb_handleBrowserMenuReq(self, opcode, data):
+               self._handle_dump(self._cb_handleBrowserMenuReq, opcode, data)
+               fbClass.getInstance().unlock()
+               eRCInput.getInstance().unlock()
+               browser = getPluginBrowser()
+               if browser is not None:
+                       browser.setCurrentPageUrl(data, self._curren_title)
+               return (0, "OK")
+
+       def _cb_handlePasteVirtualKeyboard(self, opcode, data):
+               self._handle_dump(self._cb_handlePasteVirtualKeyboard, opcode, data)
+               def _cb_PasteRefocusVirtualKeyboard():
+                       self._timer_paste_vkbd.stop()
+                       command_util = getCommandUtil()
+                       command_util.sendCommand('OP_BROWSER_VKBD_PASTE_MOUSE')
+                       try:
+                               self._timer_paste_vkbd.callback.remove(_cb_PasteMouseVirtualKeyboard)
+                       except: pass
+               def _cb_PasteKeyVirtualKeyboard():
+                       self._timer_paste_vkbd.stop()
+                       command_util = getCommandUtil()
+                       command_util.sendCommand('OP_BROWSER_VKBD_PASTE_KEY')
+                       try:
+                               self._timer_paste_vkbd.callback.remove(_cb_PasteKeyVirtualKeyboard)
+                       except: pass
+                       self._timer_paste_vkbd.callback.append(_cb_PasteRefocusVirtualKeyboard)
+                       self._timer_paste_vkbd.start(100)
+               def _cb_PasteMouseVirtualKeyboard():
+                       self._timer_paste_vkbd.stop()
+                       command_util = getCommandUtil()
+                       command_util.sendCommand('OP_BROWSER_VKBD_PASTE_MOUSE')
+                       #time.sleep(1)
+                       #command_util.sendCommand('OP_BROWSER_VKBD_PASTE_MOUSE')
+                       try:
+                               self._timer_paste_vkbd.callback.remove(_cb_PasteMouseVirtualKeyboard)
+                       except: pass
+                       #self._timer_paste_vkbd.callback.append(_cb_PasteKeyVirtualKeyboard)
+                       #self._timer_paste_vkbd.start(1000)
+               self._timer_paste_vkbd.callback.append(_cb_PasteMouseVirtualKeyboard)
+               self._timer_paste_vkbd.start(50)
+               return (0, "OK")
+
+       def _cb_virtualKeyboardClosed(self, data=None):
+               fbClass.getInstance().lock()
+               eRCInput.getInstance().lock()
+               command_util = getCommandUtil()
+               command_util.sendCommand('OP_BROWSER_VKBD_RES', data)
+       def _cb_handleShowVirtualKeyboard(self, opcode, data):
+               self._handle_dump(self._cb_handleShowVirtualKeyboard, opcode, data)
+               fbClass.getInstance().unlock()
+               eRCInput.getInstance().unlock()
+               if data == 0 or strIsEmpty(data):
+                       data = ""
+               self._session.openWithCallback(self._cb_virtualKeyboardClosed, VirtualKeyBoard, title=("Please enter URL here"), text=data)
+               return (0, "OK")
+
+       def _cb_handleVODSeekCtrl(self, opcode, data):
+               self._handle_dump(self._cb_handleVODSeekCtrl, opcode, data)
+               headLen = struct.calcsize('!I')
+               unpackedData = struct.unpack('!I', data[:headLen])
+               seekTime = unpackedData[0]
+               service = self._session.nav.getCurrentService()
+               seekable = service.seek()
+               if seekable is None or not seekable.isCurrentlySeekable():
+                       raise Exception("This stream is not support manual seek.")
+               pts = seekTime
+               seekable.seekRelative(pts<0 and -1 or 1, abs(pts))
+               return (0, "OK")
+
+       def _cb_handleHbbTVRetryOpen(self, opcode, data):
+               def _cb_HbbTVRetryOpenURL():
+                       self._timer_retry_open.stop()
+                       if self._retry_open_url is not None:
+                               command_util = getCommandUtil()
+                               command_util.sendCommand('OP_HBBTV_RETRY_OPEN_URL', params=self._retry_open_url)
+                       self._retry_open_url = None
+                       try:
+                               self._timer_retry_open.callback.remove(_cb_HbbTVRetryOpenURL)
+                       except: pass
+               self._handle_dump(self._cb_handleHbbTVRetryOpen, opcode, data)
+               headLen = struct.calcsize('!I')
+               unpackedData = struct.unpack('!I', data[:headLen])
+               delayTime = unpackedData[0]
+               restartUrl = data[headLen:]
+
+               self._retry_open_url = restartUrl.strip()
+               self._timer_retry_open.callback.append(_cb_HbbTVRetryOpenURL)
+               self._timer_retry_open.start(delayTime*1000)
+               return (0, "OK")
+
+       def _cb_handleSystemNotufyMyPID(self, opcode, data):
+               self._handle_dump(self._cb_handleSystemNotufyMyPID, opcode, data)
+               return (0, "OK")
+
+       def _cb_handleSystemOutOfMemory(self, opcode, data):
+               self._handle_dump(self._cb_handleSystemOutOfMemory, opcode, data)
+               setNeedRestart(True)
+               return (0, "OK")
+
+       def _cb_handleVODSpeedCtrl(self, opcode, data):
+               self._handle_dump(self._cb_handleVODSpeedCtrl, opcode, data)
+               headLen = struct.calcsize('!I')
+               unpackedData = struct.unpack('!I', data[:headLen])
+               playSpeed = unpackedData[0]
+               service = self._session.nav.getCurrentService()
+               pauseable = service.pause()
+               if playSpeed > 2:
+                       playSpeed = 2
+               if pauseable.setFastForward(playSpeed) == -1:
+                       pauseable.setFastForward(1)
+                       raise Exception("This stream is not support trick play.")
+               return (0, "OK")
+
+       def _cb_handleDVBAppVolUp(self, opcode, data):
+               self._handle_dump(self._cb_handleDVBAppVolUp, opcode, data)
+               vcm = VolumeControl.instance
+               vcm.volUp()
+               return (0, "OK")
+
+       def _cb_handleDVBAppVolDown(self, opcode, data):
+               self._handle_dump(self._cb_handleDVBAppVolDown, opcode, data)
+               vcm = VolumeControl.instance
+               vcm.volDown()
+               return (0, "OK")
+
        def _cb_handleGetChannelInfoForUrl(self, opcode, data):
                self._handle_dump(self._cb_handleGetChannelInfoForUrl, opcode, data)
                (sid, onid, tsid, name, orgid) = getChannelInfos()
        def _cb_handleGetChannelInfoForUrl(self, opcode, data):
                self._handle_dump(self._cb_handleGetChannelInfoForUrl, opcode, data)
                (sid, onid, tsid, name, orgid) = getChannelInfos()
@@ -464,12 +676,17 @@ class HandlerHbbTV(Handler):
                        for x in self._on_set_title_cb:
                                try:
                                        x(data)
                        for x in self._on_set_title_cb:
                                try:
                                        x(data)
+                                       self._curren_title = data
                                except Exception, ErrMsg:
                                        if x in self._on_set_title_cb:
                                                self._on_set_title_cb.remove(x)
                return (0, "OK")
 
        def _cb_handleCloseHbbTVBrowser(self, opcode, data):
                                except Exception, ErrMsg:
                                        if x in self._on_set_title_cb:
                                                self._on_set_title_cb.remove(x)
                return (0, "OK")
 
        def _cb_handleCloseHbbTVBrowser(self, opcode, data):
+               self._timer_retry_open.stop()
+               try:
+                       self._timer_retry_open.callback.remove(_cb_HbbTVRetryOpenURL)
+               except: pass
                self._handle_dump(self._cb_handleCloseHbbTVBrowser, opcode, data)
 
                if self._on_close_cb:
                self._handle_dump(self._cb_handleCloseHbbTVBrowser, opcode, data)
 
                if self._on_close_cb:
@@ -486,6 +703,7 @@ class HandlerHbbTV(Handler):
                before_service = getBeforeService()
                if before_service is not None:
                        self._session.nav.playService(before_service)
                before_service = getBeforeService()
                if before_service is not None:
                        self._session.nav.playService(before_service)
+                       self._vod_uri = None
                return (0, "OK")
 
        def _cb_handleVODPlayerURI(self, opcode, data):
                return (0, "OK")
 
        def _cb_handleVODPlayerURI(self, opcode, data):
@@ -516,7 +734,7 @@ class HandlerHbbTV(Handler):
                for ii in range(5):
                        self._vod_service = None
                        try:
                for ii in range(5):
                        self._vod_service = None
                        try:
-                               print "try to open vod [%d] : %s" % (ii, url)
+                               print "Try to open vod [%d] : %s" % (ii, url)
                                self._vod_service = eServiceReference(4097, 0, url)
                                self._session.nav.playService(self._vod_service)
                                if self._vod_service is not None:
                                self._vod_service = eServiceReference(4097, 0, url)
                                self._session.nav.playService(self._vod_service)
                                if self._vod_service is not None:
@@ -552,23 +770,29 @@ class HandlerHbbTV(Handler):
                        print "onPause ERR :", ErrMsg
                return (0, "OK")
 
                        print "onPause ERR :", ErrMsg
                return (0, "OK")
 
+from libshm import SimpleSharedMemory
+_g_ssm_ = None
 class HbbTVWindow(Screen, InfoBarNotifications):
        skin =  """
                <screen name="HbbTVWindow" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="HbbTV Plugin">
                </screen>
                """
 class HbbTVWindow(Screen, InfoBarNotifications):
        skin =  """
                <screen name="HbbTVWindow" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="HbbTV Plugin">
                </screen>
                """
-       def __init__(self, session, url=None, cbf=None, useAIT=False):
+       def __init__(self, session, url=None, cbf=None, useAIT=False, profile=0):
                self._session = session
                self._session = session
+               fbClass.getInstance().lock()
                eRCInput.getInstance().lock()
 
                Screen.__init__(self, session)
                InfoBarNotifications.__init__(self)
                self.__event_tracker = ServiceEventTracker(screen = self, eventmap = {
                        iPlayableService.evUser+20: self._serviceForbiden,
                eRCInput.getInstance().lock()
 
                Screen.__init__(self, session)
                InfoBarNotifications.__init__(self)
                self.__event_tracker = ServiceEventTracker(screen = self, eventmap = {
                        iPlayableService.evUser+20: self._serviceForbiden,
+                       iPlayableService.evStart: self._serviceStarted,
+                       iPlayableService.evEOF: self._serviceEOF,
                })
 
                self._url = url
                self._use_ait = useAIT
                })
 
                self._url = url
                self._use_ait = useAIT
+               self._profile = profile
                self._cb_closed_func = cbf
                self.onLayoutFinish.append(self._layoutFinished)
 
                self._cb_closed_func = cbf
                self.onLayoutFinish.append(self._layoutFinished)
 
@@ -582,10 +806,56 @@ class HbbTVWindow(Screen, InfoBarNotifications):
                self._closeTimer = eTimer()
                self._closeTimer.callback.append(self._do_close)
 
                self._closeTimer = eTimer()
                self._closeTimer.callback.append(self._do_close)
 
+               self._currentServicePositionTimer = eTimer()
+               self._currentServicePositionTimer.callback.append(self._cb_currentServicePosition)
+               self._vodLength = 0
+
+               global _g_ssm_
+               self._ssm = _g_ssm_
+               self._vod_length = 0
+
+       def getVodPlayTime(self):
+               try:
+                       service = self._session.nav.getCurrentService()
+                       seek = service and service.seek()
+                       l = seek.getLength()
+                       p = seek.getPlayPosition()
+                       #return (p[1]/90000, l[1]/90000)
+                       return (p[1], l[1])
+               except: pass
+               return (-1,-1)
+
+       def _cb_currentServicePosition(self):
+               def getTimeString(t):
+                       t = time.localtime(t/90000)
+                       return "%2d:%02d:%02d" % (t.tm_hour, t.tm_min, t.tm_sec)
+               position,length = 0,0
+               try:
+                       (position,length) = self.getVodPlayTime()
+                       self._vod_length = length
+                       if position == -1 and length == -1:
+                               raise Exception("Can't get play status")
+                       #print getTimeString(position), "/", getTimeString(length)
+                       self._ssm.setStatus(position, length, 1)
+               except Exception, ErrMsg:
+                       print ErrMsg
+                       self._serviceEOF()
+
+       def _serviceStarted(self):
+               try:
+                       self._ssm.setStatus(0, 0, 0)
+                       self._currentServicePositionTimer.start(1000)
+               except Exception, ErrMsg:
+                       print ErrMsg
+
+       def _serviceEOF(self):
+               self._currentServicePositionTimer.stop()
+
        def _layoutFinished(self):
                command_util = getCommandUtil()
        def _layoutFinished(self):
                command_util = getCommandUtil()
+               profile = self._profile
                (sid, onid, tsid, name, orgid) = getChannelInfos()
                (sid, onid, tsid, name, orgid) = getChannelInfos()
-               params  = struct.pack('!IIIII', orgid, sid, onid, tsid, len(name)) + name
+               params  = struct.pack('!IIIIII', orgid, profile, sid, onid, tsid, len(name)) + name
                if self._use_ait:
                        command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
                        time.sleep(1)
                if self._use_ait:
                        command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
                        time.sleep(1)
@@ -613,13 +883,14 @@ class HbbTVWindow(Screen, InfoBarNotifications):
                        if self._cb_closed_func is not None:
                                self._cb_closed_func()
                except: pass
                        if self._cb_closed_func is not None:
                                self._cb_closed_func()
                except: pass
+               fbClass.getInstance().unlock()
                eRCInput.getInstance().unlock()
                self.close()
 
        def _serviceForbiden(self):
                global __gval__
                real_url = MMSStreamURL().getLocationData(__gval__.hbbtv_handelr.getUrl())
                eRCInput.getInstance().unlock()
                self.close()
 
        def _serviceForbiden(self):
                global __gval__
                real_url = MMSStreamURL().getLocationData(__gval__.hbbtv_handelr.getUrl())
-               print "Received URI :\n",real_url
+               print "Received URI :\n", real_url
 
                if real_url is not None:
                        __gval__.hbbtv_handelr.doRetryOpen(real_url.strip())
 
                if real_url is not None:
                        __gval__.hbbtv_handelr.doRetryOpen(real_url.strip())
@@ -638,8 +909,9 @@ class HbbTVHelper(Screen):
                __gval__.command_server = ServerFactory().doListenUnixTCP('/tmp/.sock.hbbtv.url', __gval__.hbbtv_handelr)
 
                self._urls = None
                __gval__.command_server = ServerFactory().doListenUnixTCP('/tmp/.sock.hbbtv.url', __gval__.hbbtv_handelr)
 
                self._urls = None
-               self._stop_opera()
-               self._start_opera()
+               #self._stop_opera()
+               #self._start_opera()
+               self._restart_opera()
 
                Screen.__init__(self, session)
                self._session = session
 
                Screen.__init__(self, session)
                self._session = session
@@ -648,9 +920,15 @@ class HbbTVHelper(Screen):
                self._timer_infobar.start(1000)
 
                self._excuted_browser = False
                self._timer_infobar.start(1000)
 
                self._excuted_browser = False
+               self._profile = 0
 
                __gval__.command_util = BrowserCommandUtil()
 
 
                __gval__.command_util = BrowserCommandUtil()
 
+               global _g_ssm_
+               if _g_ssm_ is None:
+                       _g_ssm_ = SimpleSharedMemory()
+                       _g_ssm_.doConnect()
+
        def _cb_registrate_infobar(self):
                if InfoBar.instance:
                        self._timer_infobar.stop()
        def _cb_registrate_infobar(self):
                if InfoBar.instance:
                        self._timer_infobar.stop()
@@ -679,7 +957,7 @@ class HbbTVHelper(Screen):
                        orgid   = 0
                        namelen = len(name)
                        for x in info.getInfoObject(iServiceInformation.sHBBTVUrl):
                        orgid   = 0
                        namelen = len(name)
                        for x in info.getInfoObject(iServiceInformation.sHBBTVUrl):
-                               if x[0] == 1 :
+                               if x[0] in (1, -1) :
                                        orgid = x[3]
                                        break
                        setChannelInfo(sid, onid, tsid, name, orgid)
                                        orgid = x[3]
                                        break
                        setChannelInfo(sid, onid, tsid, name, orgid)
@@ -694,6 +972,7 @@ class HbbTVHelper(Screen):
                self._start_hbbtv_application(title, url)
 
        def _start_hbbtv_application(self, title, url):
                self._start_hbbtv_application(title, url)
 
        def _start_hbbtv_application(self, title, url):
+               use_ait = False
                tmp_url = self.getStartHbbTVUrl()
                if url is None:
                        url = tmp_url
                tmp_url = self.getStartHbbTVUrl()
                if url is None:
                        url = tmp_url
@@ -705,14 +984,18 @@ class HbbTVHelper(Screen):
                        print "already excuted opera browser!!"
                        return
 
                        print "already excuted opera browser!!"
                        return
 
-               use_ait = False
+               if isNeedRestart():
+                       self._restart_opera()
+                       time.sleep(2)
+                       setNeedRestart(False)
+
                for x in self._urls:
                        control_code = x[0]
                        tmp_url = x[2]
                        if tmp_url == url and control_code == 1:
                                use_ait = True
                self._excuted_browser = True
                for x in self._urls:
                        control_code = x[0]
                        tmp_url = x[2]
                        if tmp_url == url and control_code == 1:
                                use_ait = True
                self._excuted_browser = True
-               self._session.open(HbbTVWindow, url, self._cb_closed_browser, use_ait)
+               self._session.open(HbbTVWindow, url, self._cb_closed_browser, use_ait, self._profile)
 
        def _cb_closed_browser(self):
                self._excuted_browser = False
 
        def _cb_closed_browser(self):
                self._excuted_browser = False
@@ -728,21 +1011,28 @@ class HbbTVHelper(Screen):
                try:    os.system('%s/launcher stop'%(HBBTVAPP_PATH))
                except: pass
 
                try:    os.system('%s/launcher stop'%(HBBTVAPP_PATH))
                except: pass
 
+       def _restart_opera(self):
+               global HBBTVAPP_PATH
+               try:    os.system('%s/launcher restart'%(HBBTVAPP_PATH))
+               except: pass
+
        def getStartHbbTVUrl(self):
        def getStartHbbTVUrl(self):
-               url, self._urls = None, None
+               url, self._urls, self._profile = None, None, 0
                 service = self._session.nav.getCurrentService()
                 info = service and service.info()
                 if not info: return None
                 self._urls = info.getInfoObject(iServiceInformation.sHBBTVUrl)
                for u in self._urls:
                 service = self._session.nav.getCurrentService()
                 info = service and service.info()
                 if not info: return None
                 self._urls = info.getInfoObject(iServiceInformation.sHBBTVUrl)
                for u in self._urls:
-                       if u[0] == 1: # 0:control code, 1:name, 2:url, 3:orgid, 4:appid
+                       if u[0] in (1, -1): # 0:control code, 1:name, 2:url, 3:orgid, 4:appid, 5:profile code
                                url = u[2]
                                url = u[2]
+                               self._profile = u[5]
                if url is None:
                        url = info.getInfoString(iServiceInformation.sHBBTVUrl)
                return url
 
        def showApplicationSelectionBox(self):
                applications = []
                if url is None:
                        url = info.getInfoString(iServiceInformation.sHBBTVUrl)
                return url
 
        def showApplicationSelectionBox(self):
                applications = []
+
                if self.getStartHbbTVUrl():
                        for x in self._urls:
                                applications.append((x[1], x))
                if self.getStartHbbTVUrl():
                        for x in self._urls:
                                applications.append((x[1], x))
@@ -783,7 +1073,572 @@ class HbbTVHelper(Screen):
                        print "Check Browser Running ERR :", ErrMsg
                return False
 
                        print "Check Browser Running ERR :", ErrMsg
                return False
 
-_g_helper = None
+       def doChangeChannel(self, _sid, _tsid):
+               root = eServiceReference(service_types_tv)
+               if root is None:
+                       return False
+               serviceList = eServiceCenter.getInstance().list(root)
+               if serviceList is None:
+                       return False    
+               while True:
+                       service = serviceList.getNext()
+                       if service is None or not service.valid():
+                               break
+
+                       #1:0:19:2840:3FB:1:C00000:0:0:0:
+                       serviceRef = service.toString()
+                       if strIsEmpty(serviceRef):
+                               continue
+                       serviceRefItems = serviceRef.split(":")
+                       if len(serviceRefItems) < 5:
+                               continue
+
+                       sid  = serviceRefItems[3]
+                       tsid = serviceRefItems[4]
+                       if sid == _sid and tsid == _tsid:
+                               self._session.nav.playService(eServiceReference(serviceRef))
+                               service = self._session.nav.getCurrentlyPlayingServiceReference()
+                               setBeforeService(service)
+                               return True
+               return False
+
+class OperaBrowserSetting:
+       def __init__(self):
+               self._settingFileName = '/usr/local/hbb-browser/home/setting.ini'
+               self._start = None
+               self._read()
+       def _read(self):
+               f = open(self._settingFileName)
+               for line in f.readlines():
+                       if line.startswith('start='):
+                               self._start = line[6:len(line)-1]
+               f.close()
+       def _write(self):
+               tmpstr = []
+               tmpstr.append('start=%s\n' % (self._start))
+               f = open(self._settingFileName, 'w')
+               f.writelines(tmpstr)
+               f.close()
+       def setData(self, start):
+               self._start = start
+               self._write()
+       def getData(self):
+               return {
+                       'start':self._start
+               }
+
+class OperaBrowserPreferenceWindow(ConfigListScreen, Screen):
+       skin=   """
+               <screen position="center,center" size="600,350" title="Proference">
+                       <widget name="url" position="5,0" size="590,100" valign="center" font="Regular;20" />
+                       <widget name="config" position="0,100" size="600,200" scrollbarMode="showOnDemand" />
+
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="310,310" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="150,310" size="140,40" alphatest="on" />
+
+                       <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" />
+                       <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" />
+               </screen>
+               """
+       def __init__(self, session, currentUrl): 
+                self.session = session
+               Screen.__init__(self, session)
+
+               self.menulist = []
+               ConfigListScreen.__init__(self, self.menulist)
+
+               self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ], {
+                       "red"    : self.keyRed,
+                       "green"  : self.keyGreen,
+                       "ok"     : self.keyOK,
+                       "cancel" : self.keyRed
+                }, -2)
+               self["key_red"]   = StaticText(_("Cancel"))
+               self["key_green"] = StaticText(_("Save"))
+               self["url"]       = Label()
+
+               self._currentPageUrl = currentUrl
+               if self._currentPageUrl is None:
+                       self._currentPageUrl = ''
+               self._startPageUrl   = None
+
+               self.makeMenuEntry()
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               try:
+                       self._startPageUrl = OperaBrowserSetting().getData()['start']
+               except: self._startPageUrl = 'http://vuplus.com'
+               self.updateStartPageUrl()
+
+       def updateStartPageUrl(self):
+               if self.menuItemStartpage.value == "startpage":
+                       self["url"].setText(self._startPageUrl)
+               elif self.menuItemStartpage.value == "current":
+                       self["url"].setText(self._currentPageUrl)
+               elif self.menuItemStartpage.value == "direct":
+                       self["url"].setText('')
+
+       def keyGreen(self):
+               url = self["url"].getText()
+               if strIsEmpty(url):
+                       self.session.open(MessageBox, 'Invalid URL!!(Empty)\nPlease, Input to the URL.', type = MessageBox.TYPE_INFO)
+                       return
+               OperaBrowserSetting().setData(url)
+               self.close()
+
+       def keyRed(self):
+               self.close()
+
+       def keyOK(self):
+               def _cb_directInputUrl(data):
+                       if strIsEmpty(data):
+                               return
+                       self["url"].setText(data)
+               if self.menuItemStartpage.value == "direct":
+                       self.session.openWithCallback(_cb_directInputUrl, VirtualKeyBoard, title=("Please enter URL here"), text='http://')
+
+       def keyLeft(self):
+               ConfigListScreen.keyLeft(self)
+               self.updateStartPageUrl()
+
+       def keyRight(self):
+               ConfigListScreen.keyRight(self)
+               self.updateStartPageUrl()
+
+       def makeMenuEntry(self):
+               l = []
+               l.append(("startpage", _("Start Page")))
+               if not strIsEmpty(self._currentPageUrl):
+                       l.append(("current", _("Current Page")))
+               l.append(("direct", _("Direct Input")))
+               self.menuItemStartpage  = ConfigSelection(default="startpage", choices = l)
+               self.menuEntryStartpage = getConfigListEntry(_("Startpage"), self.menuItemStartpage)
+               self.resetMenuList()
+
+       def resetMenuList(self):
+               self.menulist = []
+               self.menulist.append(self.menuEntryStartpage)
+
+               self["config"].list = self.menulist
+               self["config"].l.setList(self.menulist)
+
+class BookmarkEditWindow(ConfigListScreen, Screen):
+       CATEGORY,BOOKMARK = 0,1
+       skin=   """
+               <screen position="center,center" size="600,140" title="Bookmark Edit">
+                       <widget name="config" position="0,0" size="600,100" scrollbarMode="showOnDemand" />
+
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="310,100" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="150,100" size="140,40" alphatest="on" />
+
+                       <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" />
+                       <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" />
+
+                       <widget name="VKeyIcon" pixmap="skin_default/buttons/key_text.png" position="0,100" zPosition="10" size="35,25" transparent="1" alphatest="on" />
+
+               </screen>
+               """
+       def __init__(self, session, _mode, _type, _data, _bm):
+               self.mMode = _mode
+               self.mType = _type
+               self.mData = _data
+                self.mSession = session
+               self.mBookmarkManager = _bm
+
+               if _data is not None:
+                       print _data.mId
+
+               Screen.__init__(self, session)
+
+               self.menulist = []
+               ConfigListScreen.__init__(self, self.menulist)
+
+               self["actions"] = ActionMap(["OkCancelActions", "ColorActions",], {
+                       "ok"     : self.keyGreen,
+                       "green"  : self.keyGreen,
+                       "red"    : self.keyRed,
+                       "cancel" : self.keyRed,
+                }, -2)
+
+               self["VKeyIcon"]  = Pixmap()
+               self["key_red"]   = StaticText(_("Cancel"))
+               self["key_green"] = StaticText(_("Save"))
+
+               self.menuItemTitle = None
+               self.menuItemUrl   = None
+               self.menuItemName  = None
+
+               self.menuEntryName = None
+               self.menuEntryTitle = None
+               self.menuEntryUrl = None
+
+               self.makeConfigList()
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setTitle('Bookmark ' + self.mMode)
+
+       def selectedItem(self):
+               currentPosition = self["config"].getCurrent()
+               if self.mType == BookmarkEditWindow.CATEGORY:
+                       return ("Name", self.menuItemName)
+               else:
+                       if currentPosition == self.menuEntryTitle:
+                               return ("Title", self.menuItemTitle)
+                       elif currentPosition == self.menuEntryUrl:
+                               return ("Url", self.menuItemUrl)
+               return None
+
+       def showMessageBox(self, text):
+               msg = "Invalid " + text + "!!(Empty)\nPlease, Input to the " + text + "."
+               self.mSession.openWithCallback(self.showVKeyWindow, MessageBox, msg, MessageBox.TYPE_INFO)
+               return False
+
+       def showVKeyWindow(self, data=None):
+               itemTitle = ""
+               itemValue = ""
+               selected = self.selectedItem()
+               if selected is not None:
+                       itemValue = selected[1].value
+                       if strIsEmpty(itemValue):
+                               itemValue = ""
+                       itemTitle = selected[0]
+
+               self.session.openWithCallback(self.cbVKeyWindow, VirtualKeyBoard, title=itemTitle, text=itemValue)
+
+       def cbVKeyWindow(self, data=None):
+               if data is not None:
+                       selected = self.selectedItem()
+                       if selected is not None:
+                               selected[1].setValue(data)
+
+       def saveData(self):
+               if self.mType == BookmarkEditWindow.CATEGORY:
+                       if self.mMode == 'Add':
+                               categoryName = self.menuItemName.value
+                               if strIsEmpty(categoryName):
+                                       return self.showMessageBox("Category Name")
+                               self.mBookmarkManager.addCategory(categoryName)
+                       else:
+                               if strIsEmpty(self.menuItemName.value):
+                                       return self.showMessageBox("Category Name")
+                               self.mData.mName = self.menuItemName.value
+                               self.mBookmarkManager.updateCategory(self.mData)
+               else:
+                       if self.mMode == 'Add':
+                               bookmarkTitle = self.menuItemTitle.value
+                               bookmarkUrl   = self.menuItemUrl.value
+                               if strIsEmpty(bookmarkTitle):
+                                       self["config"].setCurrentIndex(0)
+                                       return self.showMessageBox("Bookmark Title")
+                               if strIsEmpty(bookmarkUrl):
+                                       self["config"].setCurrentIndex(1)
+                                       return self.showMessageBox("Bookmark URL")
+                               self.mBookmarkManager.addBookmark(bookmarkTitle, bookmarkUrl, self.mData.mParent)
+                       else:
+                               if strIsEmpty(self.menuItemTitle.value):
+                                       self["config"].setCurrentIndex(0)
+                                       return self.showMessageBox("Bookmark Title")
+                               if strIsEmpty(self.menuItemUrl.value):
+                                       self["config"].setCurrentIndex(1)
+                                       return self.showMessageBox("Bookmark URL")
+                               self.mData.mTitle = self.menuItemTitle.value
+                               self.mData.mUrl   = self.menuItemUrl.value
+                               self.mBookmarkManager.updateBookmark(self.mData)
+               return True
+
+       def keyGreen(self):
+               if not self.saveData():
+                       return
+               self.close(True)
+       def keyRed(self):
+               self.close(False)
+       def keyLeft(self):
+               ConfigListScreen.keyLeft(self)
+       def keyRight(self):
+               ConfigListScreen.keyRight(self)
+       def makeConfigList(self):
+               self.menulist = []
+
+               if self.mType == BookmarkEditWindow.CATEGORY:
+                       self.menuItemName = ConfigText(default=self.mData.mName, visible_width=65, fixed_size=False)
+
+                       self.menuEntryName  = getConfigListEntry(_("Name"), self.menuItemName)
+
+                       self.menulist.append(self.menuEntryName)
+               else:
+                       self.menuItemTitle = ConfigText(default=self.mData.mTitle, visible_width=65, fixed_size=False)
+                       self.menuItemUrl   = ConfigText(default=self.mData.mUrl, visible_width=65, fixed_size=False)
+
+                       self.menuEntryTitle = getConfigListEntry(_("Title"), self.menuItemTitle)
+                       self.menuEntryUrl   = getConfigListEntry(_("Url"), self.menuItemUrl)
+
+                       self.menulist.append(self.menuEntryTitle)
+                       self.menulist.append(self.menuEntryUrl)
+                       
+               self["config"].list = self.menulist
+               self["config"].l.setList(self.menulist)
+
+class OperaBrowserBookmarkWindow(Screen):
+       skin =  """
+               <screen name="HbbTVBrowserBookmarkWindow" position="center,center" size="600,400" title="Bookmark" >
+                       <widget name="bookmarklist" position="0,0" size="600,200" zPosition="10" scrollbarMode="showOnDemand" />
+
+                       <ePixmap pixmap="skin_default/buttons/key_0.png" position="556,330" size="35,30" alphatest="on" />
+                       <widget source="key_0" render="Label" position="258,330" zPosition="1" size="300,30" font="Regular;20" halign="right" valign="center"/>
+
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="5,360" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="155,360" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,360" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="450,360" size="140,40" alphatest="on" />
+
+                       <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" />
+                       <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" />
+                       <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" />
+                       <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" />
+               </screen>
+               """
+
+       def __init__(self, _session, _url=None, _title=None):
+               self.mUrl   = _url
+               self.mTitle = _title
+               self.mBookmarkManager = BookmarkManager.getInstance()
+               self.mSession = _session
+               Screen.__init__(self, _session)
+               self["actions"] = ActionMap(["DirectionActions", "OkCancelActions","ColorActions", "NumberActions"], {
+                               "ok"    : self.keyOK,
+                               "cancel": self.keyCancel,
+                               "red"   : self.keyRed,
+                               "green" : self.keyGreen,
+                               "yellow": self.keyYellow,
+                               "blue"  : self.keyBlue,
+                               "0"     : self.keyNumber,
+                       },-2)
+
+               self["key_red"]    = StaticText(_("Exit"))
+               self["key_green"]  = StaticText(_("Add"))
+               self["key_yellow"] = StaticText(_("Edit"))
+               self["key_blue"]   = StaticText(_("Delete"))
+               self["key_0"]      = StaticText(_("Set as Startpage"))
+
+               self.mBookmarkList = self.setBookmarkList()
+               self["bookmarklist"] = MenuList(self.mBookmarkList)
+
+       def setBookmarkList(self):
+               l = []
+               #self.mBookmarkManager.dump()
+               cd = self.mBookmarkManager.getBookmarkRoot()
+               for ck in cd.iterkeys():
+                       l.append(('# ' + cd[ck].mName, cd[ck]))
+                       bd = cd[ck].mBookmarks
+                       for bk in bd.iterkeys():
+                               l.append(('    - ' + bd[bk].mTitle, bd[bk]))
+               return l
+       def updateBookmarkList(self):
+               self.mBookmarkList = self.setBookmarkList()
+               self["bookmarklist"].setList(self.mBookmarkList)
+       def cbEditWindow(self, ret=False):
+               if not ret: 
+                       return
+               self.updateBookmarkList()
+       def getParentCategory(self):
+               idx = self["bookmarklist"].getSelectedIndex()
+               try:
+                       while idx >= 0:
+                               data = self.mBookmarkList[idx][0].strip()
+                               if data[0] == '#':
+                                       return self.mBookmarkList[idx][1]
+                               idx -= 1
+               except: pass
+               return None
+       def isCategoryItem(self):
+               try:
+                       head = self["bookmarklist"].getCurrent()[0].strip()
+                       if head[0] == '#':
+                               return True
+               except: pass
+               return False
+       def keyNumber(self):
+               data = self["bookmarklist"].getCurrent()[1]
+               if strIsEmpty(data.mUrl):
+                       msg = "Invalid URL. Please check again!!"
+                       self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
+                       return
+               def cbSetStartpage(ret=None):
+                       if ret is None: return
+                       if ret:
+                               data = self["bookmarklist"].getCurrent()[1]
+                               OperaBrowserSetting().setData(data.mUrl)
+               msg = "Do you want to set selected url to the Startpage?"
+               self.mSession.openWithCallback(cbSetStartpage, MessageBox, msg, MessageBox.TYPE_YESNO, default=True)
+
+       def keyGreen(self):
+               def cbGreen(data):
+                       if data is None:
+                               return
+                       if data[1] == 1:
+                               parent = self.getParentCategory()
+                               if parent is None:
+                                       return
+                               if strIsEmpty(self.mTitle):
+                                       return
+                               retAdd = self.mBookmarkManager.addBookmark(self.mTitle, self.mUrl, parent.mId)
+                               if not retAdd:
+                                       msg = "Current page is already exist."
+                                       self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO)
+                               self.cbEditWindow(True)
+                       elif data[1] == 2:
+                               parent = self.getParentCategory()
+                               if parent is None:
+                                       return
+                               b = BookmarkData(0, '', '', parent.mId)
+                               self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Add', BookmarkEditWindow.BOOKMARK, b, self.mBookmarkManager)
+                       elif data[1] == 3:
+                               c = CategoryData(0, '')
+                               self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Add', BookmarkEditWindow.CATEGORY, c, self.mBookmarkManager)
+               if strIsEmpty(self.mUrl):
+                       l = [('Direct Input(Bookmark)',2,), ('Direct Input(Category)',3,)]
+               else:   l = [('Currentpage(Bookmark)',1,), ('Direct Input(Bookmark)',2,), ('Direct Input(Category)',3,)]
+               self.mSession.openWithCallback(cbGreen, ChoiceBox, title=_("Please choose."), list=l)
+       def keyYellow(self):
+               data = self["bookmarklist"].getCurrent()[1]
+               if self.isCategoryItem():
+                       self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Edit', BookmarkEditWindow.CATEGORY, data, self.mBookmarkManager)
+               else:   self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Edit', BookmarkEditWindow.BOOKMARK, data, self.mBookmarkManager)
+       def keyBlue(self):
+               def cbBlue(ret=None):
+                       if not ret: return
+                       data = self["bookmarklist"].getCurrent()[1]
+                       if self.isCategoryItem():
+                               self.mBookmarkManager.deleteCategory(data.mId)
+                       else:   self.mBookmarkManager.deleteBookmark(data.mId)
+                       self.updateBookmarkList()
+               if self.isCategoryItem():
+                       msg = "Do you want to delete the category and the bookmarks?"
+               else:   msg = "Do you want to delete the bookmark?"
+               self.mSession.openWithCallback(cbBlue, MessageBox, msg, MessageBox.TYPE_YESNO, default=True)
+       def keyOK(self):
+               if self.isCategoryItem(): return
+
+               data = self["bookmarklist"].getCurrent()[1]
+               url = data.mUrl.strip()
+               if len(url) == 0:
+                       self.session.open(MessageBox, "Can't open selected bookmark.\n   - URL data is empty!!", type = MessageBox.TYPE_INFO)
+                       return
+               self.close(url)
+       def keyRed(self):
+               self.keyCancel()
+       def keyCancel(self):
+               self.close()
+
+
+class BrowserHelpWindow(Screen, HelpableScreen):
+       MODE_GLOBAL,MODE_KEYBOARD,MODE_MOUSE = 1,2,3
+        skin = """
+                <screen name="BrowserHelpWindow" position="center,center" size="600,40" title="Browser Help" >
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="450,0" size="140,40" alphatest="on" />
+
+                       <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" />
+                       <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" />
+                       <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" />
+                       <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" />
+                </screen>
+               """
+        def __init__(self, session):
+                Screen.__init__(self, session)
+               HelpableScreen.__init__(self)
+
+               self["key_red"]    = StaticText(_("Exit"))
+               self["key_green"]  = StaticText(_("Global"))
+               self["key_yellow"] = StaticText(_("Mouse"))
+               self["key_blue"]   = StaticText(_("Keyboard"))
+
+               self["actions"] = ActionMap(["DirectionActions", "OkCancelActions","ColorActions"], {
+                               "ok"    : self.keyRed,
+                               "cancel": self.keyRed,
+                               "red"   : self.keyRed,
+                               "green" : self.keyGreen,
+                               "yellow": self.keyYellow,
+                               "blue"  : self.keyBlue,
+                       },-2)
+
+               self.showHelpTimer = eTimer()
+               self.showHelpTimer.callback.append(self.cbShowHelpTimerClosed)
+               self.showHelpTimer.start(500)
+
+       def cbShowHelpTimerClosed(self):
+               self.showHelpTimer.stop()
+               self.setHelpModeActions(self.MODE_GLOBAL)
+
+       def setHelpModeActions(self, _mode=0):
+               self.helpList = []
+               if _mode == self.MODE_GLOBAL:
+                       self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
+                               "cancel" : (self.keyPass, _("Exit the Opera browser.")),
+                       })
+                       self["MenuActions"] = HelpableActionMap(self, "MenuActions", {
+                               "menu" : (self.keyPass, _("Show the Menu window.")),
+                       })
+                       self["ColorActions"] = HelpableActionMap(self, "ColorActions", {
+                               "green"  : (self.keyPass, _("Enter Key")),
+                               "yellow" : (self.keyPass, _("Show the Virtual keyboard window.")),
+                               "blue"   : (self.keyPass, _("Backspace Key")),
+                       })
+                       self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
+                               "info" : (self.keyPass, _("Switch to keyboard/mouse mode.")),
+                       })
+
+               elif _mode == self.MODE_MOUSE:
+                       self["DirectionActions"] = HelpableActionMap(self, "DirectionActions", {
+                               "up"    : (self.keyPass, _("It will move the mouse pointer up.")),
+                               "down"  : (self.keyPass, _("It will move the mouse pointer down.")),
+                               "left"  : (self.keyPass, _("It will move the mouse pointer left.")),
+                               "right" : (self.keyPass, _("It will move the mouse pointer right.")),
+                       })
+                       self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
+                               "ok" : (self.keyPass, _("Left Mouse Button")),
+                       })
+                       self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
+                               "nextBouquet" : (self.keyPass, _("Right Mouse Button")),
+                               "nextService" : (self.keyPass, _("Left Key")),
+                               "prevService" : (self.keyPass, _("Right Key")),
+                       })
+               elif _mode == self.MODE_KEYBOARD:
+                       self["DirectionActions"] = HelpableActionMap(self, "DirectionActions", {
+                               "up"    : (self.keyPass, _("Up Key")),
+                               "down"  : (self.keyPass, _("Down Key")),
+                               "left"  : (self.keyPass, _("Left Key")),
+                               "right" : (self.keyPass, _("Right Key")),
+                       })
+                       self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
+                               "ok" : (self.keyPass, _("Enter Key")),
+                       })
+                       self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
+                               "nextBouquet" : (self.keyPass, _("PageUp Key")),
+                               "prevBouquet" : (self.keyPass, _("PageDown Key")),
+                               "nextService" : (self.keyPass, _("Go to previous page.")),
+                               "prevService" : (self.keyPass, _("Go to next page.")),
+                       })
+
+               if _mode > 0:
+                       self.showHelp()
+
+       def keyPass(self):
+               pass
+
+       def keyRed(self):
+               self.close()
+       def keyGreen(self):
+               self.setHelpModeActions(self.MODE_GLOBAL)
+       def keyYellow(self):
+               self.setHelpModeActions(self.MODE_MOUSE)
+       def keyBlue(self):
+               self.setHelpModeActions(self.MODE_KEYBOARD)
+
 class OperaBrowser(Screen):
        MENUBAR_ITEM_WIDTH  = 150
        MENUBAR_ITEM_HEIGHT = 30
 class OperaBrowser(Screen):
        MENUBAR_ITEM_WIDTH  = 150
        MENUBAR_ITEM_HEIGHT = 30
@@ -795,28 +1650,33 @@ class OperaBrowser(Screen):
                <screen name="Opera Browser" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="Opera Browser">
                        <widget name="topArea" zPosition="-1" position="0,0" size="1280,60" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
                        <widget name="menuitemFile" position="30,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
                <screen name="Opera Browser" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="Opera Browser">
                        <widget name="topArea" zPosition="-1" position="0,0" size="1280,60" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
                        <widget name="menuitemFile" position="30,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
-                       <widget name="menuitemHelp" position="180,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
+                       <widget name="menuitemTool" position="180,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
+                       <widget name="menuitemHelp" position="330,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
                        <widget name="menulist" position="50,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
                        <widget name="submenulist" position="%d,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
                        <widget name="bottomArea" position="0,640" size="1280,80" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
                </screen>
                        <widget name="menulist" position="50,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
                        <widget name="submenulist" position="%d,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
                        <widget name="bottomArea" position="0,640" size="1280,80" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
                </screen>
-               """ % (MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH, SUBMENULIST_WIDTH+50+SUBMENULIST_NEXT, MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH)
+               """ % (MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH, SUBMENULIST_WIDTH+50+SUBMENULIST_NEXT, MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH)# modify menu
 
 
-       MENUITEMS_LIST =[[('Open Location', None), ('Start/Stop',None), ('Exit', None)],
-                        [('About', None)]]
+       MENUITEMS_LIST =[[('Open Startpage', None), ('Open URL', None), ('Start/Stop',None), ('Exit', None)],
+                        [('Bookmark', None), ('Preference', None)],
+                        [('About', None), ('Help', None)]]
        def __init__(self, session):
                Screen.__init__(self, session)
        def __init__(self, session):
                Screen.__init__(self, session)
-
-               self["actions"] = ActionMap(["MinuteInputActions", "ColorActions", "InputActions", "InfobarChannelSelection", "EPGSelectActions", "KeyboardInputActions"], {
+               self["actions"] = ActionMap(["DirectionActions", "MenuActions", "OkCancelActions"], {
                         "cancel"      : self.keyCancel
                        ,"ok"          : self.keyOK
                        ,"left"        : self.keyLeft
                        ,"right"       : self.keyRight
                        ,"up"          : self.keyUp
                        ,"down"        : self.keyDown
                         "cancel"      : self.keyCancel
                        ,"ok"          : self.keyOK
                        ,"left"        : self.keyLeft
                        ,"right"       : self.keyRight
                        ,"up"          : self.keyUp
                        ,"down"        : self.keyDown
-                       ,"menu"        : self.keyCancel
+                       ,"menu"        : self.keyMenu
                }, -2)
 
                }, -2)
 
+               self._terminatedBrowser = True
+               self._enableKeyEvent = True
+               self._currentPageUrl = None
+               self._currentPageTitle = None
                self.menubarCurrentIndex = 0
                self.lvMenuItems = []
                self.lvSubMenuItems = []
                self.menubarCurrentIndex = 0
                self.lvMenuItems = []
                self.lvSubMenuItems = []
@@ -824,7 +1684,8 @@ class OperaBrowser(Screen):
                self["topArea"]    = Label()
                self["bottomArea"] = Label()
 
                self["topArea"]    = Label()
                self["bottomArea"] = Label()
 
-               self["menuitemFile"] = MultiColorLabel()
+               self["menuitemFile"] = MultiColorLabel()# modify menu
+               self["menuitemTool"] = MultiColorLabel()
                self["menuitemHelp"] = MultiColorLabel()
 
                self["menulist"] = MenuList(self.setListOnView())
                self["menuitemHelp"] = MultiColorLabel()
 
                self["menulist"] = MenuList(self.setListOnView())
@@ -846,19 +1707,21 @@ class OperaBrowser(Screen):
                        os.system("echo %d > %s" % (mode, rcmouse_path))
 
        def layoutFinished(self):
                        os.system("echo %d > %s" % (mode, rcmouse_path))
 
        def layoutFinished(self):
-               self["menuitemFile"].setText("File")
+               self["menuitemFile"].setText("File")# modify menu
+               self["menuitemTool"].setText("Tools")
                self["menuitemHelp"].setText("Help")
 
                self["menulist"].hide()
                self["submenulist"].hide()
 
                self["menuitemHelp"].setText("Help")
 
                self["menulist"].hide()
                self["submenulist"].hide()
 
-               self["bottomArea"].setText("Opera Web Browser Plugin v0.1")
+               self["bottomArea"].setText("Opera Web Browser Plugin v1.0")
                self.setTitle("BrowserMain")
                self.selectMenuitem()
 
        def selectMenuitem(self):
                self.setTitle("BrowserMain")
                self.selectMenuitem()
 
        def selectMenuitem(self):
-               tmp = [self["menuitemFile"], self["menuitemHelp"]]
+               tmp = [self["menuitemFile"], self["menuitemTool"], self["menuitemHelp"]]# modify menu
                self["menuitemFile"].setForegroundColorNum(0)
                self["menuitemFile"].setForegroundColorNum(0)
+               self["menuitemTool"].setForegroundColorNum(0)
                self["menuitemHelp"].setForegroundColorNum(0)
                tmp[self.menubarCurrentIndex].setForegroundColorNum(1)
 
                self["menuitemHelp"].setForegroundColorNum(0)
                tmp[self.menubarCurrentIndex].setForegroundColorNum(1)
 
@@ -869,7 +1732,10 @@ class OperaBrowser(Screen):
                self.keyCancel()
 
        def setListOnView(self):
                self.keyCancel()
 
        def setListOnView(self):
-               self.lvMenuItems = self.MENUITEMS_LIST[self.menubarCurrentIndex]        
+               l = self.MENUITEMS_LIST[self.menubarCurrentIndex]
+               if not self._terminatedBrowser and self.menubarCurrentIndex == 0: # running
+                       l = [('Return', None)]
+               self.lvMenuItems = l #self.MENUITEMS_LIST[self.menubarCurrentIndex]     
                return self.lvMenuItems
 
        def setSubListOnView(self):
                return self.lvMenuItems
 
        def setSubListOnView(self):
@@ -920,10 +1786,17 @@ class OperaBrowser(Screen):
                self._on_setPageTitle('Opera Browser')
                self.enableRCMouse(False)
                self.toggleMainScreen()
                self._on_setPageTitle('Opera Browser')
                self.enableRCMouse(False)
                self.toggleMainScreen()
+               fbClass.getInstance().unlock()
                eRCInput.getInstance().unlock()
                eRCInput.getInstance().unlock()
+               self._terminatedBrowser = True
+               self._enableKeyEvent = True
+               #if not self.toggleListViewFlag:
+               #       self.keyDown()
+               self.keyRight()
+               self.keyLeft()
 
        def _on_setPageTitle(self, title=None):
 
        def _on_setPageTitle(self, title=None):
-               print "page title :",title
+               print "Title :",title
                if title is None:
                        return
                self.setTitle(title)
                if title is None:
                        return
                self.setTitle(title)
@@ -932,6 +1805,7 @@ class OperaBrowser(Screen):
                print "Inputed Url :", data
                if strIsEmpty(data):
                        return
                print "Inputed Url :", data
                if strIsEmpty(data):
                        return
+               #self.hideSubmenu()
                command_server = getCommandServer()
                if self._on_setPageTitle not in command_server.onSetPageTitleCB:
                                command_server.onSetPageTitleCB.append(self._on_setPageTitle)
                command_server = getCommandServer()
                if self._on_setPageTitle not in command_server.onSetPageTitleCB:
                                command_server.onSetPageTitleCB.append(self._on_setPageTitle)
@@ -939,14 +1813,22 @@ class OperaBrowser(Screen):
                        command_server.onHbbTVCloseCB.append(self._on_close_window)
                self.toggleMainScreen()
                self.enableRCMouse(True)
                        command_server.onHbbTVCloseCB.append(self._on_close_window)
                self.toggleMainScreen()
                self.enableRCMouse(True)
+               fbClass.getInstance().lock()
                eRCInput.getInstance().lock()
                command_util = getCommandUtil()
                command_util.sendCommand('OP_BROWSER_OPEN_URL', data)
                eRCInput.getInstance().lock()
                command_util = getCommandUtil()
                command_util.sendCommand('OP_BROWSER_OPEN_URL', data)
+               self._terminatedBrowser = False
+               self._enableKeyEvent = False
 
        def _on_close_window(self):
                self._onCloseTimer.start(1000)
 
 
        def _on_close_window(self):
                self._onCloseTimer.start(1000)
 
-       def _cmd_on_OpenLocation(self):
+       def _cb_bookmarkWindowClosed(self, data=None):
+               if data is None:
+                       return
+               self.cbUrlText(data)
+
+       def _cmd_on_OpenUrl(self):
                global _g_helper
                if not _g_helper._is_browser_running():
                        message = "Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu."
                global _g_helper
                if not _g_helper._is_browser_running():
                        message = "Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu."
@@ -954,7 +1836,7 @@ class OperaBrowser(Screen):
                        return
                self.session.openWithCallback(self.cbUrlText, VirtualKeyBoard, title=("Please enter URL here"), text='http://')
        def _cmd_on_About(self):
                        return
                self.session.openWithCallback(self.cbUrlText, VirtualKeyBoard, title=("Please enter URL here"), text='http://')
        def _cmd_on_About(self):
-               self.session.open(MessageBox, 'Opera Web Browser Plugin v0.1(beta)', type = MessageBox.TYPE_INFO)
+               self.session.open(MessageBox, 'Opera Web Browser Plugin v1.0', type = MessageBox.TYPE_INFO)
        def _cmd_on_Exit(self):
                self.close()
        def _cmd_on_StartStop(self):
        def _cmd_on_Exit(self):
                self.close()
        def _cmd_on_StartStop(self):
@@ -962,16 +1844,51 @@ class OperaBrowser(Screen):
                if _g_helper is None: 
                        return
                _g_helper.showBrowserConfigBox()
                if _g_helper is None: 
                        return
                _g_helper.showBrowserConfigBox()
+       def _cmd_on_Bookmark(self):
+               url = self._currentPageUrl
+               if url is None:
+                       url = ''
+               title = self._currentPageTitle
+               if title is None:
+                       title = ''
+               self.session.openWithCallback(self._cb_bookmarkWindowClosed, OperaBrowserBookmarkWindow, url, title)
+       def _cmd_on_Preference(self):
+               url = self._currentPageUrl
+               if url is None:
+                       url = ''
+               self.session.open(OperaBrowserPreferenceWindow, url)
+       def _cmd_on_OpenStartpage(self):
+               global _g_helper
+               if not _g_helper._is_browser_running():
+                       message = "Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu."
+                       self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
+                       return
+               start = 'http://vuplus.com'
+               try:
+                       start = OperaBrowserSetting().getData()['start']
+               except: pass
+               self.cbUrlText(start)
+       def _cmd_on_ReturnToBrowser(self):
+               self.keyCancel()
+
+       def _cmd_on_Help(self):
+               self.session.open(BrowserHelpWindow)
+
        def doCommand(self, command):
        def doCommand(self, command):
-               cmd_map = {
-                        'Exit'          :self._cmd_on_Exit
-                       ,'About'         :self._cmd_on_About
-                       ,'Open Location' :self._cmd_on_OpenLocation
-                       ,'Start/Stop'    :self._cmd_on_StartStop
+               cmd_map = {# modify menu
+                        'Exit'         :self._cmd_on_Exit
+                       ,'Help'         :self._cmd_on_Help
+                       ,'About'        :self._cmd_on_About
+                       ,'Open URL'     :self._cmd_on_OpenUrl
+                       ,'Start/Stop'   :self._cmd_on_StartStop
+                       ,'Bookmark'     :self._cmd_on_Bookmark
+                       ,'Preference'   :self._cmd_on_Preference
+                       ,'Return'       :self._cmd_on_ReturnToBrowser
+                       ,'Open Startpage' :self._cmd_on_OpenStartpage
                }
                try:
                        cmd_map[command]()
                }
                try:
                        cmd_map[command]()
-               except: pass
+               except Exception, ErrMsg: print ErrMsg
 
        def keyOK(self):
                if not self.toggleListViewFlag:
 
        def keyOK(self):
                if not self.toggleListViewFlag:
@@ -985,8 +1902,8 @@ class OperaBrowser(Screen):
 
        def updateSelectedMenuitem(self, status):
                if self.menubarCurrentIndex == 0 and status < 0:
 
        def updateSelectedMenuitem(self, status):
                if self.menubarCurrentIndex == 0 and status < 0:
-                       self.menubarCurrentIndex = 1
-               elif self.menubarCurrentIndex == 1 and status > 0:
+                       self.menubarCurrentIndex = 2 # modify menu
+               elif self.menubarCurrentIndex == 2 and status > 0: # modify menu
                        self.menubarCurrentIndex = 0
                else:   self.menubarCurrentIndex += status
                self.selectMenuitem()
                        self.menubarCurrentIndex = 0
                else:   self.menubarCurrentIndex += status
                self.selectMenuitem()
@@ -1001,8 +1918,11 @@ class OperaBrowser(Screen):
                        self.setCurrentListView(1)
                        self.toggleSubListView()
                        return
                        self.setCurrentListView(1)
                        self.toggleSubListView()
                        return
-               if self.currentListView.getSelectedIndex():
-                       self.currentListView.pageUp()
+               #if self.currentListView.getSelectedIndex():
+               self.currentListView.pageUp()
+               self.keyUp()
+               self.keyLeft()
+               self.keyDown()
 
        def keyRight(self):
                if not self.toggleMainScreenFlag:
 
        def keyRight(self):
                if not self.toggleMainScreenFlag:
@@ -1019,6 +1939,11 @@ class OperaBrowser(Screen):
                        self.currentListView.resize(self.SUBMENULIST_WIDTH, self.SUBMENULIST_HEIGHT*len(self.lvSubMenuItems)+5)
                        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))
                        self.toggleSubListView()
                        self.currentListView.resize(self.SUBMENULIST_WIDTH, self.SUBMENULIST_HEIGHT*len(self.lvSubMenuItems)+5)
                        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))
                        self.toggleSubListView()
+                       return
+               self.currentListView.pageUp()
+               self.keyUp()
+               self.keyRight()
+               self.keyDown()
 
        def keyDown(self):
                if not self.toggleMainScreenFlag:
 
        def keyDown(self):
                if not self.toggleMainScreenFlag:
@@ -1045,19 +1970,63 @@ class OperaBrowser(Screen):
                self.currentListView.up()
 
        def keyCancel(self):
                self.currentListView.up()
 
        def keyCancel(self):
+               if not self._terminatedBrowser:
+                       #self._session.openWithCallback(self._cb_virtualKeyboardClosed, VirtualKeyBoard, title=("Please enter URL here"), text="")
+                       fbClass.getInstance().lock()
+                       eRCInput.getInstance().lock()
+                       if self.toggleListViewFlag:
+                               self.toggleMainScreen()
+                       self._currentPageUrl   = None
+                       self._currentPageTitle = None
+                       command_util = getCommandUtil()
+                       command_util.sendCommand('OP_BROWSER_MENU_RES')
+                       return
+               self.close()
+
+       def keyMenu(self):
                self.toggleMainScreen()
 
                self.toggleMainScreen()
 
+       def setCurrentPageUrl(self, url, title=None):
+               self._currentPageUrl = url
+               if title is None:
+                       idx = len(url)
+                       if idx > 10: idx = 10
+                       title = url[:idx]
+               self._currentPageTitle = title
+               print self._currentPageUrl
+               self.toggleMainScreen()
+               self.hideSubmenu()
+               self.keyDown()
+
+       def hideSubmenu(self):
+               self.currentListView.pageUp()
+               self.keyUp()
+
+
+
 def auto_start_main(reason, **kwargs):
        if reason:
                command_server = getCommandServer()
                command_server.stop()
 
 def session_start_main(session, reason, **kwargs):
 def auto_start_main(reason, **kwargs):
        if reason:
                command_server = getCommandServer()
                command_server.stop()
 
 def session_start_main(session, reason, **kwargs):
+       fbClass.getInstance().unlock()
+       eRCInput.getInstance().unlock()
        global _g_helper
        _g_helper = session.open(HbbTVHelper)
 
        global _g_helper
        _g_helper = session.open(HbbTVHelper)
 
+_g_clearBrowserDataTimer = eTimer()
 def plugin_start_main(session, **kwargs):
 def plugin_start_main(session, **kwargs):
-       session.open(OperaBrowser)
+       #session.open(OperaBrowser)
+       def _do_clean():
+               _g_clearBrowserDataTimer.stop()
+               try:    _g_clearBrowserDataTimer.callback.remove(_do_clean)
+               except: pass
+               setPluginBrowser(None)
+       def clearBrowserData():
+               _g_clearBrowserDataTimer.callback.append(_do_clean)
+               _g_clearBrowserDataTimer.start(50)
+       setPluginBrowser(session.openWithCallback(clearBrowserData, OperaBrowser))
 
 def plugin_extension_start_application(session, **kwargs):
        global _g_helper
 
 def plugin_extension_start_application(session, **kwargs):
        global _g_helper
@@ -1077,6 +2046,6 @@ def Plugins(path, **kwargs):
                PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10),
                PluginDescriptor(name="HbbTV Applications", where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_start_application),
                PluginDescriptor(name="Browser Start/Stop", where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_browser_config),
                PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10),
                PluginDescriptor(name="HbbTV Applications", where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_start_application),
                PluginDescriptor(name="Browser Start/Stop", where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_browser_config),
-               PluginDescriptor(name="Opera Web Browser", description="start opera web browser", where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=True, fnc=plugin_start_main)
+               PluginDescriptor(name="Opera Web Browser", description="start opera web browser", where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=True, fnc=plugin_start_main),
                ]
 
                ]