[pitivi] Effects: Merge icon and treeview into a single view



commit edeb4e1997ba237c5c2e329e1c9412695941db49
Author: Renà Stadler <mail renestadler de>
Date:   Fri Aug 3 19:37:38 2012 +0200

    Effects: Merge icon and treeview into a single view

 pitivi/effects.py                         |  277 ++++++++---------------------
 tests/dogtail_scripts/helper_functions.py |   11 ++
 tests/dogtail_scripts/test_effects.py     |   19 +-
 3 files changed, 94 insertions(+), 213 deletions(-)
---
diff --git a/pitivi/effects.py b/pitivi/effects.py
index 9809ed2..2a0f4c5 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -326,17 +326,9 @@ class EffectsHandler(object):
 
 
 #----------------------- UI classes to manage effects -------------------------#
-SHOW_TREEVIEW = 1
-SHOW_ICONVIEW = 2
-
 HIDDEN_EFFECTS = ["frei0r-filter-scale0tilt"]
 
 GlobalSettings.addConfigSection('effect-library')
-GlobalSettings.addConfigOption('lastEffectView',
-    section='effect-library',
-    key='last-effect-view',
-    type_=int,
-    default=SHOW_ICONVIEW)
 
 (COL_NAME_TEXT,
  COL_DESC_TEXT,
@@ -366,10 +358,6 @@ class EffectListWidget(gtk.VBox, Loggable):
         self._dragX = 0
         self._dragY = 0
 
-        #Tooltip handling
-        self._current_effect_name = None
-        self._current_tooltip_icon = None
-
         #Searchbox and combobox
         hfilters = gtk.HBox()
         hfilters.set_spacing(SPACING)
@@ -395,56 +383,41 @@ class EffectListWidget(gtk.VBox, Loggable):
         # Store
         self.storemodel = gtk.ListStore(str, str, int, object, object, str, gtk.gdk.Pixbuf)
 
-        # Scrolled Windows
-        self.treeview_scrollwin = gtk.ScrolledWindow()
-        self.treeview_scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        self.treeview_scrollwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
-
-        self.iconview_scrollwin = gtk.ScrolledWindow()
-        self.iconview_scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        self.iconview_scrollwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
-
-        # TreeView
-        # Displays name, description
-        self.treeview = gtk.TreeView(self.storemodel)
-        self.treeview_scrollwin.add(self.treeview)
-        self.treeview.set_property("rules_hint", True)
-        self.treeview.set_property("has_tooltip", True)
-        self.treeview.set_property("headers-clickable", False)
-        tsel = self.treeview.get_selection()
+        scrollwin = gtk.ScrolledWindow()
+        scrollwin.props.hscrollbar_policy = gtk.POLICY_NEVER
+        scrollwin.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC
+        scrollwin.props.shadow_type = gtk.SHADOW_ETCHED_IN
+
+        self.view = gtk.TreeView(self.storemodel)
+        scrollwin.add(self.view)
+        self.view.props.headers_visible = False
+        tsel = self.view.get_selection()
         tsel.set_mode(gtk.SELECTION_SINGLE)
 
-        namecol = gtk.TreeViewColumn(_("Name"))
-        namecol.set_sort_column_id(COL_NAME_TEXT)
-        self.treeview.append_column(namecol)
-        namecol.set_spacing(SPACING)
-        namecol.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-        namecol.set_fixed_width(150)
-        namecell = gtk.CellRendererText()
-        namecell.props.xpad = 6
-        namecell.set_property("ellipsize", pango.ELLIPSIZE_END)
-        namecol.pack_start(namecell)
-        namecol.add_attribute(namecell, "text", COL_NAME_TEXT)
-
-        desccol = gtk.TreeViewColumn(_("Description"))
-        desccol.set_sort_column_id(COL_DESC_TEXT)
-        self.treeview.append_column(desccol)
-        desccol.set_expand(True)
-        desccol.set_spacing(SPACING)
-        desccol.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
-        desccol.set_min_width(150)
-        desccell = gtk.CellRendererText()
-        desccell.props.xpad = 6
-        desccell.set_property("ellipsize", pango.ELLIPSIZE_END)
-        desccol.pack_start(desccell)
-        desccol.add_attribute(desccell, "text", COL_DESC_TEXT)
-
-        self.iconview = gtk.IconView(self.storemodel)
-        self.iconview.set_pixbuf_column(COL_ICON)
-        self.iconview.set_text_column(COL_NAME_TEXT)
-        self.iconview.set_item_width(102)
-        self.iconview_scrollwin.add(self.iconview)
-        self.iconview.set_property("has_tooltip", True)
+        icon_col = gtk.TreeViewColumn()
+        self.view.append_column(icon_col)
+        icon_col.props.spacing = SPACING
+        icon_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        icon_col.props.fixed_width = 96
+        icon_cell = gtk.CellRendererPixbuf()
+        icon_cell.props.xpad = 6
+        icon_col.pack_start(icon_cell)
+        icon_col.add_attribute(icon_cell, "pixbuf", COL_ICON)
+
+        text_col = gtk.TreeViewColumn()
+        self.view.append_column(text_col)
+        text_col.set_expand(True)
+        text_col.set_spacing(SPACING)
+        text_col.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+        text_col.set_min_width(150)
+        text_cell = gtk.CellRendererText()
+        text_cell.props.yalign = 0.0
+        text_cell.props.xpad = 6
+        text_cell.set_property("ellipsize", pango.ELLIPSIZE_END)
+        text_col.pack_start(text_cell)
+        text_col.set_cell_data_func(text_cell,
+                                    self.view_description_cell_data_func,
+                                    None)
 
         self.effectType.connect("changed", self._effectTypeChangedCb)
 
@@ -455,75 +428,43 @@ class EffectListWidget(gtk.VBox, Loggable):
         self.searchEntry.connect("focus-out-event", self.searchEntryDesactvateCb)
         self.searchEntry.connect("icon-press", self.searchEntryIconClickedCb)
 
-        self.treeview.connect("button-press-event", self._buttonPressEventCb)
-        self.treeview.connect("select-cursor-row", self._enterPressEventCb)
-        self.treeview.connect("motion-notify-event", self._motionNotifyEventCb)
-        self.treeview.connect("query-tooltip", self._queryTooltipCb)
-        self.treeview.connect("button-release-event", self._buttonReleaseCb)
-        self.treeview.drag_source_set(0, [], gtk.gdk.ACTION_COPY)
-        self.treeview.connect("drag_begin", self._dndDragBeginCb)
-        self.treeview.connect("drag_data_get", self._dndDataGetCb)
-
-        self.iconview.connect("button-press-event", self._buttonPressEventCb)
-        self.iconview.connect("activate-cursor-item", self._enterPressEventCb)
-        self.iconview.connect("query-tooltip", self._queryTooltipCb)
-        self.iconview.drag_source_set(0, [], gtk.gdk.ACTION_COPY)
-        self.iconview.connect("motion-notify-event", self._motionNotifyEventCb)
-        self.iconview.connect("button-release-event", self._buttonReleaseCb)
-        self.iconview.connect("drag_begin", self._dndDragBeginCb)
-        self.iconview.connect("drag_data_get", self._dndDataGetCb)
+        self.view.connect("button-press-event", self._buttonPressEventCb)
+        self.view.connect("select-cursor-row", self._enterPressEventCb)
+        self.view.connect("motion-notify-event", self._motionNotifyEventCb)
+        self.view.connect("button-release-event", self._buttonReleaseCb)
+        self.view.drag_source_set(0, [], gtk.gdk.ACTION_COPY)
+        self.view.connect("drag_begin", self._dndDragBeginCb)
+        self.view.connect("drag_data_get", self._dndDataGetCb)
+
         # Delay the loading of the available effects so the application
         # starts faster.
         gobject.idle_add(self._loadAvailableEffectsCb)
 
         self.pack_start(hfilters, expand=False)
         self.pack_start(hsearch, expand=False)
-        self.pack_end(self.treeview_scrollwin, expand=True)
-        self.pack_end(self.iconview_scrollwin, expand=True)
+        self.pack_end(scrollwin, expand=True)
 
         #create the filterModel
         self.modelFilter = self.storemodel.filter_new()
         self.modelFilter.set_visible_func(self._setRowVisible, data=None)
-        self.treeview.set_model(self.modelFilter)
-        self.iconview.set_model(self.modelFilter)
+        self.view.set_model(self.modelFilter)
 
-        self._addMenuItems(uiman)
         self.show_categories(VIDEO_EFFECT)
 
-        hfilters.show_all()
-        hsearch.show_all()
+        self.show_all()
+
+    @staticmethod
+    def view_description_cell_data_func(column, cell, model, iter_, data):
+
+        name, desc = model.get(iter_, COL_NAME_TEXT, COL_DESC_TEXT)
+        cell.props.markup = "<b>%s</b>\n%s" % (escape(name),
+                                               escape(desc),)
 
     def _loadAvailableEffectsCb(self):
         self._addFactories(self.app.effects.getAllVideoEffects(), VIDEO_EFFECT)
         self._addFactories(self.app.effects.getAllAudioEffects(), AUDIO_EFFECT)
         return False
 
-    def _addMenuItems(self, uiman):
-        view_menu_item = uiman.get_widget('/MainMenuBar/View')
-        view_menu = view_menu_item.get_submenu()
-        seperator = gtk.SeparatorMenuItem()
-        self.treeview_menuitem = gtk.RadioMenuItem(None,
-                _("Show Video Effects as a List"))
-        self.iconview_menuitem = gtk.RadioMenuItem(self.treeview_menuitem,
-                _("Show Video Effects as Icons"))
-
-        if self.settings.lastEffectView == SHOW_TREEVIEW:
-            self.treeview_menuitem.set_active(True)
-            self.iconview_menuitem.set_active(False)
-        else:
-            self.treeview_menuitem.set_active(False)
-            self.iconview_menuitem.set_active(True)
-
-        self.treeview_menuitem.connect("toggled", self._treeViewMenuItemToggledCb)
-        view_menu.append(seperator)
-        view_menu.append(self.treeview_menuitem)
-        view_menu.append(self.iconview_menuitem)
-        self.treeview_menuitem.show()
-        self.iconview_menuitem.show()
-        seperator.show()
-
-        self.effect_view = self.settings.lastEffectView
-
     def _addFactories(self, elements, effectType):
         for element in elements:
             name = element.get_name()
@@ -539,57 +480,40 @@ class EffectListWidget(gtk.VBox, Loggable):
     def show_categories(self, effectType):
         self.effectCategory.get_model().clear()
         self._effect_type_ref = effectType
+        icon_column = self.view.get_column(0)
 
         if effectType is VIDEO_EFFECT:
             for categorie in self.app.effects.video_categories:
                 self.effectCategory.append_text(categorie)
+            icon_column.props.visible = True
         else:
             for categorie in self.app.effects.audio_categories:
                 self.effectCategory.append_text(categorie)
+            icon_column.props.visible = False
 
-        if self.treeview_menuitem.get_active() == False:
-            self.effect_view = SHOW_ICONVIEW
-        self._displayEffectView()
         self.effectCategory.set_active(0)
 
-    def _displayEffectView(self):
-        self.treeview_scrollwin.hide()
-        self.iconview_scrollwin.hide()
-
-        if self.effect_view == SHOW_TREEVIEW or\
-                        self._effect_type_ref == AUDIO_EFFECT:
-            widget = self.treeview_scrollwin
-            self.effect_view = SHOW_TREEVIEW
-        else:
-            widget = self.iconview_scrollwin
-
-        widget.show_all()
-
     def _dndDragBeginCb(self, view, context):
         self.info("tree drag_begin")
-        if self.effect_view == SHOW_ICONVIEW:
-            path = self.iconview.get_selected_items()
-        elif self.effect_view == SHOW_TREEVIEW:
-            path = self.treeview.get_selection().get_selected_rows()[1]
 
-        if len(path) < 1:
+        model, paths = self.view.get_selection().get_selected_rows()
+
+        if not paths:
             context.drag_abort(int(time.time()))
-        else:
-            if self._current_tooltip_icon:
-                context.set_icon_pixbuf(self._current_tooltip_icon, 0, 0)
+            return
+
+        path = paths[0]
+        pixbuf = model.get_value(model.get_iter(path), COL_ICON)
+        if pixbuf:
+            context.set_icon_pixbuf(pixbuf, 0, 0)
 
     def _rowUnderMouseSelected(self, view, event):
         result = view.get_path_at_pos(int(event.x), int(event.y))
         if result:
             path = result[0]
-            if self.effect_view == SHOW_TREEVIEW or\
-                        self._effect_type_ref == AUDIO_EFFECT:
-                selection = view.get_selection()
-                return selection.path_is_selected(path) and\
-                                selection.count_selected_rows() > 0
-            elif self.effect_view == SHOW_ICONVIEW:
-                selection = view.get_selected_items()
-                return view.path_is_selected(path) and len(selection)
+            selection = view.get_selection()
+            return selection.path_is_selected(path) and\
+                selection.count_selected_rows() > 0
         return False
 
     def _enterPressEventCb(self, view, event=None):
@@ -615,29 +539,13 @@ class EffectListWidget(gtk.VBox, Loggable):
             self._dragX = int(event.x)
             self._dragY = int(event.y)
 
-        if chain_up and self.effect_view is SHOW_TREEVIEW:
+        if chain_up:
             gtk.TreeView.do_button_press_event(view, event)
-        elif chain_up and self.effect_view is SHOW_ICONVIEW:
-            gtk.IconView.do_button_press_event(view, event)
         else:
             view.grab_focus()
 
         return True
 
-    def _iconViewButtonReleaseCb(self, treeview, event):
-        if event.button == self._dragButton:
-            self._dragButton = None
-        return False
-
-    def _treeViewMenuItemToggledCb(self, unused_widget):
-        if self.effect_view is SHOW_ICONVIEW:
-            show = SHOW_TREEVIEW
-        else:
-            show = SHOW_ICONVIEW
-        self.settings.lastEffectView = show
-        self.effect_view = show
-        self._displayEffectView()
-
     def _motionNotifyEventCb(self, view, event):
         chain_up = True
 
@@ -659,44 +567,12 @@ class EffectListWidget(gtk.VBox, Loggable):
                 event)
             self._dragStarted = True
 
