bigboard r7397 - in trunk/bigboard: . core libgmail libgmail/ClientCookie stocks/files stocks/people stocks/self
- From: otaylor svn gnome org
- To: svn-commits-list gnome org
- Subject: bigboard r7397 - in trunk/bigboard: . core libgmail libgmail/ClientCookie stocks/files stocks/people stocks/self
- Date: Mon, 23 Jun 2008 21:48:49 +0000 (UTC)
Author: otaylor
Date: Mon Jun 23 21:48:48 2008
New Revision: 7397
URL: http://svn.gnome.org/viewvc/bigboard?rev=7397&view=rev
Log:
Shuffle code around:
Rename Exchange => StockHolder, move to a separate file
Rename StockManager => Exchange, move to a separate file
Rename BigBoardPanel => Panel, move to a separate file
Don't shell out to xdg-user-dir, use g_get_user_special_dir()
[bignative addition, not bound in pygobject]
Added:
trunk/bigboard/core/ (props changed)
trunk/bigboard/core/__init__.py
trunk/bigboard/core/exchange.py
trunk/bigboard/core/panel.py
trunk/bigboard/core/stock_holder.py
Modified:
trunk/bigboard/bigboard-native.c
trunk/bigboard/bigboard-native.h
trunk/bigboard/bignative.c
trunk/bigboard/global_mugshot.py
trunk/bigboard/globals.py
trunk/bigboard/libgmail/ (props changed)
trunk/bigboard/libgmail/ClientCookie/ (props changed)
trunk/bigboard/stocks/files/FilesStock.py
trunk/bigboard/stocks/files/filebrowser.py
trunk/bigboard/stocks/people/peoplewidgets.py
trunk/bigboard/stocks/self/portfoliomanager.py
Modified: trunk/bigboard/bigboard-native.c
==============================================================================
--- trunk/bigboard/bigboard-native.c (original)
+++ trunk/bigboard/bigboard-native.c Mon Jun 23 21:48:48 2008
@@ -154,3 +154,17 @@
return result;
}
+PyObject*
+bigboard_get_desktop_dir(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+
+ if (PyArg_ParseTuple(args, ":bigboard_get_desktop_dir")) {
+ const char *desktop_dir = g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP);
+
+ result = PyString_FromString(desktop_dir);
+ }
+
+ return result;
+}
+
Modified: trunk/bigboard/bigboard-native.h
==============================================================================
--- trunk/bigboard/bigboard-native.h (original)
+++ trunk/bigboard/bigboard-native.h Mon Jun 23 21:48:48 2008
@@ -12,7 +12,7 @@
PyObject* bigboard_set_program_name (PyObject *self, PyObject *args);
PyObject* bigboard_install_focus_docks_hack (PyObject *self, PyObject *args);
PyObject* bigboard_utf8_collate (PyObject *self, PyObject *args);
-
+PyObject* bigboard_get_desktop_dir (PyObject *self, PyObject *args);
G_END_DECLS
#endif /* __BIGBOARD_NATIVE_H__ */
Modified: trunk/bigboard/bignative.c
==============================================================================
--- trunk/bigboard/bignative.c (original)
+++ trunk/bigboard/bignative.c Mon Jun 23 21:48:48 2008
@@ -22,6 +22,8 @@
"Focus dock windows when clicking focusable widgets in them."},
{"utf8_collate", (PyCFunction) bigboard_utf8_collate, METH_VARARGS,
"Compare strings in lexical order."},
+ {"get_desktop_dir", (PyCFunction) bigboard_get_desktop_dir, METH_VARARGS,
+ "Get the user desktop directory."},
{NULL, NULL, 0, NULL} /* Sentinel */
};
Added: trunk/bigboard/core/__init__.py
==============================================================================
Added: trunk/bigboard/core/exchange.py
==============================================================================
--- (empty file)
+++ trunk/bigboard/core/exchange.py Mon Jun 23 21:48:48 2008
@@ -0,0 +1,173 @@
+import logging
+import os
+import sys
+import urllib2
+import urlparse
+
+import gconf
+import gobject
+import pyonlinedesktop
+import pyonlinedesktop.widget
+
+import bigboard
+from bigboard.globals import GCONF_PREFIX
+from bigboard.libbig.gutil import *
+
+from stock_holder import StockHolder
+
+_logger = logging.getLogger("bigboard.Exchange")
+
+class Exchange(gobject.GObject):
+ __gsignals__ = {
+ "listings-changed" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
+ }
+ def __init__(self, hardcoded_urls):
+ super(Exchange, self).__init__()
+ self.__stockdir = os.path.join(os.path.dirname(bigboard.__file__), 'stocks')
+ self.__widget_environ = widget_environ = pyonlinedesktop.widget.WidgetEnvironment()
+ widget_environ['google_apps_auth_path'] = ''
+ self.__listing_key = GCONF_PREFIX + 'url_listings'
+ gconf.client_get_default().notify_add(self.__listing_key, self.__on_listings_change)
+ self.__metainfo_cache = {}
+ self.__hardcoded_urls = hardcoded_urls
+
+ def set_listed(self, url, dolist):
+ curlist = list(self.get_listed_urls())
+ if (url in curlist) and dolist:
+ _logger.debug("attempting to list currently listed stock %s", url)
+ return
+ elif (url not in curlist) and (not dolist):
+ _logger.debug("attempting to delist currently unlisted stock %s", url)
+ return
+ elif dolist:
+ _logger.debug("listing %s", url)
+ curlist.append(url)
+ elif not dolist:
+ _logger.debug("delisting %s", url)
+ curlist.remove(url)
+ gconf.client_get_default().set_list(self.__listing_key, gconf.VALUE_STRING, curlist)
+
+ def move_listing(self, url, isup):
+ curlist = list(self.get_listed_urls())
+ curlen = len(curlist)
+ pos = curlist.index(url)
+ if pos < 0:
+ _logger.debug("couldn't find url in listings: %s", url)
+ return
+ if isup and pos == 0:
+ return
+ elif (not isup) and pos == (curlen-1):
+ return
+ del curlist[pos]
+ pos += (isup and -1 or 1)
+ curlist.insert(pos, url)
+ gconf.client_get_default().set_list(self.__listing_key, gconf.VALUE_STRING, curlist)
+
+ def get_all_builtin_urls(self):
+ for fname in os.listdir(self.__stockdir):
+ fpath = os.path.join(self.__stockdir, fname)
+ if fpath.endswith('.xml'):
+ url = 'builtin://' + fname
+ if url not in self.__hardcoded_urls:
+ yield url
+
+ def get_hardcoded_urls(self):
+ return self.__hardcoded_urls
+
+ def get_all_builtin_metadata(self):
+ for url in self.get_all_builtin_urls():
+ yield self.load_metainfo(url)
+
+ def get_listed_urls(self):
+ for url in gconf.client_get_default().get_list(self.__listing_key, gconf.VALUE_STRING):
+ if url not in self.__hardcoded_urls:
+ yield url
+
+ def get_listed(self):
+ for url in self.get_listed_urls():
+ yield self.load_metainfo(url)
+
+ def load_metainfo(self, url):
+ try:
+ return self.__metainfo_cache[url]
+ except KeyError, e:
+ pass
+ _logger.debug("loading stock url %s", url)
+ builtin_scheme = 'builtin://'
+ srcurl = url
+ if url.startswith(builtin_scheme):
+ srcurl = 'file://' + os.path.join(self.__stockdir, url[len(builtin_scheme):])
+ baseurl = 'file://' + self.__get_moddir_for_builtin(url)
+ else:
+ baseurl = os.path.dirname(url)
+ try:
+ metainfo = pyonlinedesktop.widget.WidgetParser(url, urllib2.urlopen(srcurl), self.__widget_environ, baseurl=baseurl)
+ ## FIXME this is a hack - we need to move async processing into StockHolder probably
+ url_contents = {}
+ for url in metainfo.get_required_urls():
+ url_contents[url] = urllib2.urlopen(url).read()
+ metainfo.process_urls(url_contents)
+ except urllib2.HTTPError, e:
+ _logger.warn("Failed to load %s", url, exc_info=True)
+
+ self.__metainfo_cache[url] = metainfo
+ return metainfo
+
+ def render(self, module, **kwargs):
+ (content_type, content_data) = module.content
+ pymodule = None
+ if content_type == 'online-desktop-builtin':
+ pymodule = self.__load_builtin(module, **kwargs)
+ if not pymodule:
+ return None
+
+ stylesheet = os.path.join(self.__get_moddir_for_builtin(module.srcurl), 'stock.css')
+ if not os.path.exists(stylesheet):
+ stylesheet = None
+
+ return StockHolder(module, self.__widget_environ, pymodule=pymodule,
+ is_notitle=(module.srcurl in self.__hardcoded_urls),
+ panel=kwargs['panel'], stylesheet=stylesheet)
+
+ def render_url(self, url, **kwargs):
+ return self.render(self.load_metainfo(url), **kwargs)
+
+ def __get_moddir_for_builtin(self, url):
+ modpath = urlparse.urlparse(url).path
+ modfile = os.path.basename(modpath)
+ dirname = modfile[:modfile.rfind('.')]
+ return os.path.join(self.__stockdir, dirname) + "/"
+
+ def __load_builtin(self, metainfo, notitle=False, panel=None):
+ dirpath = self.__get_moddir_for_builtin(metainfo.srcurl)
+ modpath = urlparse.urlparse(metainfo.srcurl).path
+ modfile = os.path.basename(modpath)
+ dirname = modfile[:modfile.rfind('.')]
+ _logger.debug("appending to path: %s", dirpath)
+ sys.path.append(dirpath)
+ pfxidx = modfile.find('_')
+ if pfxidx >= 0:
+ classname = dirname[pfxidx+1:]
+ else:
+ classname = dirname
+ classname = classname[0].upper() + classname[1:] + 'Stock'
+ try:
+ _logger.info("importing module %s (title: %s) from dir %s", classname, metainfo.title, dirpath)
+ pymodule = __import__(classname)
+ class_constructor = getattr(pymodule, classname)
+ _logger.debug("got constructor %s", class_constructor)
+ if notitle:
+ title = ''
+ else:
+ title = metainfo.title
+ stock = class_constructor(metainfo, title=title, panel=panel)
+
+ return stock
+ except:
+ _logger.exception("failed to add stock %s", classname)
+ return None
+
+ @defer_idle_func(timeout=100)
+ def __on_listings_change(self, *args):
+ _logger.debug("processing listings change")
+ self.emit("listings-changed")
Added: trunk/bigboard/core/panel.py
==============================================================================
--- (empty file)
+++ trunk/bigboard/core/panel.py Mon Jun 23 21:48:48 2008
@@ -0,0 +1,473 @@
+import logging
+import os
+
+import dbus
+import gconf
+import gobject
+import gtk
+import hippo
+
+from bigboard.big_widgets import Button, Header, Sidebar, ThemeManager
+from bigboard.globals import BUS_NAME_STR, GCONF_PREFIX
+from bigboard.libbig.gutil import *
+import bigboard.keybinder
+from bigboard.libbig.logutil import log_except
+from bigboard.stock import Stock
+
+from exchange import Exchange
+
+_logger = logging.getLogger("bigboard.Panel")
+
+BUS_IFACE=BUS_NAME_STR
+BUS_IFACE_PANEL=BUS_IFACE + ".Panel"
+
+class FirstTimeMinimizeDialog(gtk.Dialog):
+ __gsignals__ = { 'response' : 'override' }
+
+ def __init__(self, show_windows):
+ super(FirstTimeMinimizeDialog, self).__init__("Minimizing Sidebar",
+ None,
+ gtk.DIALOG_MODAL,
+ ('Undo', gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+ self.set_has_separator(False)
+ hbox = gtk.HBox(spacing=8)
+ self.vbox.add(hbox)
+ if show_windows:
+ img_filename = 'windows_key.png'
+ else:
+ img_filename = 'ctrl_esc_keys.png'
+ img_filename = bigboard.globals.find_in_datadir(img_filename)
+ _logger.debug("using img %s", img_filename)
+ img = gtk.Image()
+ img.set_from_file(img_filename)
+ hbox.add(img)
+ hbox.add(gtk.Label('''The sidebar is now hidden; press the key shown on the left or the panel button to pop it
+back up temporarily.'''))
+
+ def do_response(self, id):
+ if id != gtk.RESPONSE_CANCEL:
+ gconf.client_get_default().set_bool(GCONF_PREFIX + 'first_time_minimize_seen', True)
+ else:
+ # Avoid set of same value on notify receipt
+ gobject.timeout_add(100, self.__idle_undo_visible)
+ self.destroy()
+
+ def __idle_undo_visible(self):
+ gconf.client_get_default().set_bool(GCONF_PREFIX + 'visible', True)
+ return False
+
+class Panel(dbus.service.Object):
+ def __init__(self, bus_name):
+ dbus.service.Object.__init__(self, bus_name, '/bigboard/panel')
+
+ _logger.info("constructing")
+
+ self.__popped_out = False
+ self.__shell = None
+
+ gconf_client = gconf.client_get_default()
+ self._dw = Sidebar(GCONF_PREFIX + 'visible')
+ gconf_client.notify_add(GCONF_PREFIX + 'orientation', self.__sync_orient)
+ self.__sync_orient()
+
+ self.__keybinding = gconf_client.get_string('/apps/bigboard/focus_key')
+ if self.__keybinding:
+ bigboard.keybinder.tomboy_keybinder_bind(self.__keybinding, self.__on_focus)
+
+ self.__autohide_id = 0
+
+ self._holders = {} ## metainfo.srcurl to StockHolder
+
+ self._canvas = canvas = hippo.Canvas()
+ self._dw.get_content().add(self._canvas)
+
+ self._main_box = hippo.CanvasBox(border_right=1, border_color=0x999999FF, padding_bottom=4)
+ self._canvas.set_root(self._main_box)
+
+ self._header_box = Header()
+ self._header_box.connect("button-press-event", self.__on_header_buttonpress)
+
+ self.__unpopout_button = Button(label='Hide', label_ypadding=-2)
+ self.__unpopout_button.set_property('yalign', hippo.ALIGNMENT_CENTER)
+ self.__unpopout_button.connect("activated", lambda button: self.__do_unpopout())
+ self._header_box.append(self.__unpopout_button, hippo.PACK_END)
+
+ self._title = hippo.CanvasText(classes='header', text="My Desktop", font="Bold", xalign=hippo.ALIGNMENT_START, padding_left=8)
+
+ self._header_box.append(self._title, hippo.PACK_EXPAND)
+
+ self._size_button = None
+
+ self._main_box.append(self._header_box)
+
+ self._stocks_box = hippo.CanvasBox(spacing=4)
+
+ self._main_box.append(self._stocks_box)
+
+ self.__theme_mgr = ThemeManager.getInstance()
+ self.__theme_mgr.connect('theme-changed', self.__sync_theme)
+ self.__sync_theme()
+
+ self._canvas.get_context().connect('style-changed', self.__sync_opacity)
+ self.__sync_opacity()
+
+ gconf_client.notify_add(GCONF_PREFIX + 'expand', self._sync_size)
+ self._sync_size()
+
+ try:
+ self.__screensaver_proxy = dbus.SessionBus().get_object('org.gnome.ScreenSaver', '/org/gnome/ScreenSaver')
+ self.__screensaver_proxy.connect_to_signal('SessionIdleChanged',
+ self.__on_session_idle_changed)
+ except dbus.DBusException, e:
+ _logger.warn("Couldn't find screensaver")
+ pass
+
+ self.__exchange = Exchange(['builtin://self.xml', 'builtin://search.xml'])
+ self.__exchange.connect("listings-changed", lambda *args: self.__sync_listing())
+
+ # These are hardcoded as it isn't really sensible to remove them
+ self.__hardcoded_stocks = self.__exchange.get_hardcoded_urls()
+ hardcoded_metas = map(lambda url: self.__exchange.load_metainfo(url), self.__hardcoded_stocks)
+ for metainfo in hardcoded_metas:
+ self.__append_metainfo(metainfo, notitle=True)
+ self.__self_stock = self._holders[self.__hardcoded_stocks[0]].get_pymodule()
+ self.__search_stock = self._holders[self.__hardcoded_stocks[1]].get_pymodule()
+ gobject.idle_add(self.__sync_listing)
+
+ if self.__self_stock.info_loaded:
+ self.__initial_appearance()
+ else:
+ self.__self_stock.connect('info-loaded', lambda *args: self.__initial_appearance())
+
+ ## visible=True means we never hide, visible=False means we "autohide" and popout
+ ## when the hotkey or applet is used
+ gconf_client.notify_add(GCONF_PREFIX + 'visible', self.__sync_visible_mode)
+ self.__sync_visible_mode()
+
+ @log_except(_logger)
+ def __initial_appearance(self):
+ ## This function is where we show the canvas internally; we only want this to
+ ## happen after we've loaded information intially to avoid showing a partially-loaded
+ ## state.
+ self._canvas.show()
+ self.__queue_strut()
+ self.__idle_show_we_exist()
+
+ @log_except()
+ def __on_session_idle_changed(self, isidle):
+ if not isidle:
+ self.__idle_show_we_exist()
+
+ def __on_header_buttonpress(self, box, e):
+ _logger.debug("got shell header click: %s %s %s", e, e.button, e.modifiers)
+ if e.button == 2:
+ self.Shell()
+
+ @log_except()
+ def __idle_show_we_exist(self):
+ _logger.debug("showing we exist")
+ self.__enter_popped_out_state()
+ self.__leave_popped_out_state()
+
+ @log_except()
+ def __on_focus(self):
+ _logger.debug("got focus keypress")
+ vis = gconf.client_get_default().get_bool(GCONF_PREFIX + 'visible')
+ ts = bigboard.keybinder.tomboy_keybinder_get_current_event_time()
+ if vis:
+ self.__do_focus_search(ts)
+ else:
+ self.toggle_popout(ts)
+
+ def __append_metainfo(self, metainfo, **kwargs):
+ try:
+ exchange = self._holders[metainfo.srcurl]
+ except KeyError, e:
+ exchange = self.__exchange.render(metainfo, panel=self, **kwargs)
+ _logger.debug("rendered %s: %s", metainfo.srcurl, exchange)
+ if exchange:
+ self._holders[metainfo.srcurl] = exchange
+ if not exchange:
+ _logger.debug("failed to load stock from %s", metainfo.srcurl)
+ return
+ _logger.debug("adding stock %s", exchange)
+ self._stocks_box.append(exchange)
+
+ @log_except(_logger)
+ def __sync_listing(self):
+ _logger.debug("doing stock listing sync")
+ new_listed = list(self.__exchange.get_listed())
+ new_listed_srcurls = map(lambda mi: mi.srcurl, new_listed)
+ for exchange in list(self._stocks_box.get_children()):
+ if exchange.get_metainfo().srcurl in self.__hardcoded_stocks:
+ continue
+
+ _logger.debug("unrendering %s", exchange)
+
+ self._stocks_box.remove(exchange)
+
+ if exchange.get_metainfo().srcurl not in new_listed_srcurls:
+ _logger.debug("removing %s", exchange)
+ del self._holders[exchange.get_metainfo().srcurl]
+ exchange.on_delisted()
+
+ for metainfo in new_listed:
+ self.__append_metainfo(metainfo)
+ _logger.debug("done with stock load")
+
+ def get_exchange(self):
+ return self.__exchange
+
+ def __get_size(self):
+ return Stock.SIZE_BULL
+
+ ## If the user performs an action such as launching an app,
+ ## that should close a popped-out sidebar, call this
+ def action_taken(self):
+ _logger.debug("action taken")
+ self.__leave_popped_out_state(immediate=True)
+
+ @log_except()
+ def __sync_orient(self, *args):
+ orient = gconf.client_get_default().get_string(GCONF_PREFIX + 'orientation')
+ if not orient:
+ orient = 'west'
+ if orient.lower() == 'west':
+ gravity = gtk.gdk.GRAVITY_WEST
+ else:
+ gravity = gtk.gdk.GRAVITY_EAST
+ self._dw.set_gravity(gravity)
+ self.__queue_strut()
+
+ @log_except()
+ def _toggle_size(self):
+ _logger.debug("toggling size")
+ expanded = gconf.client_get_default().get_bool(GCONF_PREFIX + 'expand')
+ gconf.client_get_default().set_bool(GCONF_PREFIX + 'expand', not expanded)
+
+ def _sync_size(self, *args):
+ # This function should be deleted basically; we no longer support size changes.
+
+ self._canvas.set_size_request(Stock.SIZE_BULL_CONTENT_PX, 42)
+
+ _logger.debug("queuing resize")
+ self._dw.queue_resize()
+ _logger.debug("queuing strut")
+ self.__queue_strut()
+ _logger.debug("queuing strut complete")
+
+ def __sync_theme(self, *args):
+ theme = self.__theme_mgr.get_theme()
+ self._canvas.set_theme(theme)
+
+ def __sync_opacity(self, *args):
+ style = self._canvas.get_context().get_style()
+ opacity = style.get_double('opacity', False)
+ if opacity == None:
+ opacity = 1.0
+
+ self._dw.set_opacity(opacity)
+
+ @log_except()
+ def __idle_do_strut(self):
+ _logger.debug("setting strut in idle")
+ self._dw.do_set_wm_strut()
+ return False
+
+ def __queue_strut(self):
+ # TODO - this is kind of gross; we need the strut change to happen after
+ # the resize, but that appears to be an ultra-low priority internally
+ # so we can't easily queue something directly after.
+ call_timeout_once(250, self.__idle_do_strut)
+
+ ## There are two aspects to the sidebar state:
+ ## the "visible" gconf key is like the old gnome-panel "autohide"
+ ## preference. i.e. if !visible, the sidebar is normally collapsed
+ ## and you have to use a hotkey or the applet to pop it out.
+ ## So the second piece of state is self.__popped_out, which is whether
+ ## the sidebar is currently popped out. If visible=True, the sidebar
+ ## is always popped out, i.e. self.__popped_out should be True always.
+
+ def __notify_stocks_of_popped_out(self):
+ for e in self._holders.values():
+ e.on_popped_out_changed(self.__popped_out)
+
+ ## Shows the sidebar
+ def __enter_popped_out_state(self):
+ if not self.__popped_out:
+ _logger.debug("popping out")
+
+ self._dw.show()
+ # we would prefer to need this, if iconify() worked on dock windows
+ #self._dw.deiconify()
+ self.__queue_strut()
+ self.__popped_out = True
+
+ self.__notify_stocks_of_popped_out()
+
+ self.EmitPoppedOutChanged()
+
+ ## Hides the sidebar, possibly after a delay, only if visible mode is False
+ def __leave_popped_out_state(self, immediate=False):
+ vis = gconf.client_get_default().get_bool(GCONF_PREFIX + 'visible')
+ if self.__popped_out and not vis and self.__autohide_id == 0:
+ _logger.debug("enqueued autohide timeout")
+ self.__autohide_id = gobject.timeout_add(immediate and 1 or 1500, self.__idle_do_hide)
+
+ @log_except()
+ def __idle_do_hide(self):
+ _logger.debug("in idle hide")
+ self.__autohide_id = 0
+ vis = gconf.client_get_default().get_bool(GCONF_PREFIX + 'visible')
+ if vis or not self.__popped_out:
+ return
+
+ _logger.debug("unpopping out")
+ self.__popped_out = False
+ ## would be better to iconify, not hide - hide withdraws the
+ ## window, iconify should leave bigboard in the Ctrl+Alt+Tab
+ ## order.
+ ## Unfortunately, it appears metacity disallows minimize on
+ ## dock windows.
+ #self._dw.iconify()
+ self._dw.hide()
+ self.__queue_strut()
+
+ self.__notify_stocks_of_popped_out()
+
+ self.EmitPoppedOutChanged()
+
+ ## syncs our current state to a change in the gconf setting for visible mode
+ @log_except()
+ def __sync_visible_mode(self, *args):
+ ## unpopout button is only visible if unpopout is allowed
+ vis = gconf.client_get_default().get_bool(GCONF_PREFIX + 'visible')
+ self.__unpopout_button.set_visible(not vis)
+
+ if vis and not self.__popped_out:
+ self.__enter_popped_out_state()
+ elif not vis:
+ self.__leave_popped_out_state()
+ if not gconf.client_get_default().get_bool(GCONF_PREFIX + 'first_time_minimize_seen'):
+ dialog = FirstTimeMinimizeDialog(True)
+ dialog.show_all()
+
+ ## this is needed because the Sidebar widget knows about the 'visible' gconf key,
+ ## and if we're not in visible mode (in autohide mode), it never sets the strut.
+ ## However the Sidebar widget does not itself listen for changes on the gconf key.
+ self.__queue_strut()
+
+ ## Pops out the sidebar, and focuses it (if the sidebar is in visible mode, only has to focus)
+ def __do_popout(self, xtimestamp):
+ if not self.__popped_out:
+ _logger.debug("popout requested")
+ self.__enter_popped_out_state()
+ self.__do_focus_search(xtimestamp)
+
+ def __do_focus_search(self, xtimestamp):
+ ## focus even if we were already shown
+ _logger.debug("presenting with ts %s", xtimestamp)
+ self._dw.present_with_time(xtimestamp)
+ self.__search_stock.focus()
+
+ ## Hides the sidebar, only if not in visible mode
+ def __do_unpopout(self):
+ if self.__popped_out:
+ _logger.debug("unpopout requested")
+ self.__leave_popped_out_state(True)
+
+ def toggle_popout(self, xtimestamp):
+ if self.__popped_out:
+ self.__do_unpopout()
+ else:
+ self.__do_popout(xtimestamp)
+
+ def __set_visible_mode(self, setting):
+ vis = gconf.client_get_default().get_bool(GCONF_PREFIX + 'visible')
+ if setting != vis:
+ gconf.client_get_default().set_bool(GCONF_PREFIX + 'visible', setting)
+
+ @dbus.service.method(BUS_IFACE_PANEL)
+ def EmitPoppedOutChanged(self):
+ _logger.debug("got emitPoppedOutChanged method call")
+ self.PoppedOutChanged(self.__popped_out)
+
+ @dbus.service.method(BUS_IFACE_PANEL)
+ def Popout(self, xtimestamp):
+ _logger.debug("got popout method call")
+ return self.__do_popout(xtimestamp)
+
+ @dbus.service.method(BUS_IFACE_PANEL)
+ def Unpopout(self):
+ _logger.debug("got unpopout method call")
+
+ ## force us into autohide mode, since otherwise unpopout would not make sense
+ self.__set_visible_mode(False)
+
+ return self.__do_unpopout()
+
+ @dbus.service.method(BUS_IFACE_PANEL)
+ def Reboot(self):
+ import subprocess
+
+ reexec_cmd = os.getenv('BB_REEXEC') or '/usr/bin/bigboard'
+ reexec_cmd = os.path.abspath(REEXEC_CMD)
+
+ args = [reexec_cmd]
+ args.extend(sys.argv[1:])
+ if not '--replace' in args:
+ args.append('--replace')
+ _logger.debug("Got Reboot, executing %s", args)
+ subprocess.Popen(args)
+
+ @dbus.service.method(BUS_IFACE_PANEL)
+ def Logout(self):
+ master = gnome.ui.master_client()
+ master.request_save(gnome.ui.SAVE_GLOBAL,
+ True,
+ gnome.ui.INTERACT_ANY,
+ False,
+ True)
+
+
+ def __create_scratch_window(self):
+ w = hippo.CanvasWindow(gtk.WINDOW_TOPLEVEL)
+ w.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(65535,65535,65535))
+ w.set_title('Scratch Window')
+ box = CanvasVBox()
+ w.set_root(box)
+ w.connect('delete-event', lambda *args: w.destroy())
+ w.show_all()
+ w.present_with_time(gtk.get_current_event_time())
+ return box
+
+ @dbus.service.method(BUS_IFACE_PANEL)
+ def Shell(self):
+ if self.__shell:
+ self.__shell.destroy()
+ import bigboard.pyshell
+ self.__shell = bigboard.pyshell.CommandShell({'panel': self,
+ ' scratch_window': self.__create_scratch_window},
+ savepath=os.path.expanduser('~/.bigboard/pyshell.py'))
+ self.__shell.show_all()
+ self.__shell.present_with_time(gtk.get_current_event_time())
+
+ @dbus.service.method(BUS_IFACE_PANEL)
+ def Kill(self):
+ try:
+ bigboard.keybinder.tomboy_keybinder_unbind(self.__keybinding)
+ except KeyError, e:
+ pass
+ # This is a timeout so we reply to the method call
+ gobject.timeout_add(100, gtk.main_quit)
+
+ @dbus.service.method(BUS_IFACE_PANEL)
+ def Exit(self):
+ gtk.main_quit()
+
+ @dbus.service.signal(BUS_IFACE_PANEL,
+ signature='b')
+ def PoppedOutChanged(self, is_popped_out):
+ pass
+
Added: trunk/bigboard/core/stock_holder.py
==============================================================================
--- (empty file)
+++ trunk/bigboard/core/stock_holder.py Mon Jun 23 21:48:48 2008
@@ -0,0 +1,151 @@
+import gobject
+import hippo
+
+from bigboard.big_widgets import Arrow, Header, ThemeManager
+from bigboard.stock import Stock
+
+class GoogleGadgetContainer(hippo.CanvasWidget):
+ def __init__(self, metainfo, env):
+ super(GoogleGadgetContainer, self).__init__()
+ from pyonlinedesktop import ggadget
+ self.widget = ggadget.Gadget(metainfo, env)
+ self.widget.show_all()
+ self.set_property('widget', self.widget)
+
+class HeaderButton(hippo.CanvasBox):
+ def __init__(self):
+ hippo.CanvasBox.__init__(self, box_width=40, xalign=hippo.ALIGNMENT_END,
+ background_color=0x00000001)
+ self.set_clickable(True)
+ self.append(hippo.CanvasText(text=" "))
+
+ def do_paint_below_children(self, cr, dmgbox):
+ area = self.get_background_area()
+ self.get_style().paint(cr, 'more-button', area.x, area.y, area.width, area.height)
+
+gobject.type_register(HeaderButton)
+
+class Separator(hippo.CanvasBox):
+ def __init__(self):
+ hippo.CanvasBox.__init__(self, border_top=1, border_color=0x999999FF)
+
+class StockHolder(hippo.CanvasBox):
+ """A renderer for stocks."""
+
+ def __init__(self, metainfo, env, pymodule=None, is_notitle=False, panel=None, stylesheet=None):
+ hippo.CanvasBox.__init__(self,
+ orientation=hippo.ORIENTATION_VERTICAL,
+ spacing=4)
+ self.__size = None
+ self.__metainfo = metainfo
+ self.__env = env
+ self.__pymodule = pymodule
+ self.__panel = panel
+ self.__stylesheet = stylesheet
+ self.__content = None
+ self.__ticker_text = None
+ self.__ticker_container = None
+ self.__mini_more_button = None
+ self.__sep = Separator()
+ self.append(self.__sep)
+ self.__expanded = True
+ if not is_notitle:
+ self.__ticker_container = Header()
+ self.__ticker_text = hippo.CanvasText(classes='header', text=metainfo.title, xalign=hippo.ALIGNMENT_START)
+ self.__ticker_text.set_clickable(True)
+ self.__ticker_text.connect("activated", lambda text: self.__toggle_expanded())
+ self.__ticker_container.append(self.__ticker_text, hippo.PACK_EXPAND)
+
+ self.__ticker_arrow = Arrow(Arrow.LEFT, padding=4)
+ self.__ticker_arrow.connect("activated", lambda text: self.__toggle_expanded())
+ self.__ticker_container.append(self.__ticker_arrow)
+
+ if pymodule and pymodule.has_more_button():
+ more_button = HeaderButton()
+ more_button.connect("activated", lambda l: pymodule.on_more_clicked())
+ self.__ticker_container.append(more_button)
+
+ self.append(self.__ticker_container)
+
+ self.__theme_mgr = ThemeManager.getInstance()
+ self.__theme_mgr.connect('theme-changed', self.__sync_theme)
+
+ self.__stockbox = hippo.CanvasBox()
+ self.append(self.__stockbox)
+ if pymodule:
+ pymodule.connect('visible', self.__render_pymodule)
+ self.__render_pymodule()
+ else:
+ self.__render_google_gadget()
+
+ self.__sync_visibility()
+
+ def __sync_theme(self, *args):
+ if self.__content:
+ if self.__stylesheet:
+ theme = self.__theme_mgr.make_stock_theme(self.__stylesheet)
+ self.__content.set_theme(theme)
+
+ def on_delisted(self):
+ _logger.debug("on_delisted exchange %s" % (str(self)))
+ self.__unrender_pymodule()
+
+ def on_popped_out_changed(self, popped_out):
+ self.__pymodule.on_popped_out_changed(popped_out)
+
+ def __sync_visibility(self):
+ self.set_child_visible(self.__stockbox, self.__expanded)
+ if self.__ticker_container:
+ self.__ticker_container.set_child_visible(self.__ticker_arrow, not self.__expanded)
+
+ def __toggle_expanded(self):
+ self.__expanded = not self.__expanded
+ self.__sync_visibility()
+
+ def get_metainfo(self):
+ return self.__metainfo
+
+ def get_pymodule(self):
+ return self.__pymodule
+
+ def __render_google_gadget(self):
+ rendered = GoogleGadgetContainer(self.__metainfo, self.__env)
+ self.__stockbox.append(rendered)
+
+ def __render_pymodule(self, *args):
+ self.__size = size = Stock.SIZE_BULL
+ self.__stockbox.remove_all()
+ self.__pymodule.set_size(size)
+
+ self.__content = self.__pymodule.get_content(size)
+ self.__sync_theme()
+
+ if self.__ticker_container:
+ self.set_child_visible(self.__ticker_container, not not self.__content)
+ self.set_child_visible(self.__sep,
+ (not not self.__content) and \
+ ((self.__ticker_container and size == Stock.SIZE_BEAR) \
+ or (size == Stock.SIZE_BULL
+ and ((not self.__ticker_container) or (self.__pymodule.get_ticker() == "-")))))
+ if self.__mini_more_button:
+ self.set_child_visible(self.__mini_more_button, size == Stock.SIZE_BEAR)
+ self.set_child_visible(self.__stockbox, not not self.__content)
+ if not self.__content:
+ _logger.debug("no content for stock %s", self.__pymodule)
+ return
+ self.__stockbox.append(self.__content)
+ padding = 4
+ self.__stockbox.set_property("padding_left", padding)
+ self.__stockbox.set_property("padding_right", padding)
+ if self.__ticker_text:
+ self.set_child_visible(self.__ticker_container, size == Stock.SIZE_BULL)
+
+ def __unrender_pymodule(self):
+ if not self.__pymodule:
+ _logger.debug("Not a pymodule exchange")
+ return
+
+ _logger.debug("delisting pymodule %s" % (str(self.__pymodule)))
+ self.__pymodule.on_delisted()
+ self.__pymodule = None
+
Modified: trunk/bigboard/global_mugshot.py
==============================================================================
--- trunk/bigboard/global_mugshot.py (original)
+++ trunk/bigboard/global_mugshot.py Mon Jun 23 21:48:48 2008
@@ -46,8 +46,8 @@
def __create_proxy(self):
try:
bus = dbus.SessionBus()
- self._logger.debug("creating proxy for %s" % globals.bus_name)
- self.__mugshot_dbus_proxy = bus.get_object(globals.bus_name, '/com/dumbhippo/client')
+ self._logger.debug("creating proxy for %s" % globals.engine_bus_name)
+ self.__mugshot_dbus_proxy = bus.get_object(globals.engine_bus_name, '/com/dumbhippo/client')
self.__registration_pending = True
self.__mugshot_dbus_proxy.RegisterEndpoint(reply_handler=self.__on_register_endpoint, error_handler=self.__on_dbus_error)
@@ -58,15 +58,15 @@
def __create_ws_proxy(self):
try:
bus = dbus.SessionBus()
- self.__ws_proxy = bus.get_object(globals.bus_name, '/org/gnome/web_services')
+ self.__ws_proxy = bus.get_object(globals.engine_bus_name, '/org/gnome/web_services')
except dbus.DBusException:
self.__ws_proxy = None
@log_except(_logger)
def __on_dbus_name_owner_changed(self, name, prev_owner, new_owner):
- if name == globals.bus_name:
+ if name == globals.engine_bus_name:
if new_owner != '':
- self._logger.debug("owner for %s changed, recreating proxies", globals.bus_name)
+ self._logger.debug("owner for %s changed, recreating proxies", globals.engine_bus_name)
self.__create_proxy()
else:
self.__mugshot_dbus_proxy = None
Modified: trunk/bigboard/globals.py
==============================================================================
--- trunk/bigboard/globals.py (original)
+++ trunk/bigboard/globals.py Mon Jun 23 21:48:48 2008
@@ -1,8 +1,13 @@
+import os
import re
from ddm import DataModel
+import gtk
-bus_name = 'org.freedesktop.od.Engine'
+BUS_NAME_STR='org.gnome.BigBoard'
+GCONF_PREFIX = '/apps/bigboard/'
+
+engine_bus_name = 'org.freedesktop.od.Engine'
server_name = None
_do_autolaunch_raw = True
do_autolaunch = True
@@ -17,7 +22,7 @@
return re.sub(r"[^a-zA-Z0-9]", _escape_byte, server_name.encode("UTF-8"))
-def _make_bus_name(server_name):
+def _make_engine_bus_name(server_name):
if server_name == None:
return "org.freedesktop.od.Engine";
@@ -42,7 +47,7 @@
def set_server_name(value=None):
global server_name
- global bus_name
+ global engine_bus_name
global do_autolaunch
global _do_autolaunch_raw
global __the_data_model
@@ -50,7 +55,7 @@
if __the_data_model:
raise Exception("We already used the data model before setting server name")
server_name = value
- bus_name = _make_bus_name(value)
+ engine_bus_name = _make_engine_bus_name(value)
do_autolaunch = _do_autolaunch_raw and server_name == None
def set_do_autolaunch(value):
@@ -87,3 +92,37 @@
url = "http://online.gnome.org"
return url
+
+def init():
+ global BB_DATADIR
+
+ BB_DATADIR = os.getenv('BB_DATADIR')
+ if BB_DATADIR:
+ BB_DATADIR = os.path.abspath(BB_DATADIR)
+
+ icon_datadir = None
+ for path in _get_datadirs():
+ if os.path.isdir(path):
+ icon_datadir = path
+ break
+ if icon_datadir:
+ gtk.icon_theme_get_default().prepend_search_path(icon_datadir)
+
+def _get_datadirs():
+ datadir_env = os.getenv('XDG_DATA_DIRS')
+ if datadir_env:
+ datadirs = datadir_env.split(':')
+ else:
+ datadirs = ['/usr/share/']
+ return map(lambda x: os.path.join(x, 'bigboard'), datadirs)
+
+def find_in_datadir(fname):
+ if BB_DATADIR:
+ return os.path.join(BB_DATADIR, fname)
+ datadirs = _get_datadirs()
+ for dir in datadirs:
+ fpath = os.path.join(dir, fname)
+ if os.access(fpath, os.R_OK):
+ return fpath
+ return None
+
Modified: trunk/bigboard/stocks/files/FilesStock.py
==============================================================================
--- trunk/bigboard/stocks/files/FilesStock.py (original)
+++ trunk/bigboard/stocks/files/FilesStock.py Mon Jun 23 21:48:48 2008
@@ -410,8 +410,6 @@
self.__slideout_target = None
self.__last_slideout_event_time = None
- self.desktop_path = self._panel.get_desktop_path()
-
self._box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL, spacing=4, padding_top=2)
self._recentbox = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL, spacing=4)
self._box.append(self._recentbox)
Modified: trunk/bigboard/stocks/files/filebrowser.py
==============================================================================
--- trunk/bigboard/stocks/files/filebrowser.py (original)
+++ trunk/bigboard/stocks/files/filebrowser.py Mon Jun 23 21:48:48 2008
@@ -3,6 +3,11 @@
import gobject, gtk
import hippo
+try:
+ import bigboard.bignative as bignative
+except:
+ import bignative
+
from bigboard.big_widgets import BigWindow, CanvasMugshotURLImage, CanvasHBox, CanvasVBox, ActionLink, IconLink, PrelightingCanvasBox
from bigboard.overview_table import OverviewTable
@@ -173,7 +178,7 @@
self.__idle_search_id = 0
def __on_browse_local_files_clicked(self, canvas_item):
- subprocess.Popen(['nautilus', '--browser', self.__stock.desktop_path])
+ subprocess.Popen(['nautilus', '--browser', bignative.get_desktop_dir()])
def __on_search_local_files_clicked(self, canvas_item):
# we don't want to turn "" into None, or change everything to be lowercase
Modified: trunk/bigboard/stocks/people/peoplewidgets.py
==============================================================================
--- trunk/bigboard/stocks/people/peoplewidgets.py (original)
+++ trunk/bigboard/stocks/people/peoplewidgets.py Mon Jun 23 21:48:48 2008
@@ -12,6 +12,7 @@
from bigboard.big_widgets import PhotoContentItem, CanvasHBox, CanvasVBox
from bigboard.big_widgets import BigWindow
import bigboard.libbig as libbig
+from bigboard.libbig.logutil import log_except
import bigboard.globals as globals
from bigboard.libbig.format_escaped import format_escaped
@@ -71,8 +72,11 @@
'sort-changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
'destroy': 'override',
}
-
+
+ @log_except(_logger)
def __init__(self, person, themed=False, **kwargs):
+ _logger.debug("Initializing %s", self)
+
PhotoContentItem.__init__(self, **kwargs)
self.person = person
@@ -138,7 +142,10 @@
self.__update_aim_buddy(self.person)
self.__update_xmpp_buddy(self.person)
+ _logger.debug("Initialized %s", self)
+
def do_destroy(self):
+ _logger.debug("Destroying %s", self)
for handler_id in self.__handlers:
self.person.disconnect(handler_id)
Modified: trunk/bigboard/stocks/self/portfoliomanager.py
==============================================================================
--- trunk/bigboard/stocks/self/portfoliomanager.py (original)
+++ trunk/bigboard/stocks/self/portfoliomanager.py Mon Jun 23 21:48:48 2008
@@ -93,8 +93,8 @@
self.__selected_item = None
self.__search = None
- self.__mgr = self.__panel.get_stock_manager()
- self.__mgr.connect('listings-changed', lambda *args: self.__sync())
+ self.__exchange = self.__panel.get_exchange()
+ self.__exchange.connect('listings-changed', lambda *args: self.__sync())
gobject.idle_add(self.__sync)
def add_stock(self, metainfo, section):
@@ -176,8 +176,8 @@
@log_except(_logger)
def __sync(self):
- all = list(self.__mgr.get_all_builtin_metadata())
- listed = list(self.__mgr.get_listed())
+ all = list(self.__exchange.get_all_builtin_metadata())
+ listed = list(self.__exchange.get_listed())
itemsections = []
for section in self.__items:
for srcurl in self.__items[section]:
@@ -197,8 +197,8 @@
super(PortfolioManager, self).__init__(themed=False, stylesheet=stock.get_path('portfoliomanager.css'))
self.__panel = stock.get_panel()
- self.__mgr = self.__panel.get_stock_manager()
- self.__mgr.connect('listings-changed', lambda *args: self.__on_listings_change())
+ self.__exchange = self.__panel.get_exchange()
+ self.__exchange.connect('listings-changed', lambda *args: self.__on_listings_change())
self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(65535,65535,65535))
self.set_title('Sidebar Preferences')
@@ -305,7 +305,7 @@
except:
_logger.debug("invalid URL: %s", url)
return
- self.__mgr.set_listed(url, True)
+ self.__exchange.set_listed(url, True)
def __set_profile_stock(self, url):
self.__profile_box.clear()
@@ -313,8 +313,8 @@
self.__profile_box.set_property("box-height", 300)
else:
self.__profile_box.set_property("box_height", -1)
- metainfo = self.__mgr.load_metainfo(url)
- listed = url in self.__mgr.get_listed_urls()
+ metainfo = self.__exchange.load_metainfo(url)
+ listed = url in self.__exchange.get_listed_urls()
pv = StockPreview(metainfo, listed)
self.__preview = pv
self.__profile_box.append(pv)
@@ -323,11 +323,11 @@
def __on_item_add_remove(self, item):
_logger.debug("got addremove for item %s", item.metainfo.srcurl)
- self.__mgr.set_listed(item.metainfo.srcurl, not item.listed)
+ self.__exchange.set_listed(item.metainfo.srcurl, not item.listed)
def __on_item_move(self, item, isup):
_logger.debug("got move for item %s up: %s", item.metainfo.srcurl, isup)
- self.__mgr.move_listing(item.metainfo.srcurl, isup)
+ self.__exchange.move_listing(item.metainfo.srcurl, isup)
def __reset(self):
self.__search_input.set_property('text', '')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]