~ubuntu-branches/ubuntu/hardy/deskbar-applet/hardy-proposed

« back to all changes in this revision

Viewing changes to deskbar/ui/cuemiac/CuemiacTreeView.py

  • Committer: Bazaar Package Importer
  • Author(s): Aron Sisak
  • Date: 2007-08-07 17:00:18 UTC
  • mfrom: (1.1.31 upstream)
  • Revision ID: james.westby@ubuntu.com-20070807170018-ms9xlfneeo7x3aag
Tags: 2.19.6.1-0ubuntu1
* New upstream release (2.19.6.1):
  - Fixed bug #463974: 2.19.6 evolution handler does not build
  - Updated Translations: Gujarati, Spanish, Swedish, Thai
* New upstream release (2.19.6):
  - Added actions
  - Fixed bug #461627: Change the amount of items in history
  - Always show count in category header
  - Fixed evolution address book search with evo-ldap
  - Removed obsolete definitions from GConf and preferences and added
    new controls to preferences for previously unsupported options
  - Set process name to deskbar-applet
  - Cell containing the icon of a match doesn't expand anymore
  - Print tracebacks if module failed to load
  - Renamed gsoc_deskbar.py to deskbar-applet.py
  - Made sure that all icons are included in gnome-icon-theme
  - Added default icons for each category
  - Show window always in the foreground if triggered
  - Adjusted schema file so that intltool-merge works fast
  - Fixed: Pressing icon in panel didn't raise window
  - Don't show matches from a previous search if entry has been cleared by
    hand (i.e. not by hitting escape)
  - Fixed errors in epiphany and gdmactions module (Insted of printing error
    set INSTRUCION attribute)
  - Fixed bugs in BrowserMatch.py (fixes bug #438080)
  - Added: Check for duplicates
  - Make return value of get_hash() hashable for all modules
  - Only paste selection if keybinding has been activated
  - Each category has its own default icon
  - Fixed bug #456969: Desklicious plugin uses non-existent deskbar.Utils
  - Fixed bug #456968: Find /usr/lib*/firefox*/searchplugins
  - Fixed bug #456971: desklicious plugin improperly passess category to
    DeliciousMatch
  - Fixed bug #457133: DeliciousMatch has no 'name' and only default icon
  - Fixed bug #445145: Deskbar doesn't show up localized in the applet list
  - Fixed bug #456417: Poorly written schema descriptions
  - Updated Translations: Basque, Bengali, Dutch, Estonian, Finnish, French,
    German, Japanese, Norwegian, Slovenian, Spanish, Thai, Vietnamese
* New upstream release (2.19.5):
  - Major refactoring including a new GUI and Modules API.
  - Old modules won't work with this version
  - This release should contain almost all the features that Deskbar had
    before refactoring
* debian/patches/01_fix_python_interpreter.patch:
  - updated
* debian/patches/01_fix_pythonlib.patch:
  - dropped as not needed any more
* debian/patches/01_gpm_methods_naming_update.patch:
  - updated
* debian/patches/80-intltoolize.patch
  - updated via 'intltoolize --force'
* debian/patches/90_aclocal+autoconf+automake.patch:
  - updated via automagic

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
import gobject
3
3
import pango
4
4
import gconf
 
5
import logging
5
6
 
6
7
import deskbar
7
8
from deskbar.ui.cuemiac.CuemiacItems import CuemiacCategory
 
9
from deskbar.interfaces import Action, Match
8
10
 
9
11
class CellRendererCuemiacCategory (gtk.CellRendererText):
10
12
        """
68
70
                
69
71
                # Set up a pango.Layout for the category title
70
72
                cat_layout = ctx.create_layout ()
71
 
                cat_layout.set_text (self.get_property("category-header"))
72
73
                cat_layout.set_font_description (self.header_font_desc)
73
74
                
 
75
                cat_layout.set_markup("...")            
 
76
                cat_layout_width, cat_layout_height = cat_layout.get_pixel_size()
 
77
                ellipsise_size = cat_layout_width
 
78
                
 
79
                cat_text = self.get_property("category-header")
 
80
                cat_layout.set_markup(cat_text)
 
81
                cat_layout_width, cat_layout_height = cat_layout.get_pixel_size()
 
82
                
74
83
                # Set up a pango.Layout for the hit count
75
84
                count_layout = ctx.create_layout ()
76
85
                count_layout.set_text ("(" + str(self.get_property("match-count")) + ")")
77
86
                count_layout.set_font_description (self.header_font_desc)
78
87
                
79
 
                # Position and draw the layouts
80
 
                ctx.move_to (18, background_area.y + 6)
81
 
                ctx.show_layout (cat_layout)
82
 
                w, h = count_layout.get_pixel_size()
83
 
                ctx.move_to (background_area.width - w + 10, background_area.y + 6)
84
 
                ctx.show_layout (count_layout)
85
 
                
86
 
                # Draw a line in the normal background color in the top of the header,
87
 
                # to separate rows a bit.
88
 
                ctx.set_source_color (self.header_bg)
89
 
                ctx.move_to (0, background_area.y + 1)
90
 
                ctx.line_to (background_area.width + 100, background_area.y + 1) #FIXME: This 100 should really be the icon column width
91
 
                ctx.stroke ()
 
88
                count_layout_width, count_layout_height = count_layout.get_pixel_size()
 
89
                
 
90
                max_cat_layout_width = cell_area.width - count_layout_width - 10
 
91
                
 
92
                if cat_layout_width > max_cat_layout_width:
 
93
                        ratio = float(max_cat_layout_width - ellipsise_size)/cat_layout_width;
 
94
                        characters = int( ratio * len(cat_text) )
 
95
                        while (cat_layout_width > max_cat_layout_width):
 
96
                                if characters > 0:
 
97
                                        cat_layout.set_markup( cat_text[0:characters].strip() + "..." )
 
98
                                        characters -= 1
 
99
                                        cat_layout_width, cat_layout_height = cat_layout.get_pixel_size()
 
100
                                else:
 
101
                                        cat_layout.set_markup(cat_text.strip())
 
102
                                        break
 
103
                                
 
104
                state = self.renderer_state_to_widget_state(flag)
 
105
                main_gc = widget.get_style().text_gc[state]
 
106
                
 
107
                window.draw_layout(main_gc,
 
108
                                                18,
 
109
                                                cell_area.y + ( (cell_area.height - cat_layout_height) / 2) + 1,
 
110
                                                cat_layout)
 
111
                
 
112
                mod_gc = widget.get_style().text_gc[state]
 
113
                window.draw_layout(mod_gc,
 
114
                                                (cell_area.x + cell_area.width) - count_layout_width - 2,
 
115
                                                cell_area.y + ( (cell_area.height - count_layout_height) / 2 ) + 1,
 
116
                                                count_layout)
 
117
        
 
118
        def renderer_state_to_widget_state(self, flags):
 
119
                state = gtk.STATE_NORMAL
 
120
                if (gtk.CELL_RENDERER_SELECTED & flags) == gtk.CELL_RENDERER_SELECTED:
 
121
                        state = gtk.STATE_SELECTED
 
122
                return state
92
123
                
93
124
        def do_get_property(self, property):
94
125
                if property.name == 'category-header':
115
146
        activation_keys = [65293] # Enter  - Space makes a mess when users type in queries with spaces
116
147
        
117
148
        __gsignals__ = {
118
 
                "match-selected" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT]),
 
149
                "match-selected" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
119
150
        }
120
151
        
121
152
        def __init__ (self, model):
122
153
                gtk.TreeView.__init__ (self, model)
123
154
                                
124
155
                icon = gtk.CellRendererPixbuf ()
 
156
                icon.set_property("xpad", 10)
125
157
                hit_title = CellRendererCuemiacCategory ()
126
158
                hit_title.set_property ("ellipsize", pango.ELLIPSIZE_END)
127
 
                hit_title.set_property ("width-chars", 50) #FIXME: Pick width according to screen size
 
159
                
128
160
                hits = gtk.TreeViewColumn ("Hits")
129
 
                hits.pack_start (icon)
 
161
                hits.pack_start (icon, expand=False)
130
162
                hits.pack_start (hit_title)
131
163
                hits.set_cell_data_func(hit_title, self.__get_match_title_for_cell)                     
132
164
                hits.set_cell_data_func(icon, self.__get_match_icon_for_cell)
135
167
                self.connect ("cursor-changed", self.__on_cursor_changed)
136
168
                self.set_property ("headers-visible", False)
137
169
 
138
 
                self.connect ("row-activated", self.__on_activated)
 
170
                self.connect ("row-activated", self.__on_activated) # Used activate result if enter in entry has been pressed 
139
171
                self.connect ("button-press-event", self.__on_button_press)             
140
172
                self.connect ("key-press-event", self.__on_key_press)
141
173
                                
145
177
                # gtkTreeView does not use normal gtk DnD api.
146
178
                # it uses the api from hell
147
179
                
148
 
                # Stuff to handle persistant expansion states.
149
 
                # A category will be expanded if it's in __collapsed_rows
150
 
                self.__collapsed_rows = deskbar.GCONF_CLIENT.get_list(deskbar.GCONF_COLLAPSED_CAT, gconf.VALUE_STRING)
151
 
                deskbar.GCONF_CLIENT.notify_add(deskbar.GCONF_COLLAPSED_CAT, lambda x, y, z, a: self.__on_config_expanded_cat(z.value))
152
 
                
153
 
                self.connect ("row-expanded", self.__on_row_expanded, model)
154
 
                self.connect ("row-collapsed", self.__on_row_collapsed, model)
155
 
                model.connect ("category-added", self.__on_category_added)
156
 
                
157
 
                self.qstring = ""
158
 
 
159
180
        def is_ready (self):
160
181
                """ Returns True if the view is ready for user interaction """
161
182
                num_children = self.get_model().iter_n_children (None)
164
185
        def clear (self):
165
186
                self.model.clear ()
166
187
        
167
 
        def set_query_string (self, qstring):
168
 
                self.qstring = qstring
169
 
        
170
188
        def last_visible_path (self):
171
189
                """Returns the path to the last visible cell."""
172
190
                model = self.get_model ()
212
230
                        new_cell_y = rect.y - 5
213
231
                else:
214
232
                        if count != 1:
215
 
                                print "WARNING in CuemiacTreeView - in move_cursor_up_down, the count must be 1 or -1."
 
233
                                logging.warning("CuemiacTreeView - in move_cursor_up_down, the count must be 1 or -1.")
216
234
                        # Select a point in the cell below the cursor
217
235
                        new_cell_y = rect.height + rect.y + 5
218
236
                                
254
272
                        model = self.get_model ()
255
273
                        match = model[model.get_iter(path)][model.MATCHES]
256
274
                        if match.__class__ != CuemiacCategory:
257
 
                                self.emit ("row-activated", path, col)
258
 
                                #self.emit ("match-selected", match)
259
 
        
260
 
        def __on_config_expanded_cat (self, value):
261
 
                if value != None and value.type == gconf.VALUE_LIST:
262
 
                        self.__collapsed_rows = [h.get_string() for h in value.get_list()]
263
 
                        
264
 
        def __on_row_expanded (self, widget, iter, path, model):
265
 
                idx = model[iter][model.MATCHES].get_id ()
266
 
                if idx in self.__collapsed_rows:
267
 
                        self.__collapsed_rows.remove (idx)
268
 
                        deskbar.GCONF_CLIENT.set_list(deskbar.GCONF_COLLAPSED_CAT, gconf.VALUE_STRING, self.__collapsed_rows)
269
 
                
270
 
        def __on_row_collapsed (self, widget, iter, path, model):
271
 
                idx = model[iter][model.MATCHES].get_id ()
272
 
                self.__collapsed_rows.append (idx)
273
 
                deskbar.GCONF_CLIENT.set_list(deskbar.GCONF_COLLAPSED_CAT, gconf.VALUE_STRING, self.__collapsed_rows)
274
 
        
275
 
        def __on_category_added (self, widget, cat, path):
276
 
                if cat.get_id() not in self.__collapsed_rows:
277
 
                        self.expand_row (path, False)
 
275
                                self.__on_activated(treeview, path, col, event)
 
276
        
 
277
#       def __on_config_expanded_cat (self, value):
 
278
#               if value != None and value.type == gconf.VALUE_LIST:
 
279
#                       self.__collapsed_rows = [h.get_string() for h in value.get_list()]
278
280
                                
279
281
        def __on_cursor_changed (self, view):
280
282
                model, iter = self.get_selection().get_selected()
286
288
                
287
289
                if match.__class__ == CuemiacCategory:
288
290
                        cell.set_property ("pixbuf", None)
 
291
                        cell.set_property ("visible", True)
289
292
                        cell.set_property ("cell-background-gdk", self.style.bg[gtk.STATE_NORMAL])
290
 
                        
291
 
                elif match.__class__== tuple:
292
 
                        cell.set_property ("cell-background-gdk", self.style.base[gtk.STATE_NORMAL])
293
 
                        qstring, match_obj = match
294
 
                        cell.set_property ("pixbuf", match_obj.get_icon())
295
293
                else:
296
 
                        print "ERROR:See bug 359251 and report this output: Match object of unexpected type: %r - %r" % (match.__class__, match)
297
294
                        cell.set_property ("cell-background-gdk", self.style.base[gtk.STATE_NORMAL])
298
 
                        cell.set_property ("pixbuf", None)
299
 
 
300
 
 
 
295
                        if isinstance(match, Match):
 
296
                                cell.set_property ("pixbuf", match.get_icon())
 
297
                                cell.set_property ("visible", True)
 
298
                        else:
 
299
                                logging.error("See bug 359251 and report this output: Match object of unexpected type: %r - %r" % (match.__class__, match))
 
300
                                cell.set_property ("pixbuf", None)
 
301
                                cell.set_property ("visible", False)
301
302
                
302
303
        def __get_match_title_for_cell (self, column, cell, model, iter, data=None):
303
304
        
317
318
                                
318
319
                cell.set_property ("markup", model[iter][model.ACTIONS])
319
320
 
320
 
        def __on_activated (self, treeview, path, col):
 
321
        def __on_activated (self, treeview, path, col, event=None):
321
322
                model = self.get_model()
322
323
                iter = model.get_iter (path)
323
324
                match = model[iter][model.MATCHES]
 
325
                qstring = model[iter][model.QUERY]
324
326
                
325
327
                # Check if this s really a match and not just
326
328
                # a category
327
 
                if match.__class__ == CuemiacCategory:
 
329
                if isinstance(match, CuemiacCategory):
328
330
                        return
329
 
                        
330
 
                # So we have a Match, tell the world
331
 
                self.emit ("match-selected", match)
332
 
                
 
331
                else:
 
332
                        # So we have a Match, tell the world
 
333
                        self.emit ("match-selected", qstring, match, event)
333
334
                
334
335
        def __on_key_press (self, widget, event):
335
336
                # FIXME: In the future we should check for ctrl being pressed to create shortcuts