[pitivi] Refactor GTK+ actions and keyboard shortcuts
- From: Jean-FranÃois Fortin Tam <jfft src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] Refactor GTK+ actions and keyboard shortcuts
- Date: Sat, 9 Jun 2012 11:22:21 +0000 (UTC)
commit 493c226870575e3775afc9c91672e990da5fb5bb
Author: Jean-FranÃois Fortin Tam <nekohayo gmail com>
Date: Sat Jun 2 20:04:53 2012 -0400
Refactor GTK+ actions and keyboard shortcuts
Make the setActionsSensitive method simpler,
actually use action groups as they were meant to be and
remove cruft.
This makes the code more robust and a lot simpler.
pitivi/clipproperties.py | 7 +--
pitivi/effects.py | 6 +--
pitivi/mainwindow.py | 102 +++++++++++++++++--------------------------
pitivi/medialibrary.py | 6 +--
pitivi/timeline/timeline.py | 13 +++--
pitivi/transitions.py | 6 +--
pitivi/viewer.py | 8 +---
7 files changed, 59 insertions(+), 89 deletions(-)
---
diff --git a/pitivi/clipproperties.py b/pitivi/clipproperties.py
index 26b4b89..79b7343 100644
--- a/pitivi/clipproperties.py
+++ b/pitivi/clipproperties.py
@@ -468,10 +468,10 @@ class EffectProperties(gtk.Expander, gtk.HBox):
def _treeviewSelectionChangedCb(self, treeview):
if self.selection.count_selected_rows() == 0 and self.timeline_objects:
- self.app.gui.setActionsSensitive(['DeleteObj'], True)
+ self.app.gui.setActionsSensitive(True)
self._removeEffectBt.set_sensitive(False)
else:
- self.app.gui.setActionsSensitive(['DeleteObj'], False)
+ self.app.gui.setActionsSensitive(False)
self._removeEffectBt.set_sensitive(True)
self._updateEffectConfigUi()
@@ -593,8 +593,7 @@ class TransformationProperties(gtk.Expander):
def _getAndConnectToEffect(self, widget_name, property_name):
spinbtn = self.builder.get_object(widget_name)
- spinbtn.connect("output",
- self._onValueChangedCb, property_name)
+ spinbtn.connect("output", self._onValueChangedCb, property_name)
self.spin_buttons[property_name] = spinbtn
self.default_values[property_name] = spinbtn.get_value()
diff --git a/pitivi/effects.py b/pitivi/effects.py
index 16555c0..9809ed2 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -740,12 +740,10 @@ class EffectListWidget(gtk.VBox, Loggable):
entry.set_text("")
def searchEntryDesactvateCb(self, entry, event):
- self.app.gui.setActionsSensitive("default", True)
- self.app.gui.setActionsSensitive(['DeleteObj'], True)
+ self.app.gui.setActionsSensitive(True)
def searchEntryActivateCb(self, entry, event):
- self.app.gui.setActionsSensitive("default", False)
- self.app.gui.setActionsSensitive(['DeleteObj'], False)
+ self.app.gui.setActionsSensitive(False)
def _setRowVisible(self, model, iter, data):
if self.effectType.get_active() == model.get_value(iter, COL_EFFECT_TYPE):
diff --git a/pitivi/mainwindow.py b/pitivi/mainwindow.py
index 3a0433f..0128f0a 100644
--- a/pitivi/mainwindow.py
+++ b/pitivi/mainwindow.py
@@ -183,9 +183,6 @@ class PitiviMainWindow(gtk.Window, Loggable):
Loggable.__init__(self, "mainwindow")
self.app = instance
self.log("Creating MainWindow")
- self.actions = None
- self.toggleactions = None
- self.actiongroup = None
self.settings = instance.settings
self.is_fullscreen = False
self.prefsdialog = None
@@ -251,7 +248,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
#
# name (required), stock ID, translatable label,
# keyboard shortcut, translatable tooltip, callback function
- self.actions = [
+ actions = [
# In some cases we manually specify the translatable label,
# because we want to have the "..." at the end, indicating
# an action that requires "further interaction" from the user.
@@ -306,7 +303,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
("Help", None, _("_Help")),
]
- self.toggleactions = [
+ toggleactions = [
("FullScreen", gtk.STOCK_FULLSCREEN, None,
"F11", _("View the main window on the whole screen"), self._fullScreenCb),
@@ -318,49 +315,41 @@ class PitiviMainWindow(gtk.Window, Loggable):
self.settings.mainWindowShowTimelineToolbar),
]
- self.actiongroup = gtk.ActionGroup("mainwindow")
- self.actiongroup.add_actions(self.actions)
- self.actiongroup.add_toggle_actions(self.toggleactions)
+ self.main_actions = gtk.ActionGroup("mainwindow")
+ self.main_actions.add_actions(actions)
self.undock_action = gtk.Action("WindowizeViewer", _("Undock Viewer"),
_("Put the viewer in a separate window"), None)
- self.actiongroup.add_action(self.undock_action)
+ self.main_actions.add_action(self.undock_action)
+ self.toggle_actions = gtk.ActionGroup("mainwindowtoggles")
+ self.toggle_actions.add_toggle_actions(toggleactions)
- for action in self.actiongroup.list_actions():
+ important_actions = ("Undo", "SaveProject", "RenderProject")
+ for action in self.main_actions.list_actions():
action_name = action.get_name()
+ if action_name in important_actions:
+ # Force showing a label alongside the action's toolbar button
+ action.props.is_important = True
if action_name == "RenderProject":
# the button is set sensitive when the timeline duration changes
action.set_sensitive(False)
- action.props.is_important = True
self.render_button = action
- elif action_name in ["NewProject", "SaveProjectAs", "OpenProject"]:
- if instance.settings.fileSupportEnabled:
- action.set_sensitive(True)
- elif action_name == "SaveProject":
- action.props.is_important = True
+ elif action_name in ["NewProject", "SaveProject", "SaveProjectAs", "OpenProject"]:
if instance.settings.fileSupportEnabled:
action.set_sensitive(True)
- else:
- action.set_sensitive(False)
- elif action_name == "Undo":
- action.set_sensitive(True)
- action.props.is_important = True
elif action_name in [
"File", "Edit", "View", "Help",
- "About", "Quit", "ImportSourcesFolder",
- "FullScreen", "UserManual",
- "ShowHideMainToolbar", "ShowHideTimelineToolbar",
- "FrameForward", "FrameBackward",
- "SecondForward", "SecondBackward",
- "EdgeForward", "EdgeBackward",
+ "UserManual", "About", "Quit", "ImportSourcesFolder",
"Preferences", "Project", "ProjectSettings",
"Library", "Timeline", "Viewer", "WindowizeViewer"]:
action.set_sensitive(True)
else:
action.set_sensitive(False)
+ self.log("%s has been made insensitive" % action_name)
self.uimanager = gtk.UIManager()
self.add_accel_group(self.uimanager.get_accel_group())
- self.uimanager.insert_action_group(self.actiongroup, 0)
+ self.uimanager.insert_action_group(self.main_actions, 0)
+ self.uimanager.insert_action_group(self.toggle_actions, -1)
self.uimanager.add_ui_from_file(os.path.join(get_ui_dir(), "mainwindow.xml"))
def _createUi(self, instance, allow_full_screen):
@@ -464,14 +453,6 @@ class PitiviMainWindow(gtk.Window, Loggable):
if not self.settings.mainWindowShowTimelineToolbar:
ttb.props.visible = False
- # Actions with key accelerators that will be made unsensitive while
- # a gtk entry box is used to avoid conflicts.
- self.sensitive_actions = []
- for action in self.timeline_ui.playhead_actions:
- self.sensitive_actions.append(action[0])
- for action in self.toggleactions:
- self.sensitive_actions.append(action[0])
-
#application icon
self.set_icon_name("pitivi")
@@ -507,30 +488,27 @@ class PitiviMainWindow(gtk.Window, Loggable):
self.unfullscreen()
self.is_fullscreen = fullscreen
- #TODO check if it is the way to go
- def setActionsSensitive(self, action_names, sensitive):
+ def setActionsSensitive(self, sensitive):
"""
Grab (or release) keyboard letter keys focus/sensitivity
for operations such as typing text in an entry.
- @param action_names: The name of actions we want to set to (in)sensitive
- If set to "default", we use the default actions.
- @type action_names: A {list} of action names
- @param sensitive: %True if actions must be sensitive False otherwise
- @type action_names: C{Bool}
- """
- if action_names == "default":
- action_names = self.sensitive_actions
-
- for action in self.actiongroup.list_actions():
- if action.get_name() in action_names:
- action.set_sensitive(sensitive)
+ This toggles the sensitivity of all actiongroups that might interfere.
+ This means mostly the timeline's actions.
+ This method does not need to be called when creating a separate window.
+ """
+ self.log("Setting actions sensitivity to %s" % sensitive)
+ # The mainwindow's actions don't prevent typing into entry widgets;
+ # Only timeline actions (ex: deleting and play/pause) are dangerous.
if self.timeline_ui:
- for action_group in self.timeline_ui.ui_manager.get_action_groups():
- for action in action_group.list_actions():
- if action.get_name() in action_names:
- action.set_sensitive(sensitive)
+ # Don't loop in self.timeline_ui.ui_manager.get_action_groups()
+ # otherwise you'll get all the action groups of the application.
+ self.timeline_ui.playhead_actions.set_sensitive(sensitive)
+ selected = self.timeline_ui.timeline.selection.getSelectedTrackObjs()
+ if not sensitive or (sensitive and selected):
+ self.log("Setting timeline selection actions sensitivity to %s" % sensitive)
+ self.timeline_ui.selection_actions.set_sensitive(sensitive)
## Missing Plugin Support
@@ -561,8 +539,8 @@ class PitiviMainWindow(gtk.Window, Loggable):
self.settings.mainWindowHPanePosition = self.hpaned.get_position()
self.settings.mainWindowMainHPanePosition = self.mainhpaned.get_position()
self.settings.mainWindowVPanePosition = self.vpaned.get_position()
- mtb = self.actiongroup.get_action("ShowHideMainToolbar")
- ttb = self.actiongroup.get_action("ShowHideTimelineToolbar")
+ mtb = self.toggle_actions.get_action("ShowHideMainToolbar")
+ ttb = self.toggle_actions.get_action("ShowHideTimelineToolbar")
self.settings.mainWindowShowMainToolbar = mtb.props.active
self.settings.mainWindowShowTimelineToolbar = ttb.props.active
@@ -757,11 +735,11 @@ class PitiviMainWindow(gtk.Window, Loggable):
#self._syncDoUndo(self.app.action_log)
# Enable export functionality
- self.actiongroup.get_action("ExportProject").set_sensitive(True)
+ self.main_actions.get_action("ExportProject").set_sensitive(True)
if self._missingUriOnLoading:
self.app.current.setModificationState(True)
- self.actiongroup.get_action("SaveProject").set_sensitive(True)
+ self.main_actions.get_action("SaveProject").set_sensitive(True)
self._missingUriOnLoading = False
if self.app.current.timeline.props.duration != 0:
@@ -1013,19 +991,19 @@ class PitiviMainWindow(gtk.Window, Loggable):
self._syncDoUndo(action_log)
def _syncDoUndo(self, action_log):
- undo_action = self.actiongroup.get_action("Undo")
+ undo_action = self.main_actions.get_action("Undo")
can_undo = bool(action_log.undo_stacks)
undo_action.set_sensitive(can_undo)
dirty = action_log.dirty()
- save_action = self.actiongroup.get_action("SaveProject")
+ save_action = self.main_actions.get_action("SaveProject")
save_action.set_sensitive(dirty)
if self.app.current.uri is not None:
- revert_action = self.actiongroup.get_action("RevertToSavedProject")
+ revert_action = self.main_actions.get_action("RevertToSavedProject")
revert_action.set_sensitive(dirty)
self.app.current.setModificationState(dirty)
- redo_action = self.actiongroup.get_action("Redo")
+ redo_action = self.main_actions.get_action("Redo")
can_redo = bool(action_log.redo_stacks)
redo_action.set_sensitive(can_redo)
self.updateTitle()
diff --git a/pitivi/medialibrary.py b/pitivi/medialibrary.py
index ca66f3c..a279e53 100644
--- a/pitivi/medialibrary.py
+++ b/pitivi/medialibrary.py
@@ -565,16 +565,14 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
This is used when focusing the search entry, icon on tree view widgets.
"""
- self.app.gui.setActionsSensitive("default", False)
- self.app.gui.setActionsSensitive(['DeleteObj'], False)
+ self.app.gui.setActionsSensitive(False)
def _enableKeyboardShortcutsCb(self, *unused_args):
"""
When focusing out of media library widgets,
re-enable the timeline keyboard shortcuts.
"""
- self.app.gui.setActionsSensitive("default", True)
- self.app.gui.setActionsSensitive(['DeleteObj'], True)
+ self.app.gui.setActionsSensitive(True)
def _trackObjectAddedCb(self, source, trackobj):
""" After an object has been added to the first track, position it
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 2542330..4deac36 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -732,7 +732,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
"<Shift><Control>A", ALIGN, self.alignSelected),
)
- self.playhead_actions = (
+ playhead_actions = (
("PlayPause", gtk.STOCK_MEDIA_PLAY, None,
"space", _("Start Playback"), self.playPause),
@@ -753,11 +753,14 @@ class Timeline(gtk.Table, Loggable, Zoomable):
actiongroup.add_actions(actions)
self.ui_manager.insert_action_group(actiongroup, 0)
- actiongroup = gtk.ActionGroup("timelineselection")
- actiongroup.add_actions(selection_actions)
- actiongroup.add_actions(self.playhead_actions)
+ self.selection_actions = gtk.ActionGroup("timelineselection")
+ self.selection_actions.add_actions(selection_actions)
+ self.selection_actions.set_sensitive(False)
+ self.ui_manager.insert_action_group(self.selection_actions, -1)
+ self.playhead_actions = gtk.ActionGroup("timelineplayhead")
+ self.playhead_actions.add_actions(playhead_actions)
+ self.ui_manager.insert_action_group(self.playhead_actions, -1)
- self.ui_manager.insert_action_group(actiongroup, -1)
self.ui_manager.add_ui_from_string(ui)
# drag and drop
diff --git a/pitivi/transitions.py b/pitivi/transitions.py
index 0ac6879..43f43e1 100644
--- a/pitivi/transitions.py
+++ b/pitivi/transitions.py
@@ -211,12 +211,10 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
entry.set_text("")
def _searchEntryDeactivateCb(self, entry, event):
- self.app.gui.setActionsSensitive("default", True)
- self.app.gui.setActionsSensitive(['DeleteObj'], True)
+ self.app.gui.setActionsSensitive(True)
def _searchEntryActivateCb(self, entry, event):
- self.app.gui.setActionsSensitive("default", False)
- self.app.gui.setActionsSensitive(['DeleteObj'], False)
+ self.app.gui.setActionsSensitive(False)
# GES callbacks
diff --git a/pitivi/viewer.py b/pitivi/viewer.py
index 15d8bc3..f1b958f 100644
--- a/pitivi/viewer.py
+++ b/pitivi/viewer.py
@@ -266,14 +266,10 @@ class PitiviViewer(gtk.VBox, Loggable):
self.warning("could not set ratio !")
def _entryFocusInCb(self, entry, event):
- sensitive_actions = self.app.gui.sensitive_actions
- self.app.gui.setActionsSensitive(sensitive_actions, False)
- self.app.gui.setActionsSensitive(['DeleteObj'], False)
+ self.app.gui.setActionsSensitive(False)
def _entryFocusOutCb(self, entry, event):
- sensitive_actions = self.app.gui.sensitive_actions
- self.app.gui.setActionsSensitive(sensitive_actions, True)
- self.app.gui.setActionsSensitive(['DeleteObj'], True)
+ self.app.gui.setActionsSensitive(True)
## active Timeline calllbacks
def _durationChangedCb(self, unused_pipeline, duration):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]