~ubuntu-branches/ubuntu/trusty/pitivi/trusty

« back to all changes in this revision

Viewing changes to pitivi/ui/ripple_update_group.py

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2011-07-07 13:43:47 UTC
  • mto: (6.1.9 sid) (1.2.12)
  • mto: This revision was merged to the branch mainline in revision 32.
  • Revision ID: james.westby@ubuntu.com-20110707134347-cari9kxjiakzej9z
Tags: upstream-0.14.1
ImportĀ upstreamĀ versionĀ 0.14.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# PiTiVi , Non-linear video editor
2
2
#
3
 
#       ui/projectsettings.py
 
3
#       ui/ripple_update_group.py
4
4
#
5
5
# Copyright (c) 2010, Brandon Lewis <brandon.lewis@collabora.co.uk>
6
6
#
16
16
#
17
17
# You should have received a copy of the GNU Lesser General Public
18
18
# License along with this program; if not, write to the
19
 
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
 
# Boston, MA 02111-1307, USA.
 
19
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 
20
# Boston, MA 02110-1301, USA.
21
21
 
22
22
 
23
23
class RippleUpdateGroup(object):
24
 
 
25
24
    """Allows for event-driven spreadsheet-like ripple updates without
26
25
    infinite loops.
27
26
 
64
63
 
65
64
        - a function to be called whenver the edge is visited during an update
66
65
          cycle. this function will not be called if the condition function
67
 
          returns False."""
68
 
 
69
 
    def __init__(self, *widgets):
 
66
          returns False.
 
67
 
 
68
    @ivar arcs: A map from widget to a list of edges originating in the widget.
 
69
    @ivar update_funcs: A map from widget to a (callable, args) tuple.
 
70
    """
 
71
 
 
72
    def __init__(self):
70
73
        self.arcs = {}
71
74
        self.update_funcs = {}
72
75
        self.ignore_new_signals = False
73
 
        for widget in widgets:
74
 
            self.add_vertex(*widget)
75
 
 
76
 
    def add_vertex(self, widget, update_func=None, signal=None, *args):
 
76
 
 
77
    def addVertex(self, widget, signal=None, update_func=None,
 
78
            update_func_args=()):
 
79
        """Add a widget to the list of vertexes.
 
80
 
 
81
        @param widget: The vertex to be added.
 
82
        @type widget: gtk.Widget
 
83
        @param signal: A signal of the widget to be monitored.
 
84
        @type signal: str
 
85
        @param update_func: A callable object called when the vertex is visited.
 
86
        @type update_func: function
 
87
        @param update_func_args: The arguments for calling update_func.
 
88
        @type update_func_args: tuple
 
89
        """
77
90
        if signal:
78
 
            widget.connect(signal, self._widget_value_changed)
79
 
        self.update_funcs[widget] = (update_func, args)
 
91
            widget.connect(signal, self._widgetValueChanged)
 
92
        self.update_funcs[widget] = (update_func, update_func_args)
80
93
        self.arcs[widget] = []
81
94
 
82
 
    def add_edge(self, a, b, predicate = None,
83
 
        edge_func = None):
84
 
        self.arcs[a].append((b, predicate, edge_func))
85
 
 
86
 
    def add_bi_edge(self, a, b, predicate = None,
87
 
        edge_func = None):
88
 
        self.add_edge(a, b, predicate, edge_func)
89
 
        self.add_edge(b, a, predicate, edge_func)
90
 
 
91
 
    def _widget_value_changed(self, widget, *unused):
 
95
    def addEdge(self, widget_a, widget_b, predicate=None, edge_func=None):
 
96
        """Add a directional edge from widget_a to widget_b.
 
97
 
 
98
        @param widget_a: The source vertex.
 
99
        @type widget_a: gtk.Widget
 
100
        @param widget_b: The target vertex.
 
101
        @type widget_b: gtk.Widget
 
102
        @param predicate: A callable object returning whether the edge may be
 
103
            traversed.
 
104
        @type predicate: function
 
105
        @param edge_func: A callable object called when the edge is traversed.
 
106
        @type edge_func: function
 
107
        """
 
108
        self.arcs[widget_a].append((widget_b, predicate, edge_func))
 
109
 
 
110
    def addBiEdge(self, widget_a, widget_b, predicate=None, edge_func=None):
 
111
        """Add a bidirectional edge between the specified vertexes.
 
112
 
 
113
        @see: addEdge
 
114
        """
 
115
        self.addEdge(widget_a, widget_b, predicate, edge_func)
 
116
        self.addEdge(widget_b, widget_a, predicate, edge_func)
 
117
 
 
118
    def _widgetValueChanged(self, widget, *unused):
 
119
        """Handle an event generated by the specified widget."""
92
120
        if self.ignore_new_signals:
93
121
            return
94
122
 
95
123
        self.ignore_new_signals = True
96
 
        self._updateValues(widget)
97
 
        self.ignore_new_signals = False
 
124
        try:
 
125
            self._updateValues(widget)
 
126
        finally:
 
127
            self.ignore_new_signals = False
98
128
 
99
129
    def _updateValues(self, widget):
100
 
        queue = [(widget, v) for v in self.arcs[widget]]
 
130
        """Traverse the graph starting from the specified widget."""
 
131
        # Initialize the list of (source_widget, arc) to be traversed.
 
132
        queue = [(widget, arc) for arc in self.arcs[widget]]
101
133
        visited = set([widget])
102
134
        while queue:
103
 
            parent, (cur, predicate, edge_func) = queue.pop(0)
 
135
            source_widget, arc = queue.pop(0)
 
136
            target_widget, predicate, edge_func = arc
104
137
 
105
138
            # ignore nodes we've seen
106
 
            if cur in visited:
 
139
            if target_widget in visited:
107
140
                continue
108
141
 
109
142
            # check whether conditions permit this edge to be followed
110
 
            if predicate and (not predicate()):
 
143
            if predicate and not predicate():
111
144
                continue
112
145
 
113
 
            # if so call the edge function
 
146
            # traverse the edge
114
147
            if edge_func:
115
148
                edge_func()
116
149
 
117
 
            # visit node
118
 
            update_func, args = self.update_funcs[cur]
 
150
            # visit the target node
 
151
            update_func, update_func_args = self.update_funcs[target_widget]
119
152
            if update_func:
120
 
                update_func(parent, cur, *args)
121
 
            visited.add(cur)
 
153
                update_func(source_widget, target_widget, *update_func_args)
 
154
            visited.add(target_widget)
122
155
 
123
156
            # enqueue children
124
 
            queue.extend(((cur, v) for v in self.arcs[cur]))
125
 
 
 
157
            for arc in self.arcs[target_widget]:
 
158
                queue.append((target_widget, arc))