From 045eb2a20a360d3ab1c5872a6528f5843caa3f7e Mon Sep 17 00:00:00 2001 From: Andrew Benson Date: Tue, 7 Mar 2023 11:11:12 -0600 Subject: [PATCH] openshot: update to 3.0.0. --- .../openshot/patches/0001-video_widget.patch | 74 - .../patches/0002-python3.10_int.patch | 1993 ----------------- srcpkgs/openshot/template | 6 +- 3 files changed, 3 insertions(+), 2070 deletions(-) delete mode 100644 srcpkgs/openshot/patches/0001-video_widget.patch delete mode 100644 srcpkgs/openshot/patches/0002-python3.10_int.patch diff --git a/srcpkgs/openshot/patches/0001-video_widget.patch b/srcpkgs/openshot/patches/0001-video_widget.patch deleted file mode 100644 index 5e93d764c4b..00000000000 --- a/srcpkgs/openshot/patches/0001-video_widget.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 9748a13268d66a5949aebc970637b5903756d018 Mon Sep 17 00:00:00 2001 -From: Jonathan Thomas -Date: Thu, 7 Oct 2021 13:53:09 -0500 -Subject: [PATCH] Support for previewing anamorphic video profiles, including a - few code clean-ups. - ---- - src/windows/video_widget.py | 22 +++++++--------------- - 1 file changed, 7 insertions(+), 15 deletions(-) - -diff --git a/src/windows/video_widget.py b/src/windows/video_widget.py -index 7326598d3..842deb3ba 100644 ---- a/src/windows/video_widget.py -+++ b/src/windows/video_widget.py -@@ -77,28 +77,20 @@ def changed(self, action): - if action.type == "load" and action.values.get("pixel_ratio"): - pixel_ratio_changed = True - self.pixel_ratio = openshot.Fraction( -- action.values.get("pixel_ratio").get("num", 16), -- action.values.get("pixel_ratio").get("den", 9)) -+ action.values.get("pixel_ratio").get("num", 1), -+ action.values.get("pixel_ratio").get("den", 1)) - log.info( - "Set video widget pixel aspect ratio to: %s", - self.pixel_ratio.ToFloat()) - elif action.key and action.key[0] == "pixel_ratio": - pixel_ratio_changed = True - self.pixel_ratio = openshot.Fraction( -- action.values.get("num", 16), -- action.values.get("den", 9)) -+ action.values.get("num", 1), -+ action.values.get("den", 1)) - log.info( - "Update: Set video widget pixel aspect ratio to: %s", - self.pixel_ratio.ToFloat()) - -- # Update max size (to size of video preview viewport) -- if display_ratio_changed or pixel_ratio_changed: -- timeline = get_app().window.timeline_sync.timeline -- timeline.SetMaxSize( -- round(self.width() * self.pixel_ratio.ToFloat()), -- round(self.height() * self.pixel_ratio.ToFloat()) -- ) -- - - def drawTransformHandler(self, painter, sx, sy, source_width, source_height, origin_x, origin_y, - x1=None, y1=None, x2=None, y2=None, rotation = None): -@@ -236,7 +228,7 @@ def paintEvent(self, event, *args): - # Determine original size of clip's reader - source_width = self.transforming_clip.data['reader']['width'] - source_height = self.transforming_clip.data['reader']['height'] -- source_size = QSize(source_width, source_height) -+ source_size = QSize(source_width, source_height * self.pixel_ratio.Reciprocal().ToDouble()) - - # Determine scale of clip - scale = self.transforming_clip.data['scale'] -@@ -405,7 +397,7 @@ def paintEvent(self, event, *args): - self.mutex.unlock() - - def centeredViewport(self, width, height): -- """ Calculate size of viewport to maintain apsect ratio """ -+ """ Calculate size of viewport to maintain aspect ratio """ - - # Calculate padding - top_padding = (height - (height * self.zoom)) / 2.0 -@@ -416,7 +408,7 @@ def centeredViewport(self, width, height): - height = height * self.zoom - - # Calculate which direction to scale (for perfect centering) -- aspectRatio = self.aspect_ratio.ToFloat() * self.pixel_ratio.ToFloat() -+ aspectRatio = self.aspect_ratio.ToFloat() - heightFromWidth = width / aspectRatio - widthFromHeight = height * aspectRatio - diff --git a/srcpkgs/openshot/patches/0002-python3.10_int.patch b/srcpkgs/openshot/patches/0002-python3.10_int.patch deleted file mode 100644 index 8f6dc53dbf4..00000000000 --- a/srcpkgs/openshot/patches/0002-python3.10_int.patch +++ /dev/null @@ -1,1993 +0,0 @@ -From a3088503500e79877ce985e4784f75478d9b792e Mon Sep 17 00:00:00 2001 -From: "FeRD (Frank Dana)" -Date: Mon, 20 Sep 2021 05:36:19 -0400 -Subject: [PATCH 1/6] Preferences: Fix logging calls - ---- - src/launch.py | 2 +- - src/windows/preferences.py | 18 +++++++++++------- - 2 files changed, 12 insertions(+), 8 deletions(-) - -diff --git a/src/launch.py b/src/launch.py -index 9fc600b23..b614e9bc7 100755 ---- a/src/launch.py -+++ b/src/launch.py -@@ -41,7 +41,7 @@ - """ - - import sys --import os.path -+import os - import argparse - - from PyQt5.QtCore import Qt -diff --git a/src/windows/preferences.py b/src/windows/preferences.py -index bf7d67b0c..325f496b3 100644 ---- a/src/windows/preferences.py -+++ b/src/windows/preferences.py -@@ -102,7 +102,7 @@ def __init__(self): - - def txtSearch_changed(self): - """textChanged event handler for search box""" -- log.info("Search for %s" % self.txtSearch.text()) -+ log.info("Search for %s", self.txtSearch.text()) - - # Populate preferences - self.Populate(filter=self.txtSearch.text()) -@@ -317,7 +317,7 @@ def Populate(self, filter=""): - value_list.remove(value_item) - - # Remove hardware mode items which cannot decode the example video -- log.debug("Preparing to test hardware decoding: %s" % (value_list)) -+ log.debug("Preparing to test hardware decoding: %s", value_list) - for value_item in list(value_list): - v = value_item["value"] - if (not self.testHardwareDecode(value_list, v, 0) -@@ -470,7 +470,7 @@ def bool_value_changed(self, widget, param, state): - # Trigger specific actions - if param["setting"] == "debug-mode": - # Update debug setting of timeline -- log.info("Setting debug-mode to %s" % (state == Qt.Checked)) -+ log.info("Setting debug-mode to %s", state == Qt.Checked) - debug_enabled = (state == Qt.Checked) - - # Enable / Disable logger -@@ -528,7 +528,9 @@ def text_value_changed(self, widget, param, value=None): - if param.get("category") == "Keyboard": - previous_value = value - value = QKeySequence(value).toString() -- log.info("Parsing keyboard mapping via QKeySequence from %s to %s" % (previous_value, value)) -+ log.info( -+ "Parsing keyboard mapping via QKeySequence from %s to %s", -+ previous_value, value) - - # Save setting - self.s.set(param["setting"], value) -@@ -604,11 +606,13 @@ def testHardwareDecode(self, all_decoders, decoder, decoder_card="0"): - if reader.GetFrame(0).CheckPixel(0, 0, 2, 133, 255, 255, 5): - is_supported = True - self.hardware_tests_cards[decoder_card].append(int(decoder)) -- log.debug("Successful hardware decoder! %s (%s-%s)" % (decoder_name, decoder, decoder_card)) -+ log.debug( -+ "Successful hardware decoder! %s (%s-%s)", -+ decoder_name, decoder, decoder_card) - else: - log.debug( - "CheckPixel failed testing hardware decoding (i.e. wrong color found): %s (%s-%s)", -- (decoder_name, decoder, decoder_card)) -+ decoder_name, decoder, decoder_card) - - reader.Close() - clip.Close() -@@ -616,7 +620,7 @@ def testHardwareDecode(self, all_decoders, decoder, decoder_card="0"): - except Exception: - log.debug( - "Exception trying to test hardware decoding (this is expected): %s (%s-%s)", -- (decoder_name, decoder, decoder_card)) -+ decoder_name, decoder, decoder_card) - - # Resume current settings - openshot.Settings.Instance().HARDWARE_DECODER = current_decoder - -From 1b14896d2057df80b0b20ba22e1380ba9e9bd6e6 Mon Sep 17 00:00:00 2001 -From: "FeRD (Frank Dana)" -Date: Thu, 4 Nov 2021 21:01:39 -0400 -Subject: [PATCH 2/6] Enforce integer function arguments - ---- - src/windows/export.py | 8 +- - src/windows/models/properties_model.py | 34 +- - src/windows/process_effect.py | 2 +- - src/windows/video_widget.py | 596 ++++++++++++++-------- - src/windows/views/effects_listview.py | 7 +- - src/windows/views/effects_treeview.py | 7 +- - src/windows/views/emojis_listview.py | 7 +- - src/windows/views/files_listview.py | 7 +- - src/windows/views/files_treeview.py | 7 +- - src/windows/views/properties_tableview.py | 38 +- - src/windows/views/transitions_listview.py | 7 +- - src/windows/views/transitions_treeview.py | 7 +- - src/windows/views/tutorial.py | 14 +- - 13 files changed, 476 insertions(+), 265 deletions(-) - -diff --git a/src/windows/export.py b/src/windows/export.py -index a624eb2e2..6461afb25 100644 ---- a/src/windows/export.py -+++ b/src/windows/export.py -@@ -290,7 +290,7 @@ def updateProgressBar(self, title_message, start_frame, end_frame, current_frame - percentage_string = format_of_progress_string % (( current_frame - start_frame ) / ( end_frame - start_frame ) * 100) - else: - percentage_string = "100%" -- self.progressExportVideo.setValue(current_frame) -+ self.progressExportVideo.setValue(int(current_frame)) - self.progressExportVideo.setFormat(percentage_string) - self.setWindowTitle("%s %s" % (percentage_string, title_message)) - -@@ -690,9 +690,9 @@ def titlestring(sec, fps, mess): - fps_encode = 0 - - # Init progress bar -- self.progressExportVideo.setMinimum(self.txtStartFrame.value()) -- self.progressExportVideo.setMaximum(self.txtEndFrame.value()) -- self.progressExportVideo.setValue(self.txtStartFrame.value()) -+ self.progressExportVideo.setMinimum(int(self.txtStartFrame.value())) -+ self.progressExportVideo.setMaximum(int(self.txtEndFrame.value())) -+ self.progressExportVideo.setValue(int(self.txtStartFrame.value())) - - # Prompt error message - if self.txtStartFrame.value() == self.txtEndFrame.value(): -diff --git a/src/windows/models/properties_model.py b/src/windows/models/properties_model.py -index c3236ed84..40897f642 100644 ---- a/src/windows/models/properties_model.py -+++ b/src/windows/models/properties_model.py -@@ -414,8 +414,8 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail - new_value = None - - log.info( -- "%s for %s changed to %s at frame %s with interpolation: %s at closest x: %s" -- % (property_key, clip_id, new_value, self.frame_number, interpolation, closest_point_x)) -+ "%s for %s changed to %s at frame %s with interpolation: %s at closest x: %s", -+ property_key, clip_id, new_value, self.frame_number, interpolation, closest_point_x) - - # Find this clip - c = None -@@ -518,35 +518,35 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail - try: - clip_data[property_key] = int(new_value) - except Exception as ex: -- log.warn('Invalid Integer value passed to property: %s' % ex) -+ log.warn('Invalid Integer value passed to property', exc_info=1) - - elif property_type == "float": - clip_updated = True - try: - clip_data[property_key] = float(new_value) - except Exception as ex: -- log.warn('Invalid Float value passed to property: %s' % ex) -+ log.warn('Invalid Float value passed to property', exc_info=1) - - elif property_type == "bool": - clip_updated = True - try: - clip_data[property_key] = bool(new_value) - except Exception as ex: -- log.warn('Invalid Boolean value passed to property: %s' % ex) -+ log.warn('Invalid Boolean value passed to property', exc_info=1) - - elif property_type == "string": - clip_updated = True - try: - clip_data[property_key] = str(new_value) -- except Exception as ex: -- log.warn('Invalid String value passed to property: %s' % ex) -+ except Exception: -+ log.warn('Invalid String value passed to property', exc_info=1) - - elif property_type in ["font", "caption"]: - clip_updated = True - try: - clip_data[property_key] = str(new_value) -- except Exception as ex: -- log.warn('Invalid Font/Caption value passed to property: %s' % ex) -+ except Exception: -+ log.warn('Invalid Font/Caption value passed to property', exc_info=1) - - elif property_type == "reader": - # Transition -@@ -557,8 +557,8 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail - clip_data[property_key] = json.loads(clip_object.Reader().Json()) - clip_object.Close() - clip_object = None -- except Exception as ex: -- log.warn('Invalid Reader value passed to property: %s (%s)' % (value, ex)) -+ except Exception: -+ log.warn('Invalid Reader value passed to property: %s (%s)', value, exc_info=1) - - # Reduce # of clip properties we are saving (performance boost) - clip_data = {property_key: clip_data.get(property_key)} -@@ -688,9 +688,9 @@ def set_property(self, property, filter, c, item_type, object_id=None): - - if type == "color": - # Color needs to be handled special -- red = property[1]["red"]["value"] -- green = property[1]["green"]["value"] -- blue = property[1]["blue"]["value"] -+ red = int(property[1]["red"]["value"]) -+ green = int(property[1]["green"]["value"]) -+ blue = int(property[1]["blue"]["value"]) - col.setBackground(QColor(red, green, blue)) - - if readonly or type in ["color", "font", "caption"] or choices or label == "Track": -@@ -789,9 +789,9 @@ def set_property(self, property, filter, c, item_type, object_id=None): - - if type == "color": - # Update the color based on the color curves -- red = property[1]["red"]["value"] -- green = property[1]["green"]["value"] -- blue = property[1]["blue"]["value"] -+ red = int(property[1]["red"]["value"]) -+ green = int(property[1]["green"]["value"]) -+ blue = int(property[1]["blue"]["value"]) - col.setBackground(QColor(red, green, blue)) - - # Update helper dictionary -diff --git a/src/windows/process_effect.py b/src/windows/process_effect.py -index e4f3120c0..ea0c2946e 100644 ---- a/src/windows/process_effect.py -+++ b/src/windows/process_effect.py -@@ -352,7 +352,7 @@ def accept(self): - while(not processing.IsDone() ): - # update progressbar - progressionStatus = processing.GetProgress() -- self.progressBar.setValue(progressionStatus) -+ self.progressBar.setValue(int(progressionStatus)) - time.sleep(0.01) - - # Process any queued events -diff --git a/src/windows/video_widget.py b/src/windows/video_widget.py -index d5c89a204..f33696c5c 100644 ---- a/src/windows/video_widget.py -+++ b/src/windows/video_widget.py -@@ -25,8 +25,11 @@ - along with OpenShot Library. If not, see . - """ - -+import json -+ - from PyQt5.QtCore import ( -- Qt, QCoreApplication, QPointF, QPoint, QRect, QRectF, QSize, QMutex, QTimer -+ Qt, QCoreApplication, QMutex, QTimer, -+ QPoint, QPointF, QSize, QSizeF, QRect, QRectF, - ) - from PyQt5.QtGui import ( - QTransform, QPainter, QIcon, QColor, QPen, QBrush, QCursor, QImage, QRegion -@@ -41,8 +44,6 @@ - from classes.app import get_app - from classes.query import Clip, Effect - --import json -- - - class VideoWidget(QWidget, updates.UpdateInterface): - """ A QWidget used on the video display widget """ -@@ -86,37 +87,68 @@ def changed(self, action): - self.pixel_ratio.ToFloat()) - - -- def drawTransformHandler(self, painter, sx, sy, source_width, source_height, origin_x, origin_y, -- x1=None, y1=None, x2=None, y2=None, rotation = None): -+ def drawTransformHandler( -+ self, painter, sx, sy, source_width, source_height, -+ origin_x, origin_y, -+ x1=None, y1=None, x2=None, y2=None, rotation = None -+ ): - # Draw transform corners and center origin circle - # Corner size - cs = self.cs - os = 12.0 - -+ csx = cs / sx -+ csy = cs / sy -+ - # Rotate the transform handler - if rotation: -- bbox_center_x = (((x1*source_width + x2*source_width) / 2.0) ) - ( (os/2) /sx) -- bbox_center_y = (((y1*source_height + y2*source_height) / 2.0) ) - ( (os/2) /sy) -+ bbox_center_x = ((x1*source_width + x2*source_width) / 2.0) - ((os / 2) / sx) -+ bbox_center_y = ((y1*source_height + y2*source_height) / 2.0) - ((os / 2) / sy) - painter.translate(bbox_center_x, bbox_center_y) - painter.rotate(rotation) - painter.translate(-bbox_center_x, -bbox_center_y) - -- if(x1 and y1 and x2 and y2): -+ if all([x1, y1, x2, y2]): - # Calculate bounds of clip -- self.clipBounds = QRectF(QPointF(x1*source_width, y1*source_height), QPointF(x2*source_width, y2*source_height)) -+ self.clipBounds = QRectF( -+ QPointF(x1 * source_width, y1 * source_height), -+ QPointF(x2 * source_width, y2 * source_height) -+ ) - # Calculate 4 corners coordinates -- self.topLeftHandle = QRectF(x1*source_width -(cs/sx/2.0), y1*source_height-(cs/sy/2.0), cs/sx, cs/sy) -- self.topRightHandle = QRectF(x2*source_width-(cs/sx/2.0), y1*source_height-(cs/sy/2.0), cs/sx, cs/sy) -- self.bottomLeftHandle = QRectF(x1*source_width -(cs/sx/2.0), y2*source_height-(cs/sy/2.0), cs/sx, cs/sy) -- self.bottomRightHandle = QRectF(x2*source_width-(cs/sx/2.0), y2*source_height-(cs/sy/2.0), cs/sx, cs/sy) -+ self.topLeftHandle = QRectF( -+ x1 * source_width - (csx / 2.0), -+ y1 * source_height - (csy / 2.0), -+ csx, -+ csy) -+ self.topRightHandle = QRectF( -+ x2 * source_width - (csx / 2.0), -+ y1 * source_height - (csy / 2.0), -+ csx, -+ csy) -+ self.bottomLeftHandle = QRectF( -+ x1 * source_width - (csx / 2.0), -+ y2 * source_height - (csy / 2.0), -+ csx, -+ csy) -+ self.bottomRightHandle = QRectF( -+ x2 * source_width - (csx / 2.0), -+ y2 * source_height - (csy / 2.0), -+ csx, -+ csy) - else: - # Calculate bounds of clip -- self.clipBounds = QRectF(QPointF(0.0, 0.0), QPointF(source_width, source_height)) -+ self.clipBounds = QRectF( -+ QPointF(0.0, 0.0), -+ QPointF(source_width, source_height)) - # Calculate 4 corners coordinates -- self.topLeftHandle = QRectF(-cs/sx/2.0, -cs/sy/2.0, cs/sx, cs/sy) -- self.topRightHandle = QRectF(source_width - (cs/sx) + cs/sx/2.0, -cs/sy/2.0, cs/sx, cs/sy) -- self.bottomLeftHandle = QRectF(-cs/sx/2.0, source_height - (cs/sy) + cs/sy/2.0, cs/sx, cs/sy) -- self.bottomRightHandle = QRectF(source_width - (cs/sx) + cs/sx/2.0, source_height - (cs/sy) + cs/sy/2.0, cs/sx, cs/sy) -+ self.topLeftHandle = QRectF( -+ -csx / 2.0, -csy / 2.0, csx, csy) -+ self.topRightHandle = QRectF( -+ source_width - csx / 2.0, -csy / 2.0, csx, csy) -+ self.bottomLeftHandle = QRectF( -+ -csx / 2.0, source_height - csy / 2.0, csx, csy) -+ self.bottomRightHandle = QRectF( -+ source_width - csx / 2.0, source_height - csy / 2.0, csx, csy) - - # Draw 4 corners - pen = QPen(QBrush(QColor("#53a0ed")), 1.5) -@@ -127,47 +159,110 @@ def drawTransformHandler(self, painter, sx, sy, source_width, source_height, ori - painter.drawRect(self.bottomLeftHandle) - painter.drawRect(self.bottomRightHandle) - -- if(x1 and y1 and x2 and y2): -+ if all([x1, y1, x2, y2]): - # Calculate 4 side coordinates -- self.topHandle = QRectF(((x1*source_width+x2*source_width) / 2.0) - (cs/sx/2.0), (y1*source_height)-cs/sy/2.0, cs/sx, cs/sy) -- self.bottomHandle = QRectF(((x1*source_width+x2*source_width) / 2.0) - (cs/sx/2.0), (y2*source_height)-( cs/sy/2.0), cs/sx, cs/sy) -- self.leftHandle = QRectF((x1*source_width)-(cs/sx/2.0), ((y1*source_height+y2*source_height) / 2.0) - (cs/sy/2.0), cs/sx, cs/sy) -- self.rightHandle = QRectF((x2*source_width) - (cs/sx) + cs/sx/2.0, ((y1*source_height+y2*source_height) / 2.0) - (cs/sy/2.0), cs/sx, cs/sy) -+ self.topHandle = QRectF( -+ ((x1 + x2) * source_width - csx) / 2.0, -+ (y1 * source_height) - csy / 2.0, -+ csx, -+ csy) -+ self.bottomHandle = QRectF( -+ ((x1 + x2) * source_width - csx) / 2.0, -+ (y2 * source_height) - csy / 2.0, -+ csx, -+ csy) -+ self.leftHandle = QRectF( -+ (x1 * source_width) - csx / 2.0, -+ ((y1 + y2) * source_height - csy) / 2.0, -+ csx, -+ csy) -+ self.rightHandle = QRectF( -+ (x2 * source_width) - csx / 2.0, -+ ((y1 + y2) * source_height - csy) / 2.0, -+ csx, csy) - - else: - # Calculate 4 side coordinates -- self.topHandle = QRectF((source_width / 2.0) - (cs/sx/2.0), -cs/sy/2.0, cs/sx, cs/sy) -- self.bottomHandle = QRectF((source_width / 2.0) - (cs/sx/2.0), source_height - (cs/sy) + cs/sy/2.0, cs/sx, cs/sy) -- self.leftHandle = QRectF(-cs/sx/2.0, (source_height / 2.0) - (cs/sy/2.0), cs/sx, cs/sy) -- self.rightHandle = QRectF(source_width - (cs/sx) + cs/sx/2.0, (source_height / 2.0) - (cs/sy/2.0), cs/sx, cs/sy) -+ self.topHandle = QRectF( -+ (source_width - csx) / 2.0, -+ -csy / 2.0, -+ csx, -+ csy) -+ self.bottomHandle = QRectF( -+ (source_width - csx) / 2.0, -+ source_height - (csy / 2.0), -+ csx, -+ csy) -+ self.leftHandle = QRectF( -+ -csx / 2.0, -+ (source_height - csy) / 2.0, -+ csx, -+ csy) -+ self.rightHandle = QRectF( -+ source_width - (csx / 2.0), -+ (source_height - csy) / 2.0, -+ csx, -+ csy) - - # Calculate shear handles -- self.topShearHandle = QRectF(self.topLeftHandle.x(), self.topLeftHandle.y(), self.clipBounds.width(), self.topLeftHandle.height()) -- self.leftShearHandle = QRectF(self.topLeftHandle.x(), self.topLeftHandle.y(), self.topLeftHandle.width(), self.clipBounds.height()) -- self.rightShearHandle = QRectF(self.topRightHandle.x(), self.topRightHandle.y(), self.topRightHandle.width(), self.clipBounds.height()) -- self.bottomShearHandle = QRectF(self.bottomLeftHandle.x(), self.bottomLeftHandle.y(), self.clipBounds.width(), self.topLeftHandle.height()) -+ self.topShearHandle = QRectF( -+ self.topLeftHandle.x(), -+ self.topLeftHandle.y(), -+ self.clipBounds.width(), -+ self.topLeftHandle.height()) -+ self.leftShearHandle = QRectF( -+ self.topLeftHandle.x(), -+ self.topLeftHandle.y(), -+ self.topLeftHandle.width(), -+ self.clipBounds.height()) -+ self.rightShearHandle = QRectF( -+ self.topRightHandle.x(), -+ self.topRightHandle.y(), -+ self.topRightHandle.width(), -+ self.clipBounds.height()) -+ self.bottomShearHandle = QRectF( -+ self.bottomLeftHandle.x(), -+ self.bottomLeftHandle.y(), -+ self.clipBounds.width(), -+ self.topLeftHandle.height()) - - # Draw 4 sides (centered) -- painter.drawRect(self.topHandle) -- painter.drawRect(self.bottomHandle) -- painter.drawRect(self.leftHandle) -- painter.drawRect(self.rightHandle) -- painter.drawRect(self.clipBounds) -+ painter.drawRects([ -+ self.topHandle, -+ self.bottomHandle, -+ self.leftHandle, -+ self.rightHandle, -+ self.clipBounds, -+ ]) - - # Calculate center coordinate -- if(x1 and y1 and x2 and y2): -+ if all([x1, y1, x2, y2]): - cs = 5.0 - os = 7.0 -- self.centerHandle = QRectF( (((x1*source_width+x2*source_width) / 2.0) ) - (os/sx), (((y1*source_height+y2*source_height) / 2.0) ) - (os/sy), os/sx*2.0, os/sy*2.0) -+ self.centerHandle = QRectF( -+ ((x1 + x2) * source_width / 2.0) - (os / sx), -+ ((y1 + y2) * source_height / 2.0) - (os / sy), -+ os / sx * 2.0, -+ os / sy * 2.0 -+ ) - else: -- self.centerHandle = QRectF((source_width * origin_x) - (os/sx), (source_height * origin_y) - (os/sy), os/sx*2.0, os/sy*2.0) -+ self.centerHandle = QRectF( -+ source_width * origin_x - (os / sx), -+ source_height * origin_y - (os / sy), -+ os / sx * 2.0, -+ os / sy * 2.0) - - # Draw origin - painter.drawEllipse(self.centerHandle) -- painter.drawLine(self.centerHandle.x() + (self.centerHandle.width()/2.0), self.centerHandle.y() + (self.centerHandle.height()/2.0) - self.centerHandle.height(), -- self.centerHandle.x() + (self.centerHandle.width()/2.0), self.centerHandle.y() + (self.centerHandle.height()/2.0) + self.centerHandle.height()) -- painter.drawLine(self.centerHandle.x() + (self.centerHandle.width()/2.0) - self.centerHandle.width(), self.centerHandle.y() + (self.centerHandle.height()/2.0), -- self.centerHandle.x() + (self.centerHandle.width()/2.0) + self.centerHandle.width(), self.centerHandle.y() + (self.centerHandle.height()/2.0)) -+ -+ # Draw cross at origin center, extending beyond ellipse by 25% -+ center = self.centerHandle.center() -+ halfW = QPointF(self.centerHandle.width() * 0.75, 0) -+ halfH = QPointF(0, self.centerHandle.height() * 0.75) -+ painter.drawLines( -+ center - halfW, center + halfW, -+ center - halfH, center + halfH, -+ ) - - # Remove transform - painter.resetTransform() -@@ -179,7 +274,11 @@ def paintEvent(self, event, *args): - - # Paint custom frame image on QWidget - painter = QPainter(self) -- painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing, True) -+ painter.setRenderHints( -+ QPainter.Antialiasing -+ | QPainter.SmoothPixmapTransform -+ | QPainter.TextAntialiasing, -+ True) - - # Fill the whole widget with the solid color - painter.fillRect(event.rect(), QColor("#191919")) -@@ -191,7 +290,7 @@ def paintEvent(self, event, *args): - # DRAW FRAME - # Calculate new frame image size, maintaining aspect ratio - pixSize = self.current_image.size() -- pixSize.scale(event.rect().width(), event.rect().height(), Qt.KeepAspectRatio) -+ pixSize.scale(event.rect().size(), Qt.KeepAspectRatio) - self.curr_frame_size = pixSize - - # Scale image (take into account display scaling for High DPI monitors) -@@ -223,13 +322,19 @@ def paintEvent(self, event, *args): - # Determine original size of clip's reader - source_width = self.transforming_clip.data['reader']['width'] - source_height = self.transforming_clip.data['reader']['height'] -- source_size = QSize(source_width, source_height * self.pixel_ratio.Reciprocal().ToDouble()) -+ pixel_adjust = self.pixel_ratio.Reciprocal().ToDouble() -+ source_size = QSize( -+ int(source_width), -+ int(source_height * pixel_adjust)) - - # Determine scale of clip - scale = self.transforming_clip.data['scale'] - - # Set scale as STRETCH if the clip is attached to an object -- if (raw_properties.get('parentObjectId').get('memo') != 'None' and len(raw_properties.get('parentObjectId').get('memo')) > 0 ): -+ if ( -+ raw_properties.get('parentObjectId').get('memo') != 'None' -+ and len(raw_properties.get('parentObjectId').get('memo')) > 0 -+ ): - scale = openshot.SCALE_STRETCH - - if scale == openshot.SCALE_FIT: -@@ -239,12 +344,7 @@ def paintEvent(self, event, *args): - source_size.scale(player_width, player_height, Qt.IgnoreAspectRatio) - - elif scale == openshot.SCALE_CROP: -- width_size = QSize(player_width, round(player_width / (float(source_width) / float(source_height)))) -- height_size = QSize(round(player_height / (float(source_height) / float(source_width))), player_height) -- if width_size.width() >= player_width and width_size.height() >= player_height: -- source_size.scale(width_size.width(), width_size.height(), Qt.KeepAspectRatio) -- else: -- source_size.scale(height_size.width(), height_size.height(), Qt.KeepAspectRatio) -+ source_size.scale(player_width, player_height, Qt.KeepAspectRatioByExpanding) - - # Get new source width / height (after scaling mode applied) - source_width = source_size.width() -@@ -285,9 +385,6 @@ def paintEvent(self, event, *args): - x += player_width - scaled_source_width # right - y += (player_height - scaled_source_height) # bottom - -- # Track gravity starting coordinate -- self.gravity_point = QPointF(x, y) -- - # Adjust x,y for location - x_offset = raw_properties.get('location_x').get('value') - y_offset = raw_properties.get('location_y').get('value') -@@ -329,7 +426,6 @@ def paintEvent(self, event, *args): - raw_properties_effect = json.loads(self.transforming_effect_object.PropertiesJSON(clip_frame_number)) - # Get properties for the first object in dict. PropertiesJSON should return one object at the time - tmp = raw_properties_effect.get('objects') -- tmp2 = tmp.keys() - obj_id = list(tmp.keys())[0] - raw_properties_effect = raw_properties_effect.get('objects').get(obj_id) - -@@ -342,10 +438,19 @@ def paintEvent(self, event, *args): - y1 = raw_properties_effect['y1']['value'] - x2 = raw_properties_effect['x2']['value'] - y2 = raw_properties_effect['y2']['value'] -- self.drawTransformHandler(painter, sx, sy, source_width, source_height, origin_x, origin_y, -- x1, y1, x2, y2, rotation) -+ self.drawTransformHandler( -+ painter, -+ sx, sy, -+ source_width, source_height, -+ origin_x, origin_y, -+ x1, y1, x2, y2, -+ rotation) - else: -- self.drawTransformHandler(painter, sx, sy, source_width, source_height, origin_x, origin_y) -+ self.drawTransformHandler( -+ painter, -+ sx, sy, -+ source_width, source_height, -+ origin_x, origin_y) - - if self.region_enabled: - # Paint region selector onto video preview -@@ -376,11 +481,21 @@ def paintEvent(self, event, *args): - pen = QPen(QBrush(QColor("#53a0ed")), 1.5) - pen.setCosmetic(True) - painter.setPen(pen) -- painter.drawRect(self.regionTopLeftHandle.x() - (cs/2.0/self.zoom), self.regionTopLeftHandle.y() - (cs/2.0/self.zoom), self.regionTopLeftHandle.width() / self.zoom, self.regionTopLeftHandle.height() / self.zoom) -- painter.drawRect(self.regionBottomRightHandle.x() - (cs/2.0/self.zoom), self.regionBottomRightHandle.y() - (cs/2.0/self.zoom), self.regionBottomRightHandle.width() / self.zoom, self.regionBottomRightHandle.height() / self.zoom) -- region_rect = QRectF(self.regionTopLeftHandle.x(), self.regionTopLeftHandle.y(), -- self.regionBottomRightHandle.x() - self.regionTopLeftHandle.x(), -- self.regionBottomRightHandle.y() - self.regionTopLeftHandle.y()) -+ painter.drawRect( -+ self.regionTopLeftHandle.x() - (cs / 2.0 / self.zoom), -+ self.regionTopLeftHandle.y() - (cs / 2.0 / self.zoom), -+ self.regionTopLeftHandle.width() / self.zoom, -+ self.regionTopLeftHandle.height() / self.zoom) -+ painter.drawRect( -+ self.regionBottomRightHandle.x() - (cs / 2.0 / self.zoom), -+ self.regionBottomRightHandle.y() - (cs / 2.0 / self.zoom), -+ self.regionBottomRightHandle.width() / self.zoom, -+ self.regionBottomRightHandle.height() / self.zoom) -+ region_rect = QRectF( -+ self.regionTopLeftHandle.x(), -+ self.regionTopLeftHandle.y(), -+ self.regionBottomRightHandle.x() - self.regionTopLeftHandle.x(), -+ self.regionBottomRightHandle.y() - self.regionTopLeftHandle.y()) - painter.drawRect(region_rect) - - # Remove transform -@@ -394,23 +509,15 @@ def paintEvent(self, event, *args): - def centeredViewport(self, width, height): - """ Calculate size of viewport to maintain aspect ratio """ - -- # Calculate padding -- top_padding = (height - (height * self.zoom)) / 2.0 -- left_padding = (width - (width * self.zoom)) / 2.0 -+ window_size = QSizeF(width, height) -+ window_rect = QRectF(QPointF(0, 0), window_size) - -- # Adjust parameters to zoom -- width = width * self.zoom -- height = height * self.zoom -+ aspectRatio = self.aspect_ratio.ToFloat() * self.pixel_ratio.ToFloat() -+ viewport_size = QSizeF(aspectRatio, 1).scaled(window_size, Qt.KeepAspectRatio) -+ viewport_rect = QRectF(QPointF(0, 0), viewport_size) -+ viewport_rect.moveCenter(window_rect.center()) - -- # Calculate which direction to scale (for perfect centering) -- aspectRatio = self.aspect_ratio.ToFloat() -- heightFromWidth = width / aspectRatio -- widthFromHeight = height * aspectRatio -- -- if heightFromWidth <= height: -- return QRect(left_padding, ((height - heightFromWidth) / 2) + top_padding, width, heightFromWidth) -- else: -- return QRect(((width - widthFromHeight) / 2.0) + left_padding, top_padding, widthFromHeight, height) -+ return viewport_rect.toRect() - - def present(self, image, *args): - """ Present the current frame """ -@@ -448,12 +555,16 @@ def mouseReleaseEvent(self, event): - # This can be used other widgets to display the selected region - if self.region_enabled: - # Get region coordinates -- region_rect = QRectF(self.regionTopLeftHandle.x(), self.regionTopLeftHandle.y(), -- self.regionBottomRightHandle.x() - self.regionTopLeftHandle.x(), -- self.regionBottomRightHandle.y() - self.regionTopLeftHandle.y()).normalized() -+ region_rect = QRectF( -+ self.regionTopLeftHandle.x(), -+ self.regionTopLeftHandle.y(), -+ self.regionBottomRightHandle.x() - self.regionTopLeftHandle.x(), -+ self.regionBottomRightHandle.y() - self.regionTopLeftHandle.y() -+ ).normalized() - - # Map region (due to zooming) -- mapped_region_rect = self.region_transform.mapToPolygon(region_rect.toRect()).boundingRect() -+ mapped_region_rect = self.region_transform.mapToPolygon( -+ region_rect.toRect()).boundingRect() - - # Render a scaled version of the region (as a QImage) - # TODO: Grab higher quality pixmap from the QWidget, as this method seems to be 1/2 resolution -@@ -461,14 +572,25 @@ def mouseReleaseEvent(self, event): - scale = 3.0 - - # Map rect to transform (for scaling video elements) -- mapped_region_rect = QRect(mapped_region_rect.x(), mapped_region_rect.y(), mapped_region_rect.width() * scale, mapped_region_rect.height() * scale) -+ mapped_region_rect = QRect( -+ mapped_region_rect.x(), -+ mapped_region_rect.y(), -+ int(mapped_region_rect.width() * scale), -+ int(mapped_region_rect.height() * scale)) - - # Render QWidget onto scaled QImage -- self.region_qimage = QImage(mapped_region_rect.width(), mapped_region_rect.height(), QImage.Format_RGBA8888) -+ self.region_qimage = QImage( -+ mapped_region_rect.size(), QImage.Format_RGBA8888) - region_painter = QPainter(self.region_qimage) -- region_painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing, True) -+ region_painter.setRenderHints( -+ QPainter.Antialiasing -+ | QPainter.SmoothPixmapTransform -+ | QPainter.TextAntialiasing, -+ True) - region_painter.scale(scale, scale) -- self.render(region_painter, QPoint(0,0), QRegion(mapped_region_rect, QRegion.Rectangle)) -+ self.render( -+ region_painter, QPoint(0, 0), -+ QRegion(mapped_region_rect, QRegion.Rectangle)) - region_painter.end() - - # Inform UpdateManager to accept updates, and only store our final update -@@ -484,7 +606,8 @@ def mouseReleaseEvent(self, event): - def rotateCursor(self, pixmap, rotation, shear_x, shear_y): - """Rotate cursor based on the current transform""" - rotated_pixmap = pixmap.transformed( -- QTransform().rotate(rotation).shear(shear_x, shear_y).scale(0.8, 0.8), Qt.SmoothTransformation) -+ QTransform().rotate(rotation).shear(shear_x, shear_y).scale(0.8, 0.8), -+ Qt.SmoothTransformation) - return QCursor(rotated_pixmap) - - def getTransformMode(self, rotation, shear_x, shear_y, event): -@@ -627,6 +750,10 @@ def mouseMoveEvent(self, event): - - # Transform clip object - if self.transform_mode: -+ -+ x_motion = event.pos().x() - self.mouse_position.x() -+ y_motion = event.pos().y() - self.mouse_position.y() -+ - if self.transform_mode == 'origin': - # Get current keyframe value - origin_x = raw_properties.get('origin_x').get('value') -@@ -635,8 +762,8 @@ def mouseMoveEvent(self, event): - scale_y = raw_properties.get('scale_y').get('value') - - # Calculate new location coordinates -- origin_x += (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() * scale_x) -- origin_y += (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() * scale_y) -+ origin_x += x_motion / (self.clipBounds.width() * scale_x) -+ origin_y += y_motion / (self.clipBounds.height() * scale_y) - - # Constrain to clip - if origin_x < 0.0: -@@ -648,8 +775,13 @@ def mouseMoveEvent(self, event): - if origin_y > 1.0: - origin_y = 1.0 - # Update keyframe value (or create new one) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'origin_x', origin_x, refresh=False) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'origin_y', origin_y) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'origin_x', origin_x, -+ refresh=False) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'origin_y', origin_y) - - elif self.transform_mode == 'location': - # Get current keyframe value -@@ -657,12 +789,17 @@ def mouseMoveEvent(self, event): - location_y = raw_properties.get('location_y').get('value') - - # Calculate new location coordinates -- location_x += (event.pos().x() - self.mouse_position.x()) / viewport_rect.width() -- location_y += (event.pos().y() - self.mouse_position.y()) / viewport_rect.height() -+ location_x += x_motion / viewport_rect.width() -+ location_y += y_motion / viewport_rect.height() - - # Update keyframe value (or create new one) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'location_x', location_x, refresh=False) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'location_y', location_y) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'location_x', location_x, -+ refresh=False) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'location_y', location_y) - - elif self.transform_mode == 'shear_top': - # Get current keyframe shear value -@@ -672,11 +809,13 @@ def mouseMoveEvent(self, event): - # Calculate new location coordinates - aspect_ratio = (self.clipBounds.width() / self.clipBounds.height()) * 2.0 - shear_x -= ( -- event.pos().x() - self.mouse_position.x()) / ( -+ x_motion) / ( - (self.clipBounds.width() * scale_x) / aspect_ratio) - - # Update keyframe value (or create new one) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'shear_x', shear_x) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'shear_x', shear_x) - - elif self.transform_mode == 'shear_bottom': - # Get current keyframe shear value -@@ -686,11 +825,13 @@ def mouseMoveEvent(self, event): - # Calculate new location coordinates - aspect_ratio = (self.clipBounds.width() / self.clipBounds.height()) * 2.0 - shear_x += ( -- event.pos().x() - self.mouse_position.x()) / ( -+ x_motion) / ( - (self.clipBounds.width() * scale_x) / aspect_ratio) - - # Update keyframe value (or create new one) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'shear_x', shear_x) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'shear_x', shear_x) - - elif self.transform_mode == 'shear_left': - # Get current keyframe shear value -@@ -701,11 +842,13 @@ def mouseMoveEvent(self, event): - aspect_ratio = ( - self.clipBounds.height() / self.clipBounds.width()) * 2.0 - shear_y -= ( -- event.pos().y() - self.mouse_position.y()) / ( -+ y_motion) / ( - self.clipBounds.height() * scale_y / aspect_ratio) - - # Update keyframe value (or create new one) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'shear_y', shear_y) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'shear_y', shear_y) - - elif self.transform_mode == 'shear_right': - # Get current keyframe shear value -@@ -713,13 +856,16 @@ def mouseMoveEvent(self, event): - shear_y = raw_properties.get('shear_y').get('value') - - # Calculate new location coordinates -- aspect_ratio = (self.clipBounds.height() / self.clipBounds.width()) * 2.0 -+ aspect_ratio = ( -+ self.clipBounds.height() / self.clipBounds.width()) * 2.0 - shear_y += ( -- event.pos().y() - self.mouse_position.y()) / ( -+ y_motion) / ( - self.clipBounds.height() * scale_y / aspect_ratio) - - # Update keyframe value (or create new one) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'shear_y', shear_y) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'shear_y', shear_y) - - elif self.transform_mode == 'rotation': - # Get current rotation keyframe value -@@ -728,71 +874,68 @@ def mouseMoveEvent(self, event): - scale_y = max(float(raw_properties.get('scale_y').get('value')), 0.001) - - # Calculate new location coordinates -- is_on_left = event.pos().x() < self.originHandle.x() -+ is_on_right = event.pos().x() > self.originHandle.x() - is_on_top = event.pos().y() < self.originHandle.y() - -- if is_on_top: -- rotation += ( -- event.pos().x() - self.mouse_position.x()) / ( -- (self.clipBounds.width() * scale_x) / 90) -- else: -- rotation -= ( -- event.pos().x() - self.mouse_position.x()) / ( -- (self.clipBounds.width() * scale_x) / 90) -- -- if is_on_left: -- rotation -= ( -- event.pos().y() - self.mouse_position.y()) / ( -- (self.clipBounds.height() * scale_y) / 90) -- else: -- rotation += ( -- event.pos().y() - self.mouse_position.y()) / ( -- (self.clipBounds.height() * scale_y) / 90) -+ x_adjust = x_motion / ((self.clipBounds.width() * scale_x) / 90) -+ rotation += (x_adjust if is_on_top else -x_adjust) -+ -+ y_adjust = y_motion / ((self.clipBounds.height() * scale_y) / 90) -+ rotation += (y_adjust if is_on_right else -y_adjust) - - # Update keyframe value (or create new one) -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'rotation', rotation) -+ self.updateClipProperty( -+ self.transforming_clip.id, -+ clip_frame_number, -+ 'rotation', rotation) - - elif self.transform_mode.startswith('scale_'): - # Get current scale keyframe value - scale_x = max(float(raw_properties.get('scale_x').get('value')), 0.001) - scale_y = max(float(raw_properties.get('scale_y').get('value')), 0.001) - -+ half_w = self.clipBounds.width() / 2.0 -+ half_h = self.clipBounds.height() / 2.0 -+ - if self.transform_mode == 'scale_top_right': -- scale_x += (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -- scale_y -= (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_x += x_motion / half_w -+ scale_y -= y_motion / half_h - elif self.transform_mode == 'scale_bottom_right': -- scale_x += (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -- scale_y += (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_x += x_motion / half_w -+ scale_y += y_motion / half_h - elif self.transform_mode == 'scale_top_left': -- scale_x -= (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -- scale_y -= (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_x -= x_motion / half_w -+ scale_y -= y_motion / half_h - elif self.transform_mode == 'scale_bottom_left': -- scale_x -= (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -- scale_y += (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_x -= x_motion / half_w -+ scale_y += y_motion / half_h - elif self.transform_mode == 'scale_top': -- scale_y -= (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_y -= y_motion / half_h - elif self.transform_mode == 'scale_bottom': -- scale_y += (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_y += y_motion / half_h - elif self.transform_mode == 'scale_left': -- scale_x -= (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -+ scale_x -= x_motion / half_w - elif self.transform_mode == 'scale_right': -- scale_x += (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -+ scale_x += x_motion / half_w - - if int(QCoreApplication.instance().keyboardModifiers() & Qt.ControlModifier) > 0: - # If CTRL key is pressed, fix the scale_y to the correct aspect ration -- if scale_x and scale_y: -+ if scale_x: - scale_y = scale_x - elif scale_y: - scale_x = scale_y -- elif scale_x: -- scale_y = scale_x - - # Update keyframe value (or create new one) - both_scaled = scale_x != 0.001 and scale_y != 0.001 - if scale_x != 0.001: -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'scale_x', scale_x, refresh=(not both_scaled)) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'scale_x', scale_x, -+ refresh=(not both_scaled)) - if scale_y != 0.001: -- self.updateClipProperty(self.transforming_clip.id, clip_frame_number, 'scale_y', scale_y) -+ self.updateClipProperty( -+ self.transforming_clip.id, clip_frame_number, -+ 'scale_y', scale_y) - - # Force re-paint - self.update() -@@ -803,16 +946,29 @@ def mouseMoveEvent(self, event): - cs = self.cs - - # Adjust existing region coordinates (if any) -- if not self.mouse_dragging and self.resize_button.isVisible() and self.resize_button.rect().contains(event.pos()): -+ if (not self.mouse_dragging -+ and self.resize_button.isVisible() -+ and self.resize_button.rect().contains(event.pos()) -+ ): - # Mouse over resize button (and not currently dragging) - self.setCursor(Qt.ArrowCursor) -- elif self.region_transform and self.regionTopLeftHandle and self.region_transform.mapToPolygon(self.regionTopLeftHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -+ elif ( -+ self.region_transform -+ and self.regionTopLeftHandle -+ and self.region_transform.mapToPolygon( -+ self.regionTopLeftHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill) -+ ): - if not self.region_mode or self.region_mode == 'scale_top_left': - self.setCursor(self.rotateCursor(self.cursors.get('resize_fdiag'), 0, 0, 0)) - # Set the region mode - if self.mouse_dragging and not self.region_mode: - self.region_mode = 'scale_top_left' -- elif self.region_transform and self.regionBottomRightHandle and self.region_transform.mapToPolygon(self.regionBottomRightHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -+ elif ( -+ self.region_transform -+ and self.regionBottomRightHandle -+ and self.region_transform.mapToPolygon( -+ self.regionBottomRightHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill) -+ ): - if not self.region_mode or self.region_mode == 'scale_bottom_right': - self.setCursor(self.rotateCursor(self.cursors.get('resize_fdiag'), 0, 0, 0)) - # Set the region mode -@@ -824,13 +980,25 @@ def mouseMoveEvent(self, event): - # Initialize new region coordinates at current event.pos() - if self.mouse_dragging and not self.region_mode: - self.region_mode = 'scale_bottom_right' -- self.regionTopLeftHandle = QRectF(self.region_transform_inverted.map(event.pos()).x(), self.region_transform_inverted.map(event.pos()).y(), cs, cs) -- self.regionBottomRightHandle = QRectF(self.region_transform_inverted.map(event.pos()).x(), self.region_transform_inverted.map(event.pos()).y(), cs, cs) -+ self.regionTopLeftHandle = QRectF( -+ self.region_transform_inverted.map(event.pos()).x(), -+ self.region_transform_inverted.map(event.pos()).y(), -+ cs, cs) -+ self.regionBottomRightHandle = QRectF( -+ self.region_transform_inverted.map(event.pos()).x(), -+ self.region_transform_inverted.map(event.pos()).y(), -+ cs, cs) - - # Move existing region coordinates - if self.mouse_dragging: -- diff_x = self.region_transform_inverted.map(event.pos()).x() - self.region_transform_inverted.map(self.mouse_position).x() -- diff_y = self.region_transform_inverted.map(event.pos()).y() - self.region_transform_inverted.map(self.mouse_position).y() -+ diff_x = int( -+ self.region_transform_inverted.map(event.pos()).x() -+ - self.region_transform_inverted.map(self.mouse_position).x() -+ ) -+ diff_y = int( -+ self.region_transform_inverted.map(event.pos()).y() -+ - self.region_transform_inverted.map(self.mouse_position).y() -+ ) - if self.region_mode == 'scale_top_left': - self.regionTopLeftHandle.adjust(diff_x, diff_y, diff_x, diff_y) - elif self.region_mode == 'scale_bottom_right': -@@ -859,12 +1027,11 @@ def mouseMoveEvent(self, event): - if self.mouse_dragging and not self.transform_mode: - self.original_clip_data = self.transforming_clip.data - -- -- - if self.transforming_effect_object.info.has_tracked_object: - # Get properties of effect at current frame - raw_properties = json.loads(self.transforming_effect_object.PropertiesJSON(clip_frame_number)) -- # Get properties for the first object in dict. PropertiesJSON should return one object at the time -+ # Get properties for the first object in dict. -+ # PropertiesJSON should return one object at the time - obj_id = list(raw_properties.get('objects').keys())[0] - raw_properties = raw_properties.get('objects').get(obj_id) - -@@ -878,18 +1045,28 @@ def mouseMoveEvent(self, event): - # Transform effect object - if self.transform_mode: - -+ x_motion = event.pos().x() - self.mouse_position.x() -+ y_motion = event.pos().y() - self.mouse_position.y() -+ - if self.transform_mode == 'location': - # Get current keyframe value - location_x = raw_properties.get('delta_x').get('value') - location_y = raw_properties.get('delta_y').get('value') - - # Calculate new location coordinates -- location_x += (event.pos().x() - self.mouse_position.x()) / viewport_rect.width() -- location_y += (event.pos().y() - self.mouse_position.y()) / viewport_rect.height() -+ location_x += x_motion / viewport_rect.width() -+ location_y += y_motion / viewport_rect.height() - - # Update keyframe value (or create new one) -- self.updateEffectProperty(self.transforming_effect.id, clip_frame_number, obj_id, 'delta_x', location_x, refresh=False) -- self.updateEffectProperty(self.transforming_effect.id, clip_frame_number, obj_id, 'delta_y', location_y) -+ self.updateEffectProperty( -+ self.transforming_effect.id, clip_frame_number, -+ obj_id, -+ 'delta_x', location_x, -+ refresh=False) -+ self.updateEffectProperty( -+ self.transforming_effect.id, clip_frame_number, -+ obj_id, -+ 'delta_y', location_y) - - elif self.transform_mode == 'rotation': - # Get current rotation keyframe value -@@ -898,63 +1075,70 @@ def mouseMoveEvent(self, event): - scale_y = max(float(raw_properties.get('scale_y').get('value')), 0.001) - - # Calculate new location coordinates -- is_on_left = event.pos().x() < self.originHandle.x() -+ is_on_right = event.pos().x() > self.originHandle.x() - is_on_top = event.pos().y() < self.originHandle.y() - -- if is_on_top: -- rotation += (event.pos().x() - self.mouse_position.x()) / ((self.clipBounds.width() * scale_x) / 90) -- else: -- rotation -= (event.pos().x() - self.mouse_position.x()) / ((self.clipBounds.width() * scale_x) / 90) -+ x_adjust = x_motion / (self.clipBounds.width() * scale_x / 90) -+ rotation += (x_adjust if is_on_top else -x_adjust) - -- if is_on_left: -- rotation -= (event.pos().y() - self.mouse_position.y()) / ((self.clipBounds.height() * scale_y) / 90) -- else: -- rotation += (event.pos().y() - self.mouse_position.y()) / ((self.clipBounds.height() * scale_y) / 90) -+ y_adjust = y_motion / (self.clipBounds.height() * scale_y / 90) -+ rotation += (y_adjust if is_on_right else -y_adjust) - - # Update keyframe value (or create new one) -- self.updateEffectProperty(self.transforming_effect.id, clip_frame_number, obj_id, 'rotation', rotation) -+ self.updateEffectProperty( -+ self.transforming_effect.id, -+ clip_frame_number, obj_id, -+ 'rotation', rotation) - - elif self.transform_mode.startswith('scale_'): - # Get current scale keyframe value - scale_x = max(float(raw_properties.get('scale_x').get('value')), 0.001) - scale_y = max(float(raw_properties.get('scale_y').get('value')), 0.001) - -+ half_w = self.clipBounds.width() / 2.0 -+ half_h = self.clipBounds.height() / 2.0 -+ - if self.transform_mode == 'scale_top_right': -- scale_x += (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -- scale_y -= (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_x += x_motion / half_w -+ scale_y -= y_motion / half_h - elif self.transform_mode == 'scale_bottom_right': -- scale_x += (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -- scale_y += (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_x += x_motion / half_w -+ scale_y += y_motion / half_h - elif self.transform_mode == 'scale_top_left': -- scale_x -= (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -- scale_y -= (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_x -= x_motion / half_w -+ scale_y -= y_motion / half_h - elif self.transform_mode == 'scale_bottom_left': -- scale_x -= (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -- scale_y += (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_x -= x_motion / half_w -+ scale_y += y_motion / half_h - elif self.transform_mode == 'scale_top': -- scale_y -= (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_y -= y_motion / half_h - elif self.transform_mode == 'scale_bottom': -- scale_y += (event.pos().y() - self.mouse_position.y()) / (self.clipBounds.height() / 2.0) -+ scale_y += y_motion / half_h - elif self.transform_mode == 'scale_left': -- scale_x -= (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -+ scale_x -= x_motion / half_w - elif self.transform_mode == 'scale_right': -- scale_x += (event.pos().x() - self.mouse_position.x()) / (self.clipBounds.width() / 2.0) -+ scale_x += x_motion / half_w - - if int(QCoreApplication.instance().keyboardModifiers() & Qt.ControlModifier) > 0: -- # If CTRL key is pressed, fix the scale_y to the correct aspect ration -- if scale_x and scale_y: -+ # If CTRL key is pressed, fix the scale_y to the correct aspect ratio -+ if scale_x: - scale_y = scale_x - elif scale_y: - scale_x = scale_y -- elif scale_x: -- scale_y = scale_x - - # Update keyframe value (or create new one) - both_scaled = scale_x != 0.001 and scale_y != 0.001 - if scale_x != 0.001: -- self.updateEffectProperty(self.transforming_effect.id, clip_frame_number, obj_id, 'scale_x', scale_x, refresh=(not both_scaled)) -+ self.updateEffectProperty( -+ self.transforming_effect.id, -+ clip_frame_number, obj_id, -+ 'scale_x', scale_x, -+ refresh=(not both_scaled)) - if scale_y != 0.001: -- self.updateEffectProperty(self.transforming_effect.id, clip_frame_number, obj_id, 'scale_y', scale_y) -+ self.updateEffectProperty( -+ self.transforming_effect.id, -+ clip_frame_number, obj_id, -+ 'scale_y', scale_y) - - # Force re-paint - self.update() -@@ -1012,8 +1196,15 @@ def updateEffectProperty(self, effect_id, frame_number, obj_id, property_key, ne - # No clip found - return - -- for point in c.data['objects'][obj_id][property_key]["Points"]: -- log.info("looping points: co.X = %s" % point["co"]["X"]) -+ try: -+ props = c.data['objects'][obj_id] -+ points_list = props[property_key]["Points"] -+ except (TypeError, KeyError): -+ log.error("Corrupted project data!", exc_info=1) -+ return -+ -+ for point in points_list: -+ log.info("looping points: co.X = %s", point["co"]["X"]) - - if point["co"]["X"] == frame_number: - found_point = True -@@ -1023,12 +1214,15 @@ def updateEffectProperty(self, effect_id, frame_number, obj_id, property_key, ne - - if not found_point and new_value != None: - effect_updated = True -- log.info("Created new point at X=%s" % frame_number) -- c.data['objects'][obj_id][property_key]["Points"].append({'co': {'X': frame_number, 'Y': new_value}, 'interpolation': openshot.BEZIER}) -+ log.info("Created new point at X=%s", frame_number) -+ points_list.append({ -+ 'co': { 'X': frame_number, 'Y': new_value }, -+ 'interpolation': openshot.BEZIER, -+ }) - - # Reduce # of clip properties we are saving (performance boost) - #TODO: This is too slow when draging transform handlers -- c.data = {'objects': {obj_id: c.data.get('objects').get(obj_id)}} -+ c.data = {'objects': {obj_id: c.data.get('objects', {}).get(obj_id)}} - - if effect_updated: - c.save() -@@ -1040,10 +1234,10 @@ def refreshTriggered(self): - """Signal to refresh viewport (i.e. a property might have changed that effects the preview)""" - - # Update reference to clip -- if self and self.transforming_clip: -+ if self.transforming_clip: - self.transforming_clip = Clip.get(id=self.transforming_clip.id) - -- if self and self.transforming_effect: -+ if self.transforming_effect: - self.transforming_effect = Effect.get(id=self.transforming_effect.id) - - def transformTriggered(self, clip_id): -@@ -1053,7 +1247,7 @@ def transformTriggered(self, clip_id): - - # Disable Transform UI - # Is this the same clip_id already being transformed? -- if self and self.transforming_clip and not clip_id: -+ if self.transforming_clip and not clip_id: - # Clear transform - self.transforming_clip = None - need_refresh = True -@@ -1078,7 +1272,7 @@ def keyFrameTransformTriggered(self, effect_id, clip_id): - - # Disable Transform UI - # Is this the same clip_id already being transformed? -- if self and self.transforming_effect and not effect_id: -+ if self.transforming_effect and not effect_id: - # Clear transform - self.transforming_effect = None - self.transforming_clip = None -@@ -1102,12 +1296,8 @@ def keyFrameTransformTriggered(self, effect_id, clip_id): - - def regionTriggered(self, clip_id): - """Handle the 'select region' signal when it's emitted""" -- if self and not clip_id: -- # Clear transform -- self.region_enabled = False -- else: -- self.region_enabled = True -- -+ # Clear transform -+ self.region_enabled = bool(not clip_id) - get_app().window.refreshFrameSignal.emit() - - def resizeEvent(self, event): -@@ -1135,7 +1325,7 @@ def delayed_resize_callback(self): - ratio = float(project_size.width()) / float(project_size.height()) - even_width = round(project_size.width() / 2.0) * 2 - even_height = round(round(even_width / ratio) / 2.0) * 2 -- project_size = QSize(even_width, even_height) -+ project_size = QSize(int(even_width), int(even_height)) - - # Emit signal that video widget changed size - self.win.MaxSizeChanged.emit(project_size) -@@ -1199,7 +1389,6 @@ def __init__(self, watch_project=True, *args): - self.mouse_dragging = False - self.mouse_position = None - self.transform_mode = None -- self.gravity_point = None - self.original_clip_data = None - self.region_qimage = None - self.region_transform = None -@@ -1208,8 +1397,8 @@ def __init__(self, watch_project=True, *args): - self.regionTopLeftHandle = None - self.regionBottomRightHandle = None - self.curr_frame_size = None # Frame size -- self.zoom = 1.0 # Zoom of widget (does not affect video, only workspace) -- self.cs = 14.0 # Corner size of Transform Handler rectangles -+ self.zoom = 1.0 # Zoom of widget (does not affect video, only workspace) -+ self.cs = 14.0 # Corner size of Transform Handler rectangles - self.resize_button = QPushButton(_('Reset Zoom'), self) - self.resize_button.hide() - self.resize_button.setStyleSheet('QPushButton { margin: 10px; padding: 2px; }') -@@ -1251,7 +1440,6 @@ def __init__(self, watch_project=True, *args): - - # Show Property timer - # Timer to use a delay before sending MaxSizeChanged signals (so we don't spam libopenshot) -- self.delayed_size = None - self.delayed_resize_timer = QTimer(self) - self.delayed_resize_timer.setInterval(200) - self.delayed_resize_timer.setSingleShot(True) -diff --git a/src/windows/views/effects_listview.py b/src/windows/views/effects_listview.py -index b7da28dc4..3ce3b4164 100644 ---- a/src/windows/views/effects_listview.py -+++ b/src/windows/views/effects_listview.py -@@ -36,7 +36,8 @@ - - class EffectsListView(QListView): - """ A TreeView QWidget used on the main window """ -- drag_item_size = 48 -+ drag_item_size = QSize(48, 48) -+ drag_item_center = QPoint(24, 24) - - def contextMenuEvent(self, event): - # Set context menu mode -@@ -69,8 +70,8 @@ def startDrag(self, event): - # Start drag operation - drag = QDrag(self) - drag.setMimeData(self.model().mimeData(selected)) -- drag.setPixmap(icon.pixmap(QSize(self.drag_item_size, self.drag_item_size))) -- drag.setHotSpot(QPoint(self.drag_item_size / 2, self.drag_item_size / 2)) -+ drag.setPixmap(icon.pixmap(self.drag_item_size)) -+ drag.setHotSpot(self.drag_item_center) - drag.exec_() - - def filter_changed(self): -diff --git a/src/windows/views/effects_treeview.py b/src/windows/views/effects_treeview.py -index 6a5ab79f4..910593524 100644 ---- a/src/windows/views/effects_treeview.py -+++ b/src/windows/views/effects_treeview.py -@@ -36,7 +36,8 @@ - - class EffectsTreeView(QTreeView): - """ A TreeView QWidget used on the main window """ -- drag_item_size = 48 -+ drag_item_size = QSize(48, 48) -+ drag_item_center = QPoint(24, 24) - - def contextMenuEvent(self, event): - # Set context menu mode -@@ -70,8 +71,8 @@ def startDrag(self, supportedActions): - # Start drag operation - drag = QDrag(self) - drag.setMimeData(self.model().mimeData(selected)) -- drag.setPixmap(icon.pixmap(QSize(self.drag_item_size, self.drag_item_size))) -- drag.setHotSpot(QPoint(self.drag_item_size / 2, self.drag_item_size / 2)) -+ drag.setPixmap(icon.pixmap(self.drag_item_size)) -+ drag.setHotSpot(self.drag_item_center) - drag.exec_() - - def refresh_columns(self): -diff --git a/src/windows/views/emojis_listview.py b/src/windows/views/emojis_listview.py -index 6f09bc562..cb13c35a7 100644 ---- a/src/windows/views/emojis_listview.py -+++ b/src/windows/views/emojis_listview.py -@@ -39,7 +39,8 @@ - - class EmojisListView(QListView): - """ A QListView QWidget used on the main window """ -- drag_item_size = 48 -+ drag_item_size = QSize(48, 48) -+ drag_item_center = QPoint(24, 24) - - def dragEnterEvent(self, event): - # If dragging urls onto widget, accept -@@ -57,8 +58,8 @@ def startDrag(self, event): - drag = QDrag(self) - drag.setMimeData(self.model.mimeData(selected)) - icon = self.model.data(selected[0], Qt.DecorationRole) -- drag.setPixmap(icon.pixmap(QSize(self.drag_item_size, self.drag_item_size))) -- drag.setHotSpot(QPoint(self.drag_item_size / 2, self.drag_item_size / 2)) -+ drag.setPixmap(icon.pixmap(self.drag_item_size)) -+ drag.setHotSpot(self.drag_item_center) - - # Create emoji file before drag starts - data = json.loads(drag.mimeData().text()) -diff --git a/src/windows/views/files_listview.py b/src/windows/views/files_listview.py -index 83cdd0272..0e67306ae 100644 ---- a/src/windows/views/files_listview.py -+++ b/src/windows/views/files_listview.py -@@ -38,7 +38,8 @@ - - class FilesListView(QListView): - """ A ListView QWidget used on the main window """ -- drag_item_size = 48 -+ drag_item_size = QSize(48, 48) -+ drag_item_center = QPoint(24, 24) - - def contextMenuEvent(self, event): - event.accept() -@@ -113,8 +114,8 @@ def startDrag(self, supportedActions): - # Start drag operation - drag = QDrag(self) - drag.setMimeData(self.model().mimeData(selected)) -- drag.setPixmap(icon.pixmap(QSize(self.drag_item_size, self.drag_item_size))) -- drag.setHotSpot(QPoint(self.drag_item_size / 2, self.drag_item_size / 2)) -+ drag.setPixmap(icon.pixmap(self.drag_item_size)) -+ drag.setHotSpot(self.drag_item_center) - drag.exec_() - - # Without defining this method, the 'copy' action doesn't show with cursor -diff --git a/src/windows/views/files_treeview.py b/src/windows/views/files_treeview.py -index d3fe74d88..776b71cc2 100644 ---- a/src/windows/views/files_treeview.py -+++ b/src/windows/views/files_treeview.py -@@ -41,7 +41,8 @@ - - class FilesTreeView(QTreeView): - """ A TreeView QWidget used on the main window """ -- drag_item_size = 48 -+ drag_item_size = QSize(48, 48) -+ drag_item_center = QPoint(24, 24) - - def contextMenuEvent(self, event): - -@@ -114,8 +115,8 @@ def startDrag(self, supportedActions): - # Start drag operation - drag = QDrag(self) - drag.setMimeData(self.model().mimeData(selected)) -- drag.setPixmap(icon.pixmap(QSize(self.drag_item_size, self.drag_item_size))) -- drag.setHotSpot(QPoint(self.drag_item_size / 2, self.drag_item_size / 2)) -+ drag.setPixmap(icon.pixmap(self.drag_item_size)) -+ drag.setHotSpot(self.drag_item_center) - drag.exec_() - - # Without defining this method, the 'copy' action doesn't show with cursor -diff --git a/src/windows/views/properties_tableview.py b/src/windows/views/properties_tableview.py -index e79b13644..fdaa7ee24 100644 ---- a/src/windows/views/properties_tableview.py -+++ b/src/windows/views/properties_tableview.py -@@ -53,8 +53,13 @@ - - - class PropertyDelegate(QItemDelegate): -- def __init__(self, parent=None, *args): -- QItemDelegate.__init__(self, parent, *args) -+ def __init__(self, parent=None, *args, **kwargs): -+ -+ self.model = kwargs.pop("model", None) -+ if not self.model: -+ log.error("Cannot create delegate without data model!") -+ -+ super().__init__(parent, *args, **kwargs) - - # pixmaps for curve icons - self.curve_pixmaps = { -@@ -68,7 +73,7 @@ def paint(self, painter, option, index): - painter.setRenderHint(QPainter.Antialiasing) - - # Get data model and selection -- model = get_app().window.propertyTableView.clip_properties_model.model -+ model = self.model - row = model.itemFromIndex(index).row() - selected_label = model.item(row, 0) - selected_value = model.item(row, 1) -@@ -104,16 +109,16 @@ def paint(self, painter, option, index): - painter.setPen(QPen(Qt.NoPen)) - if property_type == "color": - # Color keyframe -- red = cur_property[1]["red"]["value"] -- green = cur_property[1]["green"]["value"] -- blue = cur_property[1]["blue"]["value"] -- painter.setBrush(QBrush(QColor(QColor(red, green, blue)))) -+ red = int(cur_property[1]["red"]["value"]) -+ green = int(cur_property[1]["green"]["value"]) -+ blue = int(cur_property[1]["blue"]["value"]) -+ painter.setBrush(QColor(red, green, blue)) - else: - # Normal Keyframe - if option.state & QStyle.State_Selected: -- painter.setBrush(QBrush(QColor("#575757"))) -+ painter.setBrush(QColor("#575757")) - else: -- painter.setBrush(QBrush(QColor("#3e3e3e"))) -+ painter.setBrush(QColor("#3e3e3e")) - - if readonly: - # Set text color for read only fields -@@ -146,7 +151,10 @@ def paint(self, painter, option, index): - - if points > 1: - # Draw interpolation icon on top -- painter.drawPixmap(option.rect.x() + option.rect.width() - 30.0, option.rect.y() + 4, self.curve_pixmaps[interpolation]) -+ painter.drawPixmap( -+ int(option.rect.x() + option.rect.width() - 30.0), -+ int(option.rect.y() + 4), -+ self.curve_pixmaps[interpolation]) - - # Set text color - painter.setPen(QPen(Qt.white)) -@@ -818,9 +826,9 @@ def Color_Picker_Triggered(self, cur_property): - _ = get_app()._tr - - # Get current value of color -- red = cur_property[1]["red"]["value"] -- green = cur_property[1]["green"]["value"] -- blue = cur_property[1]["blue"]["value"] -+ red = int(cur_property[1]["red"]["value"]) -+ green = int(cur_property[1]["green"]["value"]) -+ blue = int(cur_property[1]["blue"]["value"]) - - # Show color dialog - currentColor = QColor(red, green, blue) -@@ -865,7 +873,7 @@ def __init__(self, *args): - self.files_model = self.win.files_model.model - - # Connect to update signals, so our menus stay current -- self.win.files_model.ModelRefreshed.connect(self.refresh_menu) -+ self.files_model.dataChanged.connect(self.refresh_menu) - self.win.transition_model.ModelRefreshed.connect(self.refresh_menu) - self.menu_reset = False - -@@ -890,7 +898,7 @@ def __init__(self, *args): - self.setWordWrap(True) - - # Set delegate -- delegate = PropertyDelegate() -+ delegate = PropertyDelegate(model=self.clip_properties_model.model) - self.setItemDelegateForColumn(1, delegate) - self.previous_x = -1 - -diff --git a/src/windows/views/transitions_listview.py b/src/windows/views/transitions_listview.py -index 09af86b2b..3ba3346f5 100644 ---- a/src/windows/views/transitions_listview.py -+++ b/src/windows/views/transitions_listview.py -@@ -36,7 +36,8 @@ - - class TransitionsListView(QListView): - """ A QListView QWidget used on the main window """ -- drag_item_size = 48 -+ drag_item_size = QSize(48, 48) -+ drag_item_center = QPoint(24, 24) - - def contextMenuEvent(self, event): - event.accept() -@@ -70,8 +71,8 @@ def startDrag(self, supportedActions): - # Start drag operation - drag = QDrag(self) - drag.setMimeData(self.model().mimeData(selected)) -- drag.setPixmap(icon.pixmap(QSize(self.drag_item_size, self.drag_item_size))) -- drag.setHotSpot(QPoint(self.drag_item_size / 2, self.drag_item_size / 2)) -+ drag.setPixmap(icon.pixmap(self.drag_item_size)) -+ drag.setHotSpot(self.drag_item_center) - drag.exec_() - - def filter_changed(self): -diff --git a/src/windows/views/transitions_treeview.py b/src/windows/views/transitions_treeview.py -index 6f903e913..7aa0cd481 100644 ---- a/src/windows/views/transitions_treeview.py -+++ b/src/windows/views/transitions_treeview.py -@@ -36,7 +36,8 @@ - - class TransitionsTreeView(QTreeView): - """ A TreeView QWidget used on the main window """ -- drag_item_size = 48 -+ drag_item_size = QSize(48, 48) -+ drag_item_center = QPoint(24, 24) - - def contextMenuEvent(self, event): - # Set context menu mode -@@ -68,8 +69,8 @@ def startDrag(self, event): - # Start drag operation - drag = QDrag(self) - drag.setMimeData(self.model().mimeData(selected)) -- drag.setPixmap(icon.pixmap(QSize(self.drag_item_size, self.drag_item_size))) -- drag.setHotSpot(QPoint(self.drag_item_size / 2, self.drag_item_size / 2)) -+ drag.setPixmap(icon.pixmap(self.drag_item_size)) -+ drag.setHotSpot(self.drag_item_center) - drag.exec_() - - def refresh_columns(self): -diff --git a/src/windows/views/tutorial.py b/src/windows/views/tutorial.py -index e2d7fb861..24124799f 100644 ---- a/src/windows/views/tutorial.py -+++ b/src/windows/views/tutorial.py -@@ -53,7 +53,12 @@ def paintEvent(self, event, *args): - - painter.setPen(QPen(frameColor, 2)) - painter.setBrush(self.palette().color(QPalette.Window)) -- painter.drawRoundedRect(QRectF(31, 0, self.width() - 31, self.height()), 10, 10) -+ painter.drawRoundedRect( -+ QRectF(31, 0, -+ self.width() - 31, -+ self.height() -+ ), -+ 10, 10) - - # Paint blue triangle (if needed) - if self.arrow: -@@ -61,7 +66,8 @@ def paintEvent(self, event, *args): - path = QPainterPath() - path.moveTo(0, 35) - path.lineTo(31, 35 - arrow_height) -- path.lineTo(31, (35 - arrow_height) + (arrow_height * 2)) -+ path.lineTo( -+ 31, int((35 - arrow_height) + (arrow_height * 2))) - path.lineTo(0, 35) - painter.fillPath(path, frameColor) - -@@ -199,7 +205,9 @@ def process(self, parent_name=None): - - # Create tutorial - self.position_widget = tutorial_object -- self.offset = QPoint(tutorial_details["x"], tutorial_details["y"]) -+ self.offset = QPoint( -+ int(tutorial_details["x"]), -+ int(tutorial_details["y"])) - tutorial_dialog = TutorialDialog(tutorial_id, tutorial_details["text"], tutorial_details["arrow"], self) - - # Connect signals - -From 9fc55120f36c36b2b6b67e499128993c25e535cf Mon Sep 17 00:00:00 2001 -From: "FeRD (Frank Dana)" -Date: Thu, 4 Nov 2021 21:02:56 -0400 -Subject: [PATCH 3/6] VideoWidget: New checkTransformMode - -Replacement for getTransformMode with less repetitious code ---- - src/windows/video_widget.py | 160 ++++++++++++++---------------------- - 1 file changed, 61 insertions(+), 99 deletions(-) - -diff --git a/src/windows/video_widget.py b/src/windows/video_widget.py -index f33696c5c..1b9c35b54 100644 ---- a/src/windows/video_widget.py -+++ b/src/windows/video_widget.py -@@ -610,106 +610,68 @@ def rotateCursor(self, pixmap, rotation, shear_x, shear_y): - Qt.SmoothTransformation) - return QCursor(rotated_pixmap) - -- def getTransformMode(self, rotation, shear_x, shear_y, event): -+ def checkTransformMode(self, rotation, shear_x, shear_y, event): -+ handle_uis = [ -+ {"handle": self.centerHandle, "mode": 'origin', "cursor": 'hand'}, -+ {"handle": self.topRightHandle, "mode": 'scale_top_right', "cursor": 'resize_bdiag'}, -+ {"handle": self.topHandle, "mode": 'scale_top', "cursor": 'resize_y'}, -+ {"handle": self.topLeftHandle, "mode": 'scale_top_left', "cursor": 'resize_fdiag'}, -+ {"handle": self.leftHandle, "mode": 'scale_left', "cursor": 'resize_x'}, -+ {"handle": self.rightHandle, "mode": 'scale_right', "cursor": 'resize_x'}, -+ {"handle": self.bottomLeftHandle, "mode": 'scale_bottom_left', "cursor": 'resize_bdiag'}, -+ {"handle": self.bottomHandle, "mode": 'scale_bottom', "cursor": 'resize_y'}, -+ {"handle": self.bottomRightHandle, "mode": 'scale_bottom_right', "cursor": 'resize_fdiag'}, -+ {"handle": self.topShearHandle, "mode": 'shear_top', "cursor": 'shear_x'}, -+ {"handle": self.leftShearHandle, "mode": 'shear_left', "cursor": 'shear_y'}, -+ {"handle": self.rightShearHandle, "mode": 'shear_right', "cursor": 'shear_y'}, -+ {"handle": self.bottomShearHandle, "mode": 'shear_bottom', "cursor": 'shear_x'}, -+ ] -+ non_handle_uis = { -+ "region": self.clipBounds, -+ "inside": {"mode": 'location', "cursor": 'move'}, -+ "outside": {"mode": 'rotation', "cursor": "rotate"} -+ } -+ - # Mouse over resize button (and not currently dragging) -- if not self.mouse_dragging and self.resize_button.isVisible() and self.resize_button.rect().contains(event.pos()): -+ if (not self.mouse_dragging -+ and self.resize_button.isVisible() -+ and self.resize_button.rect().contains(event.pos() -+ ): - self.setCursor(Qt.ArrowCursor) -- # Determine if cursor is over a handle -- elif self.transform.mapToPolygon(self.centerHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'origin': -- self.setCursor(self.rotateCursor(self.cursors.get('hand'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'origin' -- elif self.transform.mapToPolygon(self.topRightHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'scale_top_right': -- self.setCursor(self.rotateCursor(self.cursors.get('resize_bdiag'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'scale_top_right' -- elif self.transform.mapToPolygon(self.topHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'scale_top': -- self.setCursor(self.rotateCursor(self.cursors.get('resize_y'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'scale_top' -- elif self.transform.mapToPolygon(self.topLeftHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'scale_top_left': -- self.setCursor(self.rotateCursor(self.cursors.get('resize_fdiag'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'scale_top_left' -- elif self.transform.mapToPolygon(self.leftHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'scale_left': -- self.setCursor(self.rotateCursor(self.cursors.get('resize_x'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'scale_left' -- elif self.transform.mapToPolygon(self.rightHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'scale_right': -- self.setCursor(self.rotateCursor(self.cursors.get('resize_x'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'scale_right' -- elif self.transform.mapToPolygon(self.bottomLeftHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'scale_bottom_left': -- self.setCursor(self.rotateCursor(self.cursors.get('resize_bdiag'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'scale_bottom_left' -- elif self.transform.mapToPolygon(self.bottomHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'scale_bottom': -- self.setCursor(self.rotateCursor(self.cursors.get('resize_y'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'scale_bottom' -- elif self.transform.mapToPolygon(self.bottomRightHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'scale_bottom_right': -- self.setCursor(self.rotateCursor(self.cursors.get('resize_fdiag'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'scale_bottom_right' -- elif self.transform.mapToPolygon(self.topShearHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'shear_top': -- self.setCursor(self.rotateCursor(self.cursors.get('shear_x'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'shear_top' -- elif self.transform.mapToPolygon(self.leftShearHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'shear_left': -- self.setCursor(self.rotateCursor(self.cursors.get('shear_y'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'shear_left' -- elif self.transform.mapToPolygon(self.rightShearHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'shear_right': -- self.setCursor(self.rotateCursor(self.cursors.get('shear_y'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'shear_right' -- elif self.transform.mapToPolygon(self.bottomShearHandle.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'shear_bottom': -- self.setCursor(self.rotateCursor(self.cursors.get('shear_x'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'shear_bottom' -- elif self.transform.mapToPolygon(self.clipBounds.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'location': -- self.setCursor(self.rotateCursor(self.cursors.get('move'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'location' -- elif not self.transform.mapToPolygon(self.clipBounds.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -- if not self.transform_mode or self.transform_mode == 'rotation': -- self.setCursor(self.rotateCursor(self.cursors.get('rotate'), rotation, shear_x, shear_y)) -- # Set the transform mode -- if self.mouse_dragging and not self.transform_mode: -- self.transform_mode = 'rotation' -- elif not self.transform_mode: -- # Reset cursor when not over a handle -- self.setCursor(QCursor(Qt.ArrowCursor)) -+ self.transform_mode = None -+ return -+ -+ # If mouse is over a handle, set corresponding pointer/mode -+ for h in handle_uis: -+ if self.transform.mapToPolygon( -+ h["handle"].toRect() -+ ).containsPoint(event.pos(), Qt.OddEvenFill): -+ # Handle contains cursor -+ if self.transform_mode and self.transform_mode != h["mode"]: -+ # We're in different xform mode, skip -+ continue -+ if self.mouse_dragging: -+ self.transform_mode = h["mode"] -+ self.setCursor(self.rotateCursor( -+ self.cursors.get(h["cursor"]), rotation, shear_x, shear_y)) -+ return -+ -+ # If not over any handles, determne inside/outside clip rectangle -+ r = non_handle_uis.get("region") -+ if self.transform.mapToPolygon(r.toRect()).containsPoint(event.pos(), Qt.OddEvenFill): -+ nh = non_handle_uis.get("inside", {}) -+ else: -+ nh = non_handle_uis.get("outside", {}) -+ if self.mouse_dragging and not self.transform_mode: -+ self.transform_mode = nh.get("mode") -+ if not self.transform_mode or self.transform_mode == nh.get("mode"): -+ self.setCursor(self.rotateCursor( -+ self.cursors.get(nh.get("cursor")), rotation, shear_x, shear_y)) - -- return True -+ -+ # If we got this far and we don't have a transform mode, reset the cursor -+ if not self.transform_mode: -+ self.setCursor(QCursor(Qt.ArrowCursor)) - - def mouseMoveEvent(self, event): - """Capture mouse events on video preview window """ -@@ -746,7 +708,7 @@ def mouseMoveEvent(self, event): - if self.mouse_dragging and not self.transform_mode: - self.original_clip_data = self.transforming_clip.data - -- _ = self.getTransformMode(rotation, shear_x, shear_y, event) -+ self.checkTransformMode(rotation, shear_x, shear_y, event) - - # Transform clip object - if self.transform_mode: -@@ -1040,7 +1002,7 @@ def mouseMoveEvent(self, event): - self.mutex.unlock() - return - -- _ = self.getTransformMode(0, 0, 0, event) -+ self.checkTransformMode(0, 0, 0, event) - - # Transform effect object - if self.transform_mode: - -From 1f058f730bb36068bce5c645ecea45b98279b614 Mon Sep 17 00:00:00 2001 -From: "FeRD (Frank Dana)" -Date: Thu, 4 Nov 2021 21:42:48 -0400 -Subject: [PATCH 4/6] VideoWidget: Protect property accesses - ---- - src/windows/video_widget.py | 61 +++++++++++++++++++++---------------- - 1 file changed, 34 insertions(+), 27 deletions(-) - -diff --git a/src/windows/video_widget.py b/src/windows/video_widget.py -index 1b9c35b54..a4d42969f 100644 ---- a/src/windows/video_widget.py -+++ b/src/windows/video_widget.py -@@ -635,7 +635,7 @@ def checkTransformMode(self, rotation, shear_x, shear_y, event): - # Mouse over resize button (and not currently dragging) - if (not self.mouse_dragging - and self.resize_button.isVisible() -- and self.resize_button.rect().contains(event.pos() -+ and self.resize_button.rect().contains(event.pos()) - ): - self.setCursor(Qt.ArrowCursor) - self.transform_mode = None -@@ -668,11 +668,6 @@ def checkTransformMode(self, rotation, shear_x, shear_y, event): - self.setCursor(self.rotateCursor( - self.cursors.get(nh.get("cursor")), rotation, shear_x, shear_y)) - -- -- # If we got this far and we don't have a transform mode, reset the cursor -- if not self.transform_mode: -- self.setCursor(QCursor(Qt.ArrowCursor)) -- - def mouseMoveEvent(self, event): - """Capture mouse events on video preview window """ - self.mutex.lock() -@@ -1121,27 +1116,37 @@ def updateClipProperty(self, clip_id, frame_number, property_key, new_value, ref - # No clip found - return - -- for point in c.data[property_key]["Points"]: -- log.info("looping points: co.X = %s" % point["co"]["X"]) -+ # Property missing? Create it! -+ if property_key not in c.data: -+ c.data[property_key] = {"Points": []} -+ log.warning( -+ "%s: Added missing '%s' to property data", -+ clip_id, property_key) - -- if point["co"]["X"] == frame_number: -+ points = c.data.get(property_key).get("Points") -+ for point in points: -+ co = point.get("co", {}) -+ log.info("looping points: co.X = %s" % co.get("X")) -+ -+ if co.get("X") == frame_number: - found_point = True - clip_updated = True -- point["interpolation"] = openshot.BEZIER -- point["co"]["Y"] = float(new_value) -+ point.update({ -+ "co": {"X": frame_number, "Y": float(new_value)}, -+ "interpolation": openshot.BEZIER, -+ }) - - if not found_point and new_value is not None: - clip_updated = True -- log.info("Created new point at X=%s", frame_number) -+ log.info("Creating new point at X=%s", frame_number) - c.data[property_key]["Points"].append({ -- 'co': {'X': frame_number, 'Y': new_value}, -+ 'co': {'X': frame_number, 'Y': float(new_value)}, - 'interpolation': openshot.BEZIER - }) - -- # Reduce # of clip properties we are saving (performance boost) -- c.data = {property_key: c.data.get(property_key)} -- - if clip_updated: -+ # Reduce # of clip properties we are saving (performance boost) -+ c.data = {property_key: c.data.get(property_key)} - c.save() - # Update the preview - if refresh: -@@ -1166,27 +1171,29 @@ def updateEffectProperty(self, effect_id, frame_number, obj_id, property_key, ne - return - - for point in points_list: -- log.info("looping points: co.X = %s", point["co"]["X"]) -+ co = point.get("co", {}) -+ log.info("looping points: co.X = %s", co.get("X")) - -- if point["co"]["X"] == frame_number: -+ if co.get("X") == frame_number: - found_point = True - effect_updated = True -- point["interpolation"] = openshot.BEZIER -- point["co"]["Y"] = float(new_value) -+ point.update({ -+ "co": {"X": frame_number, "Y": float(new_value)}, -+ "interpolation": openshot.BEZIER, -+ }) - -- if not found_point and new_value != None: -+ if not found_point and new_value is not None: - effect_updated = True -- log.info("Created new point at X=%s", frame_number) -+ log.info("Creating new point at X=%s", frame_number) - points_list.append({ -- 'co': { 'X': frame_number, 'Y': new_value }, -+ 'co': {'X': frame_number, 'Y': float(new_value)}, - 'interpolation': openshot.BEZIER, - }) - -- # Reduce # of clip properties we are saving (performance boost) -- #TODO: This is too slow when draging transform handlers -- c.data = {'objects': {obj_id: c.data.get('objects', {}).get(obj_id)}} -- - if effect_updated: -+ # Reduce # of clip properties we are saving (performance boost) -+ #TODO: This is too slow when draging transform handlers -+ c.data = {'objects': {obj_id: c.data.get('objects', {}).get(obj_id)}} - c.save() - # Update the preview - if refresh: - -From 7df87ddc189c5e5031fbb19df13378428fab951e Mon Sep 17 00:00:00 2001 -From: "FeRD (Frank Dana)" -Date: Thu, 4 Nov 2021 21:52:19 -0400 -Subject: [PATCH 5/6] classes/thumbnail: Fix dangling filehandles - ---- - src/classes/thumbnail.py | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/classes/thumbnail.py b/src/classes/thumbnail.py -index cca47d68f..dac7422a1 100644 ---- a/src/classes/thumbnail.py -+++ b/src/classes/thumbnail.py -@@ -209,13 +209,13 @@ def do_GET(self): - - # Send message back to client - if os.path.exists(thumb_path): -- if not only_path: -- self.wfile.write(open(thumb_path, 'rb').read()) -- else: -+ if only_path: - self.wfile.write(bytes(thumb_path, "utf-8")) -+ else: -+ with open(thumb_path, 'rb') as f: -+ self.wfile.write(f.read()) - - # Pause processing of request (since we don't currently use thread pooling, this allows - # the threads to be processed without choking the CPU as much - # TODO: Make HTTPServer work with a limited thread pool and remove this sleep() hack. - time.sleep(0.01) -- - -From 33cf68ca0b1ea57edd5dec3dbb8ba06d6a3f8fa4 Mon Sep 17 00:00:00 2001 -From: "FeRD (Frank Dana)" -Date: Thu, 25 Nov 2021 02:18:32 -0500 -Subject: [PATCH 6/6] properties_model: Fix bad logging call, Codacy flags - ---- - src/windows/models/properties_model.py | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/windows/models/properties_model.py b/src/windows/models/properties_model.py -index 40897f642..695e9f39c 100644 ---- a/src/windows/models/properties_model.py -+++ b/src/windows/models/properties_model.py -@@ -444,7 +444,7 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail - log.debug("%s: update property %s. %s", log_id, property_key, clip_data.get(property_key)) - - # Check the type of property (some are keyframe, and some are not) -- if property_type != "reader" and type(clip_data[property_key]) == dict: -+ if property_type != "reader" and isinstance(clip_data[property_key], dict): - # Keyframe - # Loop through points, find a matching points on this frame - found_point = False -@@ -517,21 +517,21 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail - clip_updated = True - try: - clip_data[property_key] = int(new_value) -- except Exception as ex: -+ except Exception: - log.warn('Invalid Integer value passed to property', exc_info=1) - - elif property_type == "float": - clip_updated = True - try: - clip_data[property_key] = float(new_value) -- except Exception as ex: -+ except Exception: - log.warn('Invalid Float value passed to property', exc_info=1) - - elif property_type == "bool": - clip_updated = True - try: - clip_data[property_key] = bool(new_value) -- except Exception as ex: -+ except Exception: - log.warn('Invalid Boolean value passed to property', exc_info=1) - - elif property_type == "string": -@@ -558,7 +558,7 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail - clip_object.Close() - clip_object = None - except Exception: -- log.warn('Invalid Reader value passed to property: %s (%s)', value, exc_info=1) -+ log.warn('Invalid Reader value passed to property: %s', value, exc_info=1) - - # Reduce # of clip properties we are saving (performance boost) - clip_data = {property_key: clip_data.get(property_key)} diff --git a/srcpkgs/openshot/template b/srcpkgs/openshot/template index a68252c18a8..322717d40ab 100644 --- a/srcpkgs/openshot/template +++ b/srcpkgs/openshot/template @@ -1,7 +1,7 @@ # Template file for 'openshot' pkgname=openshot -version=2.6.1 -revision=3 +version=3.0.0 +revision=1 build_style=python3-module hostmakedepends="python3 python3-setuptools" makedepends="ffmpeg-devel python3-PyQt5" @@ -12,5 +12,5 @@ maintainer="Spencer Hill " license="GPL-3.0-or-later" homepage="https://www.openshot.org" distfiles="https://github.com/OpenShot/openshot-qt/archive/v${version}.tar.gz" -checksum=11651d5e7287da3c766ce6b447aef8da5cdadaf5626a2816e9025c831d0e1a66 +checksum=9a6b76ebb32f34722a30af0cafeea2dee1ef11daef1d7c9c73ba9b1350ea57f9 make_check=no # tests are broken