Skip to content

Commit 4ad1d72

Browse files
authored
Merge branch 'develop' into develop
2 parents ba17cc6 + bf31cd0 commit 4ad1d72

29 files changed

+1127
-619
lines changed

.github/workflows/sphinx.yml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Github Actions workflow to generate documentation
2+
# Uses the following shared task definitions:
3+
# - (checkout, upload artifact) from Github
4+
# - sphinx-action maintained by @ammaraskar
5+
name: Sphinx build
6+
7+
# Controls when the action will run.
8+
# Triggers the workflow on push or pull request events.
9+
on:
10+
- push
11+
- pull_request
12+
13+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
14+
jobs:
15+
# This workflow contains a single job called "build"
16+
build:
17+
# The type of runner that the job will run on
18+
runs-on: ubuntu-latest
19+
20+
# Steps are a sequence of tasks that will be executed as part of the job
21+
steps:
22+
# Check out repository under $GITHUB_WORKSPACE
23+
- uses: actions/checkout@v2
24+
# Builds docs using sphinx
25+
- uses: ammaraskar/sphinx-action@master
26+
with:
27+
docs-folder: "doc/"
28+
# Create an artifact out of the generated HTML
29+
- uses: actions/upload-artifact@v1
30+
with:
31+
name: UserGuideHTML
32+
path: "doc/_build/html/"

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ python3 src/launch.py
129129

130130
## Copyright
131131

132-
Copyright (c) 2008-2019 OpenShot Studios, LLC. This file is part of
132+
Copyright (c) 2008-2020 OpenShot Studios, LLC. This file is part of
133133
OpenShot Video Editor (https://www.openshot.org), an open-source project
134134
dedicated to delivering high quality video editing and animation solutions
135135
to the world.

doc/conf.py

+9
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@
4343
except ImportError:
4444
pass
4545

46+
import sys
47+
sys.path.insert(0, '.')
48+
try:
49+
# Load our YouTube directive
50+
import youtube_directive
51+
extensions.append('youtube_directive')
52+
except ImportError:
53+
pass
54+
4655
# External links mappings for extlinks
4756
# see: http://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html
4857
extlinks = {

doc/requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
sphinx_rtd_theme
2+
sphinx_copybutton
3+

doc/youtube_directive.py

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# $Id: misc.py 8257 2019-06-24 17:11:29Z milde $
2+
# Authors: David Goodger <[email protected]>; Dethe Elza
3+
# Copyright: This module has been placed in the public domain.
4+
5+
"""Miscellaneous directives."""
6+
7+
__docformat__ = 'reStructuredText'
8+
__version__ = "0.1.0"
9+
10+
import sys
11+
import re
12+
from docutils import nodes
13+
from docutils.parsers.rst import directives
14+
from docutils.utils.error_reporting import ErrorString
15+
16+
from sphinx import addnodes
17+
from sphinx.util import parselinenos
18+
from sphinx.util.docutils import SphinxDirective
19+
20+
if False:
21+
# For type annotation
22+
from typing import Any, Dict, List, Tuple # NOQA
23+
from sphinx.application import Sphinx # NOQA
24+
from sphinx.config import Config # NOQA
25+
26+
27+
class Youtube(SphinxDirective):
28+
29+
"""
30+
Wrap YouTube URLs in embedding HTML
31+
32+
Content is included in output based on type argument
33+
34+
Content may be included inline (content section of directive) or
35+
imported from a file or url.
36+
"""
37+
38+
embed_template = """
39+
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; height: auto;">
40+
<iframe src="{url}" frameborder="0" allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe>
41+
</div>
42+
"""
43+
44+
required_arguments = 1
45+
optional_arguments = 0
46+
final_argument_whitespace = True
47+
option_spec = {'target': directives.unchanged_required,
48+
'encoding': directives.encoding}
49+
has_content = True
50+
51+
def run(self):
52+
if not self.state.document.settings.raw_enabled:
53+
raise self.warning('"%s" directive disabled.' % self.name)
54+
attributes = {'format': 'html'}
55+
encoding = self.options.get(
56+
'encoding', self.state.document.settings.input_encoding)
57+
e_handler=self.state.document.settings.input_encoding_error_handler
58+
if self.content:
59+
raise self.error(
60+
'"%s" directive may not have content.' % self.name)
61+
62+
target = self.arguments[0]
63+
64+
id = ""
65+
try:
66+
results = re.match(
67+
r'https.*(embed/|/|\?v=)(?P<ID>[a-zA-Z0-9_-]*)(?:/?)$',
68+
target)
69+
if results and 'ID' in results.groupdict():
70+
id = results.group('ID')
71+
else:
72+
id = target
73+
except AttributeError:
74+
pass
75+
76+
try:
77+
url = 'https://www.youtube.com/embed/{id}'.format(id=id)
78+
text = self.embed_template.format(url=url)
79+
except UnicodeError as error:
80+
raise self.severe('Problem with "%s" directive:\n%s'
81+
% (self.name, ErrorString(error)))
82+
83+
raw_node = nodes.raw('', text, **attributes)
84+
(raw_node.source, raw_node.line) = \
85+
self.state_machine.get_source_and_line(self.lineno)
86+
return [raw_node]
87+
88+
89+
def setup(app):
90+
# type: (Sphinx) -> Dict[str, Any]
91+
directives.register_directive('youtube', Youtube)
92+
93+
return {
94+
'version': __version__,
95+
'parallel_read_safe': True,
96+
'parallel_write_safe': True,
97+
}

freeze.py

+4
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@
108108
print("Loaded modules from openshot_qt directory: %s" % os.path.join(PATH, "openshot_qt"))
109109

110110
# Append possible build server paths
111+
111112
sys.path.insert(0, os.path.join(PATH, "build", "install-x86", "lib"))
113+
sys.path.insert(0, os.path.join(PATH, "build", "install-x86", "bin"))
114+
112115
sys.path.insert(0, os.path.join(PATH, "build", "install-x64", "lib"))
116+
sys.path.insert(0, os.path.join(PATH, "build", "install-x64", "bin"))
113117

114118

115119
from classes import info

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
# XDG Freedesktop icon paths
7373
('share/icons/hicolor/scalable/apps', ['xdg/openshot-qt.svg']),
7474
('share/icons/hicolor/64x64/apps', ['xdg/icon/64/openshot-qt.png']),
75+
('share/icons/hicolor/128x128/apps', ['xdg/icon/128/openshot-qt.png']),
7576
('share/icons/hicolor/256x256/apps', ['xdg/icon/256/openshot-qt.png']),
7677
('share/icons/hicolor/512x512/apps', ['xdg/icon/512/openshot-qt.png']),
7778
# XDG desktop mime types cache

src/blender/picture_frames_4.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,28 @@
1111
<default>TitleFileName</default>
1212
</param>
1313

14-
<param name="project_files1" type="dropdown" title="Picture 1 Path" description="">
14+
<param name="project_files1" type="dropdown" title="Picture 1" description="">
1515
<values>
1616
<value name="" num=""/>
1717
</values>
1818
<default></default>
1919
</param>
2020

21-
<param name="project_files2" type="dropdown" title="Picture 2 Path" description="">
21+
<param name="project_files2" type="dropdown" title="Picture 2" description="">
2222
<values>
2323
<value name="" num=""/>
2424
</values>
2525
<default></default>
2626
</param>
2727

28-
<param name="project_files3" type="dropdown" title="Picture 3 Path" description="">
28+
<param name="project_files3" type="dropdown" title="Picture 3" description="">
2929
<values>
3030
<value name="" num=""/>
3131
</values>
3232
<default></default>
3333
</param>
3434

35-
<param name="project_files4" type="dropdown" title="Picture 4 Path" description="">
35+
<param name="project_files4" type="dropdown" title="Picture 4" description="">
3636
<values>
3737
<value name="" num=""/>
3838
</values>

src/blender/scripts/dissolve.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def createDissolveText(title, extrude, bevel_depth, spacemode, textsize, width,
113113
ActiveObjectText.particle_systems[0].settings.count = NbQuads
114114
ActiveObjectText.particle_systems[0].settings.frame_start = 10
115115
ActiveObjectText.particle_systems[0].settings.frame_end = 60
116-
ActiveObjectText.particle_systems[0].settings.lifetime = 80
116+
ActiveObjectText.particle_systems[0].settings.lifetime = 120
117117
ActiveObjectText.particle_systems[0].point_cache.frame_step = 1
118118
ActiveObjectText.particle_systems[0].settings.normal_factor = 0.0
119119
# not useful

src/classes/app.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from PyQt5.QtCore import PYQT_VERSION_STR
3737
from PyQt5.QtCore import QT_VERSION_STR
3838
from PyQt5.QtCore import Qt
39-
from PyQt5.QtGui import QPalette, QColor, QFontDatabase, QFont
39+
from PyQt5.QtGui import QPalette, QColor, QFontDatabase, QFont, QIcon
4040
from PyQt5.QtWidgets import QApplication, QStyleFactory, QMessageBox
4141

4242
try:
@@ -70,6 +70,7 @@ def __init__(self, *args, mode=None):
7070
log.info('Starting new session'.center(48))
7171

7272
from classes import settings, project_data, updates, language, ui_util, logger_libopenshot
73+
from images import openshot_rc
7374
import openshot
7475

7576
# Re-route stdout and stderr to logger
@@ -106,6 +107,12 @@ def __init__(self, *args, mode=None):
106107
# Setup application
107108
self.setApplicationName('openshot')
108109
self.setApplicationVersion(info.SETUP['version'])
110+
self.setWindowIcon(QIcon(":/openshot.svg"))
111+
try:
112+
# Qt 5.7+ only
113+
self.setDesktopFile("org.openshot.OpenShot")
114+
except AttributeError:
115+
pass
109116

110117
# Init settings
111118
self.settings = settings.SettingStore()

src/classes/info.py

+18-12
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
import os
2929
from time import strftime
3030

31-
from PyQt5.QtCore import QDir
32-
3331
VERSION = "2.5.1-dev2"
3432
MINIMUM_LIBOPENSHOT_VERSION = "0.2.5"
3533
DATE = "20200228000000"
@@ -56,22 +54,23 @@
5654
THUMBNAIL_PATH = os.path.join(USER_PATH, "thumbnail")
5755
CACHE_PATH = os.path.join(USER_PATH, "cache")
5856
BLENDER_PATH = os.path.join(USER_PATH, "blender")
59-
ASSETS_PATH = os.path.join(USER_PATH, "assets")
6057
TITLE_PATH = os.path.join(USER_PATH, "title")
6158
TRANSITIONS_PATH = os.path.join(USER_PATH, "transitions")
6259
PREVIEW_CACHE_PATH = os.path.join(USER_PATH, "preview-cache")
6360
USER_PROFILES_PATH = os.path.join(USER_PATH, "profiles")
6461
USER_PRESETS_PATH = os.path.join(USER_PATH, "presets")
65-
62+
USER_TITLES_PATH = os.path.join(USER_PATH, "title_templates")
6663
# User files
6764
BACKUP_FILE = os.path.join(BACKUP_PATH, "backup.osp")
6865
USER_DEFAULT_PROJECT = os.path.join(USER_PATH, "default.project")
6966

7067
# Create user paths if they do not exist
7168
# (this is where temp files are stored... such as cached thumbnails)
72-
for folder in [USER_PATH, BACKUP_PATH, RECOVERY_PATH, THUMBNAIL_PATH, CACHE_PATH,
73-
BLENDER_PATH, ASSETS_PATH, TITLE_PATH, TRANSITIONS_PATH,
74-
PREVIEW_CACHE_PATH, USER_PROFILES_PATH, USER_PRESETS_PATH]:
69+
for folder in [
70+
USER_PATH, BACKUP_PATH, RECOVERY_PATH, THUMBNAIL_PATH, CACHE_PATH,
71+
BLENDER_PATH, TITLE_PATH, TRANSITIONS_PATH, PREVIEW_CACHE_PATH,
72+
USER_PROFILES_PATH, USER_PRESETS_PATH, USER_TITLES_PATH,
73+
]:
7574
if not os.path.exists(os.fsencode(folder)):
7675
os.makedirs(folder, exist_ok=True)
7776

@@ -97,11 +96,18 @@
9796
print("Loading translations from: {}".format(language_path))
9897

9998
# Compile language list from :/locale resource
100-
langdir = QDir(language_path)
101-
langs = langdir.entryList(['OpenShot.*.qm'], QDir.NoDotAndDotDot | QDir.Files,
102-
sort=QDir.Name)
103-
for trpath in langs:
104-
SUPPORTED_LANGUAGES.append(trpath.split('.')[1])
99+
try:
100+
from PyQt5.QtCore import QDir
101+
langdir = QDir(language_path)
102+
langs = langdir.entryList(
103+
['OpenShot.*.qm'],
104+
QDir.NoDotAndDotDot | QDir.Files,
105+
sort=QDir.Name)
106+
for trpath in langs:
107+
SUPPORTED_LANGUAGES.append(trpath.split('.')[1])
108+
except ImportError:
109+
# Fail gracefully if we're running without PyQt5 (e.g. CI tasks)
110+
pass
105111

106112
SETUP = {
107113
"name": NAME,

src/classes/ui_util.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,41 @@
1-
"""
1+
"""
22
@file
33
@brief This file contains PyQt help functions, to translate the interface, load icons, and connect signals
44
@author Noah Figg <[email protected]>
55
@author Jonathan Thomas <[email protected]>
66
@author Olivier Girard <[email protected]>
7-
7+
88
@section LICENSE
9-
9+
1010
Copyright (c) 2008-2018 OpenShot Studios, LLC
1111
(http://www.openshotstudios.com). This file is part of
1212
OpenShot Video Editor (http://www.openshot.org), an open-source project
1313
dedicated to delivering high quality video editing and animation solutions
1414
to the world.
15-
15+
1616
OpenShot Video Editor is free software: you can redistribute it and/or modify
1717
it under the terms of the GNU General Public License as published by
1818
the Free Software Foundation, either version 3 of the License, or
1919
(at your option) any later version.
20-
20+
2121
OpenShot Video Editor is distributed in the hope that it will be useful,
2222
but WITHOUT ANY WARRANTY; without even the implied warranty of
2323
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2424
GNU General Public License for more details.
25-
25+
2626
You should have received a copy of the GNU General Public License
2727
along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
2828
"""
2929

3030
import os
31-
import xml.etree.ElementTree
3231
import time
3332

33+
# Try to get the security-patched XML functions from defusedxml
34+
try:
35+
from defusedxml import ElementTree
36+
except ImportError:
37+
from xml.etree import ElementTree
38+
3439
from PyQt5.QtCore import QDir, QLocale
3540
from PyQt5.QtGui import QIcon
3641
from PyQt5.QtWidgets import *
@@ -85,7 +90,7 @@ def load_ui(window, path):
8590
raise error
8691

8792
# Save xml tree for ui
88-
window.uiTree = xml.etree.ElementTree.parse(path)
93+
window.uiTree = ElementTree.parse(path)
8994

9095

9196
def get_default_icon(theme_name):

0 commit comments

Comments
 (0)