diff --git a/src/settings/_default.settings b/src/settings/_default.settings
index 459370da9d..4371eef88f 100644
--- a/src/settings/_default.settings
+++ b/src/settings/_default.settings
@@ -687,10 +687,6 @@
"value": "-",
"type": "text"
},
-
-
-
-
{
"category": "Keyboard",
"title": "Previous Frame",
@@ -906,5 +902,21 @@
"setting": "nudgeRight",
"value": "Shift+Right",
"type": "text"
+ },
+ {
+ "category": "Keyboard",
+ "title": "Edit Title",
+ "restart": true,
+ "setting": "actionEditTitle",
+ "value": "",
+ "type": "text"
+ },
+ {
+ "category": "Keyboard",
+ "title": "Duplicate Title",
+ "restart": true,
+ "setting": "actionDuplicateTitle",
+ "value": "Ctrl+Shift+C",
+ "type": "text"
}
]
diff --git a/src/windows/main_window.py b/src/windows/main_window.py
index ea6ae1497d..5f39900734 100644
--- a/src/windows/main_window.py
+++ b/src/windows/main_window.py
@@ -395,20 +395,13 @@ def actionEditTitle_trigger(self, event):
file = File.get(id=selected_file_id)
file_path = file.data.get("path")
- # Delete thumbnail for this file (it will be recreated soon)
- thumb_path = os.path.join(info.THUMBNAIL_PATH, "{}.png".format(file.id))
-
- # Check if thumb exists (and delete it)
- if os.path.exists(thumb_path):
- os.remove(thumb_path)
-
# show dialog for editing title
from windows.title_editor import TitleEditor
win = TitleEditor(file_path)
# Run the dialog event loop - blocking interaction on this window during that time
result = win.exec_()
- # Force update of files model (which will rebuild missing thumbnails)
+ # Force update of files model (which will rebuild thumbnails)
get_app().window.filesTreeView.refresh_view()
# Force update of clips
@@ -423,10 +416,18 @@ def actionEditTitle_trigger(self, event):
def actionDuplicateTitle_trigger(self, event):
- # Get selected svg title file
- selected_file_id = self.selected_files[0]
- file = File.get(id=selected_file_id)
- file_path = file.data.get("path")
+ file_path = None
+
+ # Loop through selected files (set 1 selected file if more than 1)
+ for file_id in self.selected_files:
+ # Find matching file
+ f = File.get(id=file_id)
+ if f.data.get("path").endswith(".svg"):
+ file_path = f.data.get("path")
+ break
+
+ if not file_path:
+ return
# show dialog for editing title
from windows.title_editor import TitleEditor
@@ -911,7 +912,7 @@ def actionPreview_File_trigger(self, event):
# Bail out if no file selected
if not f:
- log.info(self.selected_files)
+ log.info("Preview action failed, selected files: {}".format(self.selected_files))
return
# show dialog
@@ -1260,7 +1261,6 @@ def actionArrowTool_trigger(self, event):
def actionSnappingTool_trigger(self, event):
log.info("actionSnappingTool_trigger")
- log.info(self.actionSnappingTool.isChecked())
# Enable / Disable snapping mode
self.timeline.SetSnappingMode(self.actionSnappingTool.isChecked())
@@ -1344,7 +1344,6 @@ def actionPreviousMarker_trigger(self, event):
def actionNextMarker_trigger(self, event):
log.info("actionNextMarker_trigger")
- log.info(self.preview_thread.current_frame)
# Calculate current position (in seconds)
fps = get_app().project.get("fps")
@@ -1487,7 +1486,7 @@ def keyPressEvent(self, event):
self.actionRemoveClip.trigger()
self.actionRemoveTransition.trigger()
- # Boiler plate key mappings (mostly for menu support on Ubuntu/Unity)
+ # Menu shortcuts
elif key.matches(self.getShortcutByName("actionNew")) == QKeySequence.ExactMatch:
self.actionNew.trigger()
elif key.matches(self.getShortcutByName("actionOpen")) == QKeySequence.ExactMatch:
@@ -1526,6 +1525,11 @@ def keyPressEvent(self, event):
self.actionTitle.trigger()
elif key.matches(self.getShortcutByName("actionAnimatedTitle")) == QKeySequence.ExactMatch:
self.actionAnimatedTitle.trigger()
+ elif key.matches(self.getShortcutByName("actionDuplicateTitle")) == QKeySequence.ExactMatch:
+ log.info("Duplicating title, {}".format(event))
+ self.actionDuplicateTitle.trigger()
+ elif key.matches(self.getShortcutByName("actionEditTitle")) == QKeySequence.ExactMatch:
+ self.actionEditTitle.trigger()
elif key.matches(self.getShortcutByName("actionFullscreen")) == QKeySequence.ExactMatch:
self.actionFullscreen.trigger()
elif key.matches(self.getShortcutByName("actionAbout")) == QKeySequence.ExactMatch:
@@ -1602,8 +1606,9 @@ def keyPressEvent(self, event):
elif key.matches(self.getShortcutByName("selectNone")) == QKeySequence.ExactMatch:
self.timeline.ClearAllSelections()
- # Bubble event on
- event.ignore()
+ # If we didn't act on the event, forward it to the base class
+ else:
+ super(MainWindow, self).keyPressEvent(event)
def actionProfile_trigger(self, event):
@@ -1627,7 +1632,7 @@ def actionSplitClip_trigger(self, event):
# Bail out if no file selected
if not f:
- log.info(self.selected_files)
+ log.warn("Split clip action failed, selected files: {}".format(self.selected_files))
return
# show dialog
diff --git a/src/windows/ui/main-window.ui b/src/windows/ui/main-window.ui
index 3d1d26a20c..52a94d1aaf 100644
--- a/src/windows/ui/main-window.ui
+++ b/src/windows/ui/main-window.ui
@@ -888,7 +888,7 @@
- :/icons/Humanity/actions/custom/center-on-playhead.svg:/icons/Humanity/actions/custom/center-on-playhead.svg
+ :/icons/Humanity/actions/custom/center-on-playhead.svg:/icons/Humanity/actions/custom/center-on-playhead.svg
Center on Playhead
@@ -1552,9 +1552,6 @@
Edit Title
-
- Ctrl+Shift+T
-
@@ -1568,7 +1565,7 @@
Duplicate Title
- Ctrl+Shift+T
+ Ctrl+Shift+C
diff --git a/src/windows/views/files_listview.py b/src/windows/views/files_listview.py
index 65df788872..64e3d7efb5 100644
--- a/src/windows/views/files_listview.py
+++ b/src/windows/views/files_listview.py
@@ -48,39 +48,44 @@ class FilesListView(QListView):
drag_item_size = 48
def updateSelection(self):
- log.info('updateSelection')
-
# Track selected items
- self.selected = self.selectionModel().selectedIndexes()
+ m = self.files_model.model
+ selected_items = [m.itemFromIndex(x) for x in self.selectionModel().selectedIndexes()]
# Track selected file ids on main window
- rows = []
- self.win.selected_files = []
- for selection in self.selected:
- selected_row = self.files_model.model.itemFromIndex(selection).row()
- if selected_row not in rows:
- self.win.selected_files.append(self.files_model.model.item(selected_row, 5).text())
- rows.append(selected_row)
+ self.win.selected_files = [x.text() for x in self.selected_items if x.column() == 5]
def contextMenuEvent(self, event):
- # Update selection
- self.updateSelection()
# Set context menu mode
app = get_app()
app.context_menu_object = "files"
+ index = self.indexAt(event.pos())
+
+ # Build menu
menu = QMenu(self)
menu.addAction(self.win.actionImportFiles)
menu.addAction(self.win.actionDetailsView)
- if self.selected:
- # If file selected, show file related options
+
+ if index.isValid():
+ # Look up the model item and our unique ID
+ item = self.files_model.model.itemFromIndex(index)
+ file_id = self.files_model.model.item(item.row(), 5).text()
+
+ try:
+ # Check whether we know the item is selected
+ i = self.win.selected_files.index(file_id)
+ except ValueError:
+ # Add to our list, if it's not already there
+ self.win.selected_files.append(file_id)
+
+ # If a valid file is selected, show file related options
menu.addSeparator()
# Add edit title option (if svg file)
- selected_file_id = self.win.selected_files[0]
- file = File.get(id=selected_file_id)
+ file = File.get(id=file_id)
if file and file.data.get("path").endswith(".svg"):
menu.addAction(self.win.actionEditTitle)
menu.addAction(self.win.actionDuplicateTitle)
@@ -95,7 +100,7 @@ def contextMenuEvent(self, event):
menu.addSeparator()
# Show menu
- menu.exec_(QCursor.pos())
+ menu.exec_(event.globalPos())
def dragEnterEvent(self, event):
# If dragging urls onto widget, accept
@@ -103,7 +108,7 @@ def dragEnterEvent(self, event):
event.setDropAction(Qt.CopyAction)
event.accept()
- def startDrag(self, event):
+ def startDrag(self, supportedActions):
""" Override startDrag method to display custom icon """
# Get image of selected item
@@ -325,7 +330,6 @@ def __init__(self, *args):
self.setAcceptDrops(True)
self.setDragEnabled(True)
self.setDropIndicatorShown(True)
- self.selected = []
self.ignore_image_sequence_paths = []
# Setup header columns
@@ -335,6 +339,7 @@ def __init__(self, *args):
self.setViewMode(QListView.IconMode)
self.setResizeMode(QListView.Adjust)
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
+ self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setUniformItemSizes(True)
self.setWordWrap(False)
self.setTextElideMode(Qt.ElideRight)
@@ -346,3 +351,5 @@ def __init__(self, *args):
# setup filter events
app = get_app()
app.window.filesFilter.textChanged.connect(self.filter_changed)
+ self.selectionModel().selectionChanged.connect(self.updateSelection)
+
diff --git a/src/windows/views/files_treeview.py b/src/windows/views/files_treeview.py
index a6137c768d..eb3bafa81f 100644
--- a/src/windows/views/files_treeview.py
+++ b/src/windows/views/files_treeview.py
@@ -44,43 +44,50 @@
import json
+
class FilesTreeView(QTreeView):
""" A TreeView QWidget used on the main window """
drag_item_size = 48
def updateSelection(self):
-
# Track selected items
- self.selected = self.selectionModel().selectedIndexes()
+ m = self.files_model.model
+ self.selected_items = [m.itemFromIndex(x) for x in self.selectionModel().selectedIndexes()]
# Track selected file ids on main window
- rows = []
- self.win.selected_files = []
- for selection in self.selected:
- selected_row = self.files_model.model.itemFromIndex(selection).row()
- if selected_row not in rows:
- self.win.selected_files.append(self.files_model.model.item(selected_row, 5).text())
- rows.append(selected_row)
+ self.win.selected_files = [x.text() for x in self.selected_items if x.column() == 5]
def contextMenuEvent(self, event):
- # Update selection
- self.updateSelection()
# Set context menu mode
app = get_app()
app.context_menu_object = "files"
+ index = self.indexAt(event.pos())
+
+ # Build menu
menu = QMenu(self)
menu.addAction(self.win.actionImportFiles)
- menu.addAction(self.win.actionThumbnailView)
- if self.selected:
- # If file selected, show file related options
+ menu.addAction(self.win.actionDetailsView)
+
+ if index.isValid():
+ # Look up the model item and our unique ID
+ item = self.files_model.model.itemFromIndex(index)
+ file_id = self.files_model.model.item(item.row(), 5).text()
+
+ try:
+ # Check whether we know the item is selected
+ i = self.win.selected_files.index(file_id)
+ except ValueError:
+ # Add to our list, if it's not already there
+ self.win.selected_files.append(file_id)
+
+ # If a valid file is selected, show file related options
menu.addSeparator()
# Add edit title option (if svg file)
- selected_file_id = self.win.selected_files[0]
- file = File.get(id=selected_file_id)
+ file = File.get(id=file_id)
if file and file.data.get("path").endswith(".svg"):
menu.addAction(self.win.actionEditTitle)
menu.addAction(self.win.actionDuplicateTitle)
@@ -95,7 +102,7 @@ def contextMenuEvent(self, event):
menu.addSeparator()
# Show menu
- menu.exec_(QCursor.pos())
+ menu.exec_(event.globalPos())
def dragEnterEvent(self, event):
# If dragging urls onto widget, accept
@@ -103,7 +110,7 @@ def dragEnterEvent(self, event):
event.setDropAction(Qt.CopyAction)
event.accept()
- def startDrag(self, event):
+ def startDrag(self, supportedActions):
""" Override startDrag method to display custom icon """
# Get image of selected item
@@ -377,7 +384,6 @@ def __init__(self, *args):
self.setAcceptDrops(True)
self.setDragEnabled(True)
self.setDropIndicatorShown(True)
- self.selected = []
self.ignore_image_sequence_paths = []
# Setup header columns
@@ -400,3 +406,5 @@ def __init__(self, *args):
app = get_app()
app.window.filesFilter.textChanged.connect(self.filter_changed)
self.files_model.model.itemChanged.connect(self.value_updated)
+ self.selectionModel().selectionChanged.connect(self.updateSelection)
+