diff --git a/libopenshot b/libopenshot new file mode 160000 index 0000000000..fd21a92b72 --- /dev/null +++ b/libopenshot @@ -0,0 +1 @@ +Subproject commit fd21a92b7260cce918870dff324ca5df6ec0d9fa diff --git a/src/windows/main_window.py b/src/windows/main_window.py index 9900830771..88d3550987 100644 --- a/src/windows/main_window.py +++ b/src/windows/main_window.py @@ -2979,10 +2979,15 @@ def setup_toolbars(self): self.filesActionGroup = QActionGroup(self) self.filesActionGroup.setExclusive(True) self.filesActionGroup.addAction(self.actionFilesShowAll) + self.actionFilesShowAll.setToolTip("Show all imported files") self.filesActionGroup.addAction(self.actionFilesShowVideo) + self.actionFilesShowVideo.setToolTip("Show only video files") self.filesActionGroup.addAction(self.actionFilesShowAudio) + self.actionFilesShowAudio.setToolTip("Show only audio files") self.filesActionGroup.addAction(self.actionFilesShowImage) + self.actionFilesShowImage.setToolTip("Show only image files") self.actionFilesShowAll.setChecked(True) + self.filesToolbar.addAction(self.actionFilesShowAll) self.filesToolbar.addAction(self.actionFilesShowVideo) self.filesToolbar.addAction(self.actionFilesShowAudio) @@ -2999,7 +3004,9 @@ def setup_toolbars(self): self.transitionsActionGroup = QActionGroup(self) self.transitionsActionGroup.setExclusive(True) self.transitionsActionGroup.addAction(self.actionTransitionsShowAll) + self.actionTransitionsShowAll.setToolTip("Show all transitions") self.transitionsActionGroup.addAction(self.actionTransitionsShowCommon) + self.actionTransitionsShowCommon.setToolTip("Show common transitions only") self.actionTransitionsShowAll.setChecked(True) self.transitionsToolbar.addAction(self.actionTransitionsShowAll) self.transitionsToolbar.addAction(self.actionTransitionsShowCommon) @@ -3016,8 +3023,11 @@ def setup_toolbars(self): self.effectsActionGroup = QActionGroup(self) self.effectsActionGroup.setExclusive(True) self.effectsActionGroup.addAction(self.actionEffectsShowAll) + self.actionEffectsShowAll.setToolTip("Show all effects") self.effectsActionGroup.addAction(self.actionEffectsShowVideo) + self.actionEffectsShowVideo.setToolTip("Show only video effects") self.effectsActionGroup.addAction(self.actionEffectsShowAudio) + self.actionEffectsShowAudio.setToolTip("Show only audio effects") self.actionEffectsShowAll.setChecked(True) self.effectsToolbar.addAction(self.actionEffectsShowAll) self.effectsToolbar.addAction(self.actionEffectsShowVideo) @@ -3076,6 +3086,7 @@ def setup_toolbars(self): self.sliderZoomWidget = ZoomSlider(self) self.sliderZoomWidget.setMinimumSize(200, 20) self.sliderZoomWidget.setZoomFactor(initial_scale) + self.sliderZoomWidget.setToolTip("Zoom in/out of the timeline") # add zoom widgets self.timelineToolbar.addWidget(self.sliderZoomWidget) diff --git a/src/windows/views/files_treeview.py b/src/windows/views/files_treeview.py index d0d4485de5..a584f9a4f8 100644 --- a/src/windows/views/files_treeview.py +++ b/src/windows/views/files_treeview.py @@ -104,7 +104,8 @@ def contextMenuEvent(self, event): menu.addAction(self.win.actionFile_Properties) menu.addSeparator() - menu.addAction(self.win.actionRemove_from_Project) + confirm_action = menu.addAction(_("Remove from Project")) + confirm_action.triggered.connect(self.confirm_remove_file) menu.addSeparator() # Show menu @@ -261,6 +262,19 @@ def value_updated(self, item): # Update file thumbnail self.win.FileUpdated.emit(file_id) + def confirm_remove_file(self): + from PyQt5.QtWidgets import QMessageBox + _ = get_app()._tr + + reply = QMessageBox.question( + self, + _("Confirm Delete"), + _("Are you sure you want to delete this file from the project?"), + QMessageBox.Yes | QMessageBox.Cancel + ) + + if reply == QMessageBox.Yes: + self.win.actionRemove_from_Project.trigger() def __init__(self, model, *args): # Invoke parent init super().__init__(*args) diff --git a/src/windows/views/timeline.py b/src/windows/views/timeline.py index caba4be9db..8271e6c0cc 100644 --- a/src/windows/views/timeline.py +++ b/src/windows/views/timeline.py @@ -3389,14 +3389,25 @@ def dragMoveEvent(self, event): # Drop an item on the timeline def dropEvent(self, event): log.info("Dropping item on timeline - item_ids: %s, item_type: %s" % (self.item_ids, self.item_type)) - + print("Dropped mimeData content:", event.mimeData().text()) # Accept the event event.accept() + def dragEnterEvent(self, event): + if event.mimeData().hasText() and self._is_valid_file(event.mimeData().text()): + event.acceptProposedAction() - if self.item_type == "effect": - pos = event.posF() - data = json.loads(event.mimeData().text()) - self.addEffect(data, pos) + def dropEvent(self, event): + file_path = event.mimeData().text() + position = self._pixels_to_frames(event.pos().x()) + + # Create new clip + clip = Clip(file_path) + clip.position = position + self.current_track.addClip(clip) + if self.item_type == "effect": + pos = event.posF() + data = json.loads(event.mimeData().text()) + self.addEffect(data, pos) elif self.item_type in ["clip", "transition"] and self.item_ids: # Update most recent clip or transition