[hbbtv/youtubetv] fixed volume control bug.
[vuplus_dvbapp] / lib / python / Plugins / Extensions / HbbTV / plugin.py
index 9ae4d2e..70a2ec3 100644 (file)
@@ -6,27 +6,37 @@ from Screens.ChoiceBox import ChoiceBox
 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.Language import language
 from Components.PluginComponent import plugins
 from Components.Button import Button
-from Components.Label import Label
 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.config import config, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile, getCharValue
+from Components.VolumeControl import VolumeControl
+from Components.Pixmap import Pixmap
+from Components.config import config, ConfigYesNo, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile
 
-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
 
+from __init__ import _
+
 strIsEmpty = lambda x: x is None or len(x) == 0
 
 HBBTVAPP_PATH = "/usr/local/hbb-browser"
 COMMAND_PATH = '/tmp/.sock.hbbtv.cmd'
 
+_g_helper = None
+
 class GlobalValues:
        command_util   = None
        command_server = None
@@ -44,8 +54,53 @@ class GlobalValues:
        packet_m  = 0xBBADBEE
        packet_h  = '!IIII'
        packet_hl = struct.calcsize(packet_h)
+
+       need_restart = False
+       plugin_browser = None
+
+       resX = 0
+       resY = 0
+       def UpdateInfoBar(self):
+               if self.resX == 1024 and self.resY == 720:
+                       return
+               try:
+                       infobar = InfoBar.instance
+                       if infobar._InfoBarShowHide__state != 3:
+                               return
+                       infobar.doTimerHide()
+                       infobar.serviceStarted()
+               except: pass
+       
 __gval__ = GlobalValues()
 
+def setDefaultResolution(x, y):
+       global __gval__
+       __gval__.resX = x
+       __gval__.resY = y
+
+def setResolution(xres, yres):
+       global __gval__
+       if __gval__.resX == 1280 and __gval__.resY == 720:
+               return
+       from enigma import gMainDC
+       gMainDC.getInstance().setResolution(xres, yres)
+
+def restoreResolution():
+       global __gval__
+       setResolution(1280, 720)
+       setResolution(__gval__.resX, __gval__.resY)
+
+       if __gval__.resX == 1280 and __gval__.resY == 720:
+               return
+       __gval__.UpdateInfoBar()
+
+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)
@@ -73,6 +128,15 @@ def getChannelInfos():
                __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
@@ -107,54 +171,6 @@ def _pack(opcode, params=None, reserved=0):
        packed_data = struct.pack(h, m, opcode, len(params), reserved)
        return packed_data + params
 
-class MMSStreamURL:
-       headers = [
-                   'GET %s HTTP/1.0'
-                  ,'Accept: */* '
-                  ,'User-Agent: NSPlayer/7.10.0.3059 '
-                  ,'Host: %s '
-                  ,'Connection: Close '
-                 ]
-
-       def __init__(self):
-               self.sendmsg = ''
-               for m in self.headers:
-                       self.sendmsg += m + '\n'
-               self.sendmsg += '\n\n'
-
-       def request(self, host, port=80, location='/'):
-               sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
-               sock.connect((host, port))
-               sock.send(self.sendmsg%(location, host))
-               print "Send Data : "
-               print self.sendmsg%(location, host)
-               fullydata = ''
-               while 1:
-                       res = sock.recv(1024)
-                       if res == '': break
-                       fullydata += res
-               sock.close()
-               return fullydata
-
-       def parse(self, data):
-               for d in data.splitlines():
-                       if d.startswith('Location: '):
-                               return d[9:]
-               return None
-
-       def getLocationData(self, url):
-               url_list,host,location = None,None,None
-               try:
-                       url = url[url.find(':')+3:]
-                       url_list = url.split('/')
-                       host = url_list[0]
-                       location = url[len(url_list[0]):]
-               except Exception, err_msg:
-                       print err_msg
-                       return None
-               html = self.request(host=host, location=location)
-               return self.parse(html)
-
 class OpCodeSet:
        def __init__(self):
                self._opcode_ = {
@@ -165,6 +181,8 @@ class OpCodeSet:
                        ,"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
@@ -174,7 +192,26 @@ class OpCodeSet:
                        ,"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_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_BROWSER_NEED_RELOAD_KEYMAP": 0x0313
+                       ,"OP_DVBAPP_VOL_UP"             : 0x0401
+                       ,"OP_DVBAPP_VOL_DOWN"           : 0x0402
+                       ,"OP_DVBAPP_SET_VOL"            : 0x0403
+                       ,"OP_SYSTEM_OUT_OF_MEMORY"      : 0x0501
+                       ,"OP_SYSTEM_NOTIFY_MY_PID"      : 0x0502
+                       ,"OP_VIDEOBACKEND_ENABLE"       : 0x0601
+                       ,"OP_VIDEOBACKEND_DISABLE"      : 0x0602
+                       ,"OP_BROWSER_OPEN_YOUTUBETV"    : 0x0603
                }
                self._opstr_ = {
                         0x0000 : "OP_UNKNOWN"
@@ -184,6 +221,8 @@ class OpCodeSet:
                        ,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"
@@ -193,7 +232,26 @@ class OpCodeSet:
                        ,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"
+                       ,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"
+                       ,0x0313 : "OP_BROWSER_NEED_RELOAD_KEYMAP"
+                       ,0x0401 : "OP_DVBAPP_VOL_UP"
+                       ,0x0402 : "OP_DVBAPP_VOL_DOWN"
+                       ,0x0403 : "OP_DVBAPP_SET_VOL"
+                       ,0x0501 : "OP_SYSTEM_OUT_OF_MEMORY"
+                       ,0x0502 : "OP_SYSTEM_NOTIFY_MY_PID"
+                       ,0x0601 : "OP_VIDEOBACKEND_ENABLE"
+                       ,0x0602 : "OP_VIDEOBACKEND_DISABLE"
+                       ,0x0603 : "OP_BROWSER_OPEN_YOUTUBETV"
                }
 
        def get(self, opstr):
