提交 a8b98c32 编写于 作者: J Jonathan Thomas

Update keyboard mappings, and adding new Preferences for keyboard mappings (so...

Update keyboard mappings, and adding new Preferences for keyboard mappings (so users can configure them all). Also, added scrollbar support to dynamic preferences window. Also fixed regressions with Split Clip feature. Also updated translation POT template.
上级 903972bf
此差异已折叠。
......@@ -251,5 +251,268 @@
"type": "hidden",
"category": "Tutorial",
"setting": "tutorial_ids"
},
{
"category": "Keyboard",
"title": "&Preferences",
"restart": true,
"setting": "actionPreferences",
"value": "Ctrl+Shift+P",
"type": "text"
},
{
"category": "Keyboard",
"title": "&Quit",
"restart": true,
"setting": "actionQuit",
"value": "Ctrl+Q",
"type": "text"
},
{
"category": "Keyboard",
"title": "About OpenShot",
"restart": true,
"setting": "actionAbout",
"value": "Ctrl+H",
"type": "text"
},
{
"category": "Keyboard",
"title": "Add Marker",
"restart": true,
"setting": "actionAddMarker",
"value": "Ctrl+M",
"type": "text"
},
{
"category": "Keyboard",
"title": "Add to Timeline",
"restart": true,
"setting": "actionAdd_to_Timeline",
"value": "Ctrl+A",
"type": "text"
},
{
"category": "Keyboard",
"title": "Animated Title",
"restart": true,
"setting": "actionAnimatedTitle",
"value": "Ctrl+B",
"type": "text"
},
{
"category": "Keyboard",
"title": "Choose Profile",
"restart": true,
"setting": "actionProfile",
"value": "Ctrl+P",
"type": "text"
},
{
"category": "Keyboard",
"title": "Details View",
"restart": true,
"setting": "actionDetailsView",
"value": "Ctrl+D",
"type": "text"
},
{
"category": "Keyboard",
"title": "Export Video",
"restart": true,
"setting": "actionExportVideo",
"value": "Ctrl+E",
"type": "text"
},
{
"category": "Keyboard",
"title": "Fullscreen",
"restart": true,
"setting": "actionFullscreen",
"value": "F11",
"type": "text"
},
{
"category": "Keyboard",
"title": "Import Files...",
"restart": true,
"setting": "actionImportFiles",
"value": "Ctrl+F",
"type": "text"
},
{
"category": "Keyboard",
"title": "New Project...",
"restart": true,
"setting": "actionNew",
"value": "Ctrl+N",
"type": "text"
},
{
"category": "Keyboard",
"title": "Open Project...",
"restart": true,
"setting": "actionOpen",
"value": "Ctrl+O",
"type": "text"
},
{
"category": "Keyboard",
"title": "Redo",
"restart": true,
"setting": "actionRedo",
"value": "Ctrl+Y",
"type": "text"
},
{
"category": "Keyboard",
"title": "Save Project",
"restart": true,
"setting": "actionSave",
"value": "Ctrl+S",
"type": "text"
},
{
"category": "Keyboard",
"title": "Save Project As...",
"restart": true,
"setting": "actionSaveAs",
"value": "Ctrl+Shift+S",
"type": "text"
},
{
"category": "Keyboard",
"title": "Split Clip...",
"restart": true,
"setting": "actionSplitClip",
"value": "Ctrl+X",
"type": "text"
},
{
"category": "Keyboard",
"title": "Thumbnail View",
"restart": true,
"setting": "actionThumbnailView",
"value": "Ctrl+Shift+D",
"type": "text"
},
{
"category": "Keyboard",
"title": "Title",
"restart": true,
"setting": "actionTitle",
"value": "Ctrl+T",
"type": "text"
},
{
"category": "Keyboard",
"title": "Undo",
"restart": true,
"setting": "actionUndo",
"value": "Ctrl+Z",
"type": "text"
},
{
"category": "Keyboard",
"title": "Zoom In",
"restart": true,
"setting": "actionTimelineZoomIn",
"value": "=",
"type": "text"
},
{
"category": "Keyboard",
"title": "Zoom Out",
"restart": true,
"setting": "actionTimelineZoomOut",
"value": "-",
"type": "text"
},
{
"category": "Keyboard",
"title": "Previous Frame",
"restart": true,
"setting": "seekPreviousFrame",
"value": "Left",
"type": "text"
},
{
"category": "Keyboard",
"title": "Next Frame",
"restart": true,
"setting": "seekNextFrame",
"value": "Right",
"type": "text"
},
{
"category": "Keyboard",
"title": "Rewind",
"restart": true,
"setting": "rewindVideo",
"value": "J",
"type": "text"
},
{
"category": "Keyboard",
"title": "Fast Forward",
"restart": true,
"setting": "fastforwardVideo",
"value": "L",
"type": "text"
},
{
"category": "Keyboard",
"title": "Play/Pause Toggle",
"restart": true,
"setting": "playToggle",
"value": "Space",
"type": "text"
},
{
"category": "Keyboard",
"title": "Play/Pause Toggle (Alternate 1)",
"restart": true,
"setting": "playToggle1",
"value": "Up",
"type": "text"
},
{
"category": "Keyboard",
"title": "Play/Pause Toggle (Alternate 2)",
"restart": true,
"setting": "playToggle2",
"value": "Down",
"type": "text"
},
{
"category": "Keyboard",
"title": "Play/Pause Toggle (Alternate 3)",
"restart": true,
"setting": "playToggle3",
"value": "K",
"type": "text"
},
{
"category": "Keyboard",
"title": "Delete Item",
"restart": true,
"setting": "deleteItem",
"value": "Delete",
"type": "text"
},
{
"category": "Keyboard",
"title": "Delete Item (Alternate 1)",
"restart": true,
"setting": "deleteItem1",
"value": "Backspace",
"type": "text"
}
]
\ No newline at end of file
......@@ -56,10 +56,11 @@ class Cutting(QDialog):
previewFrameSignal = pyqtSignal(int)
refreshFrameSignal = pyqtSignal()
LoadFileSignal = pyqtSignal(str)
PlaySignal = pyqtSignal()
PlaySignal = pyqtSignal(int)
PauseSignal = pyqtSignal()
SeekSignal = pyqtSignal(int)
SpeedSignal = pyqtSignal(float)
StopSignal = pyqtSignal()
def __init__(self, file=None):
......@@ -157,7 +158,7 @@ class Cutting(QDialog):
if self.btnPlay.isChecked():
log.info('play (icon to pause)')
ui_util.setup_icon(self, self.btnPlay, "actionPlay", "media-playback-pause")
self.preview_thread.Play()
self.preview_thread.Play(self.video_length)
else:
log.info('pause (icon to play)')
ui_util.setup_icon(self, self.btnPlay, "actionPlay", "media-playback-start") # to default
......
......@@ -34,7 +34,7 @@ from uuid import uuid4
from copy import deepcopy
from PyQt5.QtCore import *
from PyQt5.QtGui import QIcon, QCursor
from PyQt5.QtGui import QIcon, QCursor, QKeySequence
from PyQt5.QtWidgets import *
import openshot # Python module for libopenshot (required video editing module installed separately)
......@@ -493,10 +493,12 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
log.info('Export Video add cancelled')
def actionUndo_trigger(self, event):
log.info('actionUndo_trigger')
app = get_app()
app.updates.undo()
def actionRedo_trigger(self, event):
log.info('actionRedo_trigger')
app = get_app()
app.updates.redo()
......@@ -856,6 +858,21 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
frame_to_seek = int(closest_position * fps_float)
self.SeekSignal.emit(frame_to_seek)
def getShortcutByName(self, setting_name):
""" Get a key sequence back from the setting name """
s = settings.get_settings()
shortcut = s.get(setting_name) or ""
return shortcut.lower()
def getAllKeyboardShortcuts(self):
""" Get a key sequence back from the setting name """
keyboard_shortcuts = []
all_settings = settings.get_settings()._data
for setting in all_settings:
if setting.get('category') == 'Keyboard':
keyboard_shortcuts.append(setting)
return keyboard_shortcuts
def keyPressEvent(self, event):
""" Add some shortkey for Player """
self.key = ""
......@@ -863,10 +880,43 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
# Get the video player object
player = self.preview_thread.player
log.info("keyPressEvent: player.Position(): %s" % player.Position())
# Determine what modifier keys are pressed
keypress_string = ""
if event.modifiers() & Qt.ControlModifier:
keypress_string += "Ctrl+"
if event.modifiers() & Qt.AltModifier:
keypress_string += "Alt+"
if event.modifiers() & Qt.ShiftModifier:
keypress_string += "Shift+"
if event.key() == Qt.Key_Left:
keypress_string += "Left"
elif event.key() == Qt.Key_Right:
keypress_string += "Right"
elif event.key() == Qt.Key_Up:
keypress_string += "Up"
elif event.key() == Qt.Key_Down:
keypress_string += "Down"
elif event.key() == Qt.Key_Delete:
keypress_string += "Delete"
elif event.key() == Qt.Key_Backspace:
keypress_string += "Backspace"
elif event.key() == Qt.Key_Space:
keypress_string += "Space"
elif event.key() == Qt.Key_Home:
keypress_string += "Home"
elif event.key() == Qt.Key_End:
keypress_string += "End"
else:
keypress_string += event.text()
# Convert to lower
keypress_string = keypress_string.lower()
# Debug
log.info("keyPressEvent: %s at player.Position(): %s" % (keypress_string, player.Position()))
# Basic shortcuts i.e just a letter
if event.key() == Qt.Key_Left:
if keypress_string == self.getShortcutByName("seekPreviousFrame"):
# Pause video
self.actionPlay_trigger(event, force="pause")
# Set speed to 0
......@@ -878,7 +928,7 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
# Notify properties dialog
self.propertyTableView.select_frame(player.Position())
elif event.key() == Qt.Key_Right:
elif keypress_string == self.getShortcutByName("seekNextFrame"):
# Pause video
self.actionPlay_trigger(event, force="pause")
# Set speed to 0
......@@ -890,57 +940,81 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
# Notify properties dialog
self.propertyTableView.select_frame(player.Position())
elif event.key() == Qt.Key_Up:
self.actionPlay.trigger()
elif event.key() == Qt.Key_Down:
self.actionPlay.trigger()
elif event.key() == Qt.Key_C:
self.actionPlay.trigger()
elif event.key() == Qt.Key_J:
elif keypress_string == self.getShortcutByName("rewindVideo"):
self.actionRewind.trigger()
ui_util.setup_icon(self, self.actionPlay, "actionPlay", "media-playback-pause")
self.actionPlay.setChecked(True)
elif event.key() == Qt.Key_K or event.key() == Qt.Key_Space:
self.actionPlay.trigger()
# Notify properties dialog
self.propertyTableView.select_frame(player.Position())
elif event.key() == Qt.Key_L:
elif keypress_string == self.getShortcutByName("fastforwardVideo"):
self.actionFastForward.trigger()
ui_util.setup_icon(self, self.actionPlay, "actionPlay", "media-playback-pause")
self.actionPlay.setChecked(True)
elif event.key() == Qt.Key_M:
elif keypress_string in [self.getShortcutByName("playToggle"),
self.getShortcutByName("playToggle1"),
self.getShortcutByName("playToggle2"),
self.getShortcutByName("playToggle3")] :
self.actionPlay.trigger()
elif event.key() == Qt.Key_D:
# Add the Ctrl key
if event.modifiers() & Qt.ControlModifier:
self.actionFastForward.trigger()
elif event.key() == Qt.Key_End:
# Add the Ctrl key
if event.modifiers() & Qt.ControlModifier:
self.actionFastForward.trigger()
elif event.key() == Qt.Key_Home:
# Add the Ctrl key
if event.modifiers() & Qt.ControlModifier:
self.actionFastForward.trigger()
# Notify properties dialog
self.propertyTableView.select_frame(player.Position())
elif event.key() == Qt.Key_Delete or event.key() == Qt.Key_Backspace:
elif keypress_string in [self.getShortcutByName("deleteItem"),
self.getShortcutByName("deleteItem1")]:
# Delete selected clip / transition
self.actionRemoveClip.trigger()
self.actionRemoveTransition.trigger()
# Boiler plate key mappings (mostly for menu support on Ubuntu/Unity)
elif keypress_string == self.getShortcutByName("actionNew"):
self.actionNew.trigger()
elif keypress_string == self.getShortcutByName("actionOpen"):
self.actionOpen.trigger()
elif keypress_string == self.getShortcutByName("actionSave"):
self.actionSave.trigger()
elif keypress_string == self.getShortcutByName("actionUndo"):
self.actionUndo.trigger()
elif keypress_string == self.getShortcutByName("actionSaveAs"):
self.actionSaveAs.trigger()
elif keypress_string == self.getShortcutByName("actionImportFiles"):
self.actionImportFiles.trigger()
elif keypress_string == self.getShortcutByName("actionRedo"):
self.actionRedo.trigger()
elif keypress_string == self.getShortcutByName("actionExportVideo"):
self.actionExportVideo.trigger()
elif keypress_string == self.getShortcutByName("actionQuit"):
self.actionQuit.trigger()
elif keypress_string == self.getShortcutByName("actionPreferences"):
self.actionPreferences.trigger()
elif keypress_string == self.getShortcutByName("actionAddMarker"):
self.actionAddMarker.trigger()
elif keypress_string == self.getShortcutByName("actionTimelineZoomIn"):
self.actionTimelineZoomIn.trigger()
elif keypress_string == self.getShortcutByName("actionTimelineZoomOut"):
self.actionTimelineZoomOut.trigger()
elif keypress_string == self.getShortcutByName("actionTitle"):
self.actionTitle.trigger()
elif keypress_string == self.getShortcutByName("actionAnimatedTitle"):
self.actionAnimatedTitle.trigger()
elif keypress_string == self.getShortcutByName("actionFullscreen"):
self.actionFullscreen.trigger()
elif keypress_string == self.getShortcutByName("actionAbout"):
self.actionAbout.trigger()
elif keypress_string == self.getShortcutByName("actionThumbnailView"):
self.actionThumbnailView.trigger()
elif keypress_string == self.getShortcutByName("actionDetailsView"):
self.actionDetailsView.trigger()
elif keypress_string == self.getShortcutByName("actionProfile"):
self.actionProfile.trigger()
elif keypress_string == self.getShortcutByName("actionAdd_to_Timeline"):
self.actionAdd_to_Timeline.trigger()
elif keypress_string == self.getShortcutByName("actionSplitClip"):
self.actionSplitClip.trigger()
# Bubble event on
event.ignore()
def actionProfile_trigger(self, event):
# Show dialog
from windows.profile import Profile
......@@ -960,6 +1034,11 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
# Find matching file
f = File.get(id=file_id)
# Bail out if no file selected
if not f:
log.info(self.selected_files)
return
# show dialog
from windows.cutting import Cutting
win = Cutting(f)
......@@ -1618,6 +1697,10 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
self.selected_tracks = []
self.selected_effects = []
# Clear selection in properties view
if self.propertyTableView:
self.propertyTableView.loadProperties.emit("", "")
def foundCurrentVersion(self, version):
"""Handle the callback for detecting the current version on openshot.org"""
log.info('foundCurrentVersion: Found the latest version: %s' % version)
......@@ -1663,6 +1746,12 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
# Load UI from designer
ui_util.load_ui(self, self.ui_path)
# Update all action-based shortcuts (from settings file)
for shortcut in self.getAllKeyboardShortcuts():
for action in self.findChildren(QAction):
if shortcut.get('setting') == action.objectName():
action.setShortcut(QKeySequence(shortcut.get('value')))
# Load user settings for window
s = settings.get_settings()
self.recent_menu = None
......@@ -1683,9 +1772,6 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
# Connect signals
self.RecoverBackup.connect(self.recover_backup)
# Init selection containers
self.clearSelections()
# Setup timeline
self.timeline = TimelineWebView(self)
self.frameWeb.layout().addWidget(self.timeline)
......@@ -1721,6 +1807,9 @@ class MainWindow(QMainWindow, updates.UpdateWatcher, updates.UpdateInterface):
self.dockPropertiesContent.layout().addWidget(self.selectionLabel, 0, 1)
self.dockPropertiesContent.layout().addWidget(self.propertyTableView, 2, 1)
# Init selection containers
self.clearSelections()
# Setup video preview QWidget
self.videoPreview = VideoWidget()
self.tabVideo.layout().insertWidget(0, self.videoPreview)
......
......@@ -81,6 +81,7 @@ class Preferences(QDialog):
self.requires_restart = False
self.category_names = {}
self.category_tabs = {}
self.category_scrollareas = {}
# Loop through settings and find all unique categories
for item in self.settings_data:
category = item["category"]
......@@ -91,13 +92,22 @@ class Preferences(QDialog):
if not category in self.category_names:
self.category_names[category] = []
# Add new category as a tab
# Create scrollarea
scroll_area = QScrollArea(self)
scroll_area.setWidgetResizable(True)
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
scroll_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
# Create tab widget and layout
layout = QVBoxLayout()
tabWidget = QWidget(self)
self.tabCategories.addTab(tabWidget, _(category))
self.category_tabs[category] = tabWidget
tabWidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
tabWidget.setLayout(layout)
scroll_area.setWidget(tabWidget)
# Add form layout to this tab
layout = QFormLayout(tabWidget)
# Add tab
self.tabCategories.addTab(scroll_area, _(category))
self.category_tabs[category] = tabWidget
# Append settings into correct category
self.category_names[category].append(item)
......@@ -203,9 +213,24 @@ class Preferences(QDialog):
# Add Label and Widget to the form
if (widget and label):
tabWidget.layout().addRow(label, widget)
# Add minimum size
label.setMinimumWidth(180);
label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
# Create HBox layout
layout_hbox = QHBoxLayout()
layout_hbox.addWidget(label)
layout_hbox.addWidget(widget)
# Add widget to layout
tabWidget.layout().addLayout(layout_hbox)
elif (label):
tabWidget.layout().addRow(label)
# Add widget to layout
tabWidget.layout().addWidget(label)
# Add stretch to bottom of layout
tabWidget.layout().addStretch()
def check_for_restart(self, param):
"""Check if the app needs to restart"""
......
......@@ -922,7 +922,7 @@
<string>Thumbnail View</string>
</property>
<property name="shortcut">
<string>Ctrl+I</string>
<string>Ctrl+E</string>
</property>
</action>
<action name="actionDetailsView">
......
......@@ -291,6 +291,10 @@ class FilesListView(QListView):
def refresh_view(self):
self.files_model.update_model()
def currentChanged(self, selected, deselected):
log.info('currentChanged')
self.updateSelection()
def resize_contents(self):
pass
......
......@@ -303,6 +303,10 @@ class FilesTreeView(QTreeView):
self.resizeColumnToContents(2)
self.resizeColumnToContents(1)
def currentChanged(self, selected, deselected):
log.info('currentChanged')
self.updateSelection()
def value_updated(self, item):
""" Name or tags updated """
# Get translation method
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册