Skip to content

Commit 5468a9a

Browse files
authored
Merge pull request #4345 from OpenShot/merge-master-2.6.0
Merge master 2.6.0 into develop
2 parents 952f5e8 + 8403607 commit 5468a9a

17 files changed

+120
-90
lines changed

.vscode/launch.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Python: Current File",
9+
"type": "python",
10+
"request": "launch",
11+
"program": "src/launch.py",
12+
"console": "integratedTerminal"
13+
}
14+
]
15+
}

installer/build-mac-dmg.sh

+5
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ pat='RequestUUID = (.*)'
7070
REQUEST_UUID="${BASH_REMATCH[1]}"
7171
echo " RequestUUID Found: $REQUEST_UUID"
7272

73+
if [ "$REQUEST_UUID" == "" ]; then
74+
echo "Failed to locate REQUEST_UUID, exiting with error."
75+
exit 1
76+
fi
77+
7378
echo "Check Notarization Progress... (list recent notarization records)"
7479
xcrun altool --notarization-history 0 -u "[email protected]" -p "@keychain:NOTARIZE_AUTH" | head -n 10
7580

installer/deploy.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import re
3434
import urllib3
3535
from github3 import login
36+
from github3.models import GitHubError
3637
from requests.auth import HTTPBasicAuth
3738
from requests import post, get, head
3839
from build_server import (
@@ -185,7 +186,7 @@ def main():
185186
github_release_name,
186187
target_commitish=git_branch_name,
187188
prerelease=True,
188-
body=formatted_logs.get(repo_name))
189+
body=formatted_logs.get(repo_name)[:125000])
189190

190191
# Upload all deploy artifacts/installers to GitHub
191192
# NOTE: ONLY for `openshot-qt` repo
@@ -367,6 +368,8 @@ def main():
367368
except Exception as ex:
368369
tb = traceback.format_exc()
369370
error("Unhandled %s exception: %s - %s" % (script_mode, str(ex), str(tb)))
371+
if type(ex) == GitHubError:
372+
error(str(ex.errors))
370373

371374
if not errors_detected:
372375
output("Successfully completed %s script!" % script_mode)

src/classes/app.py

-2
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,6 @@ def check_libopenshot_version(self, info, openshot):
185185
},
186186
level="error",
187187
))
188-
raise RuntimeError(
189-
"libopenshot version {} found, minimum is {}".format(ver, min_ver))
190188

191189
def gui(self):
192190
from classes import language, sentry, ui_util, logger_libopenshot

src/classes/info.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
import os
2929
from time import strftime
3030

31-
VERSION = "2.5.1-dev3"
32-
MINIMUM_LIBOPENSHOT_VERSION = "0.2.5"
33-
DATE = "20200228000000"
31+
VERSION = "2.6.0-dev"
32+
MINIMUM_LIBOPENSHOT_VERSION = "0.2.6"
33+
DATE = "20210819000000"
3434
NAME = "openshot-qt"
3535
PRODUCT_NAME = "OpenShot Video Editor"
3636
GPL_VERSION = "3"

src/classes/json_data.py

+22-10
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,8 @@ def convert_paths_to_absolute(self, file_path, data):
253253
# Optimized regex replacement
254254
data = re.sub(path_regex, self.replace_string_to_absolute, data)
255255

256-
except Exception as ex:
257-
log.error("Error while converting relative paths to absolute paths: %s" % str(ex))
256+
except Exception:
257+
log.error("Error while converting relative paths to absolute paths", exc_info=1)
258258

259259
return data
260260

@@ -266,14 +266,16 @@ def replace_string_to_relative(self, match):
266266

267267
# Determine if thumbnail path is found
268268
if info.THUMBNAIL_PATH in folder_path:
269-
# Convert path to relative thumbnail path
269+
log.debug("Generating relative thumbnail path to %s in %s",
270+
file_path, folder_path)
270271
new_path = os.path.join("thumbnail", file_path).replace("\\", "/")
271272
new_path = json.dumps(new_path, ensure_ascii=False)
272273
return '"%s": %s' % (key, new_path)
273274

274275
# Determine if @transitions path is found
275276
elif os.path.join(info.PATH, "transitions") in folder_path:
276-
# Yes, this is an OpenShot transition
277+
log.debug("Generating relative @transitions path for %s in %s",
278+
file_path, folder_path)
277279
folder_path, category_path = os.path.split(folder_path)
278280

279281
# Convert path to @transitions/ path
@@ -283,15 +285,15 @@ def replace_string_to_relative(self, match):
283285

284286
# Determine if @emojis path is found
285287
elif os.path.join(info.PATH, "emojis") in folder_path:
286-
# Yes, this is an OpenShot emoji
287-
# Convert path to @emojis/ path
288+
log.debug("Generating relative @emojis path for %s in %s",
289+
file_path, folder_path)
288290
new_path = os.path.join("@emojis", file_path).replace("\\", "/")
289291
new_path = json.dumps(new_path, ensure_ascii=False)
290292
return '"%s": %s' % (key, new_path)
291293

292294
# Determine if @assets path is found
293295
elif path_context["new_project_assets"] in folder_path:
294-
# Yes, this is an OpenShot transitions
296+
log.debug("Replacing path to %s in %s", file_path, folder_path)
295297
folder_path = folder_path.replace(path_context["new_project_assets"], "@assets")
296298

297299
# Convert path to @assets/ path
@@ -304,10 +306,20 @@ def replace_string_to_relative(self, match):
304306
# Convert path to the correct relative path (based on the existing folder)
305307
orig_abs_path = os.path.abspath(path)
306308

309+
# Determine windows drives that the project and file are on
310+
project_win_drive = os.path.splitdrive(path_context.get("new_project_folder", ""))[0]
311+
file_win_drive = os.path.splitdrive(path)[0]
312+
if file_win_drive != project_win_drive:
313+
log.debug("Drive mismatch, not making path relative: %s", orig_abs_path)
314+
# If the file is on different drive. Don't abbreviate the path.
315+
clean_path = orig_abs_path.replace("\\", "/")
316+
clean_path = json.dumps(clean_path, ensure_ascii=False)
317+
return f"{key}: {clean_path}"
318+
307319
# Remove file from abs path
308320
orig_abs_folder = os.path.dirname(orig_abs_path)
309321

310-
# Calculate new relateive path
322+
log.debug("Generating new relative path for %s", orig_abs_path)
311323
new_rel_path_folder = os.path.relpath(orig_abs_folder, path_context.get("new_project_folder", ""))
312324
new_rel_path = os.path.join(new_rel_path_folder, file_path).replace("\\", "/")
313325
new_rel_path = json.dumps(new_rel_path, ensure_ascii=False)
@@ -328,8 +340,8 @@ def convert_paths_to_relative(self, file_path, previous_path, data):
328340
# Optimized regex replacement
329341
data = re.sub(path_regex, self.replace_string_to_relative, data)
330342

331-
except Exception as ex:
332-
log.error("Error while converting absolute paths to relative paths: %s" % str(ex))
343+
except Exception:
344+
log.error("Error while converting absolute paths to relative paths", exc_info=1)
333345

334346
return data
335347

src/launch.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,7 @@ def main():
183183
argv = [sys.argv[0]]
184184
argv.extend(extra_args)
185185
argv.extend(args.remain)
186-
try:
187-
app = OpenShotApp(argv)
188-
except Exception:
189-
app.show_errors()
186+
app = OpenShotApp(argv)
190187

191188
# Setup Qt application details
192189
app.setApplicationName('openshot')

