36 from uuid
import uuid4
37 from copy
import deepcopy
40 from PyQt5.QtGui import QIcon, QCursor, QKeySequence
44 from windows.views.timeline_webview
import TimelineWebView
45 from classes
import info, ui_util, settings, qt_types, updates
46 from classes.app
import get_app
47 from classes.logger
import log
48 from classes.timeline
import TimelineSync
49 from classes.query
import File, Clip, Transition, Marker, Track
52 from classes.conversion
import zoomToSeconds, secondsToZoom
53 from images
import openshot_rc
54 from windows.views.files_treeview
import FilesTreeView
55 from windows.views.files_listview
import FilesListView
56 from windows.views.transitions_treeview
import TransitionsTreeView
57 from windows.views.transitions_listview
import TransitionsListView
58 from windows.views.effects_treeview
import EffectsTreeView
59 from windows.views.effects_listview
import EffectsListView
60 from windows.views.properties_tableview
import PropertiesTableView, SelectionLabel
61 from windows.views.tutorial
import TutorialManager
62 from windows.video_widget
import VideoWidget
63 from windows.preview_thread
import PreviewParent
71 ui_path = os.path.join(info.PATH,
'windows',
'ui',
'main-window.ui')
73 previewFrameSignal = pyqtSignal(int)
74 refreshFrameSignal = pyqtSignal()
75 LoadFileSignal = pyqtSignal(str)
76 PlaySignal = pyqtSignal(int)
77 PauseSignal = pyqtSignal()
78 StopSignal = pyqtSignal()
79 SeekSignal = pyqtSignal(int)
80 SpeedSignal = pyqtSignal(float)
81 RecoverBackup = pyqtSignal()
82 FoundVersionSignal = pyqtSignal(str)
83 WaveformReady = pyqtSignal(str, list)
84 TransformSignal = pyqtSignal(str)
85 ExportStarted = pyqtSignal(str, int, int)
86 ExportFrame = pyqtSignal(str, int, int, int)
87 ExportEnded = pyqtSignal(str)
88 MaxSizeChanged = pyqtSignal(object)
89 InsertKeyframe = pyqtSignal(object)
95 self.tutorial_manager.exit_manager()
98 if get_app().project.needs_save()
and not self.
mode ==
"unittest":
99 log.info(
'Prompt user to save project')
104 ret = QMessageBox.question(self, _(
"Unsaved Changes"), _(
"Save changes to project before closing?"), QMessageBox.Cancel | QMessageBox.No | QMessageBox.Yes)
105 if ret == QMessageBox.Yes:
109 elif ret == QMessageBox.Cancel:
121 self.StopSignal.emit()
124 QCoreApplication.processEvents()
127 self.preview_thread.player.CloseAudioDevice()
128 self.preview_thread.kill()
129 self.preview_parent.background.exit()
130 self.preview_parent.background.wait(5000)
133 openshot.ZmqLogger.Instance().Close()
134 get_app().logger_libopenshot.kill()
142 log.info(
"recover_backup")
144 recovery_path = os.path.join(info.BACKUP_PATH,
"backup.osp")
147 if os.path.exists(recovery_path):
148 log.info(
"Recovering backup file: %s" % recovery_path)
149 self.
open_project(recovery_path, clear_thumbnails=
False)
152 get_app().project.current_filepath =
None
153 get_app().project.has_unsaved_changes =
True
161 msg.setWindowTitle(_(
"Backup Recovered"))
162 msg.setText(_(
"Your most recent unsaved project has been recovered."))
169 self.actionUndo.setEnabled(
False)
170 self.actionRedo.setEnabled(
False)
176 lock_path = os.path.join(info.USER_PATH,
".lock")
177 lock_value = str(uuid4())
180 if os.path.exists(lock_path):
182 log_path = os.path.join(info.USER_PATH,
"libopenshot.log")
184 last_stack_trace =
""
186 log_start_counter = 0
187 if os.path.exists(log_path):
188 with open(log_path,
"rb")
as f:
190 for raw_line
in reversed(self.
tail_file(f, 500)):
191 line = str(raw_line,
'utf-8')
193 if "End of Stack Trace" in line:
196 elif "Unhandled Exception: Stack Trace" in line:
199 elif "libopenshot logging:" in line:
200 log_start_counter += 1
201 if log_start_counter > 1:
207 last_stack_trace = line + last_stack_trace
210 if line.strip()
and "---" not in line
and "libopenshot logging:" not in line
and not last_log_line:
216 last_log_line = last_stack_trace.split(
"\n")[0].strip()
224 if platform.system() ==
"Darwin":
225 last_log_line =
"mac-%s" % last_log_line[58:].strip()
226 elif platform.system() ==
"Windows":
227 last_log_line =
"windows-%s" % last_log_line
228 elif platform.system() ==
"Linux":
229 last_log_line =
"linux-%s" % last_log_line.replace(
"/usr/local/lib/",
"")
232 last_log_line = last_log_line.replace(
"()",
"")
233 log_parts = last_log_line.split(
"(")
234 if len(log_parts) == 2:
235 last_log_line =
"-%s" % log_parts[0].replace(
"logger_libopenshot:INFO ",
"").strip()[:64]
236 elif len(log_parts) >= 3:
237 last_log_line =
"-%s (%s" % (log_parts[0].replace(
"logger_libopenshot:INFO ",
"").strip()[:64], log_parts[1])
242 log.error(
"Unhandled crash detected... will attempt to recover backup project: %s" % info.BACKUP_PATH)
253 with open(lock_path,
'w')
as f:
259 lock_path = os.path.join(info.USER_PATH,
".lock")
262 if os.path.exists(lock_path):
270 to_read = n + (offset
or 0)
275 f.seek(-(avg_line_length * to_read), 2)
280 lines = f.read().splitlines()
281 if len(lines) >= to_read
or pos == 0:
283 return lines[-to_read:offset
and -offset
or None]
292 if get_app().project.needs_save():
293 ret = QMessageBox.question(self, _(
"Unsaved Changes"), _(
"Save changes to project first?"), QMessageBox.Cancel | QMessageBox.No | QMessageBox.Yes)
294 if ret == QMessageBox.Yes:
297 elif ret == QMessageBox.Cancel:
312 self.filesTreeView.refresh_view()
313 log.info(
"New Project created.")
320 from windows.animated_title
import AnimatedTitle
321 win = AnimatedTitle()
324 if result == QDialog.Accepted:
325 log.info(
'animated title add confirmed')
327 log.info(
'animated title add cancelled')
331 from windows.animation
import Animation
335 if result == QDialog.Accepted:
336 log.info(
'animation confirmed')
338 log.info(
'animation cancelled')
342 from windows.title_editor
import TitleEditor
346 if result == QDialog.Accepted:
347 log.info(
'title editor add confirmed')
349 log.info(
'title editor add cancelled')
355 file = File.get(id=selected_file_id)
356 file_path = file.data.get(
"path")
359 thumb_path = os.path.join(info.THUMBNAIL_PATH,
"{}.png".format(file.id))
362 if os.path.exists(thumb_path):
363 os.remove(thumb_path)
366 from windows.title_editor
import TitleEditor
367 win = TitleEditor(file_path)
372 get_app().window.filesTreeView.refresh_view()
378 file = File.get(id=selected_file_id)
379 file_path = file.data.get(
"path")
382 from windows.title_editor
import TitleEditor
383 win = TitleEditor(file_path, duplicate=
True)
389 from windows.Import_image_seq
import ImportImageSeq
390 win = ImportImageSeq()
393 if result == QDialog.Accepted:
394 log.info(
'Import image sequence add confirmed')
396 log.info(
'Import image sequence add cancelled')
403 log.info(
'History cleared')
414 app.updates.save_history(app.project, s.get(
"history-limit"))
417 app.project.save(file_path)
425 log.info(
"Saved project {}".format(file_path))
427 except Exception
as ex:
428 log.error(
"Couldn't save project %s. %s" % (file_path, str(ex)))
429 QMessageBox.warning(self, _(
"Error Saving Project"), str(ex))
439 get_app().setOverrideCursor(QCursor(Qt.WaitCursor))
442 if os.path.exists(file_path):
448 app.project.load(file_path)
455 app.updates.load_history(app.project)
461 self.filesTreeView.refresh_view()
466 log.info(
"Loaded project {}".format(file_path))
468 except Exception
as ex:
469 log.error(
"Couldn't open project {}".format(file_path))
470 QMessageBox.warning(self, _(
"Error Opening Project"), str(ex))
473 get_app().restoreOverrideCursor()
479 if os.path.exists(info.THUMBNAIL_PATH):
480 log.info(
"Clear all thumbnails: %s" % info.THUMBNAIL_PATH)
482 shutil.rmtree(info.THUMBNAIL_PATH)
484 os.mkdir(info.THUMBNAIL_PATH)
487 if os.path.exists(info.BLENDER_PATH):
488 log.info(
"Clear all animations: %s" % info.BLENDER_PATH)
490 shutil.rmtree(info.BLENDER_PATH)
492 os.mkdir(info.BLENDER_PATH)
495 if os.path.exists(info.ASSETS_PATH):
496 log.info(
"Clear all assets: %s" % info.ASSETS_PATH)
498 shutil.rmtree(info.ASSETS_PATH)
500 os.mkdir(info.ASSETS_PATH)
503 if os.path.exists(info.BACKUP_PATH):
504 log.info(
"Clear all backups: %s" % info.BACKUP_PATH)
506 shutil.rmtree(info.BACKUP_PATH)
508 os.mkdir(info.BACKUP_PATH)
510 log.info(
"Failed to clear thumbnails: %s" % info.THUMBNAIL_PATH)
515 recommended_path = app.project.current_filepath
516 if not recommended_path:
517 recommended_path = info.HOME_PATH
520 if get_app().project.needs_save():
521 ret = QMessageBox.question(self, _(
"Unsaved Changes"), _(
"Save changes to project first?"), QMessageBox.Cancel | QMessageBox.No | QMessageBox.Yes)
522 if ret == QMessageBox.Yes:
525 elif ret == QMessageBox.Cancel:
530 file_path, file_type = QFileDialog.getOpenFileName(self, _(
"Open Project..."), recommended_path, _(
"OpenShot Project (*.osp)"))
540 file_path = app.project.current_filepath
542 recommended_path = os.path.join(info.HOME_PATH,
"%s.osp" % _(
"Untitled Project"))
543 file_path, file_type = QFileDialog.getSaveFileName(self, _(
"Save Project..."), recommended_path, _(
"OpenShot Project (*.osp)"))
547 if ".osp" not in file_path:
548 file_path =
"%s.osp" % file_path
556 log.info(
"auto_save_project")
559 file_path =
get_app().project.current_filepath
560 if get_app().project.needs_save():
564 if ".osp" not in file_path:
565 file_path =
"%s.osp" % file_path
568 log.info(
"Auto save project file: %s" % file_path)
573 recovery_path = os.path.join(info.BACKUP_PATH,
"backup.osp")
574 log.info(
"Creating backup of project file: %s" % recovery_path)
575 get_app().project.save(recovery_path, move_temp_files=
False, make_paths_relative=
False)
578 get_app().project.current_filepath =
None
579 get_app().project.has_unsaved_changes =
True
585 recommended_path = app.project.current_filepath
586 if not recommended_path:
587 recommended_path = os.path.join(info.HOME_PATH,
"%s.osp" % _(
"Untitled Project"))
588 file_path, file_type = QFileDialog.getSaveFileName(self, _(
"Save Project As..."), recommended_path, _(
"OpenShot Project (*.osp)"))
591 if ".osp" not in file_path:
592 file_path =
"%s.osp" % file_path
600 recommended_path = app.project.get([
"import_path"])
601 if not recommended_path
or not os.path.exists(recommended_path):
602 recommended_path = os.path.join(info.HOME_PATH)
603 files = QFileDialog.getOpenFileNames(self, _(
"Import File..."), recommended_path)[0]
604 for file_path
in files:
605 self.filesTreeView.add_file(file_path)
606 self.filesTreeView.refresh_view()
607 app.updates.update([
"import_path"], os.path.dirname(file_path))
608 log.info(
"Imported media file {}".format(file_path))
616 files.append(File.get(id=file_id))
619 fps =
get_app().project.get([
"fps"])
620 fps_float = float(fps[
"num"]) / float(fps[
"den"])
621 pos = (self.preview_thread.player.Position() - 1) / fps_float
624 from windows.add_to_timeline
import AddToTimeline
625 win = AddToTimeline(files, pos)
628 if result == QDialog.Accepted:
629 log.info(
'confirmed')
635 from windows.upload_video
import UploadVideo
639 if result == QDialog.Accepted:
640 log.info(
'Upload Video add confirmed')
642 log.info(
'Upload Video add cancelled')
646 from windows.export
import Export
650 if result == QDialog.Accepted:
651 log.info(
'Export Video add confirmed')
653 log.info(
'Export Video add cancelled')
656 log.info(
'actionUndo_trigger')
661 self.refreshFrameSignal.emit()
664 log.info(
'actionRedo_trigger')
669 self.refreshFrameSignal.emit()
673 self.SpeedSignal.emit(0)
675 self.actionPlay.setChecked(
False)
678 from windows.preferences
import Preferences
682 if result == QDialog.Accepted:
683 log.info(
'Preferences add confirmed')
685 log.info(
'Preferences add cancelled')
692 self.filesTreeView.refresh_view()
695 self.filesTreeView.refresh_view()
698 self.filesTreeView.refresh_view()
701 self.filesTreeView.refresh_view()
704 self.transitionsTreeView.refresh_view()
707 self.transitionsTreeView.refresh_view()
710 self.effectsTreeView.refresh_view()
713 self.effectsTreeView.refresh_view()
716 self.effectsTreeView.refresh_view()
721 log.info(
"Help Contents is open")
723 QMessageBox.information(self,
"Error !",
"Unable to open the Help Contents. Please ensure the openshot-doc package is installed.")
724 log.info(
"Unable to open the Help Contents")
729 from windows.about
import About
733 if result == QDialog.Accepted:
734 log.info(
'About Openshot add confirmed')
736 log.info(
'About Openshot add cancelled')
740 webbrowser.open(
"https://github.com/OpenShot/openshot-qt/issues/?app-menu-bug")
741 log.info(
"Open the Bug Report GitHub Issues web page with success")
743 QMessageBox.information(self,
"Error !",
"Unable to open the Bug Report GitHub Issues web page")
744 log.info(
"Unable to open the Bug Report GitHub Issues web page")
748 webbrowser.open(
"https://github.com/OpenShot/openshot-qt/issues/?app-menu-question")
749 log.info(
"Open the Questions GitHub Issues web page with success")
751 QMessageBox.information(self,
"Error !",
"Unable to open the Questions GitHub Issues web page")
752 log.info(
"Unable to open the Questions GitHub Issues web page")
756 webbrowser.open(
"https://translations.launchpad.net/openshot/2.0")
757 log.info(
"Open the Translate launchpad web page with success")
759 QMessageBox.information(self,
"Error !",
"Unable to open the Translation web page")
760 log.info(
"Unable to open the Translation web page")
765 log.info(
"Open the Donate web page with success")
767 QMessageBox.information(self,
"Error !",
"Unable to open the Donate web page")
768 log.info(
"Unable to open the Donate web page")
773 log.info(
"Open the Download web page with success")
775 QMessageBox.information(self,
"Error !",
"Unable to open the Download web page")
776 log.info(
"Unable to open the Download web page")
781 timeline_length = 0.0
782 fps =
get_app().window.timeline_sync.timeline.info.fps.ToFloat()
783 clips =
get_app().window.timeline_sync.timeline.Clips()
785 clip_last_frame = clip.Position() + clip.Duration()
786 if clip_last_frame > timeline_length:
788 timeline_length = clip_last_frame
791 timeline_length_int = round(timeline_length * fps) + 1
794 self.actionPlay.setChecked(
False)
795 elif force ==
"play":
796 self.actionPlay.setChecked(
True)
798 if self.actionPlay.isChecked():
800 self.PlaySignal.emit(timeline_length_int)
804 self.PauseSignal.emit()
809 log.info(
'actionPreview_File_trigger')
815 f = File.get(id=file_id)
823 from windows.cutting
import Cutting
824 win = Cutting(f, preview=
True)
831 self.previewFrameSignal.emit(position_frames)
834 self.propertyTableView.select_frame(position_frames)
839 self.propertyTableView.select_frame(self.preview_thread.player.Position())
845 self.timeline.movePlayhead(position_frames)
850 player = self.preview_thread.player
852 if player.Speed() + 1 != 0:
853 self.SpeedSignal.emit(player.Speed() + 1)
855 self.SpeedSignal.emit(player.Speed() + 2)
857 if player.Mode() == openshot.PLAYBACK_PAUSED:
858 self.actionPlay.trigger()
863 player = self.preview_thread.player
865 if player.Speed() - 1 != 0:
866 self.SpeedSignal.emit(player.Speed() - 1)
868 self.SpeedSignal.emit(player.Speed() - 2)
870 if player.Mode() == openshot.PLAYBACK_PAUSED:
871 self.actionPlay.trigger()
874 log.info(
"actionJumpStart_trigger")
877 self.SeekSignal.emit(1)
880 log.info(
"actionJumpEnd_trigger")
883 timeline_length = 0.0
884 fps =
get_app().window.timeline_sync.timeline.info.fps.ToFloat()
885 clips =
get_app().window.timeline_sync.timeline.Clips()
887 clip_last_frame = clip.Position() + clip.Duration()
888 if clip_last_frame > timeline_length:
890 timeline_length = clip_last_frame
893 timeline_length_int = round(timeline_length * fps) + 1
896 self.SeekSignal.emit(timeline_length_int)
899 log.info(
"actionAddTrack_trigger")
902 track_number = len(
get_app().project.get([
"layers"]))
906 track.data = {
"number": track_number,
"y": 0,
"label":
"",
"lock":
False}
910 log.info(
"actionAddTrackAbove_trigger")
913 max_track_number = len(
get_app().project.get([
"layers"]))
917 existing_track = Track.get(id=selected_layer_id)
918 selected_layer_number = int(existing_track.data[
"number"])
923 for existing_layer
in list(reversed(range(selected_layer_number+1, max_track_number))):
924 existing_track = Track.get(number=existing_layer)
926 existing_track.data[
"number"] = existing_layer + 1
927 existing_track.save()
930 for clip
in Clip.filter(layer=existing_layer):
932 clip.data[
"layer"] = int(clip.data[
"layer"]) + 1
935 for trans
in Transition.filter(layer=existing_layer):
937 trans.data[
"layer"] = int(trans.data[
"layer"]) + 1
942 track.data = {
"number": selected_layer_number+1,
"y": 0,
"label":
"",
"lock":
False}
947 log.info(
"actionAddTrackBelow_trigger")
950 max_track_number = len(
get_app().project.get([
"layers"]))
954 existing_track = Track.get(id=selected_layer_id)
955 selected_layer_number = int(existing_track.data[
"number"])
960 for existing_layer
in list(reversed(range(selected_layer_number, max_track_number))):
961 existing_track = Track.get(number=existing_layer)
963 existing_track.data[
"number"] = existing_layer + 1
964 existing_track.save()
967 for clip
in Clip.filter(layer=existing_layer):
969 clip.data[
"layer"] = int(clip.data[
"layer"]) + 1
972 for trans
in Transition.filter(layer=existing_layer):
974 trans.data[
"layer"] = int(trans.data[
"layer"]) + 1
979 track.data = {
"number": selected_layer_number,
"y": 0,
"label":
"",
"lock":
False}
984 log.info(
"actionArrowTool_trigger")
987 log.info(
"actionSnappingTool_trigger")
988 log.info(self.actionSnappingTool.isChecked())
991 self.timeline.SetSnappingMode(self.actionSnappingTool.isChecked())
996 log.info(
'actionRazorTool_trigger')
999 self.timeline.SetRazorMode(self.actionRazorTool.isChecked())
1002 log.info(
"actionAddMarker_trigger")
1005 player = self.preview_thread.player
1008 fps =
get_app().project.get([
"fps"])
1009 fps_float = float(fps[
"num"]) / float(fps[
"den"])
1012 position = (player.Position() - 1) / fps_float
1016 marker.data = {
"position": position,
"icon":
"blue.png"}
1020 log.info(
"actionPreviousMarker_trigger")
1023 fps =
get_app().project.get([
"fps"])
1024 fps_float = float(fps[
"num"]) / float(fps[
"den"])
1025 current_position = (self.preview_thread.current_frame - 1) / fps_float
1026 all_marker_positions = []
1029 for marker
in Marker.filter():
1030 all_marker_positions.append(marker.data[
"position"])
1035 selected_clip = Clip.get(id=clip_id)
1037 all_marker_positions.append(selected_clip.data[
"position"])
1038 all_marker_positions.append(selected_clip.data[
"position"] + (selected_clip.data[
"end"] - selected_clip.data[
"start"]))
1043 selected_tran = Transition.get(id=tran_id)
1045 all_marker_positions.append(selected_tran.data[
"position"])
1046 all_marker_positions.append(selected_tran.data[
"position"] + (selected_tran.data[
"end"] - selected_tran.data[
"start"]))
1049 closest_position =
None
1050 for marker_position
in sorted(all_marker_positions):
1052 if marker_position < current_position
and (abs(marker_position - current_position) > 0.1):
1054 if closest_position
and marker_position > closest_position:
1056 closest_position = marker_position
1057 elif not closest_position:
1059 closest_position = marker_position
1062 if closest_position !=
None:
1064 frame_to_seek = round(closest_position * fps_float) + 1
1065 self.SeekSignal.emit(frame_to_seek)
1068 get_app().window.refreshFrameSignal.emit()
1069 get_app().window.propertyTableView.select_frame(frame_to_seek)
1072 log.info(
"actionNextMarker_trigger")
1073 log.info(self.preview_thread.current_frame)
1076 fps =
get_app().project.get([
"fps"])
1077 fps_float = float(fps[
"num"]) / float(fps[
"den"])
1078 current_position = (self.preview_thread.current_frame - 1) / fps_float
1079 all_marker_positions = []
1082 for marker
in Marker.filter():
1083 all_marker_positions.append(marker.data[
"position"])
1088 selected_clip = Clip.get(id=clip_id)
1090 all_marker_positions.append(selected_clip.data[
"position"])
1091 all_marker_positions.append(selected_clip.data[
"position"] + (selected_clip.data[
"end"] - selected_clip.data[
"start"]))
1096 selected_tran = Transition.get(id=tran_id)
1098 all_marker_positions.append(selected_tran.data[
"position"])
1099 all_marker_positions.append(selected_tran.data[
"position"] + (selected_tran.data[
"end"] - selected_tran.data[
"start"]))
1102 closest_position =
None
1103 for marker_position
in sorted(all_marker_positions):
1105 if marker_position > current_position
and (abs(marker_position - current_position) > 0.1):
1107 if closest_position
and marker_position < closest_position:
1109 closest_position = marker_position
1110 elif not closest_position:
1112 closest_position = marker_position
1115 if closest_position !=
None:
1117 frame_to_seek = round(closest_position * fps_float) + 1
1118 self.SeekSignal.emit(frame_to_seek)
1121 get_app().window.refreshFrameSignal.emit()
1122 get_app().window.propertyTableView.select_frame(frame_to_seek)
1128 shortcut = QKeySequence(s.get(setting_name))
1134 keyboard_shortcuts = []
1136 for setting
in all_settings:
1137 if setting.get(
'category') ==
'Keyboard':
1138 keyboard_shortcuts.append(setting)
1139 return keyboard_shortcuts
1145 key_value = event.key()
1147 modifiers = int(event.modifiers())
1148 if (key_value > 0
and key_value != Qt.Key_Shift
and key_value != Qt.Key_Alt
and
1149 key_value != Qt.Key_Control
and key_value != Qt.Key_Meta):
1151 key = QKeySequence(modifiers + key_value)
1157 log.info(
"keyPressEvent: %s" % (key.toString()))
1160 player = self.preview_thread.player
1163 fps =
get_app().project.get([
"fps"])
1164 fps_float = float(fps[
"num"]) / float(fps[
"den"])
1165 playhead_position = float(self.preview_thread.current_frame - 1) / fps_float
1168 if key.matches(self.
getShortcutByName(
"seekPreviousFrame")) == QKeySequence.ExactMatch:
1172 if player.Speed() != 0:
1173 self.SpeedSignal.emit(0)
1175 self.SeekSignal.emit(player.Position() - 1)
1178 self.propertyTableView.select_frame(player.Position())
1180 elif key.matches(self.
getShortcutByName(
"seekNextFrame")) == QKeySequence.ExactMatch:
1184 if player.Speed() != 0:
1185 self.SpeedSignal.emit(0)
1187 self.SeekSignal.emit(player.Position() + 1)
1190 self.propertyTableView.select_frame(player.Position())
1192 elif key.matches(self.
getShortcutByName(
"rewindVideo")) == QKeySequence.ExactMatch:
1194 self.actionRewind.trigger()
1196 self.actionPlay.setChecked(
True)
1198 elif key.matches(self.
getShortcutByName(
"fastforwardVideo")) == QKeySequence.ExactMatch:
1200 self.actionFastForward.trigger()
1202 self.actionPlay.setChecked(
True)
1204 elif key.matches(self.
getShortcutByName(
"playToggle")) == QKeySequence.ExactMatch
or \
1205 key.matches(self.
getShortcutByName(
"playToggle1")) == QKeySequence.ExactMatch
or \
1206 key.matches(self.
getShortcutByName(
"playToggle2")) == QKeySequence.ExactMatch
or \
1209 self.actionPlay.trigger()
1210 self.propertyTableView.select_frame(player.Position())
1212 elif key.matches(self.
getShortcutByName(
"deleteItem")) == QKeySequence.ExactMatch
or \
1215 self.actionRemoveClip.trigger()
1216 self.actionRemoveTransition.trigger()
1219 elif key.matches(self.
getShortcutByName(
"actionNew")) == QKeySequence.ExactMatch:
1220 self.actionNew.trigger()
1221 elif key.matches(self.
getShortcutByName(
"actionOpen")) == QKeySequence.ExactMatch:
1222 self.actionOpen.trigger()
1223 elif key.matches(self.
getShortcutByName(
"actionSave")) == QKeySequence.ExactMatch:
1224 self.actionSave.trigger()
1225 elif key.matches(self.
getShortcutByName(
"actionUndo")) == QKeySequence.ExactMatch:
1226 self.actionUndo.trigger()
1227 elif key.matches(self.
getShortcutByName(
"actionSaveAs")) == QKeySequence.ExactMatch:
1228 self.actionSaveAs.trigger()
1229 elif key.matches(self.
getShortcutByName(
"actionImportFiles")) == QKeySequence.ExactMatch:
1230 self.actionImportFiles.trigger()
1231 elif key.matches(self.
getShortcutByName(
"actionRedo")) == QKeySequence.ExactMatch:
1232 self.actionRedo.trigger()
1233 elif key.matches(self.
getShortcutByName(
"actionExportVideo")) == QKeySequence.ExactMatch:
1234 self.actionExportVideo.trigger()
1235 elif key.matches(self.
getShortcutByName(
"actionQuit")) == QKeySequence.ExactMatch:
1236 self.actionQuit.trigger()
1237 elif key.matches(self.
getShortcutByName(
"actionPreferences")) == QKeySequence.ExactMatch:
1238 self.actionPreferences.trigger()
1239 elif key.matches(self.
getShortcutByName(
"actionAddTrack")) == QKeySequence.ExactMatch:
1240 self.actionAddTrack.trigger()
1241 elif key.matches(self.
getShortcutByName(
"actionAddMarker")) == QKeySequence.ExactMatch:
1242 self.actionAddMarker.trigger()
1243 elif key.matches(self.
getShortcutByName(
"actionPreviousMarker")) == QKeySequence.ExactMatch:
1244 self.actionPreviousMarker.trigger()
1245 elif key.matches(self.
getShortcutByName(
"actionNextMarker")) == QKeySequence.ExactMatch:
1246 self.actionNextMarker.trigger()
1247 elif key.matches(self.
getShortcutByName(
"actionTimelineZoomIn")) == QKeySequence.ExactMatch:
1248 self.actionTimelineZoomIn.trigger()
1249 elif key.matches(self.
getShortcutByName(
"actionTimelineZoomOut")) == QKeySequence.ExactMatch:
1250 self.actionTimelineZoomOut.trigger()
1251 elif key.matches(self.
getShortcutByName(
"actionTitle")) == QKeySequence.ExactMatch:
1252 self.actionTitle.trigger()
1253 elif key.matches(self.
getShortcutByName(
"actionAnimatedTitle")) == QKeySequence.ExactMatch:
1254 self.actionAnimatedTitle.trigger()
1255 elif key.matches(self.
getShortcutByName(
"actionFullscreen")) == QKeySequence.ExactMatch:
1256 self.actionFullscreen.trigger()
1257 elif key.matches(self.
getShortcutByName(
"actionAbout")) == QKeySequence.ExactMatch:
1258 self.actionAbout.trigger()
1259 elif key.matches(self.
getShortcutByName(
"actionThumbnailView")) == QKeySequence.ExactMatch:
1260 self.actionThumbnailView.trigger()
1261 elif key.matches(self.
getShortcutByName(
"actionDetailsView")) == QKeySequence.ExactMatch:
1262 self.actionDetailsView.trigger()
1263 elif key.matches(self.
getShortcutByName(
"actionProfile")) == QKeySequence.ExactMatch:
1264 self.actionProfile.trigger()
1265 elif key.matches(self.
getShortcutByName(
"actionAdd_to_Timeline")) == QKeySequence.ExactMatch:
1266 self.actionAdd_to_Timeline.trigger()
1267 elif key.matches(self.
getShortcutByName(
"actionSplitClip")) == QKeySequence.ExactMatch:
1268 self.actionSplitClip.trigger()
1269 elif key.matches(self.
getShortcutByName(
"actionSnappingTool")) == QKeySequence.ExactMatch:
1270 self.actionSnappingTool.trigger()
1271 elif key.matches(self.
getShortcutByName(
"actionJumpStart")) == QKeySequence.ExactMatch:
1272 self.actionJumpStart.trigger()
1273 elif key.matches(self.
getShortcutByName(
"actionJumpEnd")) == QKeySequence.ExactMatch:
1274 self.actionJumpEnd.trigger()
1275 elif key.matches(self.
getShortcutByName(
"actionProperties")) == QKeySequence.ExactMatch:
1276 self.actionProperties.trigger()
1277 elif key.matches(self.
getShortcutByName(
"actionTransform")) == QKeySequence.ExactMatch:
1281 self.TransformSignal.emit(
"")
1283 elif key.matches(self.
getShortcutByName(
"actionInsertKeyframe")) == QKeySequence.ExactMatch:
1284 print(
"actionInsertKeyframe")
1286 self.InsertKeyframe.emit(event)
1289 elif key.matches(self.
getShortcutByName(
"sliceAllKeepBothSides")) == QKeySequence.ExactMatch:
1290 intersecting_clips = Clip.filter(intersect=playhead_position)
1291 intersecting_trans = Transition.filter(intersect=playhead_position)
1292 if intersecting_clips
or intersecting_trans:
1294 clip_ids = [c.id
for c
in intersecting_clips]
1295 trans_ids = [t.id
for t
in intersecting_trans]
1296 self.timeline.Slice_Triggered(0, clip_ids, trans_ids, playhead_position)
1297 elif key.matches(self.
getShortcutByName(
"sliceAllKeepLeftSide")) == QKeySequence.ExactMatch:
1298 intersecting_clips = Clip.filter(intersect=playhead_position)
1299 intersecting_trans = Transition.filter(intersect=playhead_position)
1300 if intersecting_clips
or intersecting_trans:
1302 clip_ids = [c.id
for c
in intersecting_clips]
1303 trans_ids = [t.id
for t
in intersecting_trans]
1304 self.timeline.Slice_Triggered(1, clip_ids, trans_ids, playhead_position)
1305 elif key.matches(self.
getShortcutByName(
"sliceAllKeepRightSide")) == QKeySequence.ExactMatch:
1306 intersecting_clips = Clip.filter(intersect=playhead_position)
1307 intersecting_trans = Transition.filter(intersect=playhead_position)
1308 if intersecting_clips
or intersecting_trans:
1310 clip_ids = [c.id
for c
in intersecting_clips]
1311 trans_ids = [t.id
for t
in intersecting_trans]
1312 self.timeline.Slice_Triggered(2, clip_ids, trans_ids, playhead_position)
1315 elif key.matches(self.
getShortcutByName(
"pasteAll")) == QKeySequence.ExactMatch:
1316 self.timeline.Paste_Triggered(9, float(playhead_position), -1, [], [])
1319 elif key.matches(self.
getShortcutByName(
"selectAll")) == QKeySequence.ExactMatch:
1320 self.timeline.SelectAll()
1322 elif key.matches(self.
getShortcutByName(
"selectNone")) == QKeySequence.ExactMatch:
1323 self.timeline.ClearAllSelections()
1331 from windows.profile
import Profile
1334 result = win.exec_()
1335 if result == QDialog.Accepted:
1336 log.info(
'Profile add confirmed')
1340 log.info(
"actionSplitClip_trigger")
1346 f = File.get(id=file_id)
1354 from windows.cutting
import Cutting
1357 result = win.exec_()
1358 if result == QDialog.Accepted:
1359 log.info(
'Cutting Finished')
1361 log.info(
'Cutting Cancelled')
1364 log.info(
"actionRemove_from_Project_trigger")
1369 f = File.get(id=file_id)
1375 clips = Clip.filter(file_id=file_id)
1384 log.info(
'actionRemoveClip_trigger')
1389 clips = Clip.filter(id=clip_id)
1398 log.info(
'actionProperties_trigger')
1401 if not self.dockProperties.isVisible():
1402 self.dockProperties.show()
1405 log.info(
'actionRemoveEffect_trigger')
1409 log.info(
"effect id: %s" % effect_id)
1412 clips = Clip.filter()
1415 found_effect =
False
1416 log.info(
"c.data[effects]: %s" % c.data[
"effects"])
1418 for effect
in c.data[
"effects"]:
1419 if effect[
"id"] == effect_id:
1420 found_effect = effect
1425 c.data[
"effects"].remove(found_effect)
1428 c.data.pop(
"reader")
1437 log.info(
'actionRemoveTransition_trigger')
1442 transitions = Transition.filter(id=tran_id)
1443 for t
in transitions:
1451 log.info(
'actionRemoveTrack_trigger')
1457 max_track_number = len(
get_app().project.get([
"layers"]))
1460 selected_track = Track.get(id=track_id)
1461 selected_track_number = int(selected_track.data[
"number"])
1464 if max_track_number == 1:
1466 QMessageBox.warning(self, _(
"Error Removing Track"), _(
"You must keep at least 1 track"))
1470 for clip
in Clip.filter(layer=selected_track_number):
1474 for trans
in Transition.filter(layer=selected_track_number):
1478 selected_track.delete()
1481 for existing_layer
in list(range(selected_track_number + 1, max_track_number)):
1483 track = Track.get(number=existing_layer)
1484 track.data[
"number"] = existing_layer - 1
1487 for clip
in Clip.filter(layer=existing_layer):
1488 clip.data[
"layer"] = int(clip.data[
"layer"]) - 1
1491 for trans
in Transition.filter(layer=existing_layer):
1492 trans.data[
"layer"] = int(trans.data[
"layer"]) - 1
1502 log.info(
'actionLockTrack_trigger')
1506 selected_track = Track.get(id=track_id)
1509 selected_track.data[
'lock'] =
True
1510 selected_track.save()
1515 log.info(
'actionUnlockTrack_trigger')
1519 selected_track = Track.get(id=track_id)
1522 selected_track.data[
'lock'] =
False
1523 selected_track.save()
1528 log.info(
'actionRenameTrack_trigger')
1535 selected_track = Track.get(id=track_id)
1536 track_name = selected_track.data[
"label"]
or _(
"Track %s") % selected_track.data[
"number"]
1538 text, ok = QInputDialog.getText(self, _(
'Rename Track'), _(
'Track Name:'), text=track_name)
1541 selected_track.data[
"label"] = text
1542 selected_track.save()
1545 log.info(
'actionRemoveMarker_trigger')
1548 marker = Marker.filter(id=marker_id)
1554 self.sliderZoom.setValue(self.sliderZoom.value() - self.sliderZoom.singleStep())
1557 self.sliderZoom.setValue(self.sliderZoom.value() + self.sliderZoom.singleStep())
1561 if not self.isFullScreen():
1562 self.showFullScreen()
1567 log.info(
"Show file properties")
1573 f = File.get(id=file_id)
1576 from windows.file_properties
import FileProperties
1577 win = FileProperties(f)
1579 result = win.exec_()
1580 if result == QDialog.Accepted:
1581 log.info(
'File Properties Finished')
1583 log.info(
'File Properties Cancelled')
1586 log.info(
"Switch to Details View")
1594 self.filesTreeView.prepare_for_delete()
1597 if app.context_menu_object ==
"files":
1598 s.set(
"file_view",
"details")
1600 self.filesTreeView.deleteLater()
1606 elif app.context_menu_object ==
"transitions":
1607 s.set(
"transitions_view",
"details")
1609 self.transitionsTreeView.deleteLater()
1615 elif app.context_menu_object ==
"effects":
1616 s.set(
"effects_view",
"details")
1618 self.effectsTreeView.deleteLater()
1624 log.info(
"Switch to Thumbnail View")
1632 self.filesTreeView.prepare_for_delete()
1635 if app.context_menu_object ==
"files":
1636 s.set(
"file_view",
"thumbnail")
1638 self.filesTreeView.deleteLater()
1644 elif app.context_menu_object ==
"transitions":
1645 s.set(
"transitions_view",
"thumbnail")
1647 self.transitionsTreeView.deleteLater()
1653 elif app.context_menu_object ==
"effects":
1654 s.set(
"effects_view",
"thumbnail")
1656 self.effectsTreeView.deleteLater()
1663 self.filesTreeView.resize_contents()
1668 return [self.dockFiles,
1669 self.dockTransitions,
1672 self.dockProperties]
1678 self.removeDockWidget(dock)
1684 self.addDockWidget(area, dock)
1690 dock.setFloating(is_floating)
1696 if get_app().window.dockWidgetArea(dock) != Qt.NoDockWidgetArea:
1704 dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
1710 dock.setFeatures(QDockWidget.AllDockWidgetFeatures)
1722 self.
addDocks([self.dockFiles, self.dockTransitions, self.dockEffects, self.dockVideo], Qt.TopDockWidgetArea)
1724 self.tabifyDockWidget(self.dockFiles, self.dockTransitions)
1725 self.tabifyDockWidget(self.dockTransitions, self.dockEffects)
1726 self.
showDocks([self.dockFiles, self.dockTransitions, self.dockEffects, self.dockVideo])
1729 simple_state =
"AAAA/wAAAAD9AAAAAwAAAAAAAAD8AAAA9PwCAAAAAfwAAAILAAAA9AAAAAAA////+v////8CAAAAAvsAAAAcAGQAbwBjAGsAUAByAG8AcABlAHIAdABpAGUAcwAAAAAA/////wAAAKEA////+wAAABgAZABvAGMAawBLAGUAeQBmAHIAYQBtAGUAAAAAAP////8AAAATAP///wAAAAEAAAEcAAABQPwCAAAAAfsAAAAYAGQAbwBjAGsASwBlAHkAZgByAGEAbQBlAQAAAVgAAAAVAAAAAAAAAAAAAAACAAAEqwAAAdz8AQAAAAL8AAAAAAAAAWQAAAB7AP////oAAAAAAgAAAAP7AAAAEgBkAG8AYwBrAEYAaQBsAGUAcwEAAAAA/////wAAAJgA////+wAAAB4AZABvAGMAawBUAHIAYQBuAHMAaQB0AGkAbwBuAHMBAAAAAP////8AAACYAP////sAAAAWAGQAbwBjAGsARQBmAGYAZQBjAHQAcwEAAAAA/////wAAAJgA////+wAAABIAZABvAGMAawBWAGkAZABlAG8BAAABagAAA0EAAAA6AP///wAABKsAAAD2AAAABAAAAAQAAAAIAAAACPwAAAABAAAAAgAAAAEAAAAOAHQAbwBvAGwAQgBhAHIBAAAAAP////8AAAAAAAAAAA=="
1731 QCoreApplication.processEvents()
1740 self.
addDocks([self.dockFiles, self.dockTransitions, self.dockVideo], Qt.TopDockWidgetArea)
1741 self.
addDocks([self.dockEffects], Qt.RightDockWidgetArea)
1742 self.
addDocks([self.dockProperties], Qt.LeftDockWidgetArea)
1745 self.
showDocks([self.dockFiles, self.dockTransitions, self.dockVideo, self.dockEffects, self.dockProperties])
1748 advanced_state =
"AAAA/wAAAAD9AAAAAwAAAAAAAAD8AAABQPwCAAAAAfwAAAG/AAABQAAAAKEA////+gAAAAACAAAAAvsAAAAcAGQAbwBjAGsAUAByAG8AcABlAHIAdABpAGUAcwEAAAAA/////wAAAKEA////+wAAABgAZABvAGMAawBLAGUAeQBmAHIAYQBtAGUAAAAAAP////8AAAATAP///wAAAAEAAAEcAAABQPwCAAAAAvsAAAAYAGQAbwBjAGsASwBlAHkAZgByAGEAbQBlAQAAAVgAAAAVAAAAAAAAAAD7AAAAFgBkAG8AYwBrAEUAZgBmAGUAYwB0AHMBAAABvwAAAUAAAACYAP///wAAAAIAAASrAAABkvwBAAAAA/sAAAASAGQAbwBjAGsARgBpAGwAZQBzAQAAAAAAAAFeAAAAcAD////7AAAAHgBkAG8AYwBrAFQAcgBhAG4AcwBpAHQAaQBvAG4AcwEAAAFkAAABAAAAAHAA////+wAAABIAZABvAGMAawBWAGkAZABlAG8BAAACagAAAkEAAAA6AP///wAAAocAAAFAAAAABAAAAAQAAAAIAAAACPwAAAABAAAAAgAAAAEAAAAOAHQAbwBvAGwAQgBhAHIBAAAAAP////8AAAAAAAAAAA=="
1750 QCoreApplication.processEvents()
1756 self.actionFreeze_View.setVisible(
False)
1757 self.actionUn_Freeze_View.setVisible(
True)
1763 self.actionFreeze_View.setVisible(
True)
1764 self.actionUn_Freeze_View.setVisible(
False)
1777 s.set(
"tutorial_enabled",
True)
1778 s.set(
"tutorial_ids",
"")
1782 self.tutorial_manager.exit_manager()
1793 profile =
get_app().project.get([
"profile"])
1797 if get_app().project.needs_save():
1798 save_indicator =
"*"
1799 self.actionSave.setEnabled(
True)
1801 self.actionSave.setEnabled(
False)
1804 if not get_app().project.current_filepath:
1806 self.setWindowTitle(
"%s %s [%s] - %s" % (save_indicator, _(
"Untitled Project"), profile,
"OpenShot Video Editor"))
1810 parent_path, filename = os.path.split(
get_app().project.current_filepath)
1811 filename, ext = os.path.splitext(filename)
1812 filename = filename.replace(
"_",
" ").replace(
"-",
" ").capitalize()
1813 self.setWindowTitle(
"%s %s [%s] - %s" % (save_indicator, filename, profile,
"OpenShot Video Editor"))
1817 log.info(
'updateStatusChanged')
1818 self.actionUndo.setEnabled(undo_status)
1819 self.actionRedo.setEnabled(redo_status)
1824 log.info(
'main::addSelection: item_id: %s, item_type: %s, clear_existing: %s' % (item_id, item_type, clear_existing))
1828 if item_type ==
"clip":
1829 self.selected_clips.clear()
1830 elif item_type ==
"transition":
1831 self.selected_transitions.clear()
1832 elif item_type ==
"effect":
1833 self.selected_effects.clear()
1836 self.TransformSignal.emit(
"")
1841 self.selected_clips.append(item_id)
1843 self.selected_transitions.append(item_id)
1845 self.selected_effects.append(item_id)
1850 self.show_property_timer.start()
1857 self.selected_clips.remove(item_id)
1859 self.selected_transitions.remove(item_id)
1861 self.selected_effects.remove(item_id)
1864 get_app().window.TransformSignal.emit(
"")
1880 self.show_property_timer.start()
1908 recent_projects = s.get(
"recent_projects")
1914 self.
recent_menu = self.menuFile.addMenu(QIcon.fromTheme(
"document-open-recent"), _(
"Recent Projects"))
1915 self.menuFile.insertMenu(self.actionRecent_Placeholder, self.
recent_menu)
1918 self.recent_menu.clear()
1921 for file_path
in reversed(recent_projects):
1922 new_action = self.recent_menu.addAction(file_path)
1936 self.actionUndo.setEnabled(
False)
1937 self.actionRedo.setEnabled(
False)
1942 self.filesActionGroup.setExclusive(
True)
1943 self.filesActionGroup.addAction(self.actionFilesShowAll)
1944 self.filesActionGroup.addAction(self.actionFilesShowVideo)
1945 self.filesActionGroup.addAction(self.actionFilesShowAudio)
1946 self.filesActionGroup.addAction(self.actionFilesShowImage)
1947 self.actionFilesShowAll.setChecked(
True)
1948 self.filesToolbar.addAction(self.actionFilesShowAll)
1949 self.filesToolbar.addAction(self.actionFilesShowVideo)
1950 self.filesToolbar.addAction(self.actionFilesShowAudio)
1951 self.filesToolbar.addAction(self.actionFilesShowImage)
1953 self.filesFilter.setObjectName(
"filesFilter")
1954 self.filesFilter.setPlaceholderText(_(
"Filter"))
1956 self.actionFilesClear.setEnabled(
False)
1957 self.filesToolbar.addAction(self.actionFilesClear)
1963 self.transitionsActionGroup.setExclusive(
True)
1964 self.transitionsActionGroup.addAction(self.actionTransitionsShowAll)
1965 self.transitionsActionGroup.addAction(self.actionTransitionsShowCommon)
1966 self.actionTransitionsShowAll.setChecked(
True)
1967 self.transitionsToolbar.addAction(self.actionTransitionsShowAll)
1968 self.transitionsToolbar.addAction(self.actionTransitionsShowCommon)
1970 self.transitionsFilter.setObjectName(
"transitionsFilter")
1971 self.transitionsFilter.setPlaceholderText(_(
"Filter"))
1973 self.actionTransitionsClear.setEnabled(
False)
1974 self.transitionsToolbar.addAction(self.actionTransitionsClear)
1980 self.effectsActionGroup.setExclusive(
True)
1981 self.effectsActionGroup.addAction(self.actionEffectsShowAll)
1982 self.effectsActionGroup.addAction(self.actionEffectsShowVideo)
1983 self.effectsActionGroup.addAction(self.actionEffectsShowAudio)
1984 self.actionEffectsShowAll.setChecked(
True)
1985 self.effectsToolbar.addAction(self.actionEffectsShowAll)
1986 self.effectsToolbar.addAction(self.actionEffectsShowVideo)
1987 self.effectsToolbar.addAction(self.actionEffectsShowAudio)
1989 self.effectsFilter.setObjectName(
"effectsFilter")
1990 self.effectsFilter.setPlaceholderText(_(
"Filter"))
1992 self.actionEffectsClear.setEnabled(
False)
1993 self.effectsToolbar.addAction(self.actionEffectsClear)
2000 spacer = QWidget(self)
2001 spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
2002 self.videoToolbar.addWidget(spacer)
2005 self.videoToolbar.addAction(self.actionJumpStart)
2006 self.videoToolbar.addAction(self.actionRewind)
2007 self.videoToolbar.addAction(self.actionPlay)
2008 self.videoToolbar.addAction(self.actionFastForward)
2009 self.videoToolbar.addAction(self.actionJumpEnd)
2010 self.actionPlay.setCheckable(
True)
2013 spacer = QWidget(self)
2014 spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
2015 self.videoToolbar.addWidget(spacer)
2022 self.timelineToolbar.addAction(self.actionAddTrack)
2023 self.timelineToolbar.addSeparator()
2026 self.timelineToolbar.addAction(self.actionSnappingTool)
2027 self.timelineToolbar.addAction(self.actionRazorTool)
2028 self.timelineToolbar.addSeparator()
2029 self.timelineToolbar.addAction(self.actionAddMarker)
2030 self.timelineToolbar.addAction(self.actionPreviousMarker)
2031 self.timelineToolbar.addAction(self.actionNextMarker)
2032 self.timelineToolbar.addSeparator()
2035 initial_scale =
get_app().project.get([
"scale"])
or 16
2041 self.sliderZoom.setPageStep(1)
2042 self.sliderZoom.setRange(0, 30)
2043 self.sliderZoom.setValue(initial_zoom)
2044 self.sliderZoom.setInvertedControls(
True)
2045 self.sliderZoom.resize(100, 16)
2050 self.timelineToolbar.addAction(self.actionTimelineZoomIn)
2051 self.timelineToolbar.addWidget(self.
sliderZoom)
2052 self.timelineToolbar.addAction(self.actionTimelineZoomOut)
2070 self.propertyTableView.loadProperties.emit(
"",
"")
2075 log.info(
'foundCurrentVersion: Found the latest version: %s' % version)
2079 if info.VERSION < version:
2081 spacer = QWidget(self)
2082 spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
2083 self.toolBar.addWidget(spacer)
2086 self.actionUpdate.setVisible(
True)
2087 self.actionUpdate.setText(_(
"Update Available"))
2088 self.actionUpdate.setToolTip(_(
"Update Available: <b>%s</b>") % version)
2091 updateButton = QToolButton()
2092 updateButton.setDefaultAction(self.actionUpdate)
2093 updateButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
2094 self.toolBar.addWidget(updateButton)
2100 self.tutorial_manager.re_position_dialog()
2105 if e.type() == QEvent.WindowActivate:
2106 self.tutorial_manager.re_show_dialog()
2107 elif e.type() == QEvent.WindowStateChange
and self.isMinimized():
2108 self.tutorial_manager.minimize()
2117 self.show_property_timer.stop()
2131 for action
in self.findChildren(QAction):
2132 if shortcut.get(
'setting') == action.objectName():
2133 action.setShortcut(QKeySequence(_(shortcut.get(
'value'))))
2140 log.info(
"InitCacheSettings")
2141 log.info(
"cache-mode: %s" % s.get(
"cache-mode"))
2142 log.info(
"cache-limit-mb: %s" % s.get(
"cache-limit-mb"))
2145 cache_limit = s.get(
"cache-limit-mb") * 1024 * 1024
2148 new_cache_object =
None
2149 if s.get(
"cache-mode") ==
"CacheMemory":
2151 log.info(
"Creating CacheMemory object with %s byte limit" % cache_limit)
2152 new_cache_object = openshot.CacheMemory(cache_limit)
2153 self.timeline_sync.timeline.SetCache(new_cache_object)
2155 elif s.get(
"cache-mode") ==
"CacheDisk":
2157 log.info(
"Creating CacheDisk object with %s byte limit at %s" % (cache_limit, info.PREVIEW_CACHE_PATH))
2158 image_format = s.get(
"cache-image-format")
2159 image_quality = s.get(
"cache-quality")
2160 image_scale = s.get(
"cache-scale")
2161 new_cache_object = openshot.CacheDisk(info.PREVIEW_CACHE_PATH, image_format, image_quality, image_scale, cache_limit)
2162 self.timeline_sync.timeline.SetCache(new_cache_object)
2166 self.cache_object.Clear()
2177 from gi.repository
import Unity
2178 self.unity_launchers.append(Unity.LauncherEntry.get_for_desktop_id(
"openshot-qt.desktop"))
2179 self.unity_launchers.append(Unity.LauncherEntry.get_for_desktop_id(
"appimagekit-openshot-qt.desktop"))
2183 launcher.set_property(
"progress", current_frame / (end_frame - start_frame))
2184 launcher.set_property(
"progress_visible",
True)
2197 launcher.set_property(
"progress", 0.0)
2198 launcher.set_property(
"progress_visible",
False)
2214 QMainWindow.__init__(self)
2230 if not s.get(
"unique_install_id"):
2231 s.set(
"unique_install_id", str(uuid4()))
2255 get_app().updates.add_watcher(self)
2264 if not self.
mode ==
"unittest":
2272 self.frameWeb.layout().addWidget(self.
timeline)
2275 if s.get(
"file_view") ==
"details":
2280 self.filesTreeView.setFocus()
2283 if s.get(
"transitions_view") ==
"details":
2290 if s.get(
"effects_view") ==
"details":
2301 self.txtPropertyFilter.setPlaceholderText(_(
"Filter"))
2304 self.dockPropertiesContent.layout().addWidget(self.
selectionLabel, 0, 1)
2316 self.show_property_timer.setInterval(100)
2318 self.show_property_timer.stop()
2322 self.tabVideo.layout().insertWidget(0, self.
videoPreview)
2333 self.preview_parent.Init(self, self.timeline_sync.timeline, self.
videoPreview)
2341 self.auto_save_timer.setInterval(s.get(
"autosave-interval") * 1000 * 60)
2343 if s.get(
"enable-auto-save"):
2344 self.auto_save_timer.start()
2347 if s.get(
"hardware_decode"):
2348 os.environ[
'OS2_DECODE_HW'] =
"1"
2350 os.environ[
'OS2_DECODE_HW'] =
"0"
2356 if not self.
mode ==
"unittest":
2363 if sys.platform ==
"linux":
2370 self.installEventFilter(self)
2376 QTimer.singleShot(100, self.refreshFrameSignal.emit)
def actionLockTrack_trigger
Callback for locking a track.
def actionAdvanced_View_trigger
Switch to an alternative view.
def actionExportVideo_trigger
def InitCacheSettings
Set the correct cache settings for the timeline.
def actionRemoveTrack_trigger
def actionImportImageSequence_trigger
def secondsToZoom
Convert a number of seconds to a timeline zoom factor.
def save_project
Save a project to a file path, and refresh the screen.
def recent_project_clicked
Load a recent project when clicked.
def actionDuplicateTitle_trigger
def actionImportFiles_trigger
def actionRemove_from_Project_trigger
def actionAddMarker_trigger
def track_metric_screen
Track a GUI screen being shown.
def actionAbout_trigger
Show about dialog.
def open_project
Open a project from a file path, and refresh the screen.
def actionFile_Properties_trigger
def get_app
Returns the current QApplication instance of OpenShot.
def actionArrowTool_trigger
def actionAnimatedTitle_trigger
def actionSimple_View_trigger
Switch to the default / simple view.
def str_to_bytes
This is required to save Qt byte arrays into a base64 string (to save screen preferences) ...
def setup_icon
Using the window xml, set the icon on the given element, or if theme_name passed load that icon...
def getDocks
Get a list of all dockable widgets.
def freezeDocks
Freeze all dockable widgets on the main screen (no float, moving, or closing)
def actionDetailsView_trigger
def floatDocks
Float or Un-Float all dockable widgets above main screen.
def foundCurrentVersion
Handle the callback for detecting the current version on openshot.org.
def actionRazorTool_trigger
Toggle razor tool on and off.
def actionRenameTrack_trigger
Callback for renaming track.
def eventFilter
Filter out certain types of window events.
def actionUnlockTrack_trigger
Callback for unlocking a track.
def actionSnappingTool_trigger
def actionEditTitle_trigger
def getShortcutByName
Get a key sequence back from the setting name.
def actionUn_Freeze_View_trigger
Un-Freeze all dockable widgets on the main screen.
def actionAddTrackBelow_trigger
def actionFilesShowAll_trigger
def actionTimelineZoomOut_trigger
def previewFrame
Preview a specific frame.
def actionAddTrack_trigger
def actionTranslate_trigger
def track_metric_error
Track an error has occurred.
def actionAnimation_trigger
def actionEffectsShowVideo_trigger
def actionJumpStart_trigger
def clear_all_thumbnails
Clear all user thumbnails.
def actionRemoveMarker_trigger
def actionReportBug_trigger
def InitKeyboardShortcuts
Initialize all keyboard shortcuts from the settings file.
def FrameExported
Connect to Unity launcher (for Linux)
def transformTriggered
Handle transform signal (to keep track of whether a transform is happening or not) ...
def keyPressEvent
Process key press events and match with known shortcuts.
def removeDocks
Remove all dockable widgets on main screen.
def actionRemoveTransition_trigger
def actionShow_All_trigger
Show all dockable widgets.
def actionThumbnailView_trigger
def actionNextMarker_trigger
def load_ui
Load a Qt *.ui file, and also load an XML parsed version.
def recover_backup
Recover the backup file (if any)
def showDocks
Show all dockable widgets on the main screen.
def show_property_timeout
Callback for show property timer.
def tail_file
Read the end of a file (n number of lines)
def actionPreferences_trigger
def getAllKeyboardShortcuts
Get a key sequence back from the setting name.
def actionSplitClip_trigger
def actionPreview_File_trigger
Preview the selected media file.
def actionTransitionsShowAll_trigger
def website_language
Get the current website language code for URLs.
def moveEvent
Move tutorial dialogs also (if any)
def actionProfile_trigger
def actionPreviousMarker_trigger
def unFreezeDocks
Un-freeze all dockable widgets on the main screen (allow them to be moved, closed, and floated)
def destroy_lock_file
Destroy the lock file.
def actionProperties_trigger
def actionRemoveEffect_trigger
def actionHelpContents_trigger
def zoomToSeconds
Convert zoom factor (slider position) into scale-seconds.
def SetWindowTitle
Set the window title based on a variety of factors.
def actionRemoveClip_trigger
def auto_save_project
Auto save the project.
def actionAskQuestion_trigger
def clearSelections
Clear all selection containers.
def actionFastForward_trigger
def actionFilesShowImage_trigger
def actionFilesShowVideo_trigger
def get_current_Version
Get the current version.
def track_exception_stacktrace
Track an exception/stacktrace has occurred.
Interface for classes that listen for 'undo' and 'redo' events.
def handlePausedVideo
Handle the pause signal, by refreshing the properties dialog.
def actionEffectsShowAudio_trigger
def actionUploadVideo_trigger
def actionFilesShowAudio_trigger
def load_recent_menu
Clear and load the list of recent menu items.
def actionFullscreen_trigger
def init_ui
Initialize all child widgets and action of a window or dialog.
def actionTransitionsShowCommon_trigger
def actionJumpEnd_trigger
This class contains the logic for the main window widget.
def updateStatusChanged
Easily be notified each time there are 'undo' or 'redo' actions available in the UpdateManager.
def actionTutorial_trigger
Show tutorial again.
def actionAddTrackAbove_trigger
def hideDocks
Hide all dockable widgets on the main screen.
def actionTimelineZoomIn_trigger
def addDocks
Add all dockable widgets to the same dock area on the main screen.
def actionEffectsShowAll_trigger
def track_metric_session
Track a GUI screen being shown.
def bytes_to_str
This is required to load base64 Qt byte array strings into a Qt byte array (to load screen preference...
def movePlayhead
Update playhead position.
def actionAdd_to_Timeline_trigger
def ExportFinished
Export has completed.
def create_lock_file
Create a lock file.
def actionFreeze_View_trigger
Freeze all dockable widgets on the main screen.
def get_settings
Get the current QApplication's settings instance.
def actionClearHistory_trigger
Clear history for current project.