@@ -289,9 +347,12 @@ class StreamServer:
 class ServerFactory:
        def doListenUnixTCP(self, name, handler):
                def destroy(name):
-                       if os.path.exists(name):
-                               os.unlink(name)
-                               print "Removed ", name
+                       import os
+                       try:
+                               if os.path.exists(name):
+                                       os.unlink(name)
+                                       print "Removed ", name
+                       except: pass
                destroy(name)
 
                params = SocketParams()
@@ -306,11 +367,11 @@ class ServerFactory:
                return streamServer
 
        def doListenInetTCP(self, ip, port, handler):
-               print "not implemented yet!!"
+               print "Not implemented yet!!"
        def doListenUnixDGRAM(self, name, handler):
-               print "not implemented yet!!"
+               print "Not implemented yet!!"
        def doListenInetDGRAM(self, ip, port, handler):
-               print "not implemented yet!!"
+               print "Not implemented yet!!"
 
 class Handler:
        def doUnpack(self, data):
@@ -338,18 +399,17 @@ class BrowserCommandUtil(OpCodeSet):
 
        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:
-                               print "fail to open file :", filename
+                               print "Fail to open file :", filename
                                return False
                except Exception, ErrMsg:
                        print ErrMsg
                        self._fd = None
                        return False
-               print "connected!! to ", filename
                return True
 
        def doDisconnect(self):
@@ -360,7 +420,7 @@ class BrowserCommandUtil(OpCodeSet):
 
        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:
@@ -388,6 +448,8 @@ class HandlerHbbTV(Handler):
                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
@@ -395,12 +457,31 @@ class HandlerHbbTV(Handler):
                        ,0x0202 : self._cb_handleVODPlayerPlay
                        ,0x0203 : self._cb_handleVODPlayerStop
                        ,0x0204 : self._cb_handleVODPlayerPlayPause
+                       ,0x0401 : self._cb_handleDVBAppVolUp
+                       ,0x0402 : self._cb_handleDVBAppVolDown
+                       ,0x0403 : self._cb_handleDVBAppSetVol
+                       ,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
+                       ,0x0601 : self._cb_handleVideobackendEnable
+                       ,0x0602 : self._cb_handleVideobackendDisable
                }
                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
+               self._max_volume  = -1
+               self._soft_volume = -1
+
        def _handle_dump(self, handle, opcode, data=None):
                if True: return
                print str(handle)
@@ -437,6 +518,186 @@ class HandlerHbbTV(Handler):
                self._on_set_title_cb = None
                return self.doPack(opcode, params, reserved)
 
+       def _cb_handleVideobackendEnable(self, opcode, data):
+               self._handle_dump(self._cb_handleVideobackendEnable, opcode, data)
+               service = self._session.nav.getCurrentlyPlayingServiceReference()
+               setBeforeService(service)
+               self._session.nav.stopService()
+               return (0, "OK")
+
+       def _cb_handleVideobackendDisable(self, opcode, data):
+               self._handle_dump(self._cb_handleVideobackendDisable, opcode, data)
+               before_service = getBeforeService()
+               if before_service is not None:
+                       self._session.nav.playService(before_service)
+               return (0, "OK")
+
+       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)
+               #restoreResolution()
+               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()
+               #setResolution(1280, 720)
+               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)
+               #restoreResolution()
+               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 SetVolume(self, volume):
+               if self._max_volume < 0:
+                       self._max_volume = VolumeControl.instance.volctrl.getVolume()
+
+               self._max_volume += volume
+               if self._max_volume > 100:
+                       self._max_volume = 100
+               elif self._max_volume < 0:
+                       self._max_volume = 0
+
+               if self._soft_volume > 0:
+                       v = int((self._max_volume * self._soft_volume) / 100)
+                       VolumeControl.instance.volctrl.setVolume(v, v)
+               else:   VolumeControl.instance.volctrl.setVolume(self._max_volume, self._max_volume)
+
+       def _cb_handleDVBAppVolUp(self, opcode, data):
+               self._handle_dump(self._cb_handleDVBAppVolUp, opcode, data)
+               self.SetVolume(5)
+               return (0, "OK")
+
+       def _cb_handleDVBAppVolDown(self, opcode, data):
+               self._handle_dump(self._cb_handleDVBAppVolDown, opcode, data)
+               self.SetVolume(-5)
+               return (0, "OK")
+
+       def _cb_handleDVBAppSetVol(self, opcode, data):
+               self._handle_dump(self._cb_handleDVBAppSetVol, opcode, data)
+               if self._max_volume < 0:
+                       self._max_volume = VolumeControl.instance.volctrl.getVolume()
+               self._soft_volume = int(data)
+
+               v = 0
+               if self._soft_volume > 0 and self._max_volume > 0:
+                       v = int((self._max_volume * self._soft_volume) / 100)
+               VolumeControl.instance.volctrl.setVolume(v, v)
+               return (0, "OK")
+
        def _cb_handleGetChannelInfoForUrl(self, opcode, data):
                self._handle_dump(self._cb_handleGetChannelInfoForUrl, opcode, data)
                (sid, onid, tsid, name, orgid) = getChannelInfos()
@@ -457,19 +718,24 @@ class HandlerHbbTV(Handler):
                return (channel_list_size, struct.pack('!IIII', sid, onid, tsid, namelen) + name)
 
        def _cb_handleSetPageTitle(self, opcode, data):
