[pitivi] Stop using UIManager because it's obsolete
- From: Thibault Saunier <tsaunier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] Stop using UIManager because it's obsolete
- Date: Thu, 17 Dec 2015 10:02:17 +0000 (UTC)
commit 7139f4f789efe2b958596aa30901ac4c21d66ad4
Author: Alexandru Băluț <alexandru balut gmail com>
Date: Sat Oct 31 23:17:23 2015 +0100
Stop using UIManager because it's obsolete
Refactored the management of the timeline actions. Now they are not
disabled when the timeline loses focus, because they are made available
only to the layers representation layout and the timeline toolbar. This
guarantees that the accelerators will trigger only if the focus is
the (PitiviTimeline's) layout widget. For details see
TimelineContainer._createActions.
A nice result is that the toolbar buttons don't flicker because the
actions are enabled or disabled too many times.
Fixes https://phabricator.freedesktop.org/T3416
Fixes https://phabricator.freedesktop.org/T3477
Reviewed-by: Thibault Saunier <tsaunier gnome org>
Differential Revision: https://phabricator.freedesktop.org/D546
data/ui/Makefile.am | 2 +-
data/ui/medialibrary.ui | 24 +---
data/ui/timelinecontainer.xml | 31 ----
data/ui/timelinetoolbar.ui | 133 ++++++++++++++++++
pitivi/effects.py | 2 +-
pitivi/mainwindow.py | 28 ++---
pitivi/medialibrary.py | 120 +++++++---------
pitivi/preset.py | 6 +-
pitivi/timeline/layer.py | 10 +-
pitivi/timeline/ruler.py | 15 +--
pitivi/timeline/timeline.py | 303 ++++++++++++++++++-----------------------
11 files changed, 346 insertions(+), 328 deletions(-)
---
diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am
index 87e2be8..053f108 100644
--- a/data/ui/Makefile.am
+++ b/data/ui/Makefile.am
@@ -14,7 +14,7 @@ ui_DATA = \
renderingdialog.ui \
renderingprogress.ui \
startupwizard.ui \
- timelinecontainer.xml \
+ timelinetoolbar.ui \
titleeditor.ui \
$(NULL)
diff --git a/data/ui/medialibrary.ui b/data/ui/medialibrary.ui
index f9960fb..88260c1 100644
--- a/data/ui/medialibrary.ui
+++ b/data/ui/medialibrary.ui
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.18.1 -->
+<!-- Generated with glade 3.19.0 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkToolbar" id="medialibrary_toolbar">
@@ -11,7 +11,6 @@
<object class="GtkToolButton" id="media_import_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="has_tooltip">True</property>
<property name="tooltip_markup" translatable="yes">Add media files to your project</property>
<property name="is_important">True</property>
<property name="label" translatable="yes">Import</property>
@@ -32,15 +31,12 @@
<child>
<object class="GtkToolButton" id="media_remove_button">
<property name="visible">True</property>
- <property name="sensitive">False</property>
<property name="can_focus">False</property>
- <property name="has_tooltip">True</property>
- <property name="tooltip_markup" translatable="yes">Remove selected clips from the project</property>
<property name="tooltip_text" translatable="yes">Remove selected clips from the project</property>
+ <property name="action_name">medialibrary.remove_assets</property>
<property name="label" translatable="yes">_Remove from Project</property>
<property name="use_underline">True</property>
<property name="icon_name">list-remove-symbolic</property>
- <signal name="clicked" handler="_removeClickedCb" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="media_remove_button-atkobject">
<property name="AtkObject::accessible-name">media_remove_button</property>
@@ -55,11 +51,8 @@
<child>
<object class="GtkToolButton" id="media_props_button">
<property name="visible">True</property>
- <property name="sensitive">False</property>
<property name="can_focus">False</property>
- <property name="has_tooltip">True</property>
- <property name="tooltip_markup" translatable="yes">Clip Properties...</property>
- <property name="tooltip_text" translatable="yes">Clip Properties...</property>
+ <property name="tooltip_text" translatable="yes">Clip properties...</property>
<property name="use_underline">True</property>
<property name="icon_name">document-properties-symbolic</property>
<signal name="clicked" handler="_clipPropertiesCb" swapped="no"/>
@@ -77,15 +70,12 @@
<child>
<object class="GtkToolButton" id="media_insert_button">
<property name="visible">True</property>
- <property name="sensitive">False</property>
<property name="can_focus">False</property>
- <property name="has_tooltip">True</property>
- <property name="tooltip_markup" translatable="yes">Insert the selected clips at the end of the
timeline</property>
<property name="tooltip_text" translatable="yes">Insert the selected clips at the end of the
timeline</property>
+ <property name="action_name">medialibrary.insert_assets_at_end</property>
<property name="label" translatable="yes">Insert at _End of Timeline</property>
<property name="use_underline">True</property>
<property name="icon_name">insert-object-symbolic</property>
- <signal name="clicked" handler="_insertEndCb" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="media_insert_button-atkobject">
<property name="AtkObject::accessible-name">media_insert_button</property>
@@ -125,7 +115,6 @@
<object class="GtkEntry" id="media_search_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="has_tooltip">True</property>
<property name="margin_start">3</property>
<property name="invisible_char">•</property>
<property name="primary_icon_name">starred-symbolic</property>
@@ -185,7 +174,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Close this message</property>
<signal name="clicked" handler="_warningInfoBarDismissedCb" swapped="no"/>
</object>
@@ -215,8 +203,8 @@
<object class="GtkLabel" id="warning_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="wrap">True</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
@@ -267,9 +255,9 @@
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Add media to your project by dragging files and
folders here or by using the "Import" button.</property>
<property name="wrap">True</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
diff --git a/data/ui/timelinetoolbar.ui b/data/ui/timelinetoolbar.ui
new file mode 100644
index 0000000..a610d82
--- /dev/null
+++ b/data/ui/timelinetoolbar.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.19.0 -->
+<interface>
+ <requires lib="gtk+" version="3.16"/>
+ <object class="GtkToolbar" id="timeline_toolbar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="toolbar_style">icons</property>
+ <child>
+ <object class="GtkToolButton" id="toolbutton1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Split clips at playhead position</property>
+ <property name="action_name">timeline.split_clips</property>
+ <property name="label" translatable="yes">Split</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">pitivi-split</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Delete clips</property>
+ <property name="action_name">timeline.delete_selected_clips</property>
+ <property name="label" translatable="yes">Delete</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-delete</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Group clips</property>
+ <property name="action_name">timeline.group_selected_clips</property>
+ <property name="label" translatable="yes">Group</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">pitivi-group</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Ungroup clips</property>
+ <property name="action_name">timeline.ungroup_selected_clips</property>
+ <property name="label" translatable="yes">Ungroup</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">pitivi-ungroup</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Copy clips</property>
+ <property name="action_name">timeline.copy_selected_clips</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-copy</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Paste clips</property>
+ <property name="action_name">timeline.paste_clips</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-paste</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Align clips based on their soundtracks</property>
+ <property name="visible_horizontal">False</property>
+ <property name="visible_vertical">False</property>
+ <property name="action_name">timeline.align_selected_clips</property>
+ <property name="label" translatable="yes">Align</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">pitivi-align</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleToolButton" id="gapless_button">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Toggle gapless mode
+When enabled, adjacent clips automatically move to fill gaps.</property>
+ <property name="action_name">timeline.toggle_gapless_mode</property>
+ <property name="label" translatable="yes">Gapless mode</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">pitivi-gapless</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/pitivi/effects.py b/pitivi/effects.py
index c724508..8c777bd 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -287,7 +287,7 @@ class EffectListWidget(Gtk.Box, Loggable):
""" Widget for listing effects """
- def __init__(self, instance, unused_uiman):
+ def __init__(self, instance):
Gtk.Box.__init__(self)
Loggable.__init__(self)
diff --git a/pitivi/mainwindow.py b/pitivi/mainwindow.py
index 879765e..5cf2d27 100644
--- a/pitivi/mainwindow.py
+++ b/pitivi/mainwindow.py
@@ -136,11 +136,9 @@ class PitiviMainWindow(Gtk.ApplicationWindow, Loggable):
self.connect("destroy", self._destroyedCb)
- self.uimanager = Gtk.UIManager()
self.setupCss()
self.builder_handler_ids = []
self.builder = Gtk.Builder()
- self.add_accel_group(self.uimanager.get_accel_group())
self._createUi()
self.recent_manager = Gtk.RecentManager()
@@ -292,8 +290,8 @@ class PitiviMainWindow(Gtk.ApplicationWindow, Loggable):
# First set of tabs
self.main_tabs = BaseTabs(self.app)
- self.medialibrary = MediaLibraryWidget(self.app, self.uimanager)
- self.effectlist = EffectListWidget(self.app, self.uimanager)
+ self.medialibrary = MediaLibraryWidget(self.app)
+ self.effectlist = EffectListWidget(self.app)
self.main_tabs.append_page(
self.medialibrary, Gtk.Label(label=_("Media Library")))
self.main_tabs.append_page(
@@ -330,7 +328,7 @@ class PitiviMainWindow(Gtk.ApplicationWindow, Loggable):
self.mainhpaned.pack2(self.viewer, resize=True, shrink=False)
# Now, the lower part: the timeline
- self.timeline_ui = TimelineContainer(self, self.app, self.uimanager)
+ self.timeline_ui = TimelineContainer(self, self.app)
self.timeline_ui.setProjectManager(self.app.project_manager)
self.vpaned.pack2(self.timeline_ui, resize=True, shrink=False)
@@ -373,7 +371,7 @@ class PitiviMainWindow(Gtk.ApplicationWindow, Loggable):
self.connect("configure-event", self._configureCb)
# Focus the timeline by default!
- self.timeline_ui.grab_focus()
+ self.focusTimeline()
self.updateTitle()
def _setDefaultPositions(self):
@@ -435,7 +433,10 @@ class PitiviMainWindow(Gtk.ApplicationWindow, Loggable):
self.context_tabs.set_current_page(page)
def focusTimeline(self):
- self.timeline_ui.grab_focus()
+ layers_representation = self.timeline_ui.timeline.layout
+ # Check whether it has focus already, grab_focus always emits an event.
+ if not layers_representation.props.is_focus:
+ layers_representation.grab_focus()
def _create_headerbar_buttons(self):
undo_button = Gtk.Button.new_from_icon_name(
@@ -479,15 +480,6 @@ class PitiviMainWindow(Gtk.ApplicationWindow, Loggable):
self._headerbar.pack_start(self.render_button)
def _set_keyboard_shortcuts(self):
- """
- You can't rely on Glade/GTKBuilder to set accelerators properly
- on menu items or buttons, it just doesn't work.
- GAction and GActionGroup are overkill and a massive PITA.
-
- This code keeps things *really* simple, and it actually works.
- Bonus points: the accelerators disable themselves when buttons or
- menu items are set_sensitive(False), which is exactly what we want.
- """
self.save_action = Gio.SimpleAction.new("save", None)
self.save_action.connect("activate", self._saveProjectCb)
self.add_action(self.save_action)
@@ -1323,11 +1315,11 @@ class PitiviMainWindow(Gtk.ApplicationWindow, Loggable):
def __titleTypeCb(self, widget, event, project):
if event.keyval == Gdk.KEY_Return:
- self.timeline_ui.grab_focus()
+ self.focusTimeline()
return True
elif event.keyval == Gdk.KEY_Escape:
widget.set_text(project.name)
- self.timeline_ui.grab_focus()
+ self.focusTimeline()
return True
return False
diff --git a/pitivi/medialibrary.py b/pitivi/medialibrary.py
index a9f07a6..7b1d567 100644
--- a/pitivi/medialibrary.py
+++ b/pitivi/medialibrary.py
@@ -85,13 +85,6 @@ STORE_MODEL_STRUCTURE = (
COL_LENGTH,
COL_SEARCH_TEXT) = list(range(len(STORE_MODEL_STRUCTURE)))
-ui = '''
-<ui>
- <accelerator action="RemoveSources" />
- <accelerator action="InsertEnd" />
-</ui>
-'''
-
# This whitelist is made from personal knowledge of file extensions in the wild,
# from gst-inspect |grep demux,
# http://en.wikipedia.org/wiki/Comparison_of_container_formats and
@@ -116,7 +109,7 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
'play': (GObject.SignalFlags.RUN_LAST, None,
(GObject.TYPE_PYOBJECT,))}
- def __init__(self, app, uiman):
+ def __init__(self, app):
Gtk.Box.__init__(self)
Loggable.__init__(self)
@@ -129,6 +122,8 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
self._draggedPaths = None
self.dragged = False
self.clip_view = self.app.settings.lastClipView
+ if self.clip_view not in (SHOW_TREEVIEW, SHOW_ICONVIEW):
+ self.clip_view = SHOW_ICONVIEW
self.import_start_time = time.time()
self._last_imported_uris = []
@@ -150,9 +145,7 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
toolbar = builder.get_object("medialibrary_toolbar")
toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR)
self._import_button = builder.get_object("media_import_button")
- self._remove_button = builder.get_object("media_remove_button")
self._clipprops_button = builder.get_object("media_props_button")
- self._insert_button = builder.get_object("media_insert_button")
self._listview_button = builder.get_object("media_listview_button")
searchEntry = builder.get_object("media_search_entry")
@@ -289,19 +282,20 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
# Hack so that the views have the same method as self
self.treeview.getSelectedItems = self.getSelectedItems
- # Keyboard shortcuts for some items in the gtkbuilder file
- selection_actions = (
- ("RemoveSources", Gtk.STOCK_DELETE, _("_Remove from Project"),
- "<Control>Delete", None, self._removeSourcesCb),
+ actions_group = Gio.SimpleActionGroup()
+ self.insert_action_group("medialibrary", actions_group)
+
+ self.remove_assets_action = Gio.SimpleAction.new("remove_assets", None)
+ self.remove_assets_action.connect("activate", self._removeAssetsCb)
+ actions_group.add_action(self.remove_assets_action)
+ self.app.add_accelerator("<Control>Delete", "medialibrary.remove_assets", None)
+
+ self.insert_at_end_action = Gio.SimpleAction.new("insert_assets_at_end", None)
+ self.insert_at_end_action.connect("activate", self._insertEndCb)
+ actions_group.add_action(self.insert_at_end_action)
+ self.app.add_accelerator("Insert", "medialibrary.insert_assets_at_end", None)
- ("InsertEnd", Gtk.STOCK_COPY, _("Insert at _End of Timeline"),
- "Insert", None, self._insertEndCb),
- )
- self.selection_actions = Gtk.ActionGroup(name="medialibraryselection")
- self.selection_actions.add_actions(selection_actions)
- self.selection_actions.set_sensitive(False)
- uiman.insert_action_group(self.selection_actions, 0)
- uiman.add_ui_from_string(ui)
+ self._updateActions()
# Set the state of the view mode toggle button.
self._listview_button.set_active(self.clip_view == SHOW_TREEVIEW)
@@ -350,10 +344,10 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
info = asset.get_info()
asset_uri = info.get_uri()
if asset_uri == uri:
- self.debug("Found asset: %s for uri: %s" % (asset, uri))
+ self.debug("Found asset: %s for uri: %s", asset, uri)
return asset
- self.warning("Did not find any asser for uri: %s" % (uri))
+ self.warning("Did not find any asset for uri: %s", uri)
def _setupViewAsDragAndDropSource(self, view):
view.drag_source_set(0, [], Gdk.DragAction.COPY)
@@ -367,10 +361,27 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
def _importSourcesCb(self, unused_action):
self._showImportSourcesDialog()
- def _removeSourcesCb(self, unused_action):
- self._removeSources()
+ def _removeAssetsCb(self, unused_action, unused_parameter):
+ """
+ Determine which clips are selected in the icon or list view,
+ and ask MediaLibrary to remove them from the project.
+ """
+ model = self.treeview.get_model()
+ paths = self.getSelectedPaths()
+ if not paths:
+ return
+ # use row references so we don't have to care if a path has been
+ # removed
+ rows = [Gtk.TreeRowReference.new(model, path)
+ for path in paths]
- def _insertEndCb(self, unused_action):
+ self.app.action_log.begin("remove asset from media library")
+ for row in rows:
+ asset = model[row.get_path()][COL_ASSET]
+ self.app.project_manager.current_project.remove_asset(asset)
+ self.app.action_log.commit()
+
+ def _insertEndCb(self, unused_action, unused_parameter):
self.app.gui.timeline_ui.insertAssets(self.getSelectedAssets(), -1)
def _searchEntryChangedCb(self, entry):
@@ -386,6 +397,11 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
entry.set_text("")
elif icon_pos == Gtk.EntryIconPosition.PRIMARY:
self._selectUnusedSources()
+ # Focus the container so the user can use Ctrl+Delete, for example.
+ if self.clip_view == SHOW_TREEVIEW:
+ self.treeview.grab_focus()
+ elif self.clip_view == SHOW_ICONVIEW:
+ self.iconview.grab_focus()
def _setRowVisible(self, model, iter, data):
"""
@@ -792,28 +808,6 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
dialogbox.destroy()
self._importDialog = None
- def _removeSources(self):
- """
- Determine which clips are selected in the icon or list view,
- and ask MediaLibrary to remove them from the project.
- """
- model = self.treeview.get_model()
- paths = self.getSelectedPaths()
- if not paths:
- return
- # use row references so we don't have to care if a path has been
- # removed
- rows = []
- for path in paths:
- row = Gtk.TreeRowReference.new(model, path)
- rows.append(row)
-
- self.app.action_log.begin("remove clip from source list")
- for row in rows:
- asset = model[row.get_path()][COL_ASSET]
- self.app.project_manager.current_project.remove_asset(asset)
- self.app.action_log.commit()
-
def _sourceIsUsed(self, asset):
"""Check if a given URI is present in the timeline"""
layers = self.app.project_manager.current_project.timeline.get_layers()
@@ -825,7 +819,7 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
def _selectUnusedSources(self):
"""
- Select, in the media library, unused sources in the project.
+ Select the assets not used by any clip in the project's timeline.
"""
project = self.app.project_manager.current_project
unused_sources_uris = []
@@ -858,10 +852,6 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
self.app.gui.showProjectSettingsDialog()
infobar.hide()
- def _removeClickedCb(self, unused_widget=None):
- """ Called when a user clicks on the remove button """
- self._removeSources()
-
def _clipPropertiesCb(self, unused_widget=None):
"""
Show the clip properties (resolution, framerate, audio channels...)
@@ -1005,20 +995,14 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
ts.select_path(path[0])
def _viewSelectionChangedCb(self, unused):
- selected_items = len(self.getSelectedPaths())
- if selected_items:
- self.selection_actions.set_sensitive(True)
- self._remove_button.set_sensitive(True)
- self._insert_button.set_sensitive(True)
- # Some actions can only be done on a single item at a time:
- self._clipprops_button.set_sensitive(False)
- if selected_items == 1:
- self._clipprops_button.set_sensitive(True)
- else:
- self.selection_actions.set_sensitive(False)
- self._remove_button.set_sensitive(False)
- self._insert_button.set_sensitive(False)
- self._clipprops_button.set_sensitive(False)
+ self._updateActions()
+
+ def _updateActions(self):
+ selected_count = len(self.getSelectedPaths())
+ self.remove_assets_action.set_enabled(selected_count)
+ self.insert_at_end_action.set_enabled(selected_count)
+ # Some actions can only be done on a single item at a time:
+ self._clipprops_button.set_sensitive(selected_count == 1)
def _itemOrRowActivatedCb(self, unused_view, path, *unused_column):
"""
diff --git a/pitivi/preset.py b/pitivi/preset.py
index 0a824cd..9c3193f 100644
--- a/pitivi/preset.py
+++ b/pitivi/preset.py
@@ -99,19 +99,19 @@ class PresetManager(GObject.Object, Loggable):
action = Gio.SimpleAction.new("new", None)
action.connect("activate", self._addPresetCb)
- action_group.insert(action)
+ action_group.add_action(action)
menu_model.append(_("New"), "preset.%s" % action.get_name())
self.action_new = action
action = Gio.SimpleAction.new("remove", None)
action.connect("activate", self._removePresetCb)
- action_group.insert(action)
+ action_group.add_action(action)
menu_model.append(_("Remove"), "preset.%s" % action.get_name())
self.action_remove = action
action = Gio.SimpleAction.new("save", None)
action.connect("activate", self._savePresetCb)
- action_group.insert(action)
+ action_group.add_action(action)
menu_model.append(_("Save"), "preset.%s" % action.get_name())
self.action_save = action
diff --git a/pitivi/timeline/layer.py b/pitivi/timeline/layer.py
index e7c77e5..5b623ae 100644
--- a/pitivi/timeline/layer.py
+++ b/pitivi/timeline/layer.py
@@ -225,31 +225,31 @@ class LayerControls(Gtk.EventBox, Loggable):
self.__move_layer_top_action = Gio.SimpleAction.new("move_layer_to_top", None)
action = self.__move_layer_top_action
action.connect("activate", self._moveLayerCb, -2)
- action_group.insert(action)
+ action_group.add_action(action)
menu_model.append(_("Move layer to top"), "layer.%s" % action.get_name().replace(" ", "."))
self.__move_layer_up_action = Gio.SimpleAction.new("move_layer_up", None)
action = self.__move_layer_up_action
action.connect("activate", self._moveLayerCb, -1)
- action_group.insert(action)
+ action_group.add_action(action)
menu_model.append(_("Move layer up"), "layer.%s" % action.get_name().replace(" ", "."))
self.__move_layer_down_action = Gio.SimpleAction.new("move_layer_down", None)
action = self.__move_layer_down_action
action.connect("activate", self._moveLayerCb, 1)
- action_group.insert(action)
+ action_group.add_action(action)
menu_model.append(_("Move layer down"), "layer.%s" % action.get_name().replace(" ", "."))
self.__move_layer_bottom_action = Gio.SimpleAction.new("move_layer_to_bottom", None)
action = self.__move_layer_bottom_action
action.connect("activate", self._moveLayerCb, 2)
- action_group.insert(action)
+ action_group.add_action(action)
menu_model.append(_("Move layer to bottom"), "layer.%s" % action.get_name().replace(" ", "."))
self.__delete_layer_action = Gio.SimpleAction.new("delete_layer", None)
action = self.__delete_layer_action
action.connect("activate", self._deleteLayerCb)
- action_group.insert(action)
+ action_group.add_action(action)
menu_model.append(_("Delete layer"), "layer.%s" % action.get_name())
return menu_model, action_group
diff --git a/pitivi/timeline/ruler.py b/pitivi/timeline/ruler.py
index fc2040e..4d0997b 100644
--- a/pitivi/timeline/ruler.py
+++ b/pitivi/timeline/ruler.py
@@ -72,11 +72,6 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
Loggable.__init__(self)
self.log("Creating new ScaleRuler")
- # Allows stealing focus from other GTK widgets, prevent accidents:
- self.props.can_focus = True
- self.connect("focus-in-event", self._focusInCb)
- self.connect("focus-out-event", self._focusOutCb)
-
self.timeline = timeline
self._background_color = timeline.get_style_context().lookup_color(
'theme_bg_color')[1]
@@ -113,14 +108,6 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
self.scales = SCALES
- def _focusInCb(self, unused_widget, unused_arg):
- self.log("Ruler has grabbed focus")
- self.timeline.setActionsSensitivity(True)
-
- def _focusOutCb(self, unused_widget, unused_arg):
- self.log("Ruler has lost focus")
- self.timeline.setActionsSensitivity(False)
-
def _hadjValueChangedCb(self, unused_arg):
self.pixbuf_offset = self.hadj.get_value()
self.queue_draw()
@@ -182,7 +169,7 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
def do_button_release_event(self, event):
self.debug("button released at x:%d", event.x)
- self.grab_focus() # Prevent other widgets from being confused
+ self.app.gui.focusTimeline()
return False
def do_motion_notify_event(self, event):
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index bf5254e..ae98d42 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -212,15 +212,13 @@ class Marquee(Gtk.Box, Loggable):
class Timeline(Gtk.EventBox, Zoomable, Loggable):
"""
- The main timeline Widget, it contains the representation of the GESTimeline
- without any extra widgets.
+ Contains the layer controls and the layers representation.
"""
__gtype_name__ = "PitiviTimeline"
def __init__(self, container, app):
- super(Timeline, self).__init__()
-
+ Gtk.EventBox.__init__(self)
Zoomable.__init__(self)
Loggable.__init__(self)
@@ -229,12 +227,16 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
self._project = None
self.bTimeline = None
+ self.props.can_focus = False
+
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.add(hbox)
# Stuff the layers representation in a Layout so we can have other
# widgets there, see below.
self.layout = Gtk.Layout()
+ self.layout.props.can_focus = True
+ self.layout.props.can_default = True
self.__layers_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.__layers_vbox.props.width_request = self.get_allocated_width()
self.__layers_vbox.props.height_request = self.get_allocated_height()
@@ -587,9 +589,10 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
return False
def __buttonPressEventCb(self, unused_widget, event):
+ self.debug("PRESSED %s", event)
+ self.app.gui.focusTimeline()
event_widget = self.get_event_widget(event)
- self.debug("PRESSED %s", event)
res, button = event.get_button()
if res and button == 1:
self.draggingElement = self._getParentOfType(event_widget, Clip)
@@ -1121,28 +1124,23 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
Container for zoom box, ruler, timeline, scrollbars and toolbar.
"""
- def __init__(self, gui, instance, ui_manager):
+ def __init__(self, gui, instance):
Zoomable.__init__(self)
Gtk.Grid.__init__(self)
Loggable.__init__(self)
- # Allows stealing focus from other GTK widgets, prevent accidents:
- self.props.can_focus = True
-
self.gui = gui
- self.ui_manager = ui_manager
self.app = instance
self._settings = self.app.settings
+ self._autoripple_active = self._settings.timelineAutoRipple
self._projectmanager = None
self._project = None
self.bTimeline = None
self.__copiedGroup = None
- self.ui_manager.add_ui_from_file(
- os.path.join(get_ui_dir(), "timelinecontainer.xml"))
- self._createActions()
self._createUi()
+ self._createActions()
self._settings.connect("edgeSnapDeadbandChanged",
self._snapDistanceChangedCb)
@@ -1269,21 +1267,17 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
return GES.EditMode.EDIT_TRIM
return GES.EditMode.EDIT_NORMAL
- def setActionsSensitivity(self, sensitive):
- """
- The timeline's "actions" have global keyboard shortcuts that are
- dangerous in any context other than the timeline. In a text entry widget
- for example, you don't want the "Delete" key to remove clips currently
- selected on the timeline, or "Spacebar" to toggle playback.
-
- This sets the sensitivity of all actiongroups that might interfere.
- """
- self.playhead_actions.set_sensitive(sensitive)
- self.debug("Playback shortcuts sensitivity set to %s", sensitive)
-
- sensitive = sensitive and self.timeline.selection
- self.selection_actions.set_sensitive(sensitive)
- self.debug("Editing shortcuts sensitivity set to %s", sensitive)
+ def updateActions(self):
+ selection_non_empty = bool(self.timeline.selection)
+ self.delete_action.set_enabled(selection_non_empty)
+ self.group_action.set_enabled(selection_non_empty)
+ self.ungroup_action.set_enabled(selection_non_empty)
+ self.copy_action.set_enabled(selection_non_empty)
+ can_paste = bool(self.__copiedGroup and
+ self.__copiedGroup.get_children(True))
+ self.paste_action.set_enabled(can_paste)
+ self.align_action.set_enabled(selection_non_empty)
+ self.keyframe_action.set_enabled(selection_non_empty)
# Internal API
@@ -1308,14 +1302,15 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.ruler.setProjectFrameRate(24.)
self.ruler.hide()
- toolbar = self.ui_manager.get_widget("/TimelineToolBar")
- toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR)
- toolbar.set_orientation(Gtk.Orientation.VERTICAL)
- toolbar.set_style(Gtk.ToolbarStyle.ICONS)
- toolbar.get_accessible().set_name("timeline toolbar")
+ builder = Gtk.Builder()
+ builder.add_from_file(os.path.join(get_ui_dir(), "timelinetoolbar.ui"))
+ self.toolbar = builder.get_object("timeline_toolbar")
+ self.toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR)
+ self.toolbar.get_accessible().set_name("timeline toolbar")
+
+ self.gapless_button = builder.get_object("gapless_button")
+ self.gapless_button.set_active(self._autoripple_active)
- alter_style_class(".%s" % Gtk.STYLE_CLASS_INLINE_TOOLBAR, toolbar,
- "padding-left: %dpx; border-width: 0px; background: alpha (@base_color, 0.0);" %
(SPACING / 2))
alter_style_class(
".%s.trough" % Gtk.STYLE_CLASS_SCROLLBAR, self._vscrollbar,
"border: alpha (@base_color, 0.0); background: alpha (@base_color, 0.0);")
@@ -1323,24 +1318,12 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
".%s.trough" % Gtk.STYLE_CLASS_SCROLLBAR, self._hscrollbar,
"border: alpha (@base_color, 0.0); background: alpha (@base_color, 0.0);")
- # Toggle/pushbuttons like the "gapless mode" ones are special, it seems
- # you can't insert them as normal "actions", so we create them here:
- gapless_mode_button = Gtk.ToggleToolButton()
- gapless_mode_button.set_stock_id("pitivi-gapless")
- gapless_mode_button.set_tooltip_markup(_("Toggle gapless mode\n"
- "When enabled, adjacent clips automatically move to fill
gaps."))
- toolbar.add(gapless_mode_button)
- # Restore the state of the timeline's "gapless" mode:
- self._autoripple_active = self._settings.timelineAutoRipple
- gapless_mode_button.set_active(self._autoripple_active)
- gapless_mode_button.connect("toggled", self._gaplessmodeToggledCb)
-
self.attach(self.zoomBox, 0, 0, 1, 1)
self.attach(self.ruler, 1, 0, 1, 1)
self.attach(self.timeline, 0, 1, 2, 1)
self.attach(self._vscrollbar, 2, 1, 1, 1)
self.attach(self._hscrollbar, 1, 2, 1, 1)
- self.attach(toolbar, 3, 1, 1, 1)
+ self.attach(self.toolbar, 3, 1, 1, 1)
min_height = (self.ruler.get_size_request()[1] +
(EXPANDED_SIZE + SPACING) * 2 +
@@ -1396,91 +1379,86 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
return longest_layer
def _createActions(self):
- """
- Sets up the GtkActions. This allows managing the sensitivity of widgets
- to the mouse and keyboard shortcuts.
- """
- # TODO: use GAction + GActionGroup (Gio.SimpleAction +
- # Gio.SimpleActionGroup)
-
- # Action list items can vary in size (1-6 items). The first one is the
- # name, and it is the only mandatory option. All the other options are
- # optional, and if omitted will default to None.
- #
- # name (required), stock ID, translatable label,
- # keyboard shortcut, translatable tooltip, callback function
- zoom_in_tooltip = _("Zoom In")
- zoom_out_tooltip = _("Zoom Out")
- zoom_fit_tooltip = _("Zoom Fit")
- actions = (
- ("ZoomIn", Gtk.STOCK_ZOOM_IN, None,
- "<Control>plus", zoom_in_tooltip, self._zoomInCb),
-
- ("ZoomOut", Gtk.STOCK_ZOOM_OUT, None,
- "<Control>minus", zoom_out_tooltip, self._zoomOutCb),
-
- ("ZoomFit", Gtk.STOCK_ZOOM_FIT, None,
- "<Control>0", zoom_fit_tooltip, self._zoomFitCb),
-
- # Alternate keyboard shortcuts to the actions above
- ("ControlEqualAccel", Gtk.STOCK_ZOOM_IN, None,
- "<Control>equal", zoom_in_tooltip, self._zoomInCb),
-
- ("ControlKPAddAccel", Gtk.STOCK_ZOOM_IN, None,
- "<Control>KP_Add", zoom_in_tooltip, self._zoomInCb),
-
- ("ControlKPSubtractAccel", Gtk.STOCK_ZOOM_OUT, None,
- "<Control>KP_Subtract", zoom_out_tooltip, self._zoomOutCb),
- )
-
- selection_actions = (
- ("DeleteObj", Gtk.STOCK_DELETE, None,
- "Delete", _("Delete Selected"), self._deleteSelected),
-
- ("UngroupObj", "pitivi-ungroup", _("Ungroup"),
- "<Shift><Control>G", _("Ungroup clips"), self._ungroupSelected),
-
- # Translators: This is an action, the title of a button
- ("GroupObj", "pitivi-group", _("Group"),
- "<Control>G", _("Group clips"), self._groupSelected),
-
- ("Copy", "copy", _("Copy"),
- "<Control>c", _("Copy clips"), self.__copyClipsCb),
-
- ("Paste", "paste", _("Paste"),
- "<Control>v", _("Paste clips"), self.__pasteClipsCb),
-
- # TODO: Fix the align feature.
- # ("AlignObj", "pitivi-align", _("Align"),
- # "<Shift><Control>A", _("Align clips based on their soundtracks"), self._alignSelected),
- )
-
- playhead_actions = (
- ("PlayPause", Gtk.STOCK_MEDIA_PLAY, None,
- "space", _("Start Playback"), self._playPauseCb),
-
- ("Split", "pitivi-split", _("Split"),
- "S", _("Split clip at playhead position"), self._splitCb),
-
- ("Keyframe", "pitivi-keyframe", _("Add a Keyframe"),
- "K", _("Add a keyframe"), self._keyframeCb),
- )
-
- actiongroup = Gtk.ActionGroup(name="timelinepermanent")
- self.selection_actions = Gtk.ActionGroup(name="timelineselection")
- self.playhead_actions = Gtk.ActionGroup(name="timelineplayhead")
-
- actiongroup.add_actions(actions)
-
- self.ui_manager.insert_action_group(actiongroup, 0)
- 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.add_actions(playhead_actions)
- self.ui_manager.insert_action_group(self.playhead_actions, -1)
-
- self.selection_actions.get_action("Copy").set_gicon(Gio.Icon.new_for_string("edit-copy"))
- self.selection_actions.get_action("Paste").set_gicon(Gio.Icon.new_for_string("edit-paste"))
+ # The actions below are all added to this action group and they
+ # are accessible only to the self.timeline.layout and self.toolbar
+ # widgets (and their children) using the "timeline" prefix.
+ # When the action for an accelerator is searched, due to the "timeline"
+ # prefix, the accelerators work only when the focus is on one of these
+ # two widgets: the layout with the layers representation (excluding the
+ # controls) and the timeline toolbar.
+ group = Gio.SimpleActionGroup()
+ self.timeline.layout.insert_action_group("timeline", group)
+ self.toolbar.insert_action_group("timeline", group)
+
+ self.zoom_in_action = Gio.SimpleAction.new("zoom_in", None)
+ self.zoom_in_action.connect("activate", self._zoomInCb)
+ group.add_action(self.zoom_in_action)
+ self.app.add_accelerator("<Control>plus", "timeline.zoom_in", None)
+ self.app.add_accelerator("<Control>equal", "timeline.zoom_in", None)
+ self.app.add_accelerator("<Control>KP_Add", "timeline.zoom_in", None)
+
+ self.zoom_out_action = Gio.SimpleAction.new("zoom_out", None)
+ self.zoom_out_action.connect("activate", self._zoomOutCb)
+ group.add_action(self.zoom_out_action)
+ self.app.add_accelerator("<Control>minus", "timeline.zoom_out", None)
+ self.app.add_accelerator("<Control>KP_Subtract", "timeline.zoom_out", None)
+
+ self.zoom_fit_action = Gio.SimpleAction.new("zoom_fit", None)
+ self.zoom_fit_action.connect("activate", self._zoomFitCb)
+ group.add_action(self.zoom_fit_action)
+ self.app.add_accelerator("<Control>0", "timeline.zoom_fit", None)
+
+ # Clips actions.
+ self.delete_action = Gio.SimpleAction.new("delete_selected_clips", None)
+ self.delete_action.connect("activate", self._deleteSelected)
+ group.add_action(self.delete_action)
+ self.app.add_accelerator("Delete", "timeline.delete_selected_clips", None)
+
+ self.group_action = Gio.SimpleAction.new("group_selected_clips", None)
+ self.group_action.connect("activate", self._groupSelected)
+ group.add_action(self.group_action)
+ self.app.add_accelerator("<Control>g", "timeline.group_selected_clips", None)
+
+ self.ungroup_action = Gio.SimpleAction.new("ungroup_selected_clips", None)
+ self.ungroup_action.connect("activate", self._ungroupSelected)
+ group.add_action(self.ungroup_action)
+ self.app.add_accelerator("<Shift><Control>g", "timeline.ungroup_selected_clips", None)
+
+ self.copy_action = Gio.SimpleAction.new("copy_selected_clips", None)
+ self.copy_action.connect("activate", self.__copyClipsCb)
+ group.add_action(self.copy_action)
+ self.app.add_accelerator("<Control>c", "timeline.copy_selected_clips", None)
+
+ self.paste_action = Gio.SimpleAction.new("paste_clips", None)
+ self.paste_action.connect("activate", self.__pasteClipsCb)
+ group.add_action(self.paste_action)
+ self.app.add_accelerator("<Control>v", "timeline.paste_clips", None)
+
+ self.align_action = Gio.SimpleAction.new("align_selected_clips", None)
+ self.align_action.connect("activate", self._alignSelectedCb)
+ group.add_action(self.align_action)
+ self.app.add_accelerator("<Shift><Control>a", "timeline.align_selected_clips", None)
+
+ self.gapless_action = Gio.SimpleAction.new("toggle_gapless_mode", None)
+ self.gapless_action.connect("activate", self._gaplessmodeToggledCb)
+ group.add_action(self.gapless_action)
+
+ # Playhead actions.
+ self.play_action = Gio.SimpleAction.new("play", None)
+ self.play_action.connect("activate", self._playPauseCb)
+ group.add_action(self.play_action)
+ self.app.add_accelerator("space", "timeline.play", None)
+
+ self.split_action = Gio.SimpleAction.new("split_clips", None)
+ self.split_action.connect("activate", self._splitCb)
+ group.add_action(self.split_action)
+ self.app.add_accelerator("S", "timeline.split_clips", None)
+ self.split_action.set_enabled(True)
+
+ self.keyframe_action = Gio.SimpleAction.new("keyframe_selected_clips", None)
+ self.keyframe_action.connect("activate", self._keyframeCb)
+ group.add_action(self.keyframe_action)
+ self.app.add_accelerator("K", "timeline.keyframe_selected_clips", None)
def _setBestZoomRatio(self, allow_zoom_in=False):
"""
@@ -1557,7 +1535,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.timeline.queue_draw()
return False
- def _deleteSelected(self, unused_action):
+ def _deleteSelected(self, unused_action, unused_parameter):
if self.bTimeline:
self.app.action_log.begin("delete clip")
@@ -1572,7 +1550,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.timeline.selection.setSelection([], SELECT)
- def _ungroupSelected(self, unused_action):
+ def _ungroupSelected(self, unused_action, unused_parameter):
if self.bTimeline:
self.app.action_log.begin("ungroup")
@@ -1589,7 +1567,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.app.action_log.commit()
self._project.pipeline.commit_timeline()
- def _groupSelected(self, unused_action):
+ def _groupSelected(self, unused_action, unused_parameter):
if self.bTimeline:
self.app.action_log.begin("group")
@@ -1612,11 +1590,12 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self._project.pipeline.commit_timeline()
self.app.action_log.commit()
- def __copyClipsCb(self, unused_action):
+ def __copyClipsCb(self, unused_action, unused_parameter):
if self.timeline.current_group:
self.__copiedGroup = self.timeline.current_group.copy(True)
+ self.updateActions()
- def __pasteClipsCb(self, unused_action):
+ def __pasteClipsCb(self, unused_action, unused_parameter):
if self.__copiedGroup:
save = self.__copiedGroup.copy(True)
position = self._project.pipeline.getPosition()
@@ -1624,7 +1603,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.__copiedGroup = save
self._project.pipeline.commit_timeline()
- def _alignSelected(self, unused_action):
+ def _alignSelectedCb(self, unused_action, unused_parameter):
if not self.bTimeline:
self.error(
"Trying to use the autoalign feature with an empty timeline")
@@ -1647,7 +1626,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.error("Could not start the autoaligner: %s", e)
progress_dialog.window.destroy()
- def _splitCb(self, unused_action):
+ def _splitCb(self, unused_action, unused_parameter):
"""
If clips are selected, split them at the current playhead position.
Otherwise, split all clips at the playhead position.
@@ -1683,7 +1662,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
if not splitted and splitting_selection:
self._splitElements()
- def _keyframeCb(self, unused_action):
+ def _keyframeCb(self, unused_action, unused_parameter):
"""
Add or remove a keyframe at the current position of the selected clip.
"""
@@ -1708,7 +1687,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
interpolator.newKeyframe(position_in_obj)
self.app.action_log.commit()
- def _playPauseCb(self, unused_action):
+ def _playPauseCb(self, unused_action, unused_parameter):
self._project.pipeline.togglePlayback()
def transposeXY(self, x, y):
@@ -1750,12 +1729,15 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
else:
self._project.pipeline.stepFrame(self._framerate, -1)
self.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
+ return True
elif event.keyval == Gdk.KEY_Right:
if self._shiftMask:
self._seeker.seekRelative(Gst.SECOND)
else:
self._project.pipeline.stepFrame(self._framerate, 1)
self.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
+ return True
+ return False
def do_key_release_event(self, event):
if event.keyval == Gdk.KEY_Shift_L:
@@ -1765,17 +1747,11 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
def do_focus_in_event(self, unused_event):
self.log("Timeline has grabbed focus")
- self.setActionsSensitivity(True)
+ self.updateActions()
def do_focus_out_event(self, unused_event):
self.log("Timeline has lost focus")
- self.setActionsSensitivity(False)
-
- def do_button_press_event(self, event):
- self.pressed = True
- self.grab_focus() # Prevent other widgets from being confused
-
- return True
+ self.updateActions()
# Callbacks
def _renderingSettingsChangedCb(self, project, item, value):
@@ -1838,33 +1814,22 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.setProject(project)
- def _zoomInCb(self, unused_action):
+ def _zoomInCb(self, unused_action, unused_parameter):
Zoomable.zoomIn()
- def _zoomOutCb(self, unused_action):
+ def _zoomOutCb(self, unused_action, unused_parameter):
Zoomable.zoomOut()
- def _zoomFitCb(self, unused_action):
+ def _zoomFitCb(self, unused_action, unused_parameter):
self.zoomFit()
def _selectionChangedCb(self, selection):
"""
- The selected clips on the timeline canvas have changed with the
- "selection-changed" signal.
-
- This is where you apply global UI changes, unlike individual
- track elements' "selected-changed" signal from the Selected class.
+ The selected clips on the timeline have changed.
"""
- if selection:
- self.selection_actions.set_sensitive(True)
- else:
- self.selection_actions.set_sensitive(False)
+ self.updateActions()
- def _gaplessmodeToggledCb(self, button):
- if button.get_active():
- self.info("Automatic ripple activated")
- self._autoripple_active = True
- else:
- self.info("Automatic ripple deactivated")
- self._autoripple_active = False
+ def _gaplessmodeToggledCb(self, unused_action, unused_parameter):
+ self._autoripple_active = self.gapless_button.get_active()
+ self.info("Automatic ripple: %s", self._autoripple_active)
self._settings.timelineAutoRipple = self._autoripple_active
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]