From 8e45cdb2e633bee61c878f4a01bd2eb43025a3fe Mon Sep 17 00:00:00 2001 From: kos Date: Mon, 8 Oct 2012 15:11:36 +0900 Subject: [PATCH] [browser] update. - bookmark manager. - startpage configuration. - switch to mouse/keyboard mode. - help menu. - virtual keyboard on the browser. - menu on the browser. --- lib/python/Plugins/Extensions/HbbTV/Makefile.am | 1 + lib/python/Plugins/Extensions/HbbTV/bookmark.py | 268 ++++++++ lib/python/Plugins/Extensions/HbbTV/plugin.py | 775 +++++++++++++++++++++++- 3 files changed, 1014 insertions(+), 30 deletions(-) create mode 100644 lib/python/Plugins/Extensions/HbbTV/bookmark.py diff --git a/lib/python/Plugins/Extensions/HbbTV/Makefile.am b/lib/python/Plugins/Extensions/HbbTV/Makefile.am index 18e39a1..7449060 100644 --- a/lib/python/Plugins/Extensions/HbbTV/Makefile.am +++ b/lib/python/Plugins/Extensions/HbbTV/Makefile.am @@ -4,6 +4,7 @@ SUBDIRS = meta install_PYTHON = \ __init__.py \ + bookmark.py \ plugin.py diff --git a/lib/python/Plugins/Extensions/HbbTV/bookmark.py b/lib/python/Plugins/Extensions/HbbTV/bookmark.py new file mode 100644 index 0000000..0dc9ade --- /dev/null +++ b/lib/python/Plugins/Extensions/HbbTV/bookmark.py @@ -0,0 +1,268 @@ +class BookmarkData: + def __init__(self, _id, _title, _url, _parent): + self.mId = _id + self.mTitle = _title + self.mUrl = _url + self.mParent = _parent + def dump(self, _intent=' '): + print "%s-> %d, %s, %s, %d" % (_intent, self.mId, self.mTitle, self.mUrl, self.mParent) + +class CategoryData: + def __init__(self, _id, _name): + self.mId = _id + self.mName = _name + self.mBookmarks = {} + + def setBookmarks(self, _bookmarks): + self.mBookmarks = _bookmarks + + def appendBookmark(self, _bookmark): + self.mBookmarks[_bookmark.mId] = _bookmark + + def dump(self): + print " -> %d, %s" % (self.mId, self.mName) + for key in self.mBookmarks.iterkeys(): + self.mBookmarks[key].dump(' ') + +import ConfigParser +class SimpleConfigParser: + def __init__(self): + self.mFileName = None + self.mConfig = None + self.mCategoryCurrentIdx = 0 + self.mBookmarkCurrentIdx = 0 + self.mDataValid = False + self.mPopulateValid = False + + def _read(self): + if self.mDataValid: + return + print "populate!!" + self.mConfig.read(self.mFileName) + + self.mCategoryCurrentIdx = self.getNumber('__SYS__', 'category_current_idx') + self.mBookmarkCurrentIdx = self.getNumber('__SYS__', 'bookmark_current_idx') + self.mDataValid = True + + def _save(self): + with open(self.mFileName, 'wb') as bookmarkFile: + self.mConfig.write(bookmarkFile) + self.mDataValid = False + self.mPopulateValid = False + + def _del(self, _section, _option=None): + #print _section, ' :', _option + if _option is None: + if not self.exist(_section): + return + self.mConfig.remove_section(_section) + return + if not self.exist(_section, _option): + return + self.mConfig.remove_option(_section, _option) + + def _get(self, _section, _option, _default): + try: + data = self.mConfig.get(_section, _option) + except Exception, e: + #print e + return _default + else : return data + + def _set(self, _section, _option, _value): + self.mConfig.set(_section, _option, _value) + + def exist(self, _section, _option=None): + if _option is None: + return self.mConfig.has_section(_section) + return self.mConfig.has_option(_section, _option) + + def setNumber(self, _section, _option, _value): + self._set(_section, _option, str(_value)) + + def setString(self, _section, _option, _value): + self._set(_section, _option, _value) + + def getNumber(self, _section, _option, _default=0): + return int(self._get(_section, _option, _default)) + + def getString(self, _section, _option, _default=''): + return self._get(_section, _option, _default) + + def delOption(self, _section, _option): + self._del(_section, _option) + + def addSection(self, _section): + self.mConfig.add_section(_section) + + def delSection(self, _section): + self._del(_section) + + def init(self, _fileName): + self.mFileName = _fileName + self.mConfig = ConfigParser.RawConfigParser() + if self.mConfig is None: + return False + self._read() + return True + +class BookmarkManager(SimpleConfigParser): + _instance = None + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super(Singleton, cls).__new__( + cls, *args, **kwargs) + return cls._instance + + def __init__(self, _dbFileName): + SimpleConfigParser.__init__(self) + + self.mBookmarkRoot = None + self.mDebugEnable = False + + import os + if not os.path.exists(_dbFileName): + os.system('echo "[__SYS__]" > %s'%(_dbFileName)) + os.system('echo "category_current_idx = 0" >> %s'%(_dbFileName)) + os.system('echo "bookmark_current_idx = 0" >> %s'%(_dbFileName)) + + self.init(_dbFileName) + + def message(self, format, params=None): + if not self.mDebugEnable: + return + if params is None: + print format + else: print format % (params) + + def getBookmark(self, _title): + self.populate() + for key in self.mBookmarkRoot.iterkeys(): + for key2 in self.mBookmarkRoot[key].mBookmarks.iterkeys(): + if self.mBookmarkRoot[key].mBookmarks[key2].mTitle == _title: + return 'b-%d' % (self.mBookmarkRoot[key].mBookmarks[key2].mId) + return None + + def addBookmark(self, _title, _url, _parent): + if self.getBookmark(_title) is not None: + return False + i = self.mBookmarkCurrentIdx + 1 + s = "b-%d" % (i,) + self.message("add bookmark : %s, %s, %d", (_title, _url, _parent,)) + + self.mConfig.add_section(s) + self.setNumber(s, 'id', i) + self.setString(s, 'title', _title) + self.setString(s, 'url', _url) + self.setNumber(s, 'parent', _parent) + self.setNumber('__SYS__', 'bookmark_current_idx', i) + self._save() + + return True + + def deleteBookmark(self, _id): + self.populate() + self.message("delete bookmark : %d", (_id,)) + self.delSection('b-%d' % (_id,)) + self._save() + + def updateBookmark(self, _bookmark): + self.populate() + s = "b-%d" % (_bookmark.mId) + self.message("update bookmark : %s, %s, %d", (_bookmark.mTitle, _bookmark.mUrl, _bookmark.mParent,)) + self.setString(s, 'title', _bookmark.mTitle) + self.setString(s, 'url', _bookmark.mUrl) + self.setNumber(s, 'parent', _bookmark.mParent) + self._save() + + def getCategory(self, _name): + self.populate() + for key in self.mBookmarkRoot.iterkeys(): + if self.mBookmarkRoot[key].mName == _name: + return 'c-%d' % (self.mBookmarkRoot[key].mId) + return None + + def addCategory(self, _name): + if self.getCategory(_name) is not None: + return False + self.message("add category : %s", (_name,)) + i = self.mCategoryCurrentIdx + 1 + s = "c-%d" % (i) + + self.mConfig.add_section(s) + self.setNumber(s, 'id', i) + self.setNumber(s, 'name', _name) + self.setNumber('__SYS__', 'category_current_idx', i) + self._save() + + return True + + def deleteCategory(self, _id): + self.populate() + self.message("delete category : %d", (_id,)) + try: + for key in self.mBookmarkRoot[_id].mBookmarks.iterkeys(): + self.delSection('b-%d' % (key,)) + except: pass + self.delSection('c-%d' % (_id,)) + self._save() + + def updateCategory(self, _category): + self.populate() + self.message("update category : %s", (_category.mName,)) + s = "c-%d" % (_category.mId) + self.setNumber(s, 'name', _category.mName) + self._save() + + def populate(self): + cx, bx = 0, 0 + categoryList = {} + self.message("populate : %d, %d", (self.mPopulateValid, self.mDataValid)) + + self._read() + if self.mPopulateValid: + return + + while cx <= self.mCategoryCurrentIdx: + s = 'c-%d' % (cx,) + i = self.getNumber(s, 'id', -1) + if i != -1: + n = self.getString(s, 'name') + categoryList[i] = CategoryData(i, n) + cx += 1 + sorted(categoryList) + while bx <= self.mBookmarkCurrentIdx: + s = 'b-%d' % (bx,) + i = self.getNumber(s, 'id', -1) + if i != -1: + t = self.getString(s, 'title') + u = self.getString(s, 'url') + p = self.getNumber(s, 'parent') + try: + categoryList[p].appendBookmark(BookmarkData(i, t, u, p)) + except Exception, e: self._del(s) + bx += 1 + for key in categoryList.iterkeys(): + sorted(categoryList[key].mBookmarks) + self.mBookmarkRoot = categoryList + self.mPopulateValid = True + self.dump() + + def getBookmarkRoot(self): + self.populate() + return self.mBookmarkRoot + + def dump(self): + if not self.mDebugEnable: + return + self.populate() + print "-- snapshot --" + for key in self.mBookmarkRoot.iterkeys(): + self.mBookmarkRoot[key].dump() + print "--------------" + + @staticmethod + def getInstance(): + return BookmarkManager('/usr/lib/enigma2/python/Plugins/Extensions/HbbTV/bookmark.ini') + + diff --git a/lib/python/Plugins/Extensions/HbbTV/plugin.py b/lib/python/Plugins/Extensions/HbbTV/plugin.py index d67c281..b9ddd36 100644 --- a/lib/python/Plugins/Extensions/HbbTV/plugin.py +++ b/lib/python/Plugins/Extensions/HbbTV/plugin.py @@ -6,21 +6,24 @@ 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 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.VolumeControl import VolumeControl +from Components.Pixmap import Pixmap from Components.config import config, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile, getCharValue from enigma import eTimer, eConsoleAppContainer, getDesktop, eServiceReference, iPlayableService, iServiceInformation, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, getPrevAsciiCode, eRCInput, fbClass +from bookmark import BookmarkManager, BookmarkData, CategoryData + import os, struct, threading, stat, select, time, socket, select strIsEmpty = lambda x: x is None or len(x) == 0 @@ -47,8 +50,16 @@ class GlobalValues: packet_hl = struct.calcsize(packet_h) need_restart = False + plugin_browser = None __gval__ = GlobalValues() +def setPluginBrowser(browser=None): + global __gval__ + __gval__.plugin_browser = browser +def getPluginBrowser(): + global __gval__ + return __gval__.plugin_browser + def getPacketHeaders(): global __gval__ return (__gval__.packet_m, __gval__.packet_h, __gval__.packet_hl) @@ -188,7 +199,16 @@ class OpCodeSet: ,"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_DVBAPP_VOL_UP" : 0x0401 ,"OP_DVBAPP_VOL_DOWN" : 0x0402 ,"OP_SYSTEM_OUT_OF_MEMORY" : 0x0501 @@ -213,7 +233,16 @@ class OpCodeSet: ,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" ,0x0401 : "OP_DVBAPP_VOL_UP" ,0x0402 : "OP_DVBAPP_VOL_DOWN" ,0x0501 : "OP_SYSTEM_OUT_OF_MEMORY" @@ -383,7 +412,7 @@ class BrowserCommandUtil(OpCodeSet): def doSend(self, command, params=None, reserved=0): if self._fd is None: - print "Pipe was not exists!!" + print "No found pipe!!" return False data = '' try: @@ -421,8 +450,13 @@ class HandlerHbbTV(Handler): ,0x0204 : self._cb_handleVODPlayerPlayPause ,0x0401 : self._cb_handleDVBAppVolUp ,0x0402 : self._cb_handleDVBAppVolDown + ,0x0208 : self._cb_handleVODSpeedCtrl + ,0x0209 : self._cb_handleVODSeekCtrl ,0x0501 : self._cb_handleSystemOutOfMemory ,0x0502 : self._cb_handleSystemNotufyMyPID + ,0x0309 : self._cb_handleShowVirtualKeyboard + ,0x030B : self._cb_handlePasteVirtualKeyboard + ,0x030E : self._cb_handleBrowserMenuReq } self._on_close_cb = None self._on_set_title_cb = None @@ -431,7 +465,8 @@ class HandlerHbbTV(Handler): self._retry_open_url = None self._timer_retry_open = eTimer() - + self._timer_paste_vkbd = eTimer() + self._curren_title = None def _handle_dump(self, handle, opcode, data=None): if True: return @@ -469,6 +504,72 @@ class HandlerHbbTV(Handler): self._on_set_title_cb = None return self.doPack(opcode, params, reserved) + def _cb_handleBrowserMenuReq(self, opcode, data): + self._handle_dump(self._cb_handleBrowserMenuReq, opcode, data) + 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): + eRCInput.getInstance().lock() + command_util = getCommandUtil() + command_util.sendCommand('OP_BROWSER_VKBD_RES', data) + def _cb_handleShowVirtualKeyboard(self, opcode, data): + self._handle_dump(self._cb_handleShowVirtualKeyboard, opcode, data) + 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() @@ -476,6 +577,9 @@ class HandlerHbbTV(Handler): 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]) @@ -496,6 +600,20 @@ class HandlerHbbTV(Handler): setNeedRestart(True) return (0, "OK") + def _cb_handleVODSpeedCtrl(self, opcode, data): + self._handle_dump(self._cb_handleVODSpeedCtrl, opcode, data) + headLen = struct.calcsize('!I') + unpackedData = struct.unpack('!I', data[:headLen]) + playSpeed = unpackedData[0] + service = self._session.nav.getCurrentService() + pauseable = service.pause() + if playSpeed > 2: + playSpeed = 2 + if pauseable.setFastForward(playSpeed) == -1: + pauseable.setFastForward(1) + raise Exception("This stream is not support trick play.") + return (0, "OK") + def _cb_handleDVBAppVolUp(self, opcode, data): self._handle_dump(self._cb_handleDVBAppVolUp, opcode, data) vcm = VolumeControl.instance @@ -535,6 +653,7 @@ class HandlerHbbTV(Handler): 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) @@ -542,6 +661,9 @@ class HandlerHbbTV(Handler): 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: @@ -764,7 +886,7 @@ class HbbTVHelper(Screen): self._urls = None #self._stop_opera() #self._start_opera() - self._restart_opera() + #self._restart_opera() Screen.__init__(self, session) self._session = session @@ -926,6 +1048,495 @@ class HbbTVHelper(Screen): print "Check Browser Running ERR :", ErrMsg return False +class OperaBrowserSetting: + def __init__(self): + self._settingFileName = '/usr/local/hbb-browser/home/setting.ini' + self._start = None + self._read() + def _read(self): + f = open(self._settingFileName) + for line in f.readlines(): + if line.startswith('start='): + self._start = line[6:len(line)-1] + f.close() + def _write(self): + tmpstr = [] + tmpstr.append('start=%s\n' % (self._start)) + f = open(self._settingFileName, 'w') + f.writelines(tmpstr) + f.close() + def setData(self, start): + self._start = start + self._write() + def getData(self): + return { + 'start':self._start + } + +class OperaBrowserPreferenceWindow(ConfigListScreen, Screen): + skin= """ + + + + + + + + + + + """ + def __init__(self, session, currentUrl): + self.session = session + Screen.__init__(self, session) + + self.menulist = [] + ConfigListScreen.__init__(self, self.menulist) + + self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ], { + "red" : self.keyRed, + "green" : self.keyGreen, + "ok" : self.keyOK, + "cancel" : self.keyRed + }, -2) + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("Save")) + self["url"] = Label() + + self._currentPageUrl = currentUrl + if self._currentPageUrl is None: + self._currentPageUrl = '' + self._startPageUrl = None + + self.makeMenuEntry() + self.onLayoutFinish.append(self.layoutFinished) + + def layoutFinished(self): + try: + self._startPageUrl = OperaBrowserSetting().getData()['start'] + except: self._startPageUrl = 'http://vuplus.com' + self.updateStartPageUrl() + + def updateStartPageUrl(self): + if self.menuItemStartpage.value == "startpage": + self["url"].setText(self._startPageUrl) + elif self.menuItemStartpage.value == "current": + self["url"].setText(self._currentPageUrl) + elif self.menuItemStartpage.value == "direct": + self["url"].setText('') + + def keyGreen(self): + url = self["url"].getText() + if strIsEmpty(url): + self.session.open(MessageBox, 'Invalid URL!!(Empty)\nPlease, Input to the URL.', type = MessageBox.TYPE_INFO) + return + OperaBrowserSetting().setData(url) + self.close() + + def keyRed(self): + self.close() + + def keyOK(self): + def _cb_directInputUrl(data): + if strIsEmpty(data): + return + self["url"].setText(data) + if self.menuItemStartpage.value == "direct": + self.session.openWithCallback(_cb_directInputUrl, VirtualKeyBoard, title=("Please enter URL here"), text='http://') + + def keyLeft(self): + ConfigListScreen.keyLeft(self) + self.updateStartPageUrl() + + def keyRight(self): + ConfigListScreen.keyRight(self) + self.updateStartPageUrl() + + def makeMenuEntry(self): + l = [] + l.append(("startpage", _("Start Page"))) + if not strIsEmpty(self._currentPageUrl): + l.append(("current", _("Current Page"))) + l.append(("direct", _("Direct Input"))) + self.menuItemStartpage = ConfigSelection(default="startpage", choices = l) + self.menuEntryStartpage = getConfigListEntry(_("Startpage"), self.menuItemStartpage) + self.resetMenuList() + + def resetMenuList(self): + self.menulist = [] + self.menulist.append(self.menuEntryStartpage) + + self["config"].list = self.menulist + self["config"].l.setList(self.menulist) + +class BookmarkEditWindow(ConfigListScreen, Screen): + CATEGORY,BOOKMARK = 0,1 + skin= """ + + + + + + + + + + + + + """ + def __init__(self, session, _mode, _type, _data, _bm): + self.mMode = _mode + self.mType = _type + self.mData = _data + self.session = 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.makeConfigList() + self.onLayoutFinish.append(self.layoutFinished) + + def layoutFinished(self): + self.setTitle('Bookmark ' + self.mMode) + def saveData(self): + if self.mType == BookmarkEditWindow.CATEGORY: + if self.mMode == 'Add': + categoryName = self.menuItemName.value + if strIsEmpty(categoryName): + msg = "Invalid Category Name!!(Empty)\nPlease, Input to the Category Name." + self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO) + return False + self.mBookmarkManager.addCategory(categoryName) + else: + if strIsEmpty(self.menuItemName.value): + msg = "Invalid Category Name!!(Empty)\nPlease, Input to the Category Name." + self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO) + return False + 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): + msg = "Invalid Bookmark Title!!(Empty)\nPlease input to the Bookmark Title." + self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO) + return False + self.mBookmarkManager.addBookmark(bookmarkTitle, bookmarkUrl, self.mData.mParent) + else: + if strIsEmpty(self.menuItemTitle.value): + msg = "Invalid Bookmark Title!!(Empty)\nPlease input to the Bookmark Title." + self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO) + return False + 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) + menuEntryName = getConfigListEntry(_("Name"), self.menuItemName) + self.menulist.append(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) + menuEntryTitle = getConfigListEntry(_("Title"), self.menuItemTitle) + menuEntryUrl = getConfigListEntry(_("Url"), self.menuItemUrl) + self.menulist.append(menuEntryTitle) + self.menulist.append(menuEntryUrl) + + self["config"].list = self.menulist + self["config"].l.setList(self.menulist) + +class OperaBrowserBookmarkWindow(Screen): + skin = """ + + + + + + + + + + + + + + + + + """ + + def __init__(self, _session, _url=None, _title=None): + self.mUrl = _url + self.mTitle = _title + self.mBookmarkManager = BookmarkManager.getInstance() + self.mSession = _session + Screen.__init__(self, _session) + self["actions"] = ActionMap(["DirectionActions", "OkCancelActions","ColorActions", "NumberActions"], { + "ok" : self.keyOK, + "cancel": self.keyCancel, + "red" : self.keyRed, + "green" : self.keyGreen, + "yellow": self.keyYellow, + "blue" : self.keyBlue, + "0" : self.keyNumber, + },-2) + + self["key_red"] = StaticText(_("Exit")) + self["key_green"] = StaticText(_("Add")) + self["key_yellow"] = StaticText(_("Edit")) + self["key_blue"] = StaticText(_("Delete")) + self["key_0"] = StaticText(_("Set as Startpage")) + + self.mBookmarkList = self.setBookmarkList() + self["bookmarklist"] = MenuList(self.mBookmarkList) + + def setBookmarkList(self): + l = [] + #self.mBookmarkManager.dump() + cd = self.mBookmarkManager.getBookmarkRoot() + for ck in cd.iterkeys(): + l.append(('# ' + cd[ck].mName, cd[ck])) + bd = cd[ck].mBookmarks + for bk in bd.iterkeys(): + l.append((' - ' + bd[bk].mTitle, bd[bk])) + return l + def updateBookmarkList(self): + self.mBookmarkList = self.setBookmarkList() + self["bookmarklist"].setList(self.mBookmarkList) + def cbEditWindow(self, ret=False): + if not ret: + return + self.updateBookmarkList() + def getParentCategory(self): + idx = self["bookmarklist"].getSelectedIndex() + while idx >= 0: + data = self.mBookmarkList[idx][0].strip() + if data[0] == '#': + return self.mBookmarkList[idx][1] + idx -= 1 + return None + def isCategoryItem(self): + head = self["bookmarklist"].getCurrent()[0].strip() + if head[0] == '#': + return True + return False + def keyNumber(self): + data = self["bookmarklist"].getCurrent()[1] + if strIsEmpty(data.mUrl): + msg = "Invalid URL. Please check again!!" + self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO) + return + def cbSetStartpage(ret=None): + if ret is None: return + if ret: + data = self["bookmarklist"].getCurrent()[1] + OperaBrowserSetting().setData(data.mUrl) + msg = "Do you want to set selected url to the Startpage?" + self.mSession.openWithCallback(cbSetStartpage, MessageBox, msg, MessageBox.TYPE_YESNO, default=True) + + def keyGreen(self): + def cbGreen(data): + if data is None: + return + if data[1] == 1: + parent = self.getParentCategory() + if parent is None: + return + if strIsEmpty(self.mTitle): + return + retAdd = self.mBookmarkManager.addBookmark(self.mTitle, self.mUrl, parent.mId) + if not retAdd: + msg = "Current page is already exist." + self.mSession.open(MessageBox, msg, MessageBox.TYPE_INFO) + self.cbEditWindow(True) + elif data[1] == 2: + parent = self.getParentCategory() + if parent is None: + return + b = BookmarkData(0, '', '', parent.mId) + self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Add', BookmarkEditWindow.BOOKMARK, b, self.mBookmarkManager) + elif data[1] == 3: + c = CategoryData(0, '') + self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Add', BookmarkEditWindow.CATEGORY, c, self.mBookmarkManager) + if strIsEmpty(self.mUrl): + l = [('Direct Input(Bookmark)',2,), ('Direct Input(Category)',3,)] + else: l = [('Currentpage(Bookmark)',1,), ('Direct Input(Bookmark)',2,), ('Direct Input(Category)',3,)] + self.mSession.openWithCallback(cbGreen, ChoiceBox, title=_("Please choose."), list=l) + def keyYellow(self): + data = self["bookmarklist"].getCurrent()[1] + if self.isCategoryItem(): + self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Edit', BookmarkEditWindow.CATEGORY, data, self.mBookmarkManager) + else: self.mSession.openWithCallback(self.cbEditWindow, BookmarkEditWindow, 'Edit', BookmarkEditWindow.BOOKMARK, data, self.mBookmarkManager) + def keyBlue(self): + def cbBlue(ret=None): + if not ret: return + data = self["bookmarklist"].getCurrent()[1] + if self.isCategoryItem(): + self.mBookmarkManager.deleteCategory(data.mId) + else: self.mBookmarkManager.deleteBookmark(data.mId) + self.updateBookmarkList() + if self.isCategoryItem(): + msg = "Do you want to delete the category and the bookmarks?" + else: msg = "Do you want to delete the bookmark?" + self.mSession.openWithCallback(cbBlue, MessageBox, msg, MessageBox.TYPE_YESNO, default=True) + def keyOK(self): + if self.isCategoryItem(): return + + data = self["bookmarklist"].getCurrent()[1] + url = data.mUrl.strip() + if len(url) == 0: + self.session.open(MessageBox, "Can't open selected bookmark.\n - URL data is empty!!", type = MessageBox.TYPE_INFO) + return + self.close(url) + def keyRed(self): + self.keyCancel() + def keyCancel(self): + self.close() + + +class BrowserHelpWindow(Screen, HelpableScreen): + MODE_GLOBAL,MODE_KEYBOARD,MODE_MOUSE = 1,2,3 + skin = """ + + + + + + + + + + + + """ + def __init__(self, session): + Screen.__init__(self, session) + HelpableScreen.__init__(self) + + self["key_red"] = StaticText(_("Exit")) + self["key_green"] = StaticText(_("Global")) + self["key_yellow"] = StaticText(_("Mouse")) + self["key_blue"] = StaticText(_("Keyboard")) + + self["actions"] = ActionMap(["DirectionActions", "OkCancelActions","ColorActions"], { + "ok" : self.keyRed, + "cancel": self.keyRed, + "red" : self.keyRed, + "green" : self.keyGreen, + "yellow": self.keyYellow, + "blue" : self.keyBlue, + },-2) + + self.showHelpTimer = eTimer() + self.showHelpTimer.callback.append(self.cbShowHelpTimerClosed) + self.showHelpTimer.start(500) + + def cbShowHelpTimerClosed(self): + self.showHelpTimer.stop() + self.setHelpModeActions(self.MODE_GLOBAL) + + def setHelpModeActions(self, _mode=0): + self.helpList = [] + if _mode == self.MODE_GLOBAL: + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", { + "cancel" : (self.keyPass, _("Exit the Opera browser.")), + }) + self["MenuActions"] = HelpableActionMap(self, "MenuActions", { + "menu" : (self.keyPass, _("Show the Menu window.")), + }) + self["ColorActions"] = HelpableActionMap(self, "ColorActions", { + "green" : (self.keyPass, _("Enter Key")), + "yellow" : (self.keyPass, _("Show the Virtual keyboard window.")), + "blue" : (self.keyPass, _("Backspace Key")), + }) + self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", { + "info" : (self.keyPass, _("Switch to keyboard/mouse mode.")), + }) + + elif _mode == self.MODE_MOUSE: + self["DirectionActions"] = HelpableActionMap(self, "DirectionActions", { + "up" : (self.keyPass, _("It will move the mouse pointer up.")), + "down" : (self.keyPass, _("It will move the mouse pointer down.")), + "left" : (self.keyPass, _("It will move the mouse pointer left.")), + "right" : (self.keyPass, _("It will move the mouse pointer right.")), + }) + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", { + "ok" : (self.keyPass, _("Left Mouse Button")), + }) + self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", { + "nextBouquet" : (self.keyPass, _("Right Mouse Button")), + "nextService" : (self.keyPass, _("Left Key")), + "prevService" : (self.keyPass, _("Right Key")), + }) + elif _mode == self.MODE_KEYBOARD: + self["DirectionActions"] = HelpableActionMap(self, "DirectionActions", { + "up" : (self.keyPass, _("Up Key")), + "down" : (self.keyPass, _("Down Key")), + "left" : (self.keyPass, _("Left Key")), + "right" : (self.keyPass, _("Right Key")), + }) + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", { + "ok" : (self.keyPass, _("Enter Key")), + }) + self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", { + "nextBouquet" : (self.keyPass, _("PageUp Key")), + "prevBouquet" : (self.keyPass, _("PageDown Key")), + "nextService" : (self.keyPass, _("Go to previous page.")), + "prevService" : (self.keyPass, _("Go to next page.")), + }) + + if _mode > 0: + self.showHelp() + + def keyPass(self): + pass + + def keyRed(self): + self.close() + def keyGreen(self): + self.setHelpModeActions(self.MODE_GLOBAL) + def keyYellow(self): + self.setHelpModeActions(self.MODE_MOUSE) + def keyBlue(self): + self.setHelpModeActions(self.MODE_KEYBOARD) + _g_helper = None class OperaBrowser(Screen): MENUBAR_ITEM_WIDTH = 150 @@ -938,28 +1549,33 @@ class OperaBrowser(Screen): - + + - """ % (MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH, SUBMENULIST_WIDTH+50+SUBMENULIST_NEXT, MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH) + """ % (MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH, SUBMENULIST_WIDTH+50+SUBMENULIST_NEXT, MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH)# modify menu - MENUITEMS_LIST =[[('Open Location', None), ('Start/Stop',None), ('Exit', None)], - [('About', None)]] + MENUITEMS_LIST =[[('Open Startpage', None), ('Open URL', None), ('Start/Stop',None), ('Exit', None)], + [('Bookmark', None), ('Preference', None)], + [('About', None), ('Help', None)]] def __init__(self, session): Screen.__init__(self, session) - - 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._terminatedBrowser = True + self._enableKeyEvent = True + self._currentPageUrl = None + self._currentPageTitle = None self.menubarCurrentIndex = 0 self.lvMenuItems = [] self.lvSubMenuItems = [] @@ -967,7 +1583,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()) @@ -989,19 +1606,21 @@ class OperaBrowser(Screen): os.system("echo %d > %s" % (mode, rcmouse_path)) def layoutFinished(self): - self["menuitemFile"].setText("File") + self["menuitemFile"].setText("File")# modify menu + self["menuitemTool"].setText("Tools") self["menuitemHelp"].setText("Help") self["menulist"].hide() self["submenulist"].hide() - self["bottomArea"].setText("Opera Web Browser Plugin v0.1") + self["bottomArea"].setText("Opera Web Browser Plugin v1.0") self.setTitle("BrowserMain") self.selectMenuitem() def selectMenuitem(self): - 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) @@ -1012,7 +1631,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): @@ -1064,6 +1686,12 @@ class OperaBrowser(Screen): self.enableRCMouse(False) self.toggleMainScreen() eRCInput.getInstance().unlock() + self._terminatedBrowser = True + self._enableKeyEvent = True + #if not self.toggleListViewFlag: + # self.keyDown() + self.keyRight() + self.keyLeft() def _on_setPageTitle(self, title=None): print "Title :",title @@ -1075,6 +1703,7 @@ class OperaBrowser(Screen): print "Inputed Url :", data if strIsEmpty(data): return + #self.hideSubmenu() command_server = getCommandServer() if self._on_setPageTitle not in command_server.onSetPageTitleCB: command_server.onSetPageTitleCB.append(self._on_setPageTitle) @@ -1085,11 +1714,18 @@ class OperaBrowser(Screen): eRCInput.getInstance().lock() command_util = getCommandUtil() command_util.sendCommand('OP_BROWSER_OPEN_URL', data) + self._terminatedBrowser = False + self._enableKeyEvent = False def _on_close_window(self): self._onCloseTimer.start(1000) - def _cmd_on_OpenLocation(self): + def _cb_bookmarkWindowClosed(self, data=None): + if data is None: + return + self.cbUrlText(data) + + def _cmd_on_OpenUrl(self): global _g_helper if not _g_helper._is_browser_running(): message = "Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu." @@ -1097,7 +1733,7 @@ class OperaBrowser(Screen): return self.session.openWithCallback(self.cbUrlText, VirtualKeyBoard, title=("Please enter URL here"), text='http://') def _cmd_on_About(self): - self.session.open(MessageBox, 'Opera Web Browser Plugin v0.1(beta)', type = MessageBox.TYPE_INFO) + self.session.open(MessageBox, 'Opera Web Browser Plugin v1.0', type = MessageBox.TYPE_INFO) def _cmd_on_Exit(self): self.close() def _cmd_on_StartStop(self): @@ -1105,16 +1741,46 @@ class OperaBrowser(Screen): if _g_helper is None: return _g_helper.showBrowserConfigBox() + def _cmd_on_Bookmark(self): + url = self._currentPageUrl + if url is None: + url = '' + title = self._currentPageTitle + if title is None: + title = '' + self.session.openWithCallback(self._cb_bookmarkWindowClosed, OperaBrowserBookmarkWindow, url, title) + def _cmd_on_Preference(self): + url = self._currentPageUrl + if url is None: + url = '' + self.session.open(OperaBrowserPreferenceWindow, url) + def _cmd_on_OpenStartpage(self): + start = 'http://vuplus.com' + try: + start = OperaBrowserSetting().getData()['start'] + except: pass + self.cbUrlText(start) + def _cmd_on_ReturnToBrowser(self): + self.keyCancel() + + def _cmd_on_Help(self): + self.session.open(BrowserHelpWindow) + def doCommand(self, command): - cmd_map = { - 'Exit' :self._cmd_on_Exit - ,'About' :self._cmd_on_About - ,'Open Location' :self._cmd_on_OpenLocation - ,'Start/Stop' :self._cmd_on_StartStop + cmd_map = {# modify menu + 'Exit' :self._cmd_on_Exit + ,'Help' :self._cmd_on_Help + ,'About' :self._cmd_on_About + ,'Open URL' :self._cmd_on_OpenUrl + ,'Start/Stop' :self._cmd_on_StartStop + ,'Bookmark' :self._cmd_on_Bookmark + ,'Preference' :self._cmd_on_Preference + ,'Return' :self._cmd_on_ReturnToBrowser + ,'Open Startpage' :self._cmd_on_OpenStartpage } try: cmd_map[command]() - except: pass + except Exception, ErrMsg: print ErrMsg def keyOK(self): if not self.toggleListViewFlag: @@ -1128,8 +1794,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() @@ -1144,8 +1810,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: @@ -1162,6 +1831,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: @@ -1188,8 +1862,39 @@ 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="") + eRCInput.getInstance().lock() + if self.toggleListViewFlag: + self.toggleMainScreen() + self._currentPageUrl = None + self._currentPageTitle = None + command_util = getCommandUtil() + command_util.sendCommand('OP_BROWSER_MENU_RES') + return + self.close() + + def keyMenu(self): self.toggleMainScreen() + def setCurrentPageUrl(self, url, title=None): + self._currentPageUrl = url + if title is None: + idx = len(url) + if idx > 10: idx = 10 + title = url[:idx] + self._currentPageTitle = title + print self._currentPageUrl + self.toggleMainScreen() + self.hideSubmenu() + self.keyDown() + + def hideSubmenu(self): + self.currentListView.pageUp() + self.keyUp() + + + def auto_start_main(reason, **kwargs): if reason: command_server = getCommandServer() @@ -1200,8 +1905,18 @@ def session_start_main(session, reason, **kwargs): global _g_helper _g_helper = session.open(HbbTVHelper) +_g_clearBrowserDataTimer = eTimer() 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 -- 2.7.4