Skip to content

Commit 0e2e99f

Browse files
authored
Merge branch 'develop' into code-tidying
2 parents 196448e + 925427d commit 0e2e99f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+691
-463
lines changed

CONTRIBUTING.md

+29-21
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,46 @@
11
## How to contribute to OpenShot Video Editor
22

3-
#### **Did you find a bug?**
3+
### Submitting an Issue (bug report)
44

5-
* **Please check if this bug was already reported** by searching on GitHub under [Issues](https://github.com/OpenShot/openshot-qt/issues).
5+
* **Please check if this bug was already reported** by searching on GitHub under [Issues](https://github.com/OpenShot/openshot-qt/issues?q=+).
66

7-
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/OpenShot/openshot-qt/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and the steps to reproduce the crash or issue.
7+
* If you're unable to find an existing report about the problem, [open a new issue](https://github.com/OpenShot/openshot-qt/issues/new?template=bug-report.md). Be sure to include a **title and clear description**, and fill in as much relevant information as possible. Include the steps to reproduce the crash or issue, and please note what operating system(s) you tried them on. (Some bugs only occur when using OpenShot on a particular OS.)
88

99
* Please **attach log files** if you are reporting a crash. Otherwise, we will not be able to determine the cause of the crash.
1010

11-
_Please download our latest daily installer:_
11+
#### Reproducing a bug & collecting logs
1212

13-
1. www.openshot.org/download - click the '**Daily Builds**' button, then grab the latest build from the list.
14-
(Use the buttons below to download installers for a different Operating System.)
15-
2. Then enable 'Debug Mode (Verbose)' in the Preferences
16-
3. Quit OpenShot and delete both log files:
17-
* **Windows**: OpenShot stores its logs in your user profile directory (`%USERPROFILE%`, e.g. `C:\Users\username\`)
18-
* **`%USERPROFILE%/.openshot_qt/openshot-qt.log`**
19-
* **`%USERPROFILE%/.openshot_qt/libopenshot.log`**
20-
* **Linux/MacOS**: OpenShot stores its logs in your home directory (`$HOME`, e.g. `/home/username/`)
21-
* **`$HOME/.openshot_qt/openshot-qt.log`**
22-
* **`$HOME/.openshot_qt/libopenshot.log`**
23-
4. Re-launch OpenShot and trigger the crash as quickly as possible (to keep the log files small)
24-
5. Attach **both** log files
13+
1. _Please download our latest daily installer:_
14+
www.openshot.org/download - click the '**Daily Builds**' button, then grab the latest build from the list.
15+
(Use the buttons below the list to download installers for a different Operating System.)
16+
2. **Only if the bug involves video playback or Export**, or if you were asked to by the OpenShot developers, enable 'Debug Mode (Verbose)' in the Preferences. Debug Mode adds no additional information for user interface or project-editing bugs.
17+
3. Quit OpenShot and delete your log files, to ensure the files you submit contain only necessary information. (See below for logfile paths.)
18+
4. Re-launch OpenShot and trigger the problem as quickly as possible, then immediately quit the program. This helps keeps the log files small and relevant.
19+
5. Attach both log files to your issue. Github issue comments permit attaching `.log` files up to 2MB in size. You can insert the file(s) either by drag-and-drop, or using the link at the bottom of the comment edit field.
20+
21+
#### OpenShot log file locations
2522

26-
#### **Did you write a patch that fixes a bug?**
23+
##### Windows
24+
* OpenShot stores its logs in your user profile directory (`%USERPROFILE%`, e.g. `C:\Users\username\`)
25+
* **<code><var>%USERPROFILE%</var>\.openshot_qt\openshot-qt.log</code>**
26+
* **<code><var>%USERPROFILE%</var>\.openshot_qt\libopenshot.log</code>**
2727

28-
* Open a new GitHub pull request with the patch.
28+
##### Linux/MacOS
29+
* OpenShot stores its logs in your home directory (`$HOME`, e.g. `/home/username/`)
30+
* **<code><var>$HOME</var>/.openshot_qt/openshot-qt.log</code>**
31+
* **<code><var>$HOME</var>/.openshot_qt/libopenshot.log</code>**
2932

30-
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
33+
### Submitting a Pull Request (source code patch / bug fix)
3134

32-
* Before submitting, please ensure your PR passes all build / compilation / and unit tests.
35+
* Fork the repository on Github, then create a new branch for your changes. Commit the patch(es), and finally open a new GitHub Pull Request from that branch.
3336

34-
OpenShot Video Editor is a volunteer effort, and a labor of love. Please be patient with any issues you find, and feel free to get involved and help us fix them!
37+
* Ensure the PR description clearly describes the problem and your solution. If the patch is related to an existing issue report, include the issue number in your description. Github recognizes trigger phrases such as "fixes #1234" or "closes #9999", and will automatically link your PR with the referenced issue(s).
38+
39+
* After submitting, your PR will be run through a test build and various code-quality and style checks. Try to address any problems flagged by these checks. If OpenShot fails to build successfully with your changes, the PR cannot be merged until the problem is resolved.
3540

41+
Submitting "in-progress" code is fine, and can often be a good way to solicit feedback from other developers. Consider marking PRs that are unfinished or still under development with a the title that begins with "WIP", or convert the PR to draft status, to indicate to the developers that your changes are not yet ready for review.
42+
43+
OpenShot Video Editor is a volunteer effort, and a labor of love. Please be patient with any issues you find, and feel free to get involved and help us fix them!
3644

3745
Thanks!
3846

src/classes/app.py

+32-16
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,28 @@
3535

3636
from PyQt5.QtCore import PYQT_VERSION_STR
3737
from PyQt5.QtCore import QT_VERSION_STR
38-
from PyQt5.QtCore import Qt
38+
from PyQt5.QtCore import Qt, pyqtSlot
3939
from PyQt5.QtGui import QPalette, QColor, QFontDatabase, QFont
4040
from PyQt5.QtWidgets import QApplication, QStyleFactory, QMessageBox
4141

4242
try:
43-
# QtWebEngineWidgets must be loaded prior to creating a QApplication
44-
# But on systems with only WebKit, this will fail (and we ignore the failure)
45-
from PyQt5.QtWebEngineWidgets import QWebEngineView # noqa
46-
except ImportError:
43+
# This apparently has to be done before loading QtQuick
44+
# (via QtWebEgine) AND before creating the QApplication instance
45+
QApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
46+
from OpenGL import GL # noqa
47+
except (ImportError, AttributeError):
4748
pass
4849

4950
try:
50-
# Solution to solve QtWebEngineWidgets black screen caused by OpenGL not loaded
51-
from OpenGL import GL # noqa
51+
# QtWebEngineWidgets must be loaded prior to creating a QApplication
52+
# But on systems with only WebKit, this will fail (and we ignore the failure)
53+
from PyQt5.QtWebEngineWidgets import QWebEngineView
5254
except ImportError:
5355
pass
5456

5557
try:
5658
# Enable High-DPI resolutions
5759
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
58-
QApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
5960
except AttributeError:
6061
pass # Quietly fail for older Qt5 versions
6162

@@ -83,7 +84,10 @@ def __init__(self, *args, mode=None):
8384
log.info(time.asctime().center(48))
8485
log.info('Starting new session'.center(48))
8586

86-
from classes import settings, project_data, updates, language, ui_util, logger_libopenshot
87+
from classes import (
88+
settings, project_data, updates, language, ui_util,
89+
logger_libopenshot
90+
)
8791
import openshot
8892

8993
# Re-route stdout and stderr to logger
@@ -126,7 +130,7 @@ def __init__(self, *args, mode=None):
126130
pass
127131

128132
# Init settings
129-
self.settings = settings.SettingStore()
133+
self.settings = settings.SettingStore(parent=self)
130134
self.settings.load()
131135

132136
# Init and attach exception handler
@@ -250,12 +254,15 @@ def __init__(self, *args, mode=None):
250254

251255
# Create main window
252256
from windows.main_window import MainWindow
253-
self.window = MainWindow(mode)
257+
self.window = MainWindow(mode=mode)
254258

255259
# Reset undo/redo history
256260
self.updates.reset()
257261
self.window.updateStatusChanged(False, False)
258262

263+
# Connect our exit signals
264+
self.aboutToQuit.connect(self.cleanup)
265+
259266
log.info('Process command-line arguments: %s' % args)
260267
if len(args[0]) == 2:
261268
path = args[0][1]
@@ -270,24 +277,33 @@ def __init__(self, *args, mode=None):
270277
# Recover backup file (this can't happen until after the Main Window has completely loaded)
271278
self.window.RecoverBackup.emit()
272279

280+
def settings_load_error(self, filepath=None):
281+
"""Use QMessageBox to warn the user of a settings load issue"""
282+
_ = self._tr
283+
QMessageBox.warning(
284+
None,
285+
_("Settings Error"),
286+
_("Error loading settings file: %(file_path)s. Settings will be reset.")
287+
% {"file_path": filepath}
288+
)
289+
273290
def _tr(self, message):
274291
return self.translate("", message)
275292

276293
# Start event loop
277294
def run(self):
278295
""" Start the primary Qt event loop for the interface """
296+
return self.exec_()
279297

280-
res = self.exec_()
281-
298+
@pyqtSlot()
299+
def cleanup(self):
300+
"""aboutToQuit signal handler for application exit"""
282301
try:
283302
from classes.logger import log
284303
self.settings.save()
285304
except Exception:
286305
log.error("Couldn't save user settings on exit.", exc_info=1)
287306

288-
# return exit result
289-
return res
290-
291307

292308
# Log the session's end
293309
@atexit.register

src/classes/exceptions.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
"""
1+
"""
22
@file
33
@brief This file deals with unhandled exceptions
44
@author Jonathan Thomas <[email protected]>
5-
5+
66
@section LICENSE
7-
7+
88
Copyright (c) 2008-2018 OpenShot Studios, LLC
99
(http://www.openshotstudios.com). This file is part of
1010
OpenShot Video Editor (http://www.openshot.org), an open-source project
1111
dedicated to delivering high quality video editing and animation solutions
1212
to the world.
13-
13+
1414
OpenShot Video Editor is free software: you can redistribute it and/or modify
1515
it under the terms of the GNU General Public License as published by
1616
the Free Software Foundation, either version 3 of the License, or
1717
(at your option) any later version.
18-
18+
1919
OpenShot Video Editor is distributed in the hope that it will be useful,
2020
but WITHOUT ANY WARRANTY; without even the implied warranty of
2121
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2222
GNU General Public License for more details.
23-
23+
2424
You should have received a copy of the GNU General Public License
2525
along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
2626
"""

src/classes/info.py

+3
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@
9292
LOG_LEVEL_FILE = 'INFO'
9393
LOG_LEVEL_CONSOLE = 'INFO'
9494

95+
# Web backend selection, overridable at launch
96+
WEB_BACKEND = 'auto'
97+
9598
# Languages
9699
CMDLINE_LANGUAGE = None
97100
CURRENT_LANGUAGE = 'en_US'

src/classes/settings.py

+35-23
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,64 @@
1-
"""
1+
"""
22
@file
3-
@brief This file loads and saves settings
3+
@brief This file loads and saves settings
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
# SettingStore - class which allows getting/storing of settings, loading and saving to json
3131
import os
3232

33-
from PyQt5.QtCore import QStandardPaths, QCoreApplication
34-
from PyQt5.QtWidgets import QMessageBox
35-
36-
from classes.logger import log
3733
from classes import info
34+
from classes.logger import log
3835
from classes.json_data import JsonDataStore
3936

4037

4138
def get_settings():
42-
""" Get the current QApplication's settings instance """
43-
return QCoreApplication.instance().settings
39+
""" Get the current application's settings instance """
40+
return SettingStore.get_app().settings
4441

4542

4643
class SettingStore(JsonDataStore):
4744
""" This class only allows setting pre-existing keys taken from default settings file, and merges user settings
4845
on load, assumes default OS dir."""
4946

50-
def __init__(self):
51-
JsonDataStore.__init__(self)
47+
@classmethod
48+
def save_app(cls, app_reference):
49+
cls._app = app_reference
50+
51+
@classmethod
52+
def get_app(cls):
53+
if hasattr(cls, "_app"):
54+
return cls._app
55+
return None
56+
57+
def __init__(self, parent=None):
58+
super().__init__()
59+
# Also keep track of our parent, if defined
60+
if parent:
61+
SettingStore.save_app(parent)
5262
# Set the data type name for logging clarity (base class functions use this variable)
5363
self.data_type = "user settings"
5464
self.settings_filename = "openshot.settings"
@@ -72,8 +82,11 @@ def set(self, key, value):
7282
if key in user_values:
7383
user_values[key]["value"] = value
7484
else:
75-
log.warn("{} key '{}' not valid. The following are valid: {}".format(self.data_type, key,
76-
list(self._data.keys())))
85+
log.warn(
86+
"{} key '{}' not valid. The following are valid: {}".format(
87+
self.data_type, key,
88+
list(self._data.keys()),
89+
))
7790

7891
def load(self):
7992
""" Load user settings file from disk, merging with allowed settings in default settings file.
@@ -90,17 +103,16 @@ def load(self):
90103

91104
# Load user settings (if found)
92105
if os.path.exists(os.fsencode(file_path)):
93-
94106
# Will raise exception to caller on failure to read
95107
try:
96108
user_settings = self.read_from_file(file_path)
97109
except Exception as ex:
98-
log.error("Error loading settings file: %s" % ex)
99-
100-
_ = QCoreApplication.instance()._tr
101-
QMessageBox.warning(None, _("Settings Error"),
102-
_("Error loading settings file: %(file_path)s. Settings will be reset.") % { "file_path": file_path})
110+
log.error("Error loading settings file: %s", ex)
103111
user_settings = {}
112+
app = SettingStore.get_app()
113+
if app:
114+
# We have a parent, ask to show a message box
115+
app.settings_load_error(file_path)
104116

105117
# Merge default and user settings, excluding settings not in default, Save settings
106118
self._data = self.merge_settings(default_settings, user_settings)

src/classes/thumbnail.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ def run(self):
107107
self.server_address = ('127.0.0.1', self.find_free_port())
108108
self.thumbServer = httpThumbnailServer(self.server_address, httpThumbnailHandler)
109109
self.thumbServer.daemon_threads = True
110+
log.info(
111+
"Starting thumbnail server listening on port %d",
112+
self.server_address[1])
110113
self.thumbServer.serve_forever(0.5)
111114

112115
def __init__(self):
@@ -128,6 +131,8 @@ def log_error(self, msg_format, *args):
128131

129132
def do_GET(self):
130133
""" Process each GET request and return a value (image or file path)"""
134+
mask_path = os.path.join(info.IMAGES_PATH, "mask.png")
135+
131136
# Parse URL
132137
url_output = REGEX_THUMBNAIL_URL.match(self.path)
133138
if url_output and len(url_output.groups()) == 4:
@@ -147,6 +152,10 @@ def do_GET(self):
147152
only_path = url_output.group('only_path')
148153
no_cache = url_output.group('no_cache')
149154

155+
log.debug(
156+
"Processing thumbnail request for %s frame %d",
157+
file_id, file_frame)
158+
150159
try:
151160
# Look up file data
152161
file = File.get(id=file_id)
@@ -155,6 +164,7 @@ def do_GET(self):
155164
file_path = file.absolute_path()
156165
except AttributeError:
157166
# Couldn't match file ID
167+
log.debug("No ID match, returning 404")
158168
self.send_error(404)
159169
return
160170

@@ -183,7 +193,13 @@ def do_GET(self):
183193
overlay_path = os.path.join(info.IMAGES_PATH, "overlay.png")
184194

185195
# Create thumbnail image
186-
GenerateThumbnail(file_path, thumb_path, file_frame, 98, 64, os.path.join(info.IMAGES_PATH, "mask.png"), overlay_path)
196+
GenerateThumbnail(
197+
file_path,
198+
thumb_path,
199+
file_frame,
200+
98, 64,
201+
mask_path,
202+
overlay_path)
187203

188204
# Send message back to client
189205
if os.path.exists(thumb_path):

0 commit comments

Comments
 (0)