-        if self.effect_view is SHOW_TREEVIEW:
-            if chain_up:
-                gtk.TreeView.do_button_press_event(view, event)
-            else:
-                view.grab_focus()
-
-        return False
-
-    def _queryTooltipCb(self, view, x, y, keyboard_mode, tooltip):
-        context = view.get_tooltip_context(x, y, keyboard_mode)
-
-        if context is None:
-            return False
-
-        if self.effect_view is SHOW_TREEVIEW or\
-                    self._effect_type_ref == AUDIO_EFFECT:
-            view.set_tooltip_row(tooltip, context[1][0])
-        elif self.effect_view is SHOW_ICONVIEW and\
-                     self._effect_type_ref == VIDEO_EFFECT:
-            view.set_tooltip_item(tooltip, context[1][0])
-        name = self.modelFilter.get_value(context[2], COL_ELEMENT_NAME)
-        if self._current_effect_name != name:
-            self._current_effect_name = name
-            icon = self.modelFilter.get_value(context[2], COL_ICON)
-            self._current_tooltip_icon = icon
-
-        longname = escape(self.modelFilter.get_value(context[2],
-                COL_NAME_TEXT).strip())
-        description = escape(self.modelFilter.get_value(context[2],
-                COL_DESC_TEXT))
-        txt = "<b>%s:</b>\n%s" % (longname, description)
-        if self.effect_view == SHOW_ICONVIEW:
-            tooltip.set_icon(None)
+        if chain_up:
+            gtk.TreeView.do_button_press_event(view, event)
         else:
