diff --git a/src/timeline/app.js b/src/timeline/app.js index 0c03caf41d..86607fcf6f 100644 --- a/src/timeline/app.js +++ b/src/timeline/app.js @@ -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"]); @@ -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 () { @@ -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) diff --git a/src/timeline/index.html b/src/timeline/index.html index 68e2e81a7a..73d8b73d38 100644 --- a/src/timeline/index.html +++ b/src/timeline/index.html @@ -17,7 +17,7 @@ - + {{MIXIN_JS_INCLUDE}} diff --git a/src/timeline/js/mixin_webengine.js b/src/timeline/js/mixin_webengine.js new file mode 100644 index 0000000000..495972e373 --- /dev/null +++ b/src/timeline/js/mixin_webengine.js @@ -0,0 +1,46 @@ +/** + * @file + * @brief JavaScript file to initialize QtWebEngine JS mixin + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2018 OpenShot Studios, LLC + * . 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 . + * + * 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 . + */ + +/*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(); + }); + + }); + +} diff --git a/src/timeline/js/mixin_webkit.js b/src/timeline/js/mixin_webkit.js new file mode 100644 index 0000000000..0cdcce5177 --- /dev/null +++ b/src/timeline/js/mixin_webkit.js @@ -0,0 +1,42 @@ +/** + * @file + * @brief JavaScript file to initialize QtWebKit JS mixin + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2018 OpenShot Studios, LLC + * . 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 . + * + * 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 . + */ + +// 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"); + }); + +} diff --git a/src/windows/views/timeline_mixins.py b/src/windows/views/timeline_mixins.py index cd6327c9c6..bcdb8794d1 100644 --- a/src/windows/views/timeline_mixins.py +++ b/src/windows/views/timeline_mixins.py @@ -36,8 +36,8 @@ 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 @@ -45,7 +45,7 @@ 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 @@ -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""" @@ -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 @@ -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}}', + ''' + + + + ''') + 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""" @@ -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) @@ -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) @@ -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}}', + ''' + + + ''') + 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: diff --git a/src/windows/views/timeline_webview.py b/src/windows/views/timeline_webview.py index 066f606702..530850f614 100644 --- a/src/windows/views/timeline_webview.py +++ b/src/windows/views/timeline_webview.py @@ -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: