[pitivi] Set up viewing of the widget + set up bindings



commit 6a9398b01c8104891dc5c7ea8675d9e4d1da8f9c
Author: Jakub Brindza <jakub brindza gmail com>
Date:   Mon Jun 13 10:27:08 2016 +0100

    Set up viewing of the widget + set up bindings
    
    Differential Revision: https://phabricator.freedesktop.org/D1080

 data/ui/mainmenubutton.ui       |    9 +++++
 pitivi/application.py           |   18 +++++++++
 pitivi/clipproperties.py        |    7 +++-
 pitivi/dialogs/startupwizard.py |   10 +++---
 pitivi/mainwindow.py            |   10 +++++
 pitivi/medialibrary.py          |   12 +++++-
 pitivi/shortcutswindow.py       |   73 +++++++++++++++++++++++++++++++++++++++
 pitivi/timeline/timeline.py     |   43 +++++++++++++++++-----
 8 files changed, 164 insertions(+), 18 deletions(-)
---
diff --git a/data/ui/mainmenubutton.ui b/data/ui/mainmenubutton.ui
index d2e94ef..c42905e 100644
--- a/data/ui/mainmenubutton.ui
+++ b/data/ui/mainmenubutton.ui
@@ -108,6 +108,15 @@
       </object>
     </child>
     <child>
+      <object class="GtkMenuItem" id="menu_shortcuts">
+       <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="action_name">app.shortcuts_window</property>
+        <property name="label" translatable="yes">Keyboard Shortcuts</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
       <object class="GtkMenuItem" id="menu_help">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
diff --git a/pitivi/application.py b/pitivi/application.py
index e07e77c..3e9bb40 100644
--- a/pitivi/application.py
+++ b/pitivi/application.py
@@ -20,6 +20,7 @@
 # Boston, MA 02110-1301, USA.
 import os
 import time
+from gettext import gettext as _
 
 from gi.repository import Gio
 from gi.repository import GObject
@@ -36,6 +37,8 @@ from pitivi.project import ProjectManager
 from pitivi.settings import get_dir
 from pitivi.settings import GlobalSettings
 from pitivi.settings import xdg_cache_home
+from pitivi.shortcutswindow import ShortcutsWindow
+from pitivi.shortcutswindow import show_shortcuts
 from pitivi.undo.project import ProjectObserver
 from pitivi.undo.timeline import TimelineObserver
 from pitivi.undo.undo import UndoableActionLog
@@ -152,20 +155,32 @@ class Pitivi(Gtk.Application, Loggable):
         self._syncDoUndo()
 
     def _createActions(self):
+        ShortcutsWindow.register_group("app", _("General"))
         self.undo_action = Gio.SimpleAction.new("undo", None)
         self.undo_action.connect("activate", self._undoCb)
         self.add_action(self.undo_action)
         self.set_accels_for_action("app.undo", ["<Control>z"])
+        ShortcutsWindow.add_action("app.undo", _("Undo the most recent action"))
 
         self.redo_action = Gio.SimpleAction.new("redo", None)
         self.redo_action.connect("activate", self._redoCb)
         self.add_action(self.redo_action)
         self.set_accels_for_action("app.redo", ["<Control><Shift>z"])
+        ShortcutsWindow.add_action("app.redo", _("Redo the most recent action"))
 
         self.quit_action = Gio.SimpleAction.new("quit", None)
         self.quit_action.connect("activate", self._quitCb)
         self.add_action(self.quit_action)
         self.set_accels_for_action("app.quit", ["<Control>q"])
+        ShortcutsWindow.add_action("app.quit", _("Quit"))
+
+        self.show_shortcuts_action = Gio.SimpleAction.new("shortcuts_window", None)
+        self.show_shortcuts_action.connect("activate", self._show_shortcuts_cb)
+        self.add_action(self.show_shortcuts_action)
+        self.set_accels_for_action("app.shortcuts_window", ["<Control>F1",
+                                                            "<Control>question"])
+        ShortcutsWindow.add_action("app.shortcuts_window",
+                                   _("Show the Shortcuts Window"))
 
     def do_activate(self):
         if self.gui:
@@ -350,6 +365,9 @@ class Pitivi(Gtk.Application, Loggable):
     def _redoCb(self, unused_action, unused_param):
         self.action_log.redo()
 
+    def _show_shortcuts_cb(self, unused_action, unused_param):
+        show_shortcuts(self)
+
     def _action_log_pre_push_cb(self, unused_action_log, action):
         try:
             st = action.asScenarioAction()
diff --git a/pitivi/clipproperties.py b/pitivi/clipproperties.py
index 0210404..d748f25 100644
--- a/pitivi/clipproperties.py
+++ b/pitivi/clipproperties.py
@@ -33,6 +33,7 @@ from pitivi.effects import AUDIO_EFFECT
 from pitivi.effects import EffectsPropertiesManager
 from pitivi.effects import HIDDEN_EFFECTS
 from pitivi.effects import VIDEO_EFFECT
+from pitivi.shortcutswindow import ShortcutsWindow
 from pitivi.undo.timeline import CommitTimelineFinalizingAction
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.ui import disable_scroll
@@ -230,11 +231,15 @@ class EffectProperties(Gtk.Expander, Loggable):
         effects_actions_group = Gio.SimpleActionGroup()
         self.treeview.insert_action_group("clipproperties-effects", effects_actions_group)
         buttons_box.insert_action_group("clipproperties-effects", effects_actions_group)
+        ShortcutsWindow.register_group("clipproperties-effects", _("Clip Effects"))
 
         self.remove_effect_action = Gio.SimpleAction.new("remove-effect", None)
         self.remove_effect_action.connect("activate", self._removeEffectCb)
         effects_actions_group.add_action(self.remove_effect_action)
-        self.app.set_accels_for_action("clipproperties-effects.remove-effect", ["Delete"])
+        self.app.set_accels_for_action("clipproperties-effects.remove-effect",
+                                       ["Delete"])
+        ShortcutsWindow.add_action("clipproperties-effects.remove-effect",
+                                   _("Remove the selected effect"))
         self.remove_effect_action.set_enabled(False)
         remove_effect_button.set_action_name("clipproperties-effects.remove-effect")
 
diff --git a/pitivi/dialogs/startupwizard.py b/pitivi/dialogs/startupwizard.py
index c2fc9df..a6c0a5b 100644
--- a/pitivi/dialogs/startupwizard.py
+++ b/pitivi/dialogs/startupwizard.py
@@ -26,6 +26,7 @@ from gi.repository import Gtk
 from pitivi.check import missing_soft_deps
 from pitivi.configure import get_ui_dir
 from pitivi.dialogs.depsmanager import DepsManager
+from pitivi.shortcutswindow import show_shortcuts
 from pitivi.utils.misc import show_user_manual
 
 
@@ -43,13 +44,12 @@ class StartUpWizard(object):
 
     @staticmethod
     def _userManualCb(unused_button):
-        """Handle a click on the Help button."""
+        """Handles a click on the Help button."""
         show_user_manual()
 
-    @staticmethod
-    def _cheatsheetCb(unused_button):
-        """Show the cheatsheet section of the user manual"""
-        show_user_manual("cheatsheet")
+    def _cheatsheetCb(self, unused_button):
+        """Shows the shortcuts cheatsheet"""
+        show_shortcuts(self.app)
 
     def __init__(self, app):
         self.app = app
diff --git a/pitivi/mainwindow.py b/pitivi/mainwindow.py
index 5aaab22..dc612e3 100644
--- a/pitivi/mainwindow.py
+++ b/pitivi/mainwindow.py
@@ -43,6 +43,7 @@ from pitivi.mediafilespreviewer import PreviewWidget
 from pitivi.medialibrary import MediaLibraryWidget
 from pitivi.project import ProjectSettingsDialog
 from pitivi.settings import GlobalSettings
+from pitivi.shortcutswindow import ShortcutsWindow
 from pitivi.tabsmanager import BaseTabs
 from pitivi.timeline.timeline import TimelineContainer
 from pitivi.titleeditor import TitleEditor
@@ -459,36 +460,45 @@ class MainWindow(Gtk.ApplicationWindow, Loggable):
         self._headerbar.pack_start(self.render_button)
 
     def _set_keyboard_shortcuts(self):
+        ShortcutsWindow.register_group("win", _("Project"))
         self.save_action = Gio.SimpleAction.new("save", None)
         self.save_action.connect("activate", self._saveProjectCb)
         self.add_action(self.save_action)
         self.app.set_accels_for_action("win.save", ["<Control>s"])
         self.save_button.set_action_name("win.save")
+        ShortcutsWindow.add_action("win.save", _("Save the current project"))
 
         self.new_project_action = Gio.SimpleAction.new("new-project", None)
         self.new_project_action.connect("activate", self._newProjectMenuCb)
         self.add_action(self.new_project_action)
         self.app.set_accels_for_action("win.new-project", ["<Control>n"])
+        ShortcutsWindow.add_action("win.new-project", _("Create a new project"))
 
         self.open_project_action = Gio.SimpleAction.new("open-project", None)
         self.open_project_action.connect("activate", self._openProjectCb)
         self.add_action(self.open_project_action)
         self.app.set_accels_for_action("win.open-project", ["<Control>o"])
+        ShortcutsWindow.add_action("win.open-project", _("Open a project"))
 
         self.save_as_action = Gio.SimpleAction.new("save-as", None)
         self.save_as_action.connect("activate", self._saveProjectAsCb)
         self.add_action(self.save_as_action)
         self.app.set_accels_for_action("win.save-as", ["<Control><Shift>s"])
+        ShortcutsWindow.add_action("win.save-as",
+                                   _("Save the current project as"))
 
         self.help_action = Gio.SimpleAction.new("help", None)
         self.help_action.connect("activate", self._userManualCb)
         self.add_action(self.help_action)
         self.app.set_accels_for_action("win.help", ["F1"])
+        ShortcutsWindow.add_action("win.help", _("Help"))
 
         self.menu_button_action = Gio.SimpleAction.new("menu-button", None)
         self.menu_button_action.connect("activate", self._menuCb)
         self.add_action(self.menu_button_action)
         self.app.set_accels_for_action("win.menu-button", ["F10"])
+        ShortcutsWindow.add_action("win.menu-button",
+                                   _("Show the menu button content"))
 
     def showProjectStatus(self):
         project = self.app.project_manager.current_project
diff --git a/pitivi/medialibrary.py b/pitivi/medialibrary.py
index 0d95426..232e9da 100644
--- a/pitivi/medialibrary.py
+++ b/pitivi/medialibrary.py
@@ -45,6 +45,7 @@ from pitivi.dialogs.clipmediaprops import ClipMediaPropsDialog
 from pitivi.dialogs.filelisterrordialog import FileListErrorDialog
 from pitivi.mediafilespreviewer import PreviewWidget
 from pitivi.settings import GlobalSettings
+from pitivi.shortcutswindow import ShortcutsWindow
 from pitivi.timeline.previewers import getThumbnailCache
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.misc import disconnectAllByFunc
@@ -423,16 +424,23 @@ class MediaLibraryWidget(Gtk.Box, Loggable):
 
         actions_group = Gio.SimpleActionGroup()
         self.insert_action_group("medialibrary", actions_group)
+        ShortcutsWindow.register_group("medialibrary", _("Media Library"))
 
         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.set_accels_for_action("medialibrary.remove-assets", ["<Control>Delete"])
+        self.app.set_accels_for_action("medialibrary.remove-assets",
+                                       ["<Control>Delete"])
+        ShortcutsWindow.add_action("medialibrary.remove-assets",
+                                   _("Remove the selected assets"))
 
         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.set_accels_for_action("medialibrary.insert-assets-at-end", ["Insert"])
+        self.app.set_accels_for_action("medialibrary.insert-assets-at-end",
+                                       ["Insert"])
+        ShortcutsWindow.add_action("medialibrary.insert-assets-at-end",
+                                   _("Insert selected assets at the end of the timeline"))
 
         self._updateActions()
 
diff --git a/pitivi/shortcutswindow.py b/pitivi/shortcutswindow.py
new file mode 100644
index 0000000..a07f04a
--- /dev/null
+++ b/pitivi/shortcutswindow.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+# Pitivi video editor
+# Copyright (c) 2016 Jakub Brindza<jakub brindza gmail com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+from gi.repository import Gtk
+
+from pitivi.utils.misc import show_user_manual
+
+
+class ShortcutsWindow(Gtk.ShortcutsWindow):
+    group_names = {}
+    group_actions = {}
+    groups = []
+
+    def __init__(self, app):
+        Gtk.ShortcutsWindow.__init__(self)
+        self.app = app
+        self.populate()
+        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
+        self.set_modal(True)
+
+    def populate(self):
+        """Gathers the accelerators and creates the structure of the window."""
+        section = Gtk.ShortcutsSection()
+        section.show()
+        for group_id in ShortcutsWindow.groups:
+            group = Gtk.ShortcutsGroup(title=ShortcutsWindow.group_names[group_id])
+            group.show()
+            for action, action_description in ShortcutsWindow.group_actions[group_id]:
+                accelerators = " ".join(self.app.get_accels_for_action(action))
+                short = Gtk.ShortcutsShortcut(title=action_description, accelerator=accelerators)
+                short.show()
+                group.add(short)
+            section.add(group)
+        # Method below must be called after the section has been populated,
+        # otherwise the shortcuts won't show up in search.
+        self.add(section)
+
+    @classmethod
+    def add_action(cls, action, accel_description):
+        action_prefix = action.split(".")[0]
+        try:
+            cls.group_actions[action_prefix].append((action, accel_description))
+        except KeyError:
+            cls.group_actions[action_prefix] = [(action, accel_description)]
+
+    @classmethod
+    def register_group(cls, action_prefix, group_name):
+        if action_prefix not in cls.groups:
+            cls.groups.append(action_prefix)
+        cls.group_names[action_prefix] = group_name
+
+
+def show_shortcuts(app):
+    if hasattr(Gtk, "ShortcutsWindow"):
+        shortcuts_window = ShortcutsWindow(app)
+        shortcuts_window.show()
+    else:
+        show_user_manual("cheatsheet")
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 3b2feb1..fb81bc7 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -31,6 +31,7 @@ from pitivi.autoaligner import AutoAligner
 from pitivi.configure import get_ui_dir
 from pitivi.dialogs.prefs import PreferencesDialog
 from pitivi.settings import GlobalSettings