-               self._handle_dump(self._cb_handleCloseHbbTVBrowser, opcode, data)
+               self._handle_dump(self._cb_handleSetPageTitle, opcode, data)
                if data.startswith('file://') or data.startswith('http://'):
                        return "OK"
                if self._on_set_title_cb is not None:
                        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):
+               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:
@@ -486,6 +752,9 @@ class HandlerHbbTV(Handler):
                before_service = getBeforeService()
                if before_service is not None:
                        self._session.nav.playService(before_service)
+                       self._vod_uri = None
+
+               #restoreResolution()
                return (0, "OK")
 
        def _cb_handleVODPlayerURI(self, opcode, data):
@@ -516,7 +785,8 @@ class HandlerHbbTV(Handler):
                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)
+                               print "Try to open vod"
                                self._vod_service = eServiceReference(4097, 0, url)
                                self._session.nav.playService(self._vod_service)
                                if self._vod_service is not None:
@@ -552,23 +822,29 @@ class HandlerHbbTV(Handler):
                        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>
                """
-       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
+               setResolution(1280, 720)
+               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,
+                       iPlayableService.evStart: self._serviceStarted,
+                       iPlayableService.evEOF: self._serviceEOF,
                })
 
                self._url = url
                self._use_ait = useAIT
+               self._profile = profile
                self._cb_closed_func = cbf
                self.onLayoutFinish.append(self._layoutFinished)
 
@@ -582,10 +858,63 @@ class HbbTVWindow(Screen, InfoBarNotifications):
                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()
+                       if(not l[0] and not p[0]):
+                               return (p[1], l[1])
+                       return (90000,90000)
+               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):
+               (position,length) = self.getVodPlayTime()
+               self._ssm.setStatus(length, length, 1)
+               print "service EOF"
+               self._currentServicePositionTimer.stop()
+
        def _layoutFinished(self):
+               global __gval__
+               __gval__.hbbtv_handelr._soft_volume = -1
+               self.setTitle(_('HbbTV Plugin'))
                command_util = getCommandUtil()
+               profile = self._profile
                (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)
@@ -613,58 +942,80 @@ class HbbTVWindow(Screen, InfoBarNotifications):
                        if self._cb_closed_func is not None:
                                self._cb_closed_func()
                except: pass
+               restoreResolution()
+               fbClass.getInstance().unlock()
                eRCInput.getInstance().unlock()
                self.close()
 
-       def _serviceForbiden(self):
-               global __gval__
-               real_url = MMSStreamURL().getLocationData(__gval__.hbbtv_handelr.getUrl())
-               print "Received URI :\n",real_url
-
-               if real_url is not None:
-                       __gval__.hbbtv_handelr.doRetryOpen(real_url.strip())
-
        def _cb_set_page_title(self, title=None):
                print "page title :",title
                if title is None:
                        return
                self.setTitle(title)
 
-class HbbTVHelper(Screen):
+class HbbTVHelper(Screen, InfoBarNotifications):
        skin =  """<screen name="HbbTVHelper" position="0,0" size="0,0" backgroundColor="transparent" flags="wfNoBorder" title=" "></screen>"""
        def __init__(self, session):
                global __gval__
                __gval__.hbbtv_handelr = HandlerHbbTV(session)
                __gval__.command_server = ServerFactory().doListenUnixTCP('/tmp/.sock.hbbtv.url', __gval__.hbbtv_handelr)
 
-               self._urls = None
-               self._stop_opera()
-               self._start_opera()
-
                Screen.__init__(self, session)
+               InfoBarNotifications.__init__(self)
+
                self._session = session
+
+               self._restart_opera()
+
                self._timer_infobar = eTimer()
                self._timer_infobar.callback.append(self._cb_registrate_infobar)
                self._timer_infobar.start(1000)
 
                self._excuted_browser = False
+               self._profile = 0
 
                __gval__.command_util = BrowserCommandUtil()
 
+               global _g_ssm_
+               if _g_ssm_ is None:
+                       _g_ssm_ = SimpleSharedMemory()
+                       _g_ssm_.doConnect()
+
+               self._callbackStartStop = None
+
+               self.__et = ServiceEventTracker(screen=self, eventmap={
+                               iPlayableService.evHBBTVInfo: self._cb_detectedAIT,
+                               iPlayableService.evUpdatedInfo: self._cb_updateInfo
+                       })
+               self._applicationList = None
+
+               self.mVuplusBox = False
+               issue = open("/etc/issue").read()
+               if(issue.startswith("Vuplus")):
+                       self.mVuplusBox = True
+
+       def _cb_detectedAIT(self):
+               name = self._cb_ready_for_ait()
+               if name is not None and self.mVuplusBox:
+                       from Screens.InfoBarGenerics import gHbbtvApplication
+                       gHbbtvApplication.setApplicationName(str(name))
+
+       def _cb_updateInfo(self):
+               if not self._excuted_browser:
+                       command_util = getCommandUtil()
+                       command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
+               if self.mVuplusBox:
+                       from Screens.InfoBarGenerics import gHbbtvApplication
+                       gHbbtvApplication.setApplicationName("")
+               #self._applicationList = None
+
        def _cb_registrate_infobar(self):
                if InfoBar.instance:
                        self._timer_infobar.stop()
-                       if self._cb_ready_for_ait not in InfoBar.instance.onReadyForAIT:
-                               InfoBar.instance.onReadyForAIT.append(self._cb_ready_for_ait)
                        if self._cb_hbbtv_activated not in InfoBar.instance.onHBBTVActivation:
                                InfoBar.instance.onHBBTVActivation.append(self._cb_hbbtv_activated)
 
-       def _cb_ready_for_ait(self, orgId=0):
-               if orgId == 0:
-                       if not self._excuted_browser:
-                               command_util = getCommandUtil()
-                               command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
-                       return
+       def _cb_ready_for_ait(self):
                setChannelInfo(None, None, None, None, None)
 
                service = self._session.nav.getCurrentService()
@@ -676,24 +1027,37 @@ class HbbTVHelper(Screen):
                        name = info.getName()
                        if name is None:
                                name = ""
-                       orgid   = 0
-                       namelen = len(name)
-                       for x in info.getInfoObject(iServiceInformation.sHBBTVUrl):
-                               if x[0] == 1 :
-                                       orgid = x[3]
-                                       break
-                       setChannelInfo(sid, onid, tsid, name, orgid)
+
+                       pmtid = info.getInfo(iServiceInformation.sPMTPID)
+                       demux = info.getInfoString(iServiceInformation.sLiveStreamDemuxId)
+
+                       from aitreader import eAITSectionReader
+                       reader = eAITSectionReader(demux, pmtid, sid)
+                       if reader.doOpen(info, self.mVuplusBox):
+                               reader.doParseApplications()
+                               reader.doDump()
+                       else:   print "no data!!"
+
+                       try:
+                               self._applicationList = reader.getApplicationList()
+                               if len(self._applicationList) > 0:
+                                       orgid = int(self._applicationList[0]["orgid"])
+                                       setChannelInfo(sid, onid, tsid, name, orgid)
+                                       return self._applicationList[0]["name"]
+                       except: pass
+               return None
 
        def _cb_hbbtv_activated(self, title=None, url=None):
                if not self._is_browser_running():
-                       message = "HbbTV Browser was not running.\nPlease running browser before start HbbTV Application."
-                       self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
+                       message = _("HbbTV Browser was not running.\nPlease running browser before start HbbTV Application.")
+                       self._session.open(MessageBox, message, MessageBox.TYPE_INFO)
                        return
                service = self._session.nav.getCurrentlyPlayingServiceReference()
                setBeforeService(service)
                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
@@ -705,14 +1069,18 @@ class HbbTVHelper(Screen):
                        print "already excuted opera browser!!"
                        return
 
-               use_ait = False
-               for x in self._urls:
-                       control_code = x[0]
-                       tmp_url = x[2]
+               if isNeedRestart():
+                       self._restart_opera()
+                       time.sleep(2)
+                       setNeedRestart(False)
+
+               for x in self._applicationList:
+                       control_code = int(x["control"])
+                       tmp_url = x["url"]
                        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
@@ -720,53 +1088,65 @@ class HbbTVHelper(Screen):
        def _start_opera(self):
                if not self._is_browser_running():
                        global HBBTVAPP_PATH
-                       start_command = '%s/launcher start'%(HBBTVAPP_PATH)
+                       global __gval__
+                       start_command = '%s/launcher start %d %d'%(HBBTVAPP_PATH, __gval__.resX, __gval__.resY)
                        os.system(start_command)
+               return True
 
        def _stop_opera(self):
                global HBBTVAPP_PATH
                try:    os.system('%s/launcher stop'%(HBBTVAPP_PATH))
                except: pass
 
+       def _restart_opera(self):
+               global HBBTVAPP_PATH
+               global __gval__
+               try:    os.system('%s/launcher restart %d %d'%(HBBTVAPP_PATH, __gval__.resX, __gval__.resY))
+               except: pass
+               return True
+
        def getStartHbbTVUrl(self):
-               url, self._urls = None, None
-                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
-                               url = u[2]
+               url, self._profile = None, 0
+               if self._applicationList is not None:
+                       self._profile = self._applicationList[0]["profile"]
+                       url = self._applicationList[0]["url"]
                if url is None:
+                       service = self._session.nav.getCurrentService()
+                       info = service and service.info()
                        url = info.getInfoString(iServiceInformation.sHBBTVUrl)
                return url
 
        def showApplicationSelectionBox(self):
                applications = []
+
                if self.getStartHbbTVUrl():
-                       for x in self._urls:
-                               applications.append((x[1], x))
-               else: applications.append(("No detected HbbTV applications.", None))
+                       for x in self._applicationList:
+                               applications.append((x["name"], x))
+               else: applications.append((_("No detected HbbTV applications."), None))
                self._session.openWithCallback(self._application_selected, ChoiceBox, title=_("Please choose an HbbTV application."), list=applications)
 
        def _application_selected(self, selected):
+               print selected
                try:
                        if selected[1] is None: return
-                       self._cb_hbbtv_activated(selected[1][1], selected[1][2])
+                       self._cb_hbbtv_activated(selected[1]["name"], selected[1]["url"])
                except Exception, ErrMsg: print ErrMsg
 
-       def showBrowserConfigBox(self):
+       def showBrowserConfigBox(self, callback=None):
                start_stop_mode = []
+               self._callbackStartStop = callback
                if self._is_browser_running():
-                       start_stop_mode.append(('Stop',None))
-               else:   start_stop_mode.append(('Start',None))
+                       start_stop_mode.append((_('Stop'),'Stop'))
+               else:   start_stop_mode.append((_('Start'),'Start'))
                self._session.openWithCallback(self._browser_config_selected, ChoiceBox, title=_("Please choose one."), list=start_stop_mode)
 
        def _browser_config_selected(self, selected):
                if selected is None:
                        return
+               if self._callbackStartStop is not None:
+                       self._callbackStartStop()
                try:
-                       mode = selected[0]
+                       mode = selected[1]
                        if mode == 'Start':
                                if not self._is_browser_running():
                                        self._start_opera()
@@ -783,7 +1163,630 @@ class HbbTVHelper(Screen):
                        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._type  = None
+               self._keymap = None
+               self._read()
+       def _read(self):
+               f = open(self._settingFileName)
+               for line in f.readlines():
+                       if line.startswith('start='):
+                               tmp = line[6:len(line)-1].split()
+                               self._start = tmp[0]
+                               if len(tmp) > 1:
+                                       self._type = int(tmp[1])
+                               else:   self._type = 0
+                       elif line.startswith('keymap='):
+                               self._keymap = line[7:len(line)-1]
+               f.close()
+       def _write(self):
+               tmpstr = []
+               tmpstr.append('start=%s %d\n' % (self._start, self._type))
+               tmpstr.append('keymap=%s\n' % (self._keymap))
+               f = open(self._settingFileName, 'w')
+               f.writelines(tmpstr)
+               f.close()
+       def setData(self, start, types=0, keymap="us-rc"):
+               self._start = start
+               self._type = types
+               self._keymap = keymap
+               self._write()
+       def getData(self):
+               return {
+                       'start':self._start,
+                       'type':self._type,
+                       'keymap':self._keymap,
+               }
+
+class OperaBrowserPreferenceWindow(ConfigListScreen, Screen):
+       skin=   """
+               <screen position="center,120" size="600,350" title="Preference">
+                       <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._keymapType = None
+               self.makeMenuEntry()
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setTitle(_('Preference'))
+
+       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
+               mode = 0
+               if url.find('/usr/local/manual') > 0:
+                       mode = 1
+               self._keymapType = self.menuItemKeyboardLayout.value
+               OperaBrowserSetting().setData(url, mode, self._keymapType)
+               command_util = getCommandUtil()
+               command_util.sendCommand('OP_BROWSER_NEED_RELOAD_KEYMAP')
+               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 getKeymapTypeList(self):
+               types = []
+               for f in os.listdir("/usr/local/hbb-browser/keymap"):
+                       filesplit = f.split('.')
+                       if len(filesplit) < 2:
+                               continue
+                       types.append((filesplit[1], filesplit[1]))
+               types.sort()
+               return types
+
+       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)
+
+               kl = self.getKeymapTypeList()
+
+               try:
+                       d = OperaBrowserSetting().getData()
+                       self._startPageUrl = d['start']
+                       self._keymapType = d['keymap']
+                       #d['type']
+               except: self._startPageUrl = 'http://vuplus.com'
+               self.updateStartPageUrl()
+
+               if self._keymapType is None or len(self._keymapType) == 0:
+                       self._keymapType = "us-rc"
+               self.menuItemKeyboardLayout = ConfigSelection(default=self._keymapType, choices = kl)
+               self.menuEntryKeyboardLayout = getConfigListEntry(_("Keyboard Layout"), self.menuItemKeyboardLayout)
+               self.resetMenuList()
+
+       def resetMenuList(self):
+               self.menulist = []
+               self.menulist.append(self.menuEntryStartpage)
+               self.menulist.append(self.menuEntryKeyboardLayout)
+
+               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, 0)
+                       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,120" 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)
+
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setTitle(_('Bookmark'))
+
+       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, data.mType)
+               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, 0)
+                               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, 0)
+                               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
+               mode = data.mType
+               if mode:
+                       lang = language.getLanguage()
+                       if lang == 'ru_RU' and os.path.exists('/usr/local/manual/ru_RU'):
+                               url = '/usr/local/manual/ru_RU/main.html'
+                       elif lang == 'de_DE' and os.path.exists('/usr/local/manual/de_DE'):
+                               url = '/usr/local/manual/de_DE/main.html'
+               self.close((url, mode))
+       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)
+
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setTitle(_('Browser Help'))
+
+       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
@@ -791,32 +1794,50 @@ class OperaBrowser(Screen):
        SUBMENULIST_HEIGHT  = 25
        SUBMENULIST_NEXT    = 2
 
