[pitivi] undo: Use a context manager to commit the transaction
- From: Alexandru Băluț <alexbalut src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] undo: Use a context manager to commit the transaction
- Date: Sat, 16 Apr 2016 14:25:17 +0000 (UTC)
commit 2b7cacfc408bec5ccaa533d0a1e0e85dd29bb07f
Author: Alexandru Băluț <alexandru balut gmail com>
Date: Sat Apr 9 23:01:16 2016 +0200
undo: Use a context manager to commit the transaction
Differential Revision: https://phabricator.freedesktop.org/D900
pitivi/clipproperties.py | 47 +++++++---------
pitivi/effects.py | 5 +-
pitivi/medialibrary.py | 12 ++--
pitivi/project.py | 26 ++++-----
pitivi/timeline/layer.py | 7 +-
pitivi/timeline/timeline.py | 132 ++++++++++++++++++++-----------------------
pitivi/titleeditor.py | 13 ++--
pitivi/undo/undo.py | 31 ++++++++++
8 files changed, 142 insertions(+), 131 deletions(-)
---
diff --git a/pitivi/clipproperties.py b/pitivi/clipproperties.py
index 5bdbc4f..8bc7188 100644
--- a/pitivi/clipproperties.py
+++ b/pitivi/clipproperties.py
@@ -299,12 +299,11 @@ class EffectProperties(Gtk.Expander, Loggable):
self._removeEffect(effect)
def _removeEffect(self, effect):
- self.app.action_log.begin("remove effect")
- self.__remove_configuration_widget()
- self.effects_properties_manager.cleanCache(effect)
- effect.get_parent().remove(effect)
- self._project.timeline.commit()
- self.app.action_log.commit()
+ with self.app.action_log.started("remove effect"):
+ self.__remove_configuration_widget()
+ self.effects_properties_manager.cleanCache(effect)
+ effect.get_parent().remove(effect)
+ self._project.timeline.commit()
self._updateTreeview()
def addEffectToClip(self, clip, factory_name, priority=None):
@@ -317,13 +316,12 @@ class EffectProperties(Gtk.Expander, Loggable):
if track_type == GES.TrackType.AUDIO and media_type == AUDIO_EFFECT or \
track_type == GES.TrackType.VIDEO and media_type == VIDEO_EFFECT:
# Actually add the effect
- self.app.action_log.begin("add effect")
- effect = GES.Effect.new(bin_description=factory_name)
- clip.add(effect)
- if priority is not None and priority < len(model):
- clip.set_top_effect_priority(effect, priority)
- self._project.timeline.commit()
- self.app.action_log.commit()
+ with self.app.action_log.started("add effect"):
+ effect = GES.Effect.new(bin_description=factory_name)
+ clip.add(effect)
+ if priority is not None and priority < len(model):
+ clip.set_top_effect_priority(effect, priority)
+ self._project.timeline.commit()
self.__updateAll()
break
@@ -413,10 +411,9 @@ class EffectProperties(Gtk.Expander, Loggable):
# The paths are different.
effects = clip.get_top_effects()
effect = effects[source_index]
- self.app.action_log.begin("move effect")
- clip.set_top_effect_priority(effect, drop_index)
- self._project.timeline.commit()
- self.app.action_log.commit()
+ with self.app.action_log.started("move effect"):
+ clip.set_top_effect_priority(effect, drop_index)
+ self._project.timeline.commit()
self._project.pipeline.flushSeek()
new_path = Gtk.TreePath.new()
new_path.append_index(drop_index)
@@ -440,12 +437,11 @@ class EffectProperties(Gtk.Expander, Loggable):
def _effectActiveToggleCb(self, cellrenderertoggle, path):
_iter = self.storemodel.get_iter(path)
tck_effect = self.storemodel.get_value(_iter, COL_TRACK_EFFECT)
- self.app.action_log.begin("change active state")
- tck_effect.set_active(not tck_effect.is_active())
- cellrenderertoggle.set_active(tck_effect.is_active())
- self._updateTreeview()
- self._project.timeline.commit()
- self.app.action_log.commit()
+ with self.app.action_log.started("change active state"):
+ tck_effect.set_active(not tck_effect.is_active())
+ cellrenderertoggle.set_active(tck_effect.is_active())
+ self._updateTreeview()
+ self._project.timeline.commit()
def _expandedCb(self, unused_expander, unused_params):
self.__updateAll()
@@ -627,9 +623,8 @@ class TransformationProperties(Gtk.Expander, Loggable):
res, cvalue = self.source.get_child_property(prop)
assert res
if value != cvalue:
- self.app.action_log.begin("Transformation property change")
- self.source.set_child_property(prop, value)
- self.app.action_log.commit()
+ with self.app.action_log.started("Transformation property change"):
+ self.source.set_child_property(prop, value)
self._project.pipeline.commit_timeline()
self.app.gui.viewer.target.overlay_stack.update(self.source)
diff --git a/pitivi/effects.py b/pitivi/effects.py
index 4ef38e9..cd84209 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -591,9 +591,8 @@ class EffectsPropertiesManager:
value = Gst.Fraction(int(value.num), int(value.denom))
if value != self._current_element_values.get(prop.name):
- self.app.action_log.begin("Effect property change")
- effect.set_child_property(prop.name, value)
- self.app.action_log.commit()
+ with self.app.action_log.started("Effect property change"):
+ effect.set_child_property(prop.name, value)
self.app.project_manager.current_project.pipeline.flushSeek()
self._current_element_values[prop.name] = value
diff --git a/pitivi/medialibrary.py b/pitivi/medialibrary.py
index 4e089c3..3db82f0 100644
--- a/pitivi/medialibrary.py
+++ b/pitivi/medialibrary.py
@@ -541,13 +541,11 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
rows = [Gtk.TreeRowReference.new(model, path)
for path in paths]
- self.app.action_log.begin("remove asset from media library")
- for row in rows:
- asset = model[row.get_path()][COL_ASSET]
- self._project.remove_asset(asset)
- self.app.gui.timeline_ui.purgeAsset(asset.props.id)
-
- self.app.action_log.commit()
+ with self.app.action_log.started("remove asset from media library"):
+ for row in rows:
+ asset = model[row.get_path()][COL_ASSET]
+ self._project.remove_asset(asset)
+ self.app.gui.timeline_ui.purgeAsset(asset.props.id)
# The treeview can make some of the remaining items selected, so
# make sure none are selected.
diff --git a/pitivi/project.py b/pitivi/project.py
index fdaaedc..0ed89bc 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -1827,20 +1827,18 @@ class ProjectSettingsDialog(object):
self.year_spinbutton.get_adjustment().set_value(year)
def updateProject(self):
- self.app.action_log.begin("change project settings")
- self.project.name = self.title_entry.get_text()
- self.project.author = self.author_entry.get_text()
- self.project.year = str(self.year_spinbutton.get_value_as_int())
-
- self.project.videowidth = int(self.width_spinbutton.get_value())
- self.project.videoheight = int(self.height_spinbutton.get_value())
- self.project.videopar = self.par_fraction_widget.getWidgetValue()
- self.project.videorate = self.frame_rate_fraction_widget.getWidgetValue(
- )
-
- self.project.audiochannels = get_combo_value(self.channels_combo)
- self.project.audiorate = get_combo_value(self.sample_rate_combo)
- self.app.action_log.commit()
+ with self.app.action_log.started("change project settings"):
+ self.project.name = self.title_entry.get_text()
+ self.project.author = self.author_entry.get_text()
+ self.project.year = str(self.year_spinbutton.get_value_as_int())
+
+ self.project.videowidth = int(self.width_spinbutton.get_value())
+ self.project.videoheight = int(self.height_spinbutton.get_value())
+ self.project.videopar = self.par_fraction_widget.getWidgetValue()
+ self.project.videorate = self.frame_rate_fraction_widget.getWidgetValue()
+
+ self.project.audiochannels = get_combo_value(self.channels_combo)
+ self.project.audiorate = get_combo_value(self.sample_rate_combo)
def _responseCb(self, unused_widget, response):
"""Handle the dialog being closed."""
diff --git a/pitivi/timeline/layer.py b/pitivi/timeline/layer.py
index 11ec4a5..0fed9d1 100644
--- a/pitivi/timeline/layer.py
+++ b/pitivi/timeline/layer.py
@@ -253,10 +253,9 @@ class LayerControls(Gtk.EventBox, Loggable):
return menu_model, action_group
def _deleteLayerCb(self, unused_action, unused_parametter):
- self.app.action_log.begin("delete layer")
- self.ges_timeline.remove_layer(self.ges_layer)
- self.ges_timeline.get_asset().pipeline.commit_timeline()
- self.app.action_log.commit()
+ with self.app.action_log.started("delete layer"):
+ self.ges_timeline.remove_layer(self.ges_layer)
+ self.ges_timeline.get_asset().pipeline.commit_timeline()
def _moveLayerCb(self, unused_simple_action, unused_parametter, step):
index = self.ges_layer.get_priority()
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index ac835bf..3ae342a 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -781,16 +781,15 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
self.debug("Creating %s at %s", asset.props.id, Gst.TIME_ARGS(placement))
- self.app.action_log.begin("add clip")
- ges_clip = ges_layer.add_asset(asset,
- placement,
- 0,
- clip_duration,
- asset.get_supported_formats())
- placement += clip_duration
- self.current_group.add(ges_clip.get_toplevel_parent())
- self.selection.setSelection([], SELECT_ADD)
- self.app.action_log.commit()
+ with self.app.action_log.started("add clip"):
+ ges_clip = ges_layer.add_asset(asset,
+ placement,
+ 0,
+ clip_duration,
+ asset.get_supported_formats())
+ placement += clip_duration
+ self.current_group.add(ges_clip.get_toplevel_parent())
+ self.selection.setSelection([], SELECT_ADD)
self._project.pipeline.commit_timeline()
if not self.draggingElement:
@@ -1255,28 +1254,27 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
initial_position = self.__getInsertPosition(position)
clip_position = initial_position
- self.app.action_log.begin("add asset")
- for obj in objs:
- if isinstance(obj, GES.Clip):
- obj.set_start(clip_position)
- layer.add_clip(obj)
- duration = obj.get_duration()
- elif isinstance(obj, GES.Asset):
- if obj.is_image():
- duration = self.app.settings.imageClipLength * \
- Gst.SECOND / 1000.0
- else:
+ with self.app.action_log.started("add asset"):
+ for obj in objs:
+ if isinstance(obj, GES.Clip):
+ obj.set_start(clip_position)
+ layer.add_clip(obj)
duration = obj.get_duration()
+ elif isinstance(obj, GES.Asset):
+ if obj.is_image():
+ duration = self.app.settings.imageClipLength * \
+ Gst.SECOND / 1000.0
+ else:
+ duration = obj.get_duration()
- layer.add_asset(obj,
- start=clip_position,
- inpoint=0,
- duration=duration,
- track_types=obj.get_supported_formats())
- else:
- raise TimelineError("Cannot insert: %s" % type(obj))
- clip_position += duration
- self.app.action_log.commit()
+ layer.add_asset(obj,
+ start=clip_position,
+ inpoint=0,
+ duration=duration,
+ track_types=obj.get_supported_formats())
+ else:
+ raise TimelineError("Cannot insert: %s" % type(obj))
+ clip_position += duration
self._project.pipeline.commit_timeline()
if zoom_was_fitted:
@@ -1585,16 +1583,14 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
def _deleteSelected(self, unused_action, unused_parameter):
if self.ges_timeline:
- self.app.action_log.begin("delete clip")
-
- for clip in self.timeline.selection:
- layer = clip.get_layer()
- if isinstance(clip, GES.TransitionClip):
- continue
- layer.remove_clip(clip)
+ with self.app.action_log.started("delete clip"):
+ for clip in self.timeline.selection:
+ layer = clip.get_layer()
+ if isinstance(clip, GES.TransitionClip):
+ continue
+ layer.remove_clip(clip)
- self._project.pipeline.commit_timeline()
- self.app.action_log.commit()
+ self._project.pipeline.commit_timeline()
self.timeline.selection.setSelection([], SELECT)
@@ -1603,18 +1599,16 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.info("No ges_timeline set yet!")
return
- self.app.action_log.begin("ungroup")
+ with self.app.action_log.started("ungroup"):
+ for obj in self.timeline.selection:
+ toplevel = obj.get_toplevel_parent()
+ if toplevel == self.timeline.current_group:
+ for child in toplevel.get_children(False):
+ child.ungroup(False)
- for obj in self.timeline.selection:
- toplevel = obj.get_toplevel_parent()
- if toplevel == self.timeline.current_group:
- for child in toplevel.get_children(False):
- child.ungroup(False)
-
- self.timeline.resetSelectionGroup()
- self.timeline.selection.setSelection([], SELECT)
+ self.timeline.resetSelectionGroup()
+ self.timeline.selection.setSelection([], SELECT)
- self.app.action_log.commit()
self._project.pipeline.commit_timeline()
def _groupSelected(self, unused_action, unused_parameter):
@@ -1622,28 +1616,27 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.info("No timeline set yet?")
return
- self.app.action_log.begin("group")
- containers = set()
- new_group = None
- for obj in self.timeline.selection:
- toplevel = obj.get_toplevel_parent()
- if toplevel == self.timeline.current_group:
- for child in toplevel.get_children(False):
- containers.add(child)
- toplevel.ungroup(False)
- else:
- containers.add(toplevel)
+ with self.app.action_log.started("group"):
+ containers = set()
+ new_group = None
+ for obj in self.timeline.selection:
+ toplevel = obj.get_toplevel_parent()
+ if toplevel == self.timeline.current_group:
+ for child in toplevel.get_children(False):
+ containers.add(child)
+ toplevel.ungroup(False)
+ else:
+ containers.add(toplevel)
- if containers:
- new_group = GES.Container.group(list(containers))
+ if containers:
+ new_group = GES.Container.group(list(containers))
- self.timeline.resetSelectionGroup()
+ self.timeline.resetSelectionGroup()
- if new_group:
- self.timeline.current_group.add(new_group)
+ if new_group:
+ self.timeline.current_group.add(new_group)
- self._project.pipeline.commit_timeline()
- self.app.action_log.commit()
+ self._project.pipeline.commit_timeline()
def __copyClipsCb(self, unused_action, unused_parameter):
if self.timeline.current_group:
@@ -1686,9 +1679,8 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
If clips are selected, split them at the current playhead position.
Otherwise, split all clips at the playhead position.
"""
- self.app.action_log.begin("split clip")
- self._splitElements(self.timeline.selection.selected)
- self.app.action_log.commit()
+ with self.app.action_log.started("split clip"):
+ self._splitElements(self.timeline.selection.selected)
self.timeline.hideSnapBar()
self._project.pipeline.commit_timeline()
diff --git a/pitivi/titleeditor.py b/pitivi/titleeditor.py
index d3812fc..07f1ffb 100644
--- a/pitivi/titleeditor.py
+++ b/pitivi/titleeditor.py
@@ -103,13 +103,12 @@ class TitleEditor(Loggable):
self.settings["halignment"].append(en, n)
def _setChildProperty(self, name, value):
- self.app.action_log.begin("Title %s change" % name)
- self._setting_props = True
- try:
- assert self.source.set_child_property(name, value)
- finally:
- self._setting_props = False
- self.app.action_log.commit()
+ with self.app.action_log.started("Title %s change" % name):
+ self._setting_props = True
+ try:
+ assert self.source.set_child_property(name, value)
+ finally:
+ self._setting_props = False
def _backgroundColorButtonCb(self, widget):
color = gdk_rgba_to_argb(widget.get_rgba())
diff --git a/pitivi/undo/undo.py b/pitivi/undo/undo.py
index 690becc..dd6eb84 100644
--- a/pitivi/undo/undo.py
+++ b/pitivi/undo/undo.py
@@ -21,6 +21,7 @@
"""
Base classes for undo/redo.
"""
+import contextlib
import weakref
from gi.repository import GObject
@@ -146,7 +147,19 @@ class UndoableActionLog(GObject.Object, Loggable):
self.running = False
self._checkpoint = self._takeSnapshot()
+ @contextlib.contextmanager
+ def started(self, action_group_name, finalizing_action=None):
+ """
+ Returns a context manager which commits the transaction at the end.
+ """
+ self.begin(action_group_name, finalizing_action)
+ yield
+ self.commit()
+
def begin(self, action_group_name, finalizing_action=None):
+ """
+ Starts a transaction aka a high-level operation.
+ """
if self.running:
self.debug("Abort because running")
return
@@ -158,6 +171,9 @@ class UndoableActionLog(GObject.Object, Loggable):
self.emit("begin", stack)
def push(self, action):
+ """
+ Adds an action to the current transaction.
+ """
if action is not None:
try:
st = action.asScenarioAction()
@@ -181,6 +197,9 @@ class UndoableActionLog(GObject.Object, Loggable):
self.emit("push", stack, action)
def rollback(self):
+ """
+ Forgets about the last started transaction.
+ """
if self.running:
self.debug("Ignore rollback because running")
return
@@ -193,6 +212,9 @@ class UndoableActionLog(GObject.Object, Loggable):
stack.undo()
def commit(self):
+ """
+ Commits the last started transaction.
+ """
if self.running:
self.debug("Ignore commit because running")
return
@@ -212,6 +234,9 @@ class UndoableActionLog(GObject.Object, Loggable):
self.emit("commit", stack)
def undo(self):
+ """
+ Undo the last recorded operation.
+ """
if self.stacks:
raise UndoWrongStateError("Recording a transaction")
if not self.undo_stacks:
@@ -223,6 +248,9 @@ class UndoableActionLog(GObject.Object, Loggable):
self.emit("undo", stack)
def redo(self):
+ """
+ Redo the last undone operation.
+ """
if self.stacks:
raise UndoWrongStateError("Recording a transaction")
if not self.redo_stacks:
@@ -265,6 +293,9 @@ class UndoableActionLog(GObject.Object, Loggable):
return stack
def is_in_transaction(self):
+ """
+ Whether currently recording an operation.
+ """
return bool(self.stacks)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]