Skip to content

Commit

Permalink
Adding JS mixin support for QtWebEngine and QtWebKit (so either one w…
Browse files Browse the repository at this point in the history
…ill be found and will work)
  • Loading branch information
jonoomph committed Aug 13, 2020
1 parent 3464d1e commit 0b394ca
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 34 deletions.
21 changes: 5 additions & 16 deletions src/timeline/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
*/

// Initialize Angular application
/*global App, timeline, angular*/
var timeline = null;
/*global App, angular*/
var App = angular.module("openshot-timeline", ["ui.bootstrap", "ngAnimate"]);


Expand All @@ -37,18 +36,8 @@ $(document).ready(function () {

var body_object = $("body");

// Check for Qt Integration
new QWebChannel(qt.webChannelTransport, function (channel) {
timeline = channel.objects.timeline;
timeline.qt_log("INFO", "Qt Ready");

// Only enable Qt once Angular as initialized
angular.element(document).ready(function () {
timeline.qt_log("INFO", "Angular Ready");
body_object.scope().enableQt();
});

});
// Initialize Qt Mixin (WebEngine or WebKit)
init_mixin();

/// Capture window resize event, and resize scrollable divs (i.e. track container)
$(window).resize(function () {
Expand All @@ -64,8 +53,8 @@ $(document).ready(function () {

track_controls.height(new_track_height);
$("#scrolling_tracks").height(new_track_height);
body_object.scope().playhead_height = $("#track-container").height();
$(".playhead-line").height(body_object.scope().playhead_height);
body_object.scope().playhead_height = $("#track-container").height();
$(".playhead-line").height(body_object.scope().playhead_height);
});

// Bind to keydown event (to detect SHIFT)
Expand Down
2 changes: 1 addition & 1 deletion src/timeline/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<script type="text/javascript" src="media/js/angular-animate.min.js"></script>

<!-- OpenShot JavaScript Sources -->
<script type="text/javascript" src="js/qwebchannel.js"></script>
{{MIXIN_JS_INCLUDE}}
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="js/functions.js"></script>
<script type="text/javascript" src="js/controllers.js"></script>
Expand Down
46 changes: 46 additions & 0 deletions src/timeline/js/mixin_webengine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* @file
* @brief JavaScript file to initialize QtWebEngine JS mixin
* @author Jonathan Thomas <jonathan@openshot.org>
*
* @section LICENSE
*
* Copyright (c) 2008-2018 OpenShot Studios, LLC
* <http://www.openshotstudios.com/>. This file is part of
* OpenShot Video Editor, an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
* world. For more information visit <http://www.openshot.org/>.
*
* OpenShot Video Editor is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* OpenShot Video Editor is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
*/

/*global timeline*/
var timeline = null;

function init_mixin() {

// Check for Qt Integration
new QWebChannel(qt.webChannelTransport, function (channel) {
timeline = channel.objects.timeline;
timeline.qt_log("INFO", "Qt Ready");

// Only enable Qt once Angular as initialized
angular.element(document).ready(function () {
timeline.qt_log("INFO", "Angular Ready");
$("body").scope().enableQt();
});

});

}
42 changes: 42 additions & 0 deletions src/timeline/js/mixin_webkit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @file
* @brief JavaScript file to initialize QtWebKit JS mixin
* @author Jonathan Thomas <jonathan@openshot.org>
*
* @section LICENSE
*
* Copyright (c) 2008-2018 OpenShot Studios, LLC
* <http://www.openshotstudios.com/>. This file is part of
* OpenShot Video Editor, an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
* world. For more information visit <http://www.openshot.org/>.
*
* OpenShot Video Editor is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* OpenShot Video Editor is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
*/

// undef global timeline var
//timeline = undefined;

function init_mixin() {

// Only enable Qt once Angular as initialized
angular.element(document).ready(function () {
if (typeof timeline !== "undefined") {
timeline.qt_log("INFO", "Qt Ready");
$("body").scope().enableQt();
}
timeline.qt_log("INFO", "Angular Ready");
});

}
68 changes: 63 additions & 5 deletions src/windows/views/timeline_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@

try:
# Attempt to import QtWebEngine
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView
IS_WEBENGINE_VALID = True
except ImportError:
QWebEngineView = object # Prevent inheritance errors
IS_WEBENGINE_VALID = False

try:
# Attempt to import QtWebKit
from PyQt5.QtWebKitWidgets import QWebView
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
IS_WEBKIT_VALID = True
except ImportError:
QWebView = object # Prevent inheritance errors
Expand All @@ -63,6 +63,10 @@ def run_js(self, code, callback=None, retries=0):
"""Run javascript code snippet"""
raise Exception("run_js not implemented")

def get_html(self):
"""Get HTML for Timeline, adjusted for mixin"""
raise Exception("get_html not implemented")


class TimelineQtWebEngineMixin(TimelineBaseMixin, QWebEngineView):
"""QtWebEngine Timeline Widget"""
Expand All @@ -83,7 +87,7 @@ def __init__(self):

# Set url from configuration (QUrl takes absolute paths for file system paths, create from QFileInfo)
self.webchannel = QWebChannel(self.page())
self.setUrl(QUrl.fromLocalFile(QFileInfo(self.html_path).absoluteFilePath()))
self.setHtml(self.get_html(), QUrl.fromLocalFile(QFileInfo(self.html_path).absoluteFilePath()))
self.page().setWebChannel(self.webchannel)

# Connect signal of javascript initialization to our javascript reference init function
Expand Down Expand Up @@ -114,6 +118,34 @@ def setup_js_data(self):
# Export self as a javascript object in webview
self.webchannel.registerObject('timeline', self)

def get_html(self):
"""Get HTML for Timeline, adjusted for mixin"""
html = open(self.html_path, 'r', encoding='utf-8').read()
html = html.replace('{{MIXIN_JS_INCLUDE}}',
'''
<script type="text/javascript" src="js/qwebchannel.js"></script>
<script type="text/javascript" src="js/mixin_webengine.js"></script>
''')
return html

def keyPressEvent(self, event):
""" Keypress callback for timeline """
key_value = event.key()
if (key_value == Qt.Key_Shift or key_value == Qt.Key_Control):

# Only pass a few keystrokes to the webview (CTRL and SHIFT)
return QWebEngineView.keyPressEvent(self, event)

else:
# Ignore most keypresses
event.ignore()


class LoggingWebPage(QWebPage):
"""Override console.log message to display messages"""
def javaScriptConsoleMessage(self, msg, line, source):
log.warning('JS: %s line %d: %s' % (source, line, msg))

class TimelineQtWebKitMixin(TimelineBaseMixin, QWebView):
"""QtWebKit Timeline Widget"""
Expand All @@ -126,11 +158,15 @@ def __init__(self):
# Delete the webview when closed
self.setAttribute(Qt.WA_DeleteOnClose)

# Connect logging web page (for console.log)
page = LoggingWebPage()
self.setPage(page)

# Disable image caching on timeline
self.settings().setObjectCacheCapacities(0, 0, 0)

# Set url from configuration (QUrl takes absolute paths for file system paths, create from QFileInfo)
self.setUrl(QUrl.fromLocalFile(QFileInfo(self.html_path).absoluteFilePath()))
self.setHtml(self.get_html(), QUrl.fromLocalFile(QFileInfo(self.html_path).absoluteFilePath()))

# Connect signal of javascript initialization to our javascript reference init function
self.page().mainFrame().javaScriptWindowObjectCleared.connect(self.setup_js_data)
Expand All @@ -152,7 +188,8 @@ def run_js(self, code, callback=None, retries=0):
else:
# Execute JS code
if callback:
return self.page().mainFrame().evaluateJavaScript(code, callback)
# Pass output to callback
callback(self.page().mainFrame().evaluateJavaScript(code))
else:
return self.page().mainFrame().evaluateJavaScript(code)

Expand All @@ -161,6 +198,27 @@ def setup_js_data(self):
self.page().mainFrame().addToJavaScriptWindowObject('timeline', self)
self.page().mainFrame().addToJavaScriptWindowObject('mainWindow', self.window)

def get_html(self):
"""Get HTML for Timeline, adjusted for mixin"""
html = open(self.html_path, 'r', encoding='utf-8').read()
html = html.replace('{{MIXIN_JS_INCLUDE}}',
'''
<script type="text/javascript" src="js/mixin_webkit.js"></script>
''')
return html

def keyPressEvent(self, event):
""" Keypress callback for timeline """
key_value = event.key()
if (key_value == Qt.Key_Shift or key_value == Qt.Key_Control):

# Only pass a few keystrokes to the webview (CTRL and SHIFT)
return QWebView.keyPressEvent(self, event)

else:
# Ignore most keypresses
event.ignore()

# Set correct Mixin (with QtWebEngine preference)
if IS_WEBENGINE_VALID:
Expand Down
12 changes: 0 additions & 12 deletions src/windows/views/timeline_webview.py
Original file line number Diff line number Diff line change
Expand Up @@ -2748,18 +2748,6 @@ def update_zoom(self, newValue):
get_app().updates.update(["scale"], newScale)
get_app().updates.ignore_history = False

def keyPressEvent(self, event):
""" Keypress callback for timeline """
key_value = event.key()
if (key_value == Qt.Key_Shift or key_value == Qt.Key_Control):

# Only pass a few keystrokes to the webview (CTRL and SHIFT)
return QWebEngineView.keyPressEvent(self, event)

else:
# Ignore most keypresses
event.ignore()

# Capture wheel event to alter zoom slider control
def wheelEvent(self, event):
if int(QCoreApplication.instance().keyboardModifiers() & Qt.ControlModifier) > 0:
Expand Down

0 comments on commit 0b394ca

Please sign in to comment.