+       # menulist->position->y : MENUBAR_ITEM_HEIGHT+30
+       # menulist->size->x     : SUBMENULIST_WIDTH
+       # submenulist->position->x : SUBMENULIST_WIDTH+50+SUBMENULIST_NEXT
+       # submenulist->position->y : MENUBAR_ITEM_HEIGHT+30
+       # submenulist->size->x  : SUBMENULIST_WIDTH
+
+       size = getDesktop(0).size()
+       WIDTH  = int(size.width())
+       HEIGHT = int(size.height())
        skin =  """
-               <screen name="Opera Browser" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="Opera Browser">
+               <screen name="OperaBrowser" position="0,0" size="%(width)d,%(height)d" 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="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)
-
-       MENUITEMS_LIST =[[('Open Location', None), ('Start/Stop',None), ('Exit', None)],
-                        [('About', None)]]
-       def __init__(self, session):
+                       <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,60" size="200,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
+                       <widget name="submenulist" position="252,60" size="200,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
+                       <widget name="bottomArea" position="0,%(bottom_pos_y)d" size="%(bottom_size_x)d,80" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
+               </screen>
+               """ % { 'width'  :WIDTH,
+                       'height' :HEIGHT,
+                       'bottom_pos_y'  :HEIGHT-80,
+                       'bottom_size_x' :WIDTH }
+
+       COMMAND_MAP = {}
+       MENUITEMS_LIST =[]
+       def __init__(self, session, url=None, isWebAppMode=False):
                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
