Skip to content

Commit 3ece90d

Browse files
authored
Merge pull request #3721 from ferdnyc/jump-to-ends
Teach Prev/Next Marker to jump to 0, end
2 parents 2121020 + 0e365f2 commit 3ece90d

File tree

1 file changed

+58
-51
lines changed

1 file changed

+58
-51
lines changed

src/windows/main_window.py

+58-51
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,12 @@
4747
from classes.app import get_app
4848
from classes.logger import log
4949
from classes.timeline import TimelineSync
50-
from classes.query import File, Clip, Transition, Marker, Track
51-
from classes.metrics import *
52-
from classes.version import *
50+
from classes.query import Clip, Transition, Marker, Track
51+
from classes.metrics import (
52+
track_metric_session, track_metric_screen,
53+
track_metric_error, track_exception_stacktrace,
54+
)
55+
from classes.version import get_current_Version
5356
from classes.conversion import zoomToSeconds, secondsToZoom
5457
from classes.thumbnail import httpThumbnailServerThread
5558
from windows.models.files_model import FilesModel
@@ -753,7 +756,7 @@ def promptImageSequence(self, filename=None):
753756
)
754757
return bool(ret == QMessageBox.Yes)
755758

756-
def actionAdd_to_Timeline_trigger(self, event):
759+
def actionAdd_to_Timeline_trigger(self, checked=False):
757760
# Loop through selected files
758761
files = self.selected_files()
759762

@@ -776,7 +779,7 @@ def actionAdd_to_Timeline_trigger(self, event):
776779
else:
777780
log.info('canceled')
778781

779-
def actionExportVideo_trigger(self, event):
782+
def actionExportVideo_trigger(self, checked=True):
780783
# show window
781784
from windows.export import Export
782785
win = Export()
@@ -787,37 +790,37 @@ def actionExportVideo_trigger(self, event):
787790
else:
788791
log.info('Export Video add cancelled')
789792

790-
def actionExportEDL_trigger(self, event):
793+
def actionExportEDL_trigger(self, checked=True):
791794
"""Export EDL File"""
792795
export_edl()
793796

794-
def actionExportFCPXML_trigger(self, event):
797+
def actionExportFCPXML_trigger(self, checked=True):
795798
"""Export XML (Final Cut Pro) File"""
796799
export_xml()
797800

798-
def actionImportEDL_trigger(self, event):
801+
def actionImportEDL_trigger(self, checked=True):
799802
"""Import EDL File"""
800803
import_edl()
801804

802-
def actionImportFCPXML_trigger(self, event):
805+
def actionImportFCPXML_trigger(self, checked=True):
803806
"""Import XML (Final Cut Pro) File"""
804807
import_xml()
805808

806-
def actionUndo_trigger(self, event):
809+
def actionUndo_trigger(self, checked=True):
807810
log.info('actionUndo_trigger')
808811
get_app().updates.undo()
809812

810813
# Update the preview
811814
self.refreshFrameSignal.emit()
812815

813-
def actionRedo_trigger(self, event):
816+
def actionRedo_trigger(self, checked=True):
814817
log.info('actionRedo_trigger')
815818
get_app().updates.redo()
816819

817820
# Update the preview
818821
self.refreshFrameSignal.emit()
819822

820-
def actionPreferences_trigger(self, event):
823+
def actionPreferences_trigger(self, checked=True):
821824
# Stop preview thread
822825
self.SpeedSignal.emit(0)
823826
ui_util.setup_icon(self, self.actionPlay, "actionPlay", "media-playback-start")
@@ -843,74 +846,74 @@ def actionPreferences_trigger(self, event):
843846
# Restore normal cursor
844847
get_app().restoreOverrideCursor()
845848

846-
def actionFilesShowAll_trigger(self, event):
849+
def actionFilesShowAll_trigger(self, checked=True):
847850
self.refreshFilesSignal.emit()
848851

849-
def actionFilesShowVideo_trigger(self, event):
852+
def actionFilesShowVideo_trigger(self, checked=True):
850853
self.refreshFilesSignal.emit()
851854

852-
def actionFilesShowAudio_trigger(self, event):
855+
def actionFilesShowAudio_trigger(self, checked=True):
853856
self.refreshFilesSignal.emit()
854857