-            tooltip.set_icon(self._current_tooltip_icon)
-        tooltip.set_markup(txt)
+            view.grab_focus()
 
-        return True
+        return False
 
     def _buttonReleaseCb(self, treeview, event):
         if event.button == self._dragButton:
@@ -704,15 +580,8 @@ class EffectListWidget(gtk.VBox, Loggable):
         return False
 
     def getSelectedItems(self):
-        if self.effect_view == SHOW_TREEVIEW or\
-                        self._effect_type_ref == AUDIO_EFFECT:
-            model, rows = self.treeview.get_selection().get_selected_rows()
-            path = self.modelFilter.convert_path_to_child_path(rows[0])
-        elif self.effect_view == SHOW_ICONVIEW:
-            path = self.iconview.get_selected_items()
-            if path == []:
-                return None
-            path = self.modelFilter.convert_path_to_child_path(path[0])
+        model, rows = self.view.get_selection().get_selected_rows()
+        path = self.modelFilter.convert_path_to_child_path(rows[0])
 
         return self.storemodel[path][COL_ELEMENT_NAME]
 
diff --git a/tests/dogtail_scripts/helper_functions.py b/tests/dogtail_scripts/helper_functions.py
index 65f7bd3..ab66ce0 100644
--- a/tests/dogtail_scripts/helper_functions.py
+++ b/tests/dogtail_scripts/helper_functions.py
@@ -2,6 +2,7 @@
 # -*- coding: utf-8 -*-
 import unittest
 import os