-                       ,"menu"        : self.keyCancel
+                       ,"menu"        : self.keyMenu
                }, -2)
 
+               self.UpdateLanguageCB()
+
+               self._terminatedBrowser = True
+               self._enableKeyEvent = True
+               self._currentPageUrl = None
+               self._currentPageTitle = None
                self.menubarCurrentIndex = 0
                self.lvMenuItems = []
                self.lvSubMenuItems = []
@@ -824,7 +1845,8 @@ class OperaBrowser(Screen):
                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())
@@ -840,25 +1862,54 @@ class OperaBrowser(Screen):
                self._onCloseTimer = eTimer()
                self._onCloseTimer.callback.append(self._cb_onClose)
 
+               self.paramUrl = url
+               self.paramIsWebAppMode = isWebAppMode
+               language.addCallback(self.UpdateLanguageCB)
+
+       def UpdateLanguageCB(self):
+               # modify menu
+               self.MENUITEMS_LIST = [
+                       [(_('Open Startpage'), None), (_('Open URL'), None), (_('Start/Stop'),None), (_('Exit'), None)],
+                       [(_('Bookmark'), None), (_('Preference'), None)],
+                       [(_('About'), None), (_('Help'), None)]]
+               self.COMMAND_MAP = {}
+               self.COMMAND_MAP[_('Exit')] = self._cmd_on_Exit
+               self.COMMAND_MAP[_('Help')] = self._cmd_on_Help
+               self.COMMAND_MAP[_('About')] = self._cmd_on_About
+               self.COMMAND_MAP[_('Open URL')] = self._cmd_on_OpenUrl
+               self.COMMAND_MAP[_('Start/Stop')] = self._cmd_on_StartStop
+               self.COMMAND_MAP[_('Bookmark')] = self._cmd_on_Bookmark
+               self.COMMAND_MAP[_('Preference')] = self._cmd_on_Preference
+               self.COMMAND_MAP[_('Return')] = self._cmd_on_ReturnToBrowser
+               self.COMMAND_MAP[_('Open Startpage')] = self._cmd_on_OpenStartpage
+
        def enableRCMouse(self, mode): #mode=[0|1]|[False|True]
                rcmouse_path = "/proc/stb/fp/mouse"
                if os.path.exists(rcmouse_path):
                        os.system("echo %d > %s" % (mode, rcmouse_path))
 
        def layoutFinished(self):