855-
def actionFilesShowImage_trigger(self, event):
858+
def actionFilesShowImage_trigger(self, checked=True):
856859
self.refreshFilesSignal.emit()
857860

858-
def actionTransitionsShowAll_trigger(self, event):
861+
def actionTransitionsShowAll_trigger(self, checked=True):
859862
self.refreshTransitionsSignal.emit()
860863

861-
def actionTransitionsShowCommon_trigger(self, event):
864+
def actionTransitionsShowCommon_trigger(self, checked=True):
862865
self.refreshTransitionsSignal.emit()
863866

864-
def actionHelpContents_trigger(self, event):
867+
def actionHelpContents_trigger(self, checked=True):
865868
try:
866869
webbrowser.open("https://www.openshot.org/%suser-guide/?app-menu" % info.website_language(), new=1)
867870
except Exception:
868871
QMessageBox.information(self, "Error !", "Unable to open the online help")
869872
log.error("Unable to open the Help Contents", exc_info=1)
870873

871-
def actionAbout_trigger(self, event):
874+
def actionAbout_trigger(self, checked=True):
872875
"""Show about dialog"""
873876
from windows.about import About
874877
win = About()
875878
# Run the dialog event loop - blocking interaction on this window during this time
876879
win.exec_()
877880

878-
def actionReportBug_trigger(self, event):
881+
def actionReportBug_trigger(self, checked=True):
879882
try:
880883
webbrowser.open("https://www.openshot.org/%sissues/new/?app-menu" % info.website_language(), new=1)
881884
except Exception:
882885
QMessageBox.information(self, "Error !", "Unable to open the Bug Report GitHub Issues web page")
883886
log.error("Unable to open the Bug Report page", exc_info=1)
884887

885-
def actionAskQuestion_trigger(self, event):
888+
def actionAskQuestion_trigger(self, checked=True):
886889
try:
887890
webbrowser.open("https://www.reddit.com/r/OpenShot/", new=1)
888891
except Exception:
889892
QMessageBox.information(self, "Error !", "Unable to open the official OpenShot subreddit web page")
890893
log.error("Unable to open the subreddit page", exc_info=1)
891894

892-
def actionTranslate_trigger(self, event):
895+
def actionTranslate_trigger(self, checked=True):
893896
try:
894897
webbrowser.open("https://translations.launchpad.net/openshot/2.0", new=1)
895898
except Exception:
896899
QMessageBox.information(self, "Error !", "Unable to open the Translation web page")
897900
log.error("Unable to open the translation page", exc_info=1)
898901

899-
def actionDonate_trigger(self, event):
902+
def actionDonate_trigger(self, checked=True):
900903
try:
901904
webbrowser.open("https://www.openshot.org/%sdonate/?app-menu" % info.website_language(), new=1)
902905
except Exception:
903906
QMessageBox.information(self, "Error !", "Unable to open the Donate web page")
904907
log.error("Unable to open the donation page", exc_info=1)
905908

906-
def actionUpdate_trigger(self, event):
909+
def actionUpdate_trigger(self, checked=True):
907910
try:
908911
webbrowser.open("https://www.openshot.org/%sdownload/?app-toolbar" % info.website_language(), new=1)
909912
except Exception:
910913
QMessageBox.information(self, "Error !", "Unable to open the Download web page")
911914
log.error("Unable to open the download page", exc_info=1)
912915

913-
def actionPlay_trigger(self, event, force=None):
916+
def actionPlay_trigger(self, checked, force=None):
914917
if force == "pause":
915918
self.actionPlay.setChecked(False)
916919
elif force == "play":
@@ -926,7 +929,7 @@ def actionPlay_trigger(self, event, force=None):
926929
ui_util.setup_icon(self, self.actionPlay, "actionPlay") # to default
927930
self.PauseSignal.emit()
928931

929-
def actionPreview_File_trigger(self, event):
932+
def actionPreview_File_trigger(self, checked=True):
930933
""" Preview the selected media file """
931934
log.info('actionPreview_File_trigger')
932935