+from pitivi.shortcutswindow import ShortcutsWindow
 from pitivi.timeline.elements import Clip
 from pitivi.timeline.elements import TransitionClip
 from pitivi.timeline.elements import TrimHandle
@@ -1423,55 +1424,71 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         group = Gio.SimpleActionGroup()
         self.timeline.layout.insert_action_group("timeline", group)
         self.toolbar.insert_action_group("timeline", group)
+        ShortcutsWindow.register_group("timeline", _("Timeline"))
 
         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.set_accels_for_action("timeline.zoom-in", ["<Control>plus",
-                                                            "<Control>equal",
-                                                            "<Control>KP_Add"])
+                                                            "<Control>equal"])
+        ShortcutsWindow.add_action("timeline.zoom-in", _("Zoom in"))
 
         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.set_accels_for_action("timeline.zoom-out", ["<Control>minus",
-                                                             "<Control>KP_Subtract"])
+        self.app.set_accels_for_action("timeline.zoom-out", ["<Control>minus"])
+        ShortcutsWindow.add_action("timeline.zoom-out", _("Zoom out"))
 
         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.set_accels_for_action("timeline.zoom-fit", ["<Control>0"])
+        ShortcutsWindow.add_action("timeline.zoom-fit",
+                                   _("Adjust zoom to fit the project to the window"))
 
         # 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.set_accels_for_action("timeline.delete-selected-clips", ["Delete"])
+        self.app.set_accels_for_action("timeline.delete-selected-clips",
+                                       ["Delete"])
+        ShortcutsWindow.add_action("timeline.delete-selected-clips",
+                                   _("Delete selected clips"))
 
         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.set_accels_for_action("timeline.group-selected-clips", ["<Control>g"])
+        self.app.set_accels_for_action("timeline.group-selected-clips",
+                                       ["<Control>g"])
+        ShortcutsWindow.add_action("timeline.group-selected-clips",
+                                   _("Group selected clips together"))
 
         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.set_accels_for_action("timeline.ungroup-selected-clips", ["<Shift><Control>g"])
+        self.app.set_accels_for_action("timeline.ungroup-selected-clips",
+                                       ["<Shift><Control>g"])
+        ShortcutsWindow.add_action("timeline.ungroup-selected-clips",
+                                   _("Ungroup selected clips"))
 
         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.set_accels_for_action("timeline.copy-selected-clips", ["<Control>c"])
+        self.app.set_accels_for_action("timeline.copy-selected-clips",
+                                       ["<Control>c"])
+        ShortcutsWindow.add_action("timeline.copy-selected-clips",
+                                   _("Copy selected clips"))
 
         self.paste_action = Gio.SimpleAction.new("paste-clips", None)
         self.paste_action.connect("activate", self.__pasteClipsCb)
         group.add_action(self.paste_action)
         self.app.set_accels_for_action("timeline.paste-clips", ["<Control>v"])
+        ShortcutsWindow.add_action("timeline.paste-clips",
+                                   _("Paste selected clips"))
 
         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.set_accels_for_action("timeline.align-selected-clips", ["<Shift><Control>a"])
 
         self.gapless_action = Gio.SimpleAction.new("toggle-gapless-mode", None)
         self.gapless_action.connect("activate", self._gaplessmodeToggledCb)
@@ -1482,17 +1499,23 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         self.play_action.connect("activate", self._playPauseCb)
         group.add_action(self.play_action)
         self.app.set_accels_for_action("timeline.play", ["space"])
+        ShortcutsWindow.add_action("timeline.play", _("Play"))
 
         self.split_action = Gio.SimpleAction.new("split-clips", None)
         self.split_action.connect("activate", self._splitCb)
         group.add_action(self.split_action)
         self.app.set_accels_for_action("timeline.split-clips", ["S"])
         self.split_action.set_enabled(True)
+        ShortcutsWindow.add_action("timeline.split-clips",
+                                   _("Split the clip at the position"))
 
         self.keyframe_action = Gio.SimpleAction.new("keyframe-selected-clips", None)
         self.keyframe_action.connect("activate", self._keyframe_cb)
         group.add_action(self.keyframe_action)
-        self.app.set_accels_for_action("timeline.keyframe-selected-clips", ["K"])
+        self.app.set_accels_for_action("timeline.keyframe-selected-clips",
+                                       ["K"])
+        ShortcutsWindow.add_action("timeline.keyframe-selected-clips",
+                                   _("Add keyframe to the keyframe curve of selected clip"))
 
     def _setBestZoomRatio(self, allow_zoom_in=False):
         """


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