-               self["menuitemFile"].setText("File")
-               self["menuitemHelp"].setText("Help")
+               self["menuitemFile"].setText(_("File"))# modify menu
+               self["menuitemTool"].setText(_("Tools"))
+               self["menuitemHelp"].setText(_("Help"))
 
                self["menulist"].hide()
                self["submenulist"].hide()
 
-               self["bottomArea"].setText("Opera Web Browser Plugin v0.1")
-               self.setTitle("BrowserMain")
+               self["bottomArea"].setText(_("Opera Web Browser Plugin v1.0"))
+               self.setTitle(_("BrowserMain"))
                self.selectMenuitem()
 
+               if self.paramUrl is not None:
+                       self.keyMenu()
+                       if self.paramIsWebAppMode:
+                               self.cbUrlText(data=self.paramUrl, mode=1, opcode='OP_BROWSER_OPEN_YOUTUBETV')
+                       else:   self.cbUrlText(data=self.paramUrl, mode=1)
+
        def selectMenuitem(self):
-               tmp = [self["menuitemFile"], self["menuitemHelp"]]
+               tmp = [self["menuitemFile"], self["menuitemTool"], self["menuitemHelp"]]# modify menu
                self["menuitemFile"].setForegroundColorNum(0)
+               self["menuitemTool"].setForegroundColorNum(0)
                self["menuitemHelp"].setForegroundColorNum(0)
                tmp[self.menubarCurrentIndex].setForegroundColorNum(1)
 
@@ -869,7 +1920,10 @@ class OperaBrowser(Screen):
                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):
@@ -917,21 +1971,38 @@ class OperaBrowser(Screen):
                        if self._on_setPageTitle in command_server.onSetPageTitleCB:
                                command_server.onSetPageTitleCB.remove(self._on_setPageTitle)
                except Exception, ErrMsg: pass
-               self._on_setPageTitle('Opera Browser')
+               self._on_setPageTitle(_('Opera Browser'))
                self.enableRCMouse(False)
                self.toggleMainScreen()
+               restoreResolution()
+               fbClass.getInstance().unlock()
                eRCInput.getInstance().unlock()
+               self._terminatedBrowser = True
+               self._enableKeyEvent = True
+               #if not self.toggleListViewFlag:
+               #       self.keyDown()
+
+               self._currentPageUrl = ''
+               if self.paramUrl is not None:
+                       self.keyCancel()
+               else:
+                       self.keyRight()
+                       self.keyLeft()
 
        def _on_setPageTitle(self, title=None):
-               print "page title :",title
+               print "Title :",title
                if title is None:
                        return
                self.setTitle(title)
 
-       def cbUrlText(self, data=None):
-               print "Inputed Url :", data
+       def cbUrlText(self, data=None, mode=0, opcode='OP_BROWSER_OPEN_URL'):
+               global _g_helper
+               if not _g_helper._is_browser_running():
+                       return
+               print "Inputed Url :", data, mode
                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)
@@ -939,41 +2010,95 @@ class OperaBrowser(Screen):
                        command_server.onHbbTVCloseCB.append(self._on_close_window)
                self.toggleMainScreen()
                self.enableRCMouse(True)
+
+               fbClass.getInstance().lock()
                eRCInput.getInstance().lock()
+
+               #setResolution(1280, 720)
+
                command_util = getCommandUtil()
-               command_util.sendCommand('OP_BROWSER_OPEN_URL', data)
+               command_util.sendCommand(opcode, data, mode)
+               self._terminatedBrowser = False
+               self._enableKeyEvent = False
+
+               global __gval__
+               __gval__.hbbtv_handelr._soft_volume = -1
 
        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
+               (url, mode) = data
                global _g_helper
                if not _g_helper._is_browser_running():
-                       message = "Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu."
+                       message = _("Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu.")
                        self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
                        return
-               self.session.openWithCallback(self.cbUrlText, VirtualKeyBoard, title=("Please enter URL here"), text='http://')
+               self.cbUrlText(url, mode)
+
+       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.")
+                       self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
+                       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 _cb_cmdOnStartSTop(self):
+               self.keyMenu()
        def _cmd_on_StartStop(self):
                global _g_helper
                if _g_helper is None: 
                        return
