deskbar-applet r2252 - in trunk: . deskbar/core deskbar/ui deskbar/ui/cuemiac
- From: sebp svn gnome org
- To: svn-commits-list gnome org
- Subject: deskbar-applet r2252 - in trunk: . deskbar/core deskbar/ui deskbar/ui/cuemiac
- Date: Mon, 21 Jul 2008 14:43:38 +0000 (UTC)
Author: sebp
Date: Mon Jul 21 14:43:38 2008
New Revision: 2252
URL: http://svn.gnome.org/viewvc/deskbar-applet?rev=2252&view=rev
Log:
Access history like in 2.18.
Added arrow beside the Deskbar icon. Clicking on it will show the a list of previously activated actions.
History is still missing in tray mode.
Modified:
trunk/ChangeLog
trunk/deskbar/core/DeskbarHistory.py
trunk/deskbar/ui/AbstractCuemiacView.py
trunk/deskbar/ui/CuemiacAlignedView.py
trunk/deskbar/ui/CuemiacWindowView.py
trunk/deskbar/ui/DeskbarApplet.py
trunk/deskbar/ui/cuemiac/CuemiacHistory.py
Modified: trunk/deskbar/core/DeskbarHistory.py
==============================================================================
--- trunk/deskbar/core/DeskbarHistory.py (original)
+++ trunk/deskbar/core/DeskbarHistory.py Mon Jul 21 14:43:38 2008
@@ -10,17 +10,16 @@
LOGGER = logging.getLogger(__name__)
-class ChooseFromHistoryAction (deskbar.interfaces.Action):
+class EmptyHistoryAction (deskbar.interfaces.Action):
"""
- This will be displayed always at the top of the history
- and is just there to display "Choose action"
+ This will be displayed if history is empty
"""
def __init__(self):
deskbar.interfaces.Action.__init__(self, "")
def get_verb(self):
- return _("<i>Choose action</i>")
+ return _("<i>Empty history</i>")
def activate(self, text=None):
pass
@@ -57,10 +56,8 @@
self.set_sort_order (gtk.SORT_DESCENDING)
self.set_sort_func (self.COL_TIME, self.__sort_actions)
- self._index = 0 # We don't want to show ChooseFromHistoryAction
+ self._index = -1
self.set_max_history_items(max_history_items)
-
- self.append(0, "", ChooseFromHistoryAction())
def set_sort_order(self, order):
"""
@@ -98,23 +95,18 @@
"""
action1 = model[iter1][self.COL_ACTION]
action2 = model[iter2][self.COL_ACTION]
-
- if isinstance(action1, ChooseFromHistoryAction):
+
+ if self[iter1][self.COL_TIME] > self[iter2][self.COL_TIME] :
return 1
- elif isinstance(action2, ChooseFromHistoryAction):
+ else:
return -1
- else:
- if self[iter1][self.COL_TIME] > self[iter2][self.COL_TIME] :
- return 1
- else:
- return -1
def clear (self):
"""
Clear the history
"""
gtk.ListStore.clear(self)
- self.append("", "", ChooseFromHistoryAction())
+ self.append("", "", EmptyHistoryAction())
self._index = -1
self.emit("cleared")
@@ -144,6 +136,9 @@
LOGGER.error("Could not restore history")
LOGGER.exception(e)
pass
+
+ if len(self) == 0:
+ self.append(0, "", EmptyHistoryAction())
def save (self):
"""
@@ -151,7 +146,7 @@
"""
save = []
for timestamp, text, action in self:
- if not isinstance(action, ChooseFromHistoryAction):
+ if not isinstance(action, EmptyHistoryAction):
save.append((timestamp, text, action))
try:
@@ -181,7 +176,10 @@
"""
assert text != None and action != None
- if isinstance(action, ChooseFromHistoryAction):
+ if not isinstance(action, deskbar.interfaces.Action):
+ raise TypeError("Action must be a deskbar.interfaces.Action instance")
+
+ if isinstance(action, EmptyHistoryAction):
return
if action.skip_history():
self.reset()
@@ -189,6 +187,10 @@
for idx, val in enumerate(self):
htime, htext, haction = val
+ if isinstance(haction, EmptyHistoryAction):
+ self.remove (self.get_iter_from_string (str(idx)))
+ continue
+
if (action.get_hash() == haction.get_hash() and action.__class__.__name__ == haction.__class__.__name__):
self.remove (self.get_iter_from_string (str(idx)))
break
@@ -225,8 +227,8 @@
"""
Reset index
"""
- if self._index != 0:
- self._index = 0
+ if self._index != -1:
+ self._index = -1
return self.get_current()
def last(self):
@@ -248,7 +250,7 @@
"""
Get action where the current index points to
"""
- if self._index == 0:
+ if self._index == -1:
return None
col_id, direction = self.get_sort_column_id()
index = self._index
Modified: trunk/deskbar/ui/AbstractCuemiacView.py
==============================================================================
--- trunk/deskbar/ui/AbstractCuemiacView.py (original)
+++ trunk/deskbar/ui/AbstractCuemiacView.py Mon Jul 21 14:43:38 2008
@@ -9,7 +9,6 @@
from deskbar.ui.cuemiac.CuemiacModel import CuemiacModel
from deskbar.ui.cuemiac.CuemiacTreeView import CuemiacTreeView
from deskbar.ui.cuemiac.CuemiacItems import CuemiacCategory
-from deskbar.ui.cuemiac.CuemiacHistory import CuemiacHistoryView
from deskbar.ui.cuemiac.CuemiacActionsTreeView import CuemiacActionsTreeView, CuemiacActionsModel
from deskbar.ui.cuemiac.LingeringSelectionWindow import LingeringSelectionWindow
@@ -42,10 +41,6 @@
self._create_header()
self.header.show()
- # History TreeView
- self._create_history_box()
- self.history_box.show()
-
# Results TreeView
self._create_results_treeview()
self.cview.show()
@@ -92,34 +87,7 @@
self.entry.show()
self.header = CuemiacHeader ( self.entry )
-
- def _create_history_box(self):
- """
- Sets:
- * self.history_box
- * self.hview
- * self.empty_button
- """
- self.history_box = gtk.HBox(spacing=6)
-
- hlabel = gtk.Label()
- # translators: _H is a mnemonic, i.e. pressing Alt+h will focus the widget
- hlabel.set_markup_with_mnemonic("<b>%s:</b>" % _("_History"))
- hlabel.show()
- self.history_box.pack_start(hlabel, False)
-
- self.hview = CuemiacHistoryView(self._model.get_history())
- self.hview.connect("match-selected", self._controller.on_history_match_selected)
- self.hview.show()
- self.history_box.pack_start(self.hview)
- hlabel.set_mnemonic_widget(self.hview)
-
- self.empty_button = gtk.Button()
- self.empty_button.set_image( gtk.image_new_from_stock(gtk.STOCK_CLEAR, gtk.ICON_SIZE_MENU) )
- self.empty_button.connect("clicked", self._controller.on_clear_history)
- self.empty_button.show()
- self.history_box.pack_start(self.empty_button, False)
-
+
def _create_results_treeview(self):
"""
Sets:
@@ -215,7 +183,6 @@
def clear_query(self):
self.entry.set_text("")
self.entry.set_icon( self.default_entry_pixbuf )
-
def get_entry(self):
return self.entry
@@ -228,8 +195,7 @@
self._do_clear = True
def mark_history_empty(self, val):
- self.hview.set_sensitive (not val)
- self.empty_button.set_sensitive (not val)
+ pass
def show_results(self):
self.results_box.show()
@@ -278,5 +244,4 @@
# Display default icon in entry
self.update_entry_icon()
self.treeview_model.append (matches, self.entry.get_text())
-
\ No newline at end of file
Modified: trunk/deskbar/ui/CuemiacAlignedView.py
==============================================================================
--- trunk/deskbar/ui/CuemiacAlignedView.py (original)
+++ trunk/deskbar/ui/CuemiacAlignedView.py Mon Jul 21 14:43:38 2008
@@ -39,7 +39,7 @@
self.set_default_size( self._model.get_window_width(), -1 )
self.set_role("deskbar-search-window")
-
+
# VBox
self.add(self.vbox_main)
@@ -85,9 +85,9 @@
# FIXME: Should we handle width intelligently also?
w, h = self.cview.size_request ()
# To ensure we don't always show scrollbars
- h += self.header.allocation.height + self.history_box.allocation.height
- # Spacing between header and history_box and between history_box and results_box
- h += 2*self.VBOX_MAIN_SPACING
+ h += self.header.allocation.height
+ # Spacing between header and results_box
+ h += self.VBOX_MAIN_SPACING
# Border at the top and the bottom
h += 2*self.VBOX_MAIN_BORDER_WIDTH
# Some additional space
@@ -109,12 +109,10 @@
"""
if orient in [gnomeapplet.ORIENT_LEFT, gnomeapplet.ORIENT_RIGHT, gnomeapplet.ORIENT_DOWN]:
self.vbox_main.pack_start(self.header, False)
- self.vbox_main.pack_start(self.history_box, False)
self.vbox_main.pack_start(self.results_box)
else:
# We are at a bottom panel. Put entry on bottom, and prepend matches (instead of append).
self.vbox_main.pack_start(self.results_box)
- self.vbox_main.pack_start(self.history_box, False)
self.vbox_main.pack_start(self.header, False)
def __set_sort_order_by_orientation(self, orient):
Modified: trunk/deskbar/ui/CuemiacWindowView.py
==============================================================================
--- trunk/deskbar/ui/CuemiacWindowView.py (original)
+++ trunk/deskbar/ui/CuemiacWindowView.py Mon Jul 21 14:43:38 2008
@@ -30,9 +30,6 @@
# Search entry
self.vbox_main.pack_start(self.header, False)
- # History TreeView
- self.vbox_main.pack_start(self.history_box, False)
-
# Results
self.results_box = gtk.HBox()
self.results_box.connect("unmap", self.__save_window_height)
Modified: trunk/deskbar/ui/DeskbarApplet.py
==============================================================================
--- trunk/deskbar/ui/DeskbarApplet.py (original)
+++ trunk/deskbar/ui/DeskbarApplet.py Mon Jul 21 14:43:38 2008
@@ -4,8 +4,136 @@
import os.path
import gobject
from deskbar.ui.AbstractCuemiacDeskbarIcon import AbstractCuemiacDeskbarIcon
+from deskbar.ui.cuemiac.CuemiacHistory import CuemiacHistoryView, CuemiacHistoryPopup
from gettext import gettext as _
+class ToggleEventBox(gtk.EventBox):
+ __gsignals__ = {
+ "toggled" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
+ }
+
+ def __init__(self):
+ gtk.EventBox.__init__(self)
+ self.active = False
+ self.set_visible_window(False)
+ self.connect('button-press-event', self.on_button_press)
+
+ def on_button_press(self, widget, event):
+ if event.button == 1:
+ self.set_active(not self.active)
+ return True
+
+ def get_active(self):
+ return self.active
+
+ def set_active(self, active):
+ changed = (self.active != active)
+ self.active = active
+
+ if changed:
+ self.emit("toggled")
+
+class CuemiacAppletButton (gtk.HBox):
+ """
+ Button consisting of two toggle buttons. A "main" with and image, and an "arrow"
+ with a gtk.Arrow.
+
+ It automatically arranges itself according to one of
+ gnomeapplet.ORIENT_UP,gnomeapplet.ORIENT_{UP,DOWN,LEFT,RIGHT}.
+
+ Signals:
+ toggled-main: The main button has been toggled
+ toggle-arrow: the arrow button has been toggled
+
+ The widget implements an interface like the gtk.ToggleButton, with _main or _arrow
+ appended to method names for each button.
+ """
+ __gsignals__ = {
+ "toggled-main" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
+ "toggled-arrow" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [])
+ }
+
+ def __init__ (self, applet):
+ gtk.HBox.__init__ (self)
+ self.applet = applet
+ self.applet.connect("change-orient", lambda applet, orient: self.set_layout_by_orientation(orient))
+ self.arrow = None
+ self.box = None
+ popup_dir = applet.get_orient()
+
+ self.button_main = ToggleEventBox()
+ self.button_main.connect ("toggled", lambda widget: self.emit ("toggled-main"))
+
+ self.image = gtk.Image ()
+ self.button_main.add (self.image)
+
+ self.button_arrow = ToggleEventBox()
+ self.button_arrow.connect ("toggled", lambda widget: self.emit ("toggled-arrow"))
+
+ self.button_main.set_tooltip_markup(_("Show search entry"))
+ self.button_arrow.set_tooltip_markup(_("Show previously used actions"))
+
+ self.set_layout_by_orientation(popup_dir)
+
+ def get_active_main (self):
+ return self.button_main.get_active ()
+
+ def set_active_main (self, is_active):
+ self.button_main.set_active (is_active)
+
+ def get_active_arrow (self):
+ return self.button_arrow.get_active ()
+
+ def set_active_arrow (self, is_active):
+ self.button_arrow.set_active (is_active)
+
+ def set_button_image_from_pixbuf (self, pixbuf):
+ self.image.set_from_pixbuf (pixbuf)
+
+ def gnomeapplet_dir_to_arrow_dir (self, gnomeapplet_dir):
+ """
+ Returns the appropriate gtk.ARROW_{UP,DOWN,LEFT,RIGHT} corresponding
+ to gnomeapplet_dir; which can be one of
+ gnomeapplet.ORIENT_{UP,DOWN,LEFT,RIGHT}
+ """
+ if gnomeapplet_dir == gnomeapplet.ORIENT_DOWN:
+ return gtk.ARROW_DOWN
+ elif gnomeapplet_dir == gnomeapplet.ORIENT_UP:
+ return gtk.ARROW_UP
+ elif gnomeapplet_dir == gnomeapplet.ORIENT_LEFT:
+ return gtk.ARROW_LEFT
+ else:
+ return gtk.ARROW_RIGHT
+
+ def set_layout_by_orientation (self, orientation):
+ """
+ @param orientation: should be a gnomeapplet.ORIENT_{UP,DOWN,LEFT,RIGHT}.
+
+ This method calls self.show_all()
+ """
+ if self.box != None:
+ self.box.remove (self.button_arrow)
+ self.box.remove (self.button_main)
+ self.remove (self.box)
+ if self.arrow != None:
+ self.button_arrow.remove (self.arrow)
+
+ if orientation in [gnomeapplet.ORIENT_UP,gnomeapplet.ORIENT_DOWN]:
+ self.box = gtk.HBox ()
+ else:
+ self.box = gtk.VBox ()
+
+ self.arrow = gtk.Arrow (self.gnomeapplet_dir_to_arrow_dir(orientation), gtk.SHADOW_IN)
+
+ self.add (self.box)
+ self.button_arrow.add (self.arrow)
+
+ self.box.pack_start (self.button_main)
+ self.box.pack_end (self.button_arrow, False, False)
+
+ self.show_all ()
+
+
class DeskbarApplet (gnomeapplet.Applet, AbstractCuemiacDeskbarIcon):
def __init__(self, applet):
@@ -18,26 +146,30 @@
self.applet.set_applet_flags (gnomeapplet.EXPAND_MINOR)
self.applet.set_background_widget(self.applet)
- self.tray = gtk.EventBox()
- self.tray.set_visible_window(False)
- self.tray.set_sensitive(False)
- self.tray.connect('button-press-event', self.on_button_press)
+ self.tray = CuemiacAppletButton(applet)
+ self.tray.connect('toggled-main', self.on_toggled_main)
+ self.tray.connect('toggled-arrow', self.on_toggled_arrow)
self.applet.add(self.tray)
self.tray.show()
- self.tray.set_tooltip_markup(_("Show search entry"))
-
- self.image = gtk.Image ()
- self.tray.add(self.image)
- self.image.show()
-
self.setup_menu()
self._setup_mvc()
self._set_image(self.applet.get_size())
+ self._setup_history()
+
self.applet.show_all()
+ def _setup_history(self):
+ self.hview = CuemiacHistoryView(self._core.get_history())
+ self.hview.connect("match-selected", self._controller.on_history_match_selected)
+ self.hview.show()
+
+ self.history_popup = CuemiacHistoryPopup (self.tray.button_arrow,
+ self.applet,
+ self.hview)
+
def on_allocate(self, applet, alloc):
if self.applet.get_orient () in [gnomeapplet.ORIENT_UP, gnomeapplet.ORIENT_DOWN]:
size_alloc = alloc.height
@@ -53,8 +185,7 @@
pixbuf = self.get_deskbar_icon(size_alloc)
self.applet.handler_block(self.handler_size_allocate_id)
- self.image.set_from_pixbuf (pixbuf)
- self.tray.set_size_request (size_alloc, size_alloc)
+ self.tray.set_button_image_from_pixbuf(pixbuf)
# If we unblock immediately we get an infinite loop
gobject.timeout_add(100, self.unblock_allocate)
@@ -62,13 +193,16 @@
self.applet.handler_unblock (self.handler_size_allocate_id)
return False
- def on_button_press(self, widget, event):
- if event.button == 1: # left mouse button
- self.set_active (not self.get_active(), event.time)
- return True
+ def on_toggled_main(self, widget):
+ self.set_active (not self.get_active(),
+ gtk.get_current_event_time())
+
+ def on_toggled_arrow(self, widget):
+ self._controller.on_quit()
+ self.history_popup.popup ()
def get_reference_widget(self):
- return self.image
+ return self.tray
def get_applet(self):
return self.applet
Modified: trunk/deskbar/ui/cuemiac/CuemiacHistory.py
==============================================================================
--- trunk/deskbar/ui/cuemiac/CuemiacHistory.py (original)
+++ trunk/deskbar/ui/cuemiac/CuemiacHistory.py Mon Jul 21 14:43:38 2008
@@ -2,18 +2,23 @@
import pango
import gobject
import logging
+from deskbar.ui.cuemiac.CuemiacAlignedWindow import CuemiacAlignedWindow
LOGGER = logging.getLogger(__name__)
-class CuemiacHistoryView (gtk.ComboBox):
+class CuemiacHistoryView (gtk.TreeView):
__gsignals__ = {
"match-selected" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_STRING, gobject.TYPE_PYOBJECT]),
}
def __init__ (self, historystore):
- gtk.ComboBox.__init__ (self, historystore)
- historystore.connect("cleared", self.__select_default_item)
+ gtk.TreeView.__init__ (self, historystore)
+
+ self.connect ("row-activated", lambda w,p,c: self.__on_activated())
+ self.connect ("button-press-event", lambda w,e: self.__on_activated())
+ self.set_property ("headers-visible", False)
+ self.set_property ("hover-selection", True)
icon = gtk.CellRendererPixbuf ()
icon.set_property("xpad", 4)
@@ -23,14 +28,12 @@
title.set_property ("ellipsize", pango.ELLIPSIZE_END)
title.set_property ("width-chars", 25) #FIXME: Pick width according to screen size
- self.pack_start (icon, expand=False)
- self.pack_start (title)
- self.set_cell_data_func(title, self.__get_action_title_for_cell)
- self.set_cell_data_func(icon, self.__get_action_icon_for_cell)
-
- self.set_active(0)
-
- self.__changed_id = self.connect ("changed", lambda w: self.__on_activated())
+ hits = gtk.TreeViewColumn ("Hits")
+ hits.pack_start (icon)
+ hits.pack_start (title)
+ hits.set_cell_data_func(icon, self.__get_action_icon_for_cell)
+ hits.set_cell_data_func(title, self.__get_action_title_for_cell)
+ self.append_column (hits)
def __get_action_icon_for_cell (self, celllayout, cell, model, iter, user_data=None):
@@ -53,7 +56,7 @@
cell.set_property ("markup", text)
def __on_activated (self):
- iter = self.get_active_iter()
+ model, iter = self.get_selection().get_selected()
if iter != None:
timestamp, text, action = self.get_model()[iter]
if not action.is_valid():
@@ -62,14 +65,102 @@
self.__select_default_item()
return False
self.emit ("match-selected", text, action)
- self.__select_default_item()
return False
- def __select_default_item(self, model=None):
- self.handler_block(self.__changed_id)
- self.set_active ( 0 )
- self.handler_unblock(self.__changed_id)
+class CuemiacHistoryPopup (CuemiacAlignedWindow) :
+
+ def __init__ (self, widget_to_align_with, applet, history_view):
+ """
+ @param widget_to_align_with: A widget the popup should align itself to.
+ @param applet: A gnomeapplet.Applet instance. However - all that is needed is a .window attribute and a get_orient() method.
+ @param history_view: A L{CuemiacHistoryView} instance.
+ """
+ CuemiacAlignedWindow.__init__ (self, widget_to_align_with, applet, window_type=gtk.WINDOW_POPUP)
+ self.applet = applet
+ self.window_group = None
+
+ self.view = history_view
+
+ self.add (self.view)
+ self.view.connect('enter-notify-event', self.on_view_enter)
+ self.view.connect('motion-notify-event', self.on_view_motion)
+ self.view.connect('button-press-event', self.on_view_button_press)
+
+ def on_view_button_press (self, widget, event):
+ self.popdown()
+ return False
+
+ def on_view_enter (self, widget, event):
+ return self.ignore_enter
+
+ def on_view_motion (self, widget, event):
+ self.ignore_enter = False
+ return False
+
+ def popup (self, time=None):
+ if not (self.widgetToAlignWith.flags() & gtk.REALIZED):
+ return
+ if (self.flags()>k.MAPPED):
+ return
+ if not (self.widgetToAlignWith.flags()>k.MAPPED):
+ return
+ if len(self.view.get_model()) <= 0:
+ return
+
+ self.ignore_enter = True
+
+ if not self.window_group :
+ target_toplevel = self.widgetToAlignWith.get_toplevel()
+ if target_toplevel != None and target_toplevel.group != None:
+ target_toplevel.group.add_window (self)
+ self.target_group = target_toplevel.group
+ elif target_toplevel is not None:
+ self.window_group = gtk.WindowGroup ()
+ self.window_group.add_window (target_toplevel)
+ self.window_group.add_window (self)
+ else:
+ print "WARNING in CuemiacEntryPopup : No toplevel window for widgetToAlignWith!"
+ return
+
+ self.update_position()
+ gtk.Window.show_all (self) # We issue warnings on the native methods, so bypass that
+
+ # For grabbing to work we need the view realized
+ if not (self.view.flags() & gtk.REALIZED):
+ self.view.realize ()
+
+ # Grab pointer
+ self.view.grab_add()
+ gtk.gdk.pointer_grab(
+ self.view.window, True,
+ gtk.gdk.BUTTON_PRESS_MASK|
+ gtk.gdk.BUTTON_RELEASE_MASK|
+ gtk.gdk.POINTER_MOTION_MASK,
+ None, None, gtk.get_current_event_time())
+
+ def popdown (self):
+ if not (self.flags()>k.MAPPED):
+ return
+
+ self.ignore_enter = False
+
+ gtk.Window.hide (self) # Bypass the warning we issue on hide()
+ # Ungrab pointer
+ gtk.gdk.pointer_ungrab(gtk.get_current_event_time())
+ self.view.grab_remove()
+
+ def show (self):
+ LOGGER.warning("CuemiacHistoryPopup : Use of show() detected. Please use popup() instead.")
+
+ def show_all (self):
+ LOGGER.warning("WARNING, CuemiacHistoryPopup : Use of show_all() detected. Please use popup() instead.")
+
+ def hide (self):
+ LOGGER.warning("WARNING, CuemiacHistoryPopup : Use of hide() detected. Please use popdown() instead.")
+
if gtk.pygtk_version < (2,8,0):
gobject.type_register (CuemiacHistoryView)
+ gobject.type_register (CuemiacHistoryPopup)
+
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]