@@ -964,7 +967,7 @@ def SetPlayheadFollow(self, enable_follow):
964967
""" Enable / Disable follow mode """
965968
self.timeline.SetPlayheadFollow(enable_follow)
966969

967-
def actionFastForward_trigger(self, event):
970+
def actionFastForward_trigger(self, checked=True):
968971

969972
# Get the video player object
970973
player = self.preview_thread.player
@@ -977,7 +980,7 @@ def actionFastForward_trigger(self, event):
977980
if player.Mode() == openshot.PLAYBACK_PAUSED:
978981
self.actionPlay.trigger()
979982

980-
def actionRewind_trigger(self, event):
983+
def actionRewind_trigger(self, checked=True):
981984

982985
# Get the video player object
983986
player = self.preview_thread.player
@@ -990,20 +993,20 @@ def actionRewind_trigger(self, event):
990993
if player.Mode() == openshot.PLAYBACK_PAUSED:
991994
self.actionPlay.trigger()
992995

993-
def actionJumpStart_trigger(self, event):
996+
def actionJumpStart_trigger(self, checked=True):
994997
log.info("actionJumpStart_trigger")
995998

996999
# Seek to the 1st frame
9971000
self.SeekSignal.emit(1)
9981001

999-
def actionJumpEnd_trigger(self, event):
1002+
def actionJumpEnd_trigger(self, checked=True):
10001003
log.info("actionJumpEnd_trigger")
10011004

10021005
# Determine last frame (based on clips) & seek there
10031006
max_frame = get_app().window.timeline_sync.timeline.GetMaxFrame()
10041007
self.SeekSignal.emit(max_frame)
10051008

1006-
def actionSaveFrame_trigger(self, event):
1009+
def actionSaveFrame_trigger(self, checked=True):
10071010
log.info("actionSaveFrame_trigger")
10081011

10091012
# Translate object
@@ -1158,7 +1161,7 @@ def renumber_all_layers(self, insert_at=None, stride=1000000):
11581161
" (inserted {} at {})".format(insert_num, insert_at) if insert_at else "")
11591162
)
11601163

1161-
def actionAddTrack_trigger(self, event):
1164+
def actionAddTrack_trigger(self, checked=True):
11621165
log.info("actionAddTrack_trigger")
11631166

11641167
# Get # of tracks
@@ -1171,7 +1174,7 @@ def actionAddTrack_trigger(self, event):
11711174
track.data = {"number": track_number, "y": 0, "label": "", "lock": False}
11721175
track.save()
11731176

1174-
def actionAddTrackAbove_trigger(self, event):
1177+
def actionAddTrackAbove_trigger(self, checked=True):
11751178
# Get selected track
11761179
all_tracks = get_app().project.get("layers")
11771180
selected_layer_id = self.selected_tracks[0]
@@ -1218,7 +1221,7 @@ def actionAddTrackAbove_trigger(self, event):
12181221
# Temporarily for debugging
12191222
log.info("Tracks after: {}".format([{x['number']: x['id']} for x in reversed(tracks)]))
12201223

1221-
def actionAddTrackBelow_trigger(self, event):
1224+
def actionAddTrackBelow_trigger(self, checked=True):
12221225
# Get selected track
12231226
all_tracks = get_app().project.get("layers")
12241227
selected_layer_id = self.selected_tracks[0]
@@ -1268,23 +1271,23 @@ def actionAddTrackBelow_trigger(self, event):
12681271
# Temporarily for debugging
12691272
log.info("Tracks after: {}".format([{x['number']: x['id']} for x in reversed(tracks)]))
12701273

1271-
def actionArrowTool_trigger(self, event):
1274+
def actionArrowTool_trigger(self, checked=True):
12721275
log.info("actionArrowTool_trigger")
12731276

1274-
def actionSnappingTool_trigger(self, event):
1277+
def actionSnappingTool_trigger(self, checked=True):
12751278
log.info("actionSnappingTool_trigger")
12761279

12771280
# Enable / Disable snapping mode
12781281
self.timeline.SetSnappingMode(self.actionSnappingTool.isChecked())
12791282