-               _g_helper.showBrowserConfigBox()
-       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
-               }
+               _g_helper.showBrowserConfigBox(self._cb_cmdOnStartSTop)
+
+       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
+               mode = 0
+               start = 'http://vuplus.com'
                try:
-                       cmd_map[command]()
+                       d = OperaBrowserSetting().getData()
+                       start = d['start']
+                       mode = d['type']
                except: pass
+               self.cbUrlText(start, mode)
+       def _cmd_on_ReturnToBrowser(self):
+               self.keyCancel()
+
+       def _cmd_on_Help(self):
+               self.session.open(BrowserHelpWindow)
+
+       def doCommand(self, command):
+               try:
+                       self.COMMAND_MAP[command]()
+               except Exception, ErrMsg: print ErrMsg
 
        def keyOK(self):
+               if not self.toggleMainScreenFlag:
+                       self.keyMenu()
+                       return
                if not self.toggleListViewFlag:
                        self.keyDown()
                        return
@@ -985,8 +2110,8 @@ class OperaBrowser(Screen):
 
        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()
@@ -1001,8 +2126,11 @@ class OperaBrowser(Screen):
                        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:
@@ -1019,6 +2147,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()
+                       return
+               self.currentListView.pageUp()
+               self.keyUp()
+               self.keyRight()
+               self.keyDown()
 
        def keyDown(self):
                if not self.toggleMainScreenFlag:
@@ -1045,19 +2178,286 @@ class OperaBrowser(Screen):
                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()
+                       #setResolution(1280, 720)
+                       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()
 
+       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()
+
+config.plugins.youtubetv = ConfigSubsection()
+config.plugins.youtubetv.showhelp = ConfigYesNo(default = False)
+config.plugins.youtubetv.uri = ConfigText(default = "http://www.youtube.com/tv", visible_width = 50, fixed_size = False)
+class YoutubeTVWindow(Screen, HelpableScreen):
+        skin = """
+                <screen name="YoutubeTVWindow" position="center,center" size="550,160" title="Start YouTube TV" >
+                       <widget name="infomation" position="5,0" size="540,80" valign="center" halign="center" font="Regular;20" />
+                       <widget name="startdesc" position="10,80" size="395,40" valign="center" font="Regular;20" />
+                       <widget name="helpdesc" position="10,120" size="395,40" valign="center" font="Regular;20" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="400,80" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="400,120" size="140,40" alphatest="on" />
+                       <widget source="key_green" render="Label" position="400,80" 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="400,120" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
+                </screen>
+               """
+        def __init__(self, session):
+                Screen.__init__(self, session)
+               HelpableScreen.__init__(self)
+
+               self["actions"] = ActionMap(["WizardActions", "DirectionActions", "OkCancelActions","ColorActions", "EPGSelectActions",], {
+                               "cancel": self.keyCancel,
+                               "red"   : self.keyCancel,
+                               "green" : self.keyGreen,
+                               "yellow": self.keyYellow,
+                       },-2)
+
+               self["key_green"]  = StaticText(_("Start"))
+               self["key_yellow"] = StaticText(_("Help"))
+
+               self["infomation"] = Label()
+               self["startdesc"]  = Label()
+               self["helpdesc"]   = Label()
+
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setTitle(_('Start YouTube TV'))
+               self["infomation"].setText(_("YouTube TV is a new way to watch YouTube videos on Vu+"))
+               self["startdesc" ].setText(_("* Start YouTube TV"))
+               self["helpdesc"  ].setText(_("* RC Help"))
+
+       def setHelpModeActions(self):
+               self.helpList = []
+               self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
+                       "ok"    : (self.keyPass, _("Play ther selected the video")),
+                       "cancel": (self.keyPass, _("Exit the YouTube TV")),
+               })
+               self["EventViewActions"] = HelpableActionMap(self, "EventViewActions", {
+                       "pageUp"    : (self.keyPass, _("Move up")),
+                       "pageDown"  : (self.keyPass, _("Move down")),
+                       "prevEvent" : (self.keyPass, _("Move left")),
+                       "nextEvent" : (self.keyPass, _("Move right")),
+               })
+               self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
+                       "info"        : (self.keyPass, _("Search a video")),
+                       "nextService" : (self.keyPass, _("Skip forward 10 sec")),
+                       "prevService" : (self.keyPass, _("Skip backward 10 sec")),
+               })
+               self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions", {
+                       "play"  : (self.keyPass, _("Play current video")),
+                       "pause" : (self.keyPass, _("Pause current video")),
+                       "stop"  : (self.keyPass, _("Stop current video")),
+               })
+               self["ColorActions"] = HelpableActionMap(self, "ColorActions", {
+                       "red"   : (self.keyPass, _("Back")),
+               })
+               self.showHelp()
+
+       def keyPass(self):
+               pass
+       def keyCancel(self):
+               config.plugins.youtubetv.showhelp.cancel()
+               self.close(False)
+       def keyGreen(self):
+               config.plugins.youtubetv.showhelp.save()
+               config.plugins.youtubetv.save()
+               config.plugins.save()
+               self.close(True)
+       def keyYellow(self):
+               self.setHelpModeActions()
+       def keyBlue(self):
+               if config.plugins.youtubetv.showhelp.value == True :
+                       config.plugins.youtubetv.showhelp.setValue(False)
+               else:   config.plugins.youtubetv.showhelp.setValue(True)
+
+class YoutubeTVSettings(ConfigListScreen, Screen):
+    skin=   """
+       <screen position="center,center" size="600,140" title="YouTube TV Settings">
+           <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" />
+       </screen>
+       """
+    def __init__(self, session):
+       self.session = session
+       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["key_red"]   = StaticText(_("Cancel"))
+       self["key_green"] = StaticText(_("Save"))
+
+       self.makeConfigList()
+       self.onLayoutFinish.append(self.layoutFinished)
+
+    def layoutFinished(self):
+       self.setTitle(_('YouTube TV Settings'))
+
+    def keyGreen(self):
+       config.plugins.youtubetv.showhelp.save()
+       config.plugins.youtubetv.uri.save()
+       config.plugins.youtubetv.save()
+       config.plugins.save()
+       self.close()
+    def keyRed(self):
+       config.plugins.youtubetv.showhelp.cancel()
+       config.plugins.youtubetv.uri.cancel()
+       self.close()
+
+    def keyLeft(self):
+       ConfigListScreen.keyLeft(self)
+
+    def keyRight(self):
+       ConfigListScreen.keyRight(self)
+
+    def makeConfigList(self):
+       self.menulist = []
+       entryUri = getConfigListEntry(_("YouTube TV URL"), config.plugins.youtubetv.uri)
+       entryShowHelp = getConfigListEntry(_("Do not show YouTube TV Stater again"), config.plugins.youtubetv.showhelp)
+       self.menulist.append(entryUri)
+       self.menulist.append(entryShowHelp)
+
+       self["config"].list = self.menulist
+       self["config"].l.setList(self.menulist)
+
 def auto_start_main(reason, **kwargs):
        if reason:
                command_server = getCommandServer()
                command_server.stop()
 