+import re
 from dogtail.predicate import GenericPredicate
 from test_base import BaseDogTail
 import dogtail.rawinput
@@ -57,6 +58,16 @@ class HelpFunc(BaseDogTail):
             if child.text == text:
                 return child
 
+    def search_by_regex(self, regex, parent, name=None, roleName=None, regex_flags=0):
+        """
+        Search a parent widget for childs containing the given regular expression
+        """
+        children = parent.findChildren(GenericPredicate(roleName=roleName, name=name))
+        r = re.compile(regex, regex_flags)
+        for child in children:
+            if child.text is not None and r.match(child.text):
+                return child
+
     def insert_clip(self, icon, n=1):
         icon.select()
         lib = self.menubar.menu("Library")
diff --git a/tests/dogtail_scripts/test_effects.py b/tests/dogtail_scripts/test_effects.py
index 76cf372..7a0adc3 100644
--- a/tests/dogtail_scripts/test_effects.py
+++ b/tests/dogtail_scripts/test_effects.py
@@ -10,17 +10,18 @@ class EffectLibraryTest(HelpFunc):
         tab = self.pitivi.tab("Effect Library")
         tab.click()
         search = tab.textentry("")
-        iconview = tab.child(roleName="layered pane")
+        view = tab.child(roleName="table")
         combotypes = tab.child(name="All effects", roleName="combo box")