1280-
def actionRazorTool_trigger(self, event):
1283+
def actionRazorTool_trigger(self, checked=True):
12811284
"""Toggle razor tool on and off"""
12821285
log.info('actionRazorTool_trigger')
12831286

12841287
# Enable / Disable razor mode
1285-
self.timeline.SetRazorMode(self.actionRazorTool.isChecked())
1288+
self.timeline.SetRazorMode(checked)
12861289

1287-
def actionAddMarker_trigger(self, event):
1290+
def actionAddMarker_trigger(self, checked=True):
12881291
log.info("actionAddMarker_trigger")
12891292

12901293
# Get player object
@@ -1302,7 +1305,6 @@ def actionAddMarker_trigger(self, event):
13021305
marker.data = {"position": position, "icon": "blue.png"}
13031306
marker.save()
13041307

1305-
13061308
def findAllMarkerPositions(self):
13071309
"""Build and return a list of all seekable locations for the currently-selected timeline elements"""
13081310

@@ -1322,31 +1324,36 @@ def getTimelineObjectPositions(obj):
13221324
positions.append(clip_stop_time)
13231325

13241326
# add all keyframes
1325-
for property in obj.data :
1326-
try :
1327-
for point in obj.data[property]["Points"] :
1327+
for property in obj.data:
1328+
try:
1329+
for point in obj.data[property]["Points"]:
13281330
keyframe_time = (point["co"]["X"]-1)/fps_float - obj.data["start"] + obj.data["position"]
1329-
if keyframe_time > clip_start_time and keyframe_time < clip_stop_time :
1331+
if clip_start_time < keyframe_time < clip_stop_time:
13301332
positions.append(keyframe_time)
13311333
except (TypeError, KeyError):
13321334
pass
13331335

1334-
13351336
# Add all Effect keyframes
13361337
if "effects" in obj.data:
13371338
for effect_data in obj.data["effects"]:
13381339
for property in effect_data:
13391340
try:
13401341
for point in effect_data[property]["Points"]:
13411342
keyframe_time = (point["co"]["X"]-1)/fps_float + clip_orig_time
1342-
if keyframe_time > clip_start_time and keyframe_time < clip_stop_time:
1343+
if clip_start_time < keyframe_time < clip_stop_time:
13431344
positions.append(keyframe_time)
13441345
except (TypeError, KeyError):
13451346
pass
13461347

13471348
return positions
13481349

1349-
all_marker_positions = []
1350+
# We can always jump to the beginning of the timeline
1351+
all_marker_positions = [0]
1352+
1353+
# If nothing is selected, also add the end of the last clip
1354+
if not self.selected_clips + self.selected_transitions:
1355+
all_marker_positions.append(
1356+
get_app().window.timeline_sync.timeline.GetMaxTime())
13501357

13511358
# Get list of marker and important positions (like selected clip bounds)
13521359
for marker in Marker.filter():
@@ -1371,7 +1378,7 @@ def getTimelineObjectPositions(obj):
13711378

13721379
return all_marker_positions
13731380

1374-
def actionPreviousMarker_trigger(self, event):
1381+
def actionPreviousMarker_trigger(self, checked=True):
13751382
log.info("actionPreviousMarker_trigger")
13761383

13771384
# Calculate current position (in seconds)
@@ -1403,7 +1410,7 @@ def actionPreviousMarker_trigger(self, event):
14031410
get_app().window.refreshFrameSignal.emit()
14041411
get_app().window.propertyTableView.select_frame(frame_to_seek)
14051412

1406-
def actionNextMarker_trigger(self, event):
1413+
def actionNextMarker_trigger(self, checked=True):
14071414
log.info("actionNextMarker_trigger")
14081415

14091416
# Calculate current position (in seconds)
@@ -1435,7 +1442,7 @@ def actionNextMarker_trigger(self, event):
14351442
get_app().window.refreshFrameSignal.emit()
14361443
get_app().window.propertyTableView.select_frame(frame_to_seek)
14371444

1438-
def actionCenterOnPlayhead_trigger(self, event):
1445+
def actionCenterOnPlayhead_trigger(self, checked=True):
14391446
""" Center the timeline on the current playhead position """
14401447
self.timeline.centerOnPlayhead()
14411448

0 commit comments

Comments
 (0)