src/timeline/js/controllers.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,9 @@ App.controller("TimelineCtrl", function ($scope) {
848848
timeline.add_missing_transition(JSON.stringify(missing_transition_details));
849849
}
850850
// Remove manual move stylesheet
851-
bounding_box.element.removeClass("manual-move");
851+
if (bounding_box.element) {
852+
bounding_box.element.removeClass("manual-move");
853+
}
852854

853855
// Remove CSS class (after the drag)
854856
bounding_box = {};
@@ -894,7 +896,7 @@ App.controller("TimelineCtrl", function ($scope) {
894896
bounding_box.track_position = 0;
895897

896898
// Set z-order to be above other clips/transitions
897-
if (item_type !== "os_drop") {
899+
if (item_type !== "os_drop" && bounding_box.element) {
898900
bounding_box.element.addClass("manual-move");
899901
}
900902
};
@@ -938,8 +940,10 @@ App.controller("TimelineCtrl", function ($scope) {
938940
}
939941
}
940942
//change the element location
941-
bounding_box.element.css("left", results.position.left);
942-
bounding_box.element.css("top", bounding_box.track_position - scrolling_tracks_offset_top);
943+
if (bounding_box.element) {
944+
bounding_box.element.css("left", results.position.left);
945+
bounding_box.element.css("top", bounding_box.track_position - scrolling_tracks_offset_top);
946+
}
943947
};
944948

945949
// Update X,Y indexes of tracks / layers (anytime the project.layers scope changes)
@@ -1393,7 +1397,6 @@ App.controller("TimelineCtrl", function ($scope) {
13931397
// Re-index Layer Y values
13941398
$scope.updateLayerIndex();
13951399
}
1396-
$scope.$digest();
13971400
}
13981401
// return true
13991402
return true;

src/timeline/js/directives/clip.js

+9-15
Original file line numberDiff line numberDiff line change
@@ -330,22 +330,16 @@ App.directive("tlClip", function ($timeout) {
330330

331331
// Move all other selected clips with this one if we have more than one clip
332332
$(".ui-selected").each(function () {
333-
clip_name = $(this).attr("id");
334-
var newX, newY;
335-
if (move_clips[clip_name] && ( move_clips[clip_name]['top'] && move_clips[clip_name]['left'] )) {
336-
newY = move_clips[clip_name]['top'] + y_offset;
337-
newX = move_clips[clip_name]['left'] + x_offset;
338-
} else {
339-
move_clips[clip_name] = {};
340-
newY = this.style.top + y_offset;
341-
newX = this.style.left + x_offset;
333+
if (move_clips[$(this).attr("id")]) {
334+
let newY = move_clips[$(this).attr("id")]["top"] + y_offset;
335+
let newX = move_clips[$(this).attr("id")]["left"] + x_offset;
336+
//update the clip location in the array
337+
move_clips[$(this).attr("id")]["top"] = newY;
338+
move_clips[$(this).attr("id")]["left"] = newX;
339+
//change the element location
340+
$(this).css("left", newX);
341+
$(this).css("top", newY);
342342
}
343-
//update the clip location in the array
344-
move_clips[$(this).attr("id")]["top"] = newY;
345-
move_clips[$(this).attr("id")]["left"] = newX;
346-
//change the element location
347-
$(this).css("left", newX);
348-
$(this).css("top", newY);
349343
});
350344
},
351345
revert: function (valid) {

src/timeline/js/directives/transition.js

+9-17
Original file line numberDiff line numberDiff line change
@@ -278,24 +278,16 @@ App.directive("tlTransition", function () {
278278

279279
// Move all other selected transitions with this one
280280
$(".ui-selected").each(function () {
281-
transition_name = $(this).attr("id");
282-
var newX, newY;
283-
if (move_clips[transition_name] && ( move_clips[transition_name]['top'] && move_clips[clip_name]['left'] )) {
284-
newY = move_clips[transition_name]['top'] + y_offset;
285-
newX = move_clips[transition_name]['left'] + x_offset;
286-
} else {
287-
// If this transition is not yet in move_clips, add it.
288-
move_clips[transition_name] = {};
289-
newY = this.style.top + y_offset;
290-
newX = this.style.left + x_offset;
281+
if (move_transitions[$(this).attr("id")]) {
282+
let newY = move_transitions[$(this).attr("id")]["top"] + y_offset;
283+
let newX = move_transitions[$(this).attr("id")]["left"] + x_offset;
284+
// Update the transition location in the array
285+
move_transitions[$(this).attr("id")]["top"] = newY;
286+
move_transitions[$(this).attr("id")]["left"] = newX;
287+
// Change the element location
288+
$(this).css("left", newX);
289+
$(this).css("top", newY);
291290
}
292-
// Update the transition location in the array
293-
move_transitions[$(this).attr("id")]["top"] = newY;
294-
move_transitions[$(this).attr("id")]["left"] = newX;
295-
// Change the element location
296-
$(this).css("left", newX);
297-
$(this).css("top", newY);
298-
299291
});
300292

301293
},

src/windows/export.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,10 @@ def titlestring(sec, fps, mess):
685685
# get translations
686686
_ = get_app()._tr
687687

688+
# Init some variables
689+
seconds_run = 0
690+
fps_encode = 0
691+
688692
# Init progress bar
689693
self.progressExportVideo.setMinimum(self.txtStartFrame.value())
690694
self.progressExportVideo.setMaximum(self.txtEndFrame.value())
@@ -872,7 +876,6 @@ def titlestring(sec, fps, mess):
872876

873877
progressstep = max(1 , round(( video_settings.get("end_frame") - video_settings.get("start_frame") ) / 1000))
874878
start_time_export = time.time()
875-
seconds_run = 0
876879
start_frame_export = video_settings.get("start_frame")
877880
end_frame_export = video_settings.get("end_frame")
878881
last_exported_time = time.time()
@@ -881,7 +884,7 @@ def titlestring(sec, fps, mess):
881884
digits_after_decimalpoint = 1
882885
# Precision of the progress bar
883886
format_of_progress_string = "%4.1f%% "
884-
fps_encode = 0
887+
885888
# Write each frame in the selected range
886889
for frame in range(video_settings.get("start_frame"), video_settings.get("end_frame") + 1):
887890
# Update progress bar (emit signal to main window)

src/windows/models/properties_model.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,11 @@ def remove_keyframe(self, item):
195195
if not c:
196196
return
197197

198-
# Create reference
198+
# Create reference
199199
clip_data = c.data
200200
if object_id:
201201
clip_data = c.data.get('objects').get(object_id)
202-
202+
203203
if property_key in clip_data: # Update clip attribute
204204
log_id = "{}/{}".format(clip_id, object_id) if object_id else clip_id
205205
log.debug("%s: remove %s keyframe. %s", log_id, property_key, clip_data.get(property_key))
@@ -281,7 +281,7 @@ def color_update(self, item, new_color, interpolation=-1, interpolation_details=
281281
c = Effect.get(id=clip_id)
282282

283283
if c:
284-
# Create reference
284+
# Create reference
285285
clip_data = c.data
286286
if object_id:
287287
clip_data = c.data.get('objects').get(object_id)
@@ -301,7 +301,7 @@ def color_update(self, item, new_color, interpolation=-1, interpolation_details=
301301
# Keyframe
302302
# Loop through points, find a matching points on this frame
303303
found_point = False
304-
for point in clip_data[property_key][color]["Points"]:
304+
for point in clip_data[property_key][color].get("Points", []):
305305
log.debug("looping points: co.X = %s" % point["co"]["X"])
306306
if interpolation == -1 and point["co"]["X"] == self.frame_number:
307307
# Found point, Update value
@@ -348,7 +348,7 @@ def color_update(self, item, new_color, interpolation=-1, interpolation_details=
348348
if not found_point:
349349
clip_updated = True
350350
log.debug("Created new point at X=%d", self.frame_number)
351-
clip_data[property_key][color]["Points"].append({
351+
clip_data[property_key][color].setdefault("Points", []).append({
352352
'co': {'X': self.frame_number, 'Y': new_value},
353353
'interpolation': 1,
354354
})
@@ -357,7 +357,7 @@ def color_update(self, item, new_color, interpolation=-1, interpolation_details=
357357
clip_data = {property_key: clip_data[property_key]}
358358
if object_id:
359359
clip_data = {'objects': {object_id: clip_data}}
360-
360+
361361
# Save changes
362362
if clip_updated:
363363
# Save
@@ -430,8 +430,8 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail
430430
c = Effect.get(id=clip_id)
431431

432432
if c:
433-
434-
# Create reference
433+
434+
# Create reference
435435
clip_data = c.data
436436
if object_id:
437437
clip_data = c.data.get('objects').get(object_id)
@@ -447,7 +447,7 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail
447447
# Loop through points, find a matching points on this frame
448448
found_point = False
449449
point_to_delete = None
450-
for point in clip_data[property_key]["Points"]:
450+
for point in clip_data[property_key].get('Points', []):
451451
log.debug("looping points: co.X = %s" % point["co"]["X"])
452452
if interpolation == -1 and point["co"]["X"] == self.frame_number:
453453
# Found point, Update value
@@ -503,7 +503,7 @@ def value_updated(self, item, interpolation=-1, value=None, interpolation_detail
503503
elif not found_point and new_value is not None:
504504
clip_updated = True
505505
log.debug("Created new point at X=%d", self.frame_number)
506-
clip_data[property_key]["Points"].append({
506+
clip_data[property_key].setdefault('Points', []).append({
507507
'co': {'X': self.frame_number, 'Y': new_value},
508508
'interpolation': 1})
509509

src/windows/preferences.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def Populate(self, filter=""):
224224
widget.setMinimum(int(param["min"]))
225225
widget.setMaximum(int(param["max"]))
226226
widget.setValue(int(param["value"]))
227-
widget.setSingleStep(1.0)
227+
widget.setSingleStep(1)
228228
widget.setToolTip(param["title"])
229229
widget.valueChanged.connect(functools.partial(self.spinner_value_changed, param))
230230

0 commit comments

Comments
 (0)