-        #Some test of video effects and search
+        # Some test of video effects and search. The two column headers are
+        # also children and are always present, and each row has two children:
         search.text = "Crop"
-        self.assertEqual(len(iconview.children), 3)
+        self.assertEqual(len(view.children), 2 + 2 * 3)
         combotypes.click()
         tab.menuItem("Colors").click()
-        self.assertEqual(len(iconview.children), 0)
+        self.assertEqual(len(view.children), 2 + 2 * 0)
         combotypes.click()
         tab.menuItem("Geometry").click()
-        self.assertEqual(len(iconview.children), 3)
+        self.assertEqual(len(view.children), 2 + 2 * 3)
 
         #Audio effects
         tab.child(name="Video effects", roleName="combo box").click()
@@ -47,25 +48,25 @@ class EffectLibraryTest(HelpFunc):
         self.assertEqual(len(table.children), 3)
 
         center = lambda obj: (obj.position[0] + obj.size[0] / 2, obj.position[1] + obj.size[1] / 2)
-        icon = self.search_by_text("Agingtv ", tab, roleName="icon")
+        icon = self.search_by_regex("^Agingtv", tab, roleName="table cell")
 
         #Drag video effect on the clip
         self.improved_drag(center(icon), clippos)
         self.assertEqual(len(table.children), 6)
         #Drag video effect to the table
-        icon = self.search_by_text("3Dflippo", tab, roleName="icon")
+        icon = self.search_by_regex("^3Dflippo", tab, roleName="table cell")
         self.improved_drag(center(icon), center(table))
         self.assertEqual(len(table.children), 9)
 
         #Drag audio effect on the clip
         tab.child(name="Video effects", roleName="combo box").click()
         tab.menuItem("Audio effects").click()
-        effect = tab.child(name="Amplifier")
+        effect = self.search_by_regex("^Amplifier", tab, roleName="table cell")
         self.improved_drag(center(effect), clippos)
         self.assertEqual(len(table.children), 12)
 
         #Drag audio effect on the table
-        effect = tab.child(name="Audiokaraoke")
+        effect = self.search_by_regex("^Audiokaraoke", tab, roleName="table cell")
         self.improved_drag(center(effect), center(table))
         self.assertEqual(len(table.children), 15)
 



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