deskbar-applet r2099 - in trunk: . deskbar/ui/cuemiac



Author: sebp
Date: Fri Apr 11 18:22:38 2008
New Revision: 2099
URL: http://svn.gnome.org/viewvc/deskbar-applet?rev=2099&view=rev

Log:
Added CuemiacCellRendererAction class that renders either a categories match count or an arrow for a match that has more than one action.
Replaced CuemiacCellRendererCategory with CuemiacCellRendererMatch that either renders category's title or the description of a match.
Added CuemiacCellRenderer: base class for CuemiacCellRendererAction and CuemiacCellRendererCategory.

Added:
   trunk/deskbar/ui/cuemiac/CuemiacCellRenderer.py
   trunk/deskbar/ui/cuemiac/CuemiacCellRendererAction.py
   trunk/deskbar/ui/cuemiac/CuemiacCellRendererMatch.py
      - copied, changed from r2098, /trunk/deskbar/ui/cuemiac/CuemiacCellRendererCategory.py
Removed:
   trunk/deskbar/ui/cuemiac/CuemiacCellRendererCategory.py
Modified:
   trunk/ChangeLog
   trunk/deskbar/ui/cuemiac/CuemiacTreeView.py
   trunk/deskbar/ui/cuemiac/Makefile.am

Added: trunk/deskbar/ui/cuemiac/CuemiacCellRenderer.py
==============================================================================
--- (empty file)
+++ trunk/deskbar/ui/cuemiac/CuemiacCellRenderer.py	Fri Apr 11 18:22:38 2008
@@ -0,0 +1,62 @@
+import gtk
+import gobject
+import pango
+
+class CuemiacCellRenderer (gtk.CellRendererText):
+    """
+    Base class for CuemiacCellRendererAction and CuemiacCellRendererMatch
+    """
+    
+    __gsignals__ = {
+        "activated": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT]),
+    }
+    
+    def __init__ (self):
+        gtk.CellRendererText.__init__ (self)
+        
+        self.set_property("mode", gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+        self.__relative_header_size = -0.2 # Make header 20% smaller than normal fonts
+        
+        # Grab some default theme settings
+        # they are probably incorrect, but we reset
+        # them on each render anyway.
+        style = gtk.Style ()
+        self.header_font_desc = style.font_desc
+        self.header_font_desc.set_weight (pango.WEIGHT_BOLD)        
+        self.header_font_desc.set_size (self.header_font_desc.get_size () + int(self.header_font_desc.get_size ()*self.__relative_header_size))
+        self.header_bg = style.base [gtk.STATE_NORMAL]
+        
+    def set_style (self, widget):
+        """
+        Apply the style from widget, to this cellrenderer
+        """
+        self.header_font_desc = widget.style.font_desc
+        self.header_font_desc.set_weight (pango.WEIGHT_BOLD)
+        self.header_font_desc.set_size (self.header_font_desc.get_size () + int(self.header_font_desc.get_size ()*self.__relative_header_size))
+        self.header_bg = widget.style.base [gtk.STATE_NORMAL]
+    
+    def renderer_state_to_widget_state(self, flags):
+        state = 0
+        
+        if (gtk.CELL_RENDERER_SELECTED & flags) == gtk.CELL_RENDERER_SELECTED:
+            state |= gtk.STATE_SELECTED
+        if (gtk.CELL_RENDERER_PRELIT & flags) == gtk.CELL_RENDERER_PRELIT:
+            state |= gtk.STATE_PRELIGHT
+        if (gtk.CELL_RENDERER_INSENSITIVE & flags) == gtk.CELL_RENDERER_INSENSITIVE:
+            state |= gtk.STATE_INSENSITIVE
+        if state == 0:
+            state= gtk.STATE_NORMAL
+        return state
+    
+    def do_activate(self, event, widget, path_string, background_area, cell_area, flags):
+        if not isinstance(widget, gtk.TreeView):
+            # Not a treeview
+            return False
+        
+        if event == None or event.type != gtk.gdk.BUTTON_PRESS:
+            # Event type not GDK_BUTTON_PRESS
+            return True
+        
+        path = tuple([int(i) for i in path_string.split(':')])
+        self.emit("activated", path)
+        return True

Added: trunk/deskbar/ui/cuemiac/CuemiacCellRendererAction.py
==============================================================================
--- (empty file)
+++ trunk/deskbar/ui/cuemiac/CuemiacCellRendererAction.py	Fri Apr 11 18:22:38 2008
@@ -0,0 +1,170 @@
+import gtk
+import gobject
+import pango
+from deskbar.ui.cuemiac.CuemiacCellRenderer import CuemiacCellRenderer
+
+class CuemiacCellRendererAction (CuemiacCellRenderer):
+    """
+    Special cell renderer for the CuemiacTreeView.
+    
+    If the cell to be rendered is a normal Match that has
+    more than one action an arrow is displayed.
+    If it's CuemiacCategory the match-count is displayed.
+    """
+    
+    __gproperties__ = {
+                 'is-header' : (gobject.TYPE_BOOLEAN, 'whether we render a category header',
+                                'Render the header of a category, i.e. display the match-count',
+                                False, gobject.PARAM_READWRITE),
+                 'match-count' : (gobject.TYPE_INT, 'number of hits in the category',
+                                  'the number of hits for the CuemiacCategory to be rendered',
+                                  0, 1000, 0, gobject.PARAM_READWRITE),
+                 'has-more-actions' : (gobject.TYPE_BOOLEAN, 'whether the match has more than one action',
+                                       'If set to True a symbol will be displayed on the right',
+                                       False, gobject.PARAM_READWRITE),
+        }
+    
+    def __init__ (self):
+        CuemiacCellRenderer.__init__ (self)
+        self.__match_count = 0
+        self.__has_more_actions = False
+        self.__is_header = False
+        
+    def do_get_property(self, property):
+        if property.name == 'match-count':
+            return self.__match_count
+        elif property.name == 'has-more-actions':
+            return self.__has_more_actions
+        elif property.name == 'is-header':
+            return self.__is_header
+        else:
+            raise AttributeError, 'unknown property %s' % property.name
+
+    def do_set_property(self, property, value):
+        if property.name == 'match-count':
+            self.__match_count = value
+        elif property.name == 'has-more-actions':
+            self.__has_more_actions = value
+        elif property.name == 'is-header':
+            self.__is_header = value
+        else:
+            raise AttributeError, 'unknown property %s' % property.name
+    
+    def do_render (self, window, widget, background_area, cell_area, expose_area, flags):
+        self.set_style(widget)
+        if self.get_property ("is-header"):
+            self.render_category (window, widget, background_area, cell_area, expose_area, flags)
+        elif self.get_property ("has-more-actions"):
+                self.render_match (window, widget, background_area, cell_area, expose_area, flags)
+   
+    def do_get_size(self, widget, cell_area):
+        """
+        Calculate size that is required to display
+        """
+        (xoffset, yoffset, w, h) = gtk.CellRendererText.do_get_size (self, widget, cell_area)
+        
+        context = widget.get_pango_context()
+        metrics = context.get_metrics(self.header_font_desc, context.get_language())
+        char_width = metrics.get_approximate_char_width()
+        
+        if self.get_property("is-header"):
+            num_chars = len(str(self.get_property("match-count"))) + 2
+        else:
+            num_chars = 1
+        
+        width = self.get_property("xpad") * 2 + ((char_width/pango.SCALE) * num_chars);
+        
+        return (xoffset, yoffset, width, h)
+   
+    def _calculate_arrow_geometry (self, x, y, width, height):
+        """
+        Stolen from calculate_arrow_geometry at
+        http://svn.gnome.org/svn/gtk+/trunk/gtk/gtkstyle.c
+        """
+        # For right arrows only
+        h = height + (height % 2) - 1
+        w = (h / 2 + 1)
+        
+        if w > width:
+            w = width
+            h = 2 * w - 1
+            
+        if (width % 2 == 1 or w % 2 == 0):
+            w += 1
+            
+        new_x = x + (width - w) / 2;
+        new_y = y + (height - h) / 2;
+        return (new_x, new_y, w, h)
+        
+   
+    def _draw_arrow_right(self, window, color, state, area, x, y, width, height):
+        (x, y, width, height) = self._calculate_arrow_geometry(x, y, width, height)
+        
+        cr = window.cairo_create()
+        cr.set_source_color (color)
+        
+        if area:
+            cr.rectangle (area)
+            cr.clip()
+    
+        # Draw right arrow
+        cr.move_to(x,y)
+        cr.line_to(x + width, y + height / 2)
+        cr.line_to(x, y + height)
+
+        cr.close_path()
+        
+        cr.fill()
+   
+    def _shift_color (self, color, amount):
+        """
+        @type color: gtk.gdk.Color
+        """
+        r = color.red + amount
+        g = color.green + amount
+        b = color.blue + amount
+        
+        return gtk.gdk.Color (r, g, b, color.pixel)
+   
+    def render_match (self, window, widget, background_area, cell_area, expose_area, flags):
+        """
+        Renders an arrow
+        """
+        state = self.renderer_state_to_widget_state(flags)
+        
+        if state & gtk.STATE_PRELIGHT:
+            color = color = widget.style.bg[state]
+        else:
+            color = color = widget.style.fg[state]
+        
+        arrow_width = cell_area.width / 2
+        arrow_height = cell_area.height / 2
+        
+        self._draw_arrow_right(window, color, state, cell_area,
+                               cell_area.x + cell_area.width / 2,
+                               cell_area.y + ((cell_area.height - arrow_height) / 2) + 1,
+                               arrow_width,
+                               arrow_height)
+        
+    def render_category (self, window, widget, background_area, cell_area, expose_area, flag):
+        """
+        Renders the hit count (read from the "match-count" property).
+        """
+        ctx = window.cairo_create ()
+        
+        # Set up a pango.Layout for the hit count
+        count_layout = ctx.create_layout ()
+        count_layout.set_text  ("(" + str(self.get_property("match-count")) + ")")
+        count_layout.set_font_description (self.header_font_desc)
+        
+        count_layout_width, count_layout_height = count_layout.get_pixel_size()
+                
+        state = self.renderer_state_to_widget_state(flag)
+        
+        mod_gc = widget.get_style().text_gc[state]
+        
+        window.draw_layout(mod_gc,
+                           cell_area.x + (cell_area.width - count_layout_width) / 2,
+                           cell_area.y + ( (cell_area.height - count_layout_height) / 2) + 1,
+                           count_layout)
+    
\ No newline at end of file

Copied: trunk/deskbar/ui/cuemiac/CuemiacCellRendererMatch.py (from r2098, /trunk/deskbar/ui/cuemiac/CuemiacCellRendererCategory.py)
==============================================================================
--- /trunk/deskbar/ui/cuemiac/CuemiacCellRendererCategory.py	(original)
+++ trunk/deskbar/ui/cuemiac/CuemiacCellRendererMatch.py	Fri Apr 11 18:22:38 2008
@@ -1,8 +1,9 @@
 import gtk
 import gobject
 import pango
+from deskbar.ui.cuemiac.CuemiacCellRenderer import CuemiacCellRenderer
 
-class CuemiacCellRendererCategory (gtk.CellRendererText):
+class CuemiacCellRendererMatch (CuemiacCellRenderer):
     """
     Special cell renderer for the CuemiacTreeView.
     If the cell to be rendered is a normal Match, it falls back to the normal
@@ -17,114 +18,36 @@
                 'category-header' : (gobject.TYPE_STRING, 'markup for category title string',
                       'markup for category title string, None if this is not a category header',
                       None, gobject.PARAM_READWRITE),
-                      
-                 'match-count' : (gobject.TYPE_INT, 'number of hits in the category',
-                      'the number of hits for the CuemiacCategory to be rendered',
-                      0,1000,0, gobject.PARAM_READWRITE),
-                 'has-more-actions' : (gobject.TYPE_BOOLEAN, 'whether the match has more than one action',
-                                    'If set to True a symbol will be displayed on the right',
-                                    False, gobject.PARAM_READWRITE),
         }
-    __gsignals__ = {
-        # This signal will be emited when '>' on the right is clicked
-        "show-actions-activated": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT]),
-        # This signal will be emited then an area that's not the '>' from above is clicked
-        "do-action-activated": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT]),
-    }
     
     def __init__ (self):
-        gtk.CellRendererText.__init__ (self)
+        CuemiacCellRenderer.__init__ (self)
         self.__category_header = None
-        self.__match_count = 0
-        self.__has_more_actions = False
-        self.__match_markup = ""
-        self.__button_x = 0
-        self.__button_y = 0
-        self.__button_width = 0
-        self.__button_height = 0
-        self.__relative_header_size = -0.2 # Make header 20% smaller than normal fonts
-        
-        self.set_property("mode", gtk.CELL_RENDERER_MODE_ACTIVATABLE)
-        
-        # Grab some default theme settings
-        # they are probably incorrect, but we reset
-        # them on each render anyway.
-        style = gtk.Style ()
-        self.header_font_desc = style.font_desc
-        self.header_font_desc.set_weight (pango.WEIGHT_BOLD)        
-        self.header_font_desc.set_size (self.header_font_desc.get_size () + int(self.header_font_desc.get_size ()*self.__relative_header_size))
-        self.header_bg = style.base [gtk.STATE_NORMAL]
-    
-    def set_style (self, widget):
-        """
-        Apply the style from widget, to this cellrenderer
-        """
-        self.header_font_desc = widget.style.font_desc
-        self.header_font_desc.set_weight (pango.WEIGHT_BOLD)
-        self.header_font_desc.set_size (self.header_font_desc.get_size () + int(self.header_font_desc.get_size ()*self.__relative_header_size))
-        self.header_bg = widget.style.base [gtk.STATE_NORMAL]
-    
-    def do_render (self, window, widget, background_area, cell_area, expose_area, flags):
-        if not self.get_property ("category-header"):
-            self.render_match (window, widget, background_area, cell_area, expose_area, flags)
-        else:
-            self.render_category (window, widget, background_area, cell_area, expose_area, flags)
-   
-    def render_match (self, window, widget, background_area, cell_area, expose_area, flags):
-        ctx = window.cairo_create ()
         
-        # Set up a pango.Layout
-        more_actions_layout = ctx.create_layout ()
-        if self.get_property("has-more-actions"):
-            more_actions_layout.set_markup ("<b>&gt;</b>")
-        
-        more_actions_layout.set_font_description (self.header_font_desc)
-        
-        more_actions_layout_width, more_actions_layout_height = more_actions_layout.get_pixel_size()
-                
-        state = self.renderer_state_to_widget_state(flags)
-        
-        self.__button_width = more_actions_layout_width + 2
-        self.__button_height = cell_area.height 
-        
-        # Draw the actual text in the remaining area
-        cell_area_width = cell_area.width
-        cell_area.width -= self.__button_width
-        gtk.CellRendererText.do_render (self, window, widget, background_area, cell_area, expose_area, flags)
-        
-        mod_gc = widget.get_style().text_gc[state]
-        
-        self.__button_x = (cell_area.x + cell_area_width) - more_actions_layout_width - 2
-        self.__button_y = cell_area.y + ( (cell_area.height - more_actions_layout_height) / 2 ) + 1
-        
-        window.draw_layout(mod_gc,
-                        self.__button_x,
-                        self.__button_y,
-                        more_actions_layout)
-        
-        if self.get_property("has-more-actions"):
-            # Add some additional area around the '>' to activate it
-            self.__button_x -= 3
-            self.__button_y = cell_area.y
-            self.__button_width += 3
+    def do_get_property(self, property):
+        if property.name == 'category-header':
+            return self.__category_header
+        else:
+            raise AttributeError, 'unknown property %s' % property.name
+
+    def do_set_property(self, property, value):
+        if property.name == 'category-header':
+            self.__category_header = value
         else:
-            self.__button_height = 0
-            self.__button_width = 0
-            self.__button_x = 0
-            self.__button_y = 0
-        
-        #window.draw_rectangle(mod_gc, False, self.__button_x, self.__button_y,
-        #            self.__button_width, self.__button_height          
-        #            )
+            raise AttributeError, 'unknown property %s' % property.name
         
+    def do_render (self, window, widget, background_area, cell_area, expose_area, flags):
+        self.set_style(widget)
+        if self.get_property ("category-header"):
+            self.render_category (window, widget, background_area, cell_area, expose_area, flags)
+        else:
+            gtk.CellRendererText.do_render (self, window, widget, background_area, cell_area, expose_area, flags)
+   
     def render_category (self, window, widget, background_area, cell_area, expose_area, flag):
         """
         Renders the category title from the "category-header" property and displays a rigth aligned
         hit count (read from the "match-count" property).
         """
-        # Ensure we have fresh style settings
-        self.set_style (widget)
-        
         ctx = window.cairo_create ()
         
         # Set up a pango.Layout for the category title
@@ -138,28 +61,7 @@
         cat_text = self.get_property("category-header")
         cat_layout.set_markup(cat_text)
         cat_layout_width, cat_layout_height = cat_layout.get_pixel_size()
-        
-        # Set up a pango.Layout for the hit count
-        count_layout = ctx.create_layout ()
-        count_layout.set_text ("(" + str(self.get_property("match-count")) + ")")
-        count_layout.set_font_description (self.header_font_desc)
-        
-        count_layout_width, count_layout_height = count_layout.get_pixel_size()
-        
-        max_cat_layout_width = cell_area.width - count_layout_width - 10
-        
-        if cat_layout_width > max_cat_layout_width:
-            ratio = float(max_cat_layout_width - ellipsise_size)/cat_layout_width;
-            characters = int( ratio * len(cat_text) )
-            while (cat_layout_width > max_cat_layout_width):
-                if characters > 0:
-                    cat_layout.set_markup( cat_text[0:characters].strip() + "..." )
-                    characters -= 1
-                    cat_layout_width, cat_layout_height = cat_layout.get_pixel_size()
-                else:
-                    cat_layout.set_markup(cat_text.strip())
-                    break
-                
+         
         state = self.renderer_state_to_widget_state(flag)
         main_gc = widget.get_style().text_gc[state]
         
@@ -167,63 +69,4 @@
                         18,
                         cell_area.y + ( (cell_area.height - cat_layout_height) / 2) + 1,
                         cat_layout)
-        
-        mod_gc = widget.get_style().text_gc[state]
-        window.draw_layout(mod_gc,
-                        (cell_area.x + cell_area.width) - count_layout_width - 2,
-                        cell_area.y + ( (cell_area.height - count_layout_height) / 2 ) + 1,
-                        count_layout)
-    
-    def renderer_state_to_widget_state(self, flags):
-        state = gtk.STATE_NORMAL
-        if (gtk.CELL_RENDERER_SELECTED & flags) == gtk.CELL_RENDERER_SELECTED:
-            state = gtk.STATE_SELECTED
-        return state
-    
-    def do_activate(self, event, widget, path_string, background_area, cell_area, flags):
-        if not isinstance(widget, gtk.TreeView):
-            # Not a treeview
-            return False
-        
-        if event == None or event.type != gtk.gdk.BUTTON_PRESS:
-            # Event type not GDK_BUTTON_PRESS
-            return True
-        
-        ex = event.x
-        ey = event.y
-        bx = self.__button_x
-        # Otherwise, we get problems when the cell
-        # is at the top of the visible part of the treeview
-        by = cell_area.y 
-        bw = self.__button_width
-        bh = self.__button_height
-        
-        path = tuple([int(i) for i in path_string.split(':')])
-        if (ex < bx or ex > (bx+bw) or ey < by or ey > (by+bh)):
-            # Click wasn't on the icon
-            self.emit("do-action-activated", path)
-            return True
-        else:
-            self.emit("show-actions-activated", path)
-            return False
-        
-    def do_get_property(self, property):
-        if property.name == 'category-header':
-            return self.__category_header
-        elif property.name == 'match-count':
-            return self.__match_count
-        elif property.name == 'has-more-actions':
-            return self.__has_more_actions
-        else:
-            raise AttributeError, 'unknown property %s' % property.name
-
-    def do_set_property(self, property, value):
-        if property.name == 'category-header':
-            self.__category_header = value
-        elif property.name == 'match-count':
-            self.__match_count = value
-        elif property.name == 'has-more-actions':
-            self.__has_more_actions = value
-        else:
-            raise AttributeError, 'unknown property %s' % property.name
     
\ No newline at end of file

Modified: trunk/deskbar/ui/cuemiac/CuemiacTreeView.py
==============================================================================
--- trunk/deskbar/ui/cuemiac/CuemiacTreeView.py	(original)
+++ trunk/deskbar/ui/cuemiac/CuemiacTreeView.py	Fri Apr 11 18:22:38 2008
@@ -5,7 +5,8 @@
 import logging
 
 from deskbar.ui.cuemiac.CuemiacItems import CuemiacCategory
-from deskbar.ui.cuemiac.CuemiacCellRendererCategory import CuemiacCellRendererCategory
+from deskbar.ui.cuemiac.CuemiacCellRendererMatch import CuemiacCellRendererMatch
+from deskbar.ui.cuemiac.CuemiacCellRendererAction import CuemiacCellRendererAction
 from deskbar.interfaces import Match
 
 LOGGER = logging.getLogger(__name__)
@@ -34,17 +35,22 @@
         self.connect ("key-press-event", self.__on_key_press)
                 
         icon = gtk.CellRendererPixbuf ()
-        icon.set_property("xpad", 10)
-        hit_title = CuemiacCellRendererCategory ()
-        hit_title.connect("show-actions-activated", self.__on_show_actions_activated)
-        hit_title.connect("do-action-activated", self.__on_do_action_activated)
+        #icon.set_property("xpad", 10)
+        
+        hit_title = CuemiacCellRendererMatch ()
+        hit_title.connect("activated", self.__on_do_action_activated)
         hit_title.set_property ("ellipsize", pango.ELLIPSIZE_END)
-       
+        
+        action = CuemiacCellRendererAction ()
+        action.connect("activated", self.__on_show_actions_activated)
+        
         self._hits_column = gtk.TreeViewColumn ("Hits")
         self._hits_column.pack_start (icon, expand=False)
         self._hits_column.pack_start (hit_title)
+        self._hits_column.pack_end (action, expand=False)
         self._hits_column.set_cell_data_func(hit_title, self.__get_match_title_for_cell)            
         self._hits_column.set_cell_data_func(icon, self.__get_match_icon_for_cell)
+        self._hits_column.set_cell_data_func(action, self.__get_match_action_for_cell)
         self.append_column (self._hits_column)
         
         #self.set_reorderable(True)
@@ -157,7 +163,6 @@
             cell.set_property ("cell-background-gdk", self.style.bg[gtk.STATE_NORMAL])
             cell.set_property ("height", 20)
             cell.set_property ("category-header", match.get_name())
-            cell.set_property ("match-count", match.get_count ())
             return
         
         cell.set_property ("category-header", None)
@@ -166,11 +171,20 @@
         
         if match == None:
             LOGGER.error("See bug 359251 or 471672 and report this output: Match object of unexpected type: %r - %r" % (match.__class__, match))
-            cell.set_property ("has-more-actions", False)
             cell.set_property ("markup", "")
         else:
-            cell.set_property ("has-more-actions", len(match.get_actions()) > 1)
             cell.set_property ("markup", model[iter][model.ACTIONS])
+            
+    def __get_match_action_for_cell (self, column, cell, model, iter, data=None):
+        match = model[iter][model.MATCHES]
+        if isinstance(match, CuemiacCategory):
+            cell.set_property ("is-header", True)
+            cell.set_property ("match-count", match.get_count ())
+            cell.set_property ("cell-background-gdk", self.style.bg[gtk.STATE_NORMAL])
+        else:
+            cell.set_property ("is-header", False)
+            cell.set_property ("has-more-actions", len(match.get_actions()) > 1)
+            cell.set_property ("cell-background-gdk", self.style.base[gtk.STATE_NORMAL])
         
     def __on_show_actions_activated(self, widget, path):
         col = self.get_model().ACTIONS

Modified: trunk/deskbar/ui/cuemiac/Makefile.am
==============================================================================
--- trunk/deskbar/ui/cuemiac/Makefile.am	(original)
+++ trunk/deskbar/ui/cuemiac/Makefile.am	Fri Apr 11 18:22:38 2008
@@ -2,7 +2,9 @@
 deskbar_cuemiac_PYTHON = \
 	__init__.py \
 	CuemiacActionsTreeView.py \
-	CuemiacCellRendererCategory.py \
+	CuemiacCellRenderer.py \
+	CuemiacCellRendererAction.py \
+	CuemiacCellRendererMatch.py \
 	CuemiacEntry.py \
 	CuemiacHeader.py \
 	CuemiacHistory.py \



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]