+from  Screens.HelpMenu import HelpableScreen
 def session_start_main(session, reason, **kwargs):
+       fbClass.getInstance().unlock()
+       eRCInput.getInstance().unlock()
+
+       from enigma import getDesktop
+       desktopSize = getDesktop(0).size()
+       setDefaultResolution(desktopSize.width(), desktopSize.height())
+
        global _g_helper
        _g_helper = session.open(HbbTVHelper)
 
+       HelpableScreen.__init__ = HelpableScreen__init__
+       HelpableScreen.session = session
+
+def HelpableScreen__init__(self):
+       if isinstance(self, HelpableScreen):
+               HelpableScreen.showManual = showManual
+
+               self["helpActions"] = ActionMap(["HelpbuttonActions"], {
+                       "help_b" : self.showHelp,
+                       "help_l" : self.showManual, 
+               }, -2)
+
+_g_clearBrowserDataTimer = eTimer()
+def showManual(self):
+       if not os.path.exists('/usr/local/manual'):
+               return
+
+       url = 'file:///usr/local/manual/main.html'
+       lang = language.getLanguage()
+       if lang == 'ru_RU' and os.path.exists('/usr/local/manual/ru_RU'):
+               url = 'file:///usr/local/manual/ru_RU/main.html'
+       elif lang == 'de_DE' and os.path.exists('/usr/local/manual/de_DE'):
+               url = 'file:///usr/local/manual/de_DE/main.html'
+
+       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(self.session.openWithCallback(clearBrowserData, OperaBrowser, url))
+
+_g_backupSession = None
+def showYoutubeTV(session, **kwargs):
+       def _do_clean():
+               _g_clearBrowserDataTimer.stop()
+               try:    _g_clearBrowserDataTimer.callback.remove(_do_clean)
+               except: pass
+               setPluginBrowser(None)
+               global _g_backupSession
+               
+               service = getBeforeService()
+               if service is not None:
+                       _g_backupSession.nav.playService(eServiceReference(service))
+                       _g_backupSession = None
+       def clearBrowserData():
+               _g_clearBrowserDataTimer.callback.append(_do_clean)
+               _g_clearBrowserDataTimer.start(50)
+       def cbYoutubeTVClose(ret):
+               if ret:
+                       global _g_backupSession
+                       _g_backupSession = session
+                       service = session.nav.getCurrentlyPlayingServiceReference()
+                       if service is not None:
+                               setBeforeService(service.toString())
+                               session.nav.stopService()
+                       else:   setBeforeService(service)
+                       setPluginBrowser(session.openWithCallback(clearBrowserData, OperaBrowser, config.plugins.youtubetv.uri.value, True))
+       if config.plugins.youtubetv.showhelp.value == True:
+               cbYoutubeTVClose(True)
+       else:   session.openWithCallback(cbYoutubeTVClose, YoutubeTVWindow)
+
+def youtube_setting_main(session, **kwargs):
+       session.open(YoutubeTVSettings)
+
+def start_menu_main(menuid, **kwargs):
+       if menuid == "mainmenu":
+               return [(_("YouTube TV"), showYoutubeTV, "youtube_tv", 46)]
+       return []
+
 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
@@ -1072,11 +2472,14 @@ def plugin_extension_browser_config(session, **kwargs):
        _g_helper.showBrowserConfigBox()
 
 def Plugins(path, **kwargs):
-       return  [
-               PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=auto_start_main),
-               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)
-               ]
+       l = []
+       l.append(PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=auto_start_main))
+       l.append(PluginDescriptor(name=_("YouTube TV"), where=PluginDescriptor.WHERE_MENU, fnc=start_menu_main))
+       l.append(PluginDescriptor(name=_("YouTube TV Settings"), where=PluginDescriptor.WHERE_PLUGINMENU, fnc=youtube_setting_main))
+       l.append(PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10))
+       l.append(PluginDescriptor(name=_("HbbTV Applications"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_start_application))
+       l.append(PluginDescriptor(name=_("Browser Start/Stop"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_browser_config))
+       l.append(PluginDescriptor(name=_("Opera Web Browser"), description=_("start opera web browser"), where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=True, fnc=plugin_start_main))
+
+       return l