Skip to content

Commit

Permalink
add menu items to choose which web view to use (fix #346)
Browse files Browse the repository at this point in the history
  • Loading branch information
minorua committed Sep 26, 2024
1 parent 6b4b625 commit 7677c03
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 70 deletions.
3 changes: 0 additions & 3 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
PLUGIN_VERSION = "2.7.3"
PLUGIN_VERSION_INT = 20703

# 3D view
PREFER_WEBKIT = True

# vector layer
FEATURES_PER_BLOCK = 50 # max number of features in a data block

Expand Down
55 changes: 20 additions & 35 deletions q3dview.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,36 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# begin: 2023-10-03


from .conf import PREFER_WEBKIT
from qgis.core import Qgis
from .utils import logMessage

USE_WEBKIT = False
USE_WEBENGINE = False

if PREFER_WEBKIT:
try:
from PyQt5.QtWebKitWidgets import QWebView
USE_WEBKIT = True

except ModuleNotFoundError:
pass
WEBVIEWTYPE_NONE = 0
WEBVIEWTYPE_WEBKIT = 1
WEBVIEWTYPE_WEBENGINE = 2

if not USE_WEBKIT:
try:
from PyQt5.QtWebEngineWidgets import QWebEngineView
USE_WEBENGINE = True
WEBENGINE_AVAILABLE = False
WEBKIT_AVAILABLE = False

except ModuleNotFoundError:
pass

else:
if Qgis.QGIS_VERSION_INT >= 33800:
try:
from PyQt5.QtWebEngineWidgets import QWebEngineView
USE_WEBENGINE = True
WEBENGINE_AVAILABLE = True

except ModuleNotFoundError:
except:
pass

if not USE_WEBENGINE:
try:
from PyQt5.QtWebKitWidgets import QWebView
USE_WEBKIT = True

except ModuleNotFoundError:
pass
try:
from PyQt5.QtWebKitWidgets import QWebView
WEBKIT_AVAILABLE = True

if USE_WEBKIT:
from .q3dwebkitview import Q3DWebKitView as Q3DView, Q3DWebKitPage as Q3DWebPage
except: # ModuleNotFoundError
pass

elif USE_WEBENGINE:
from .q3dwebengineview import Q3DWebEngineView as Q3DView, Q3DWebEnginePage as Q3DWebPage

else:
from .q3ddummyview import Q3DDummyView as Q3DView, Q3DDummyPage as Q3DWebPage
if not (WEBENGINE_AVAILABLE or WEBKIT_AVAILABLE):
logMessage("Both webkit widgets and web engine widgets modules not found. The preview gets disabled.")


Q3DView = None
Q3DWebPage = None
currentWebViewType = None
54 changes: 46 additions & 8 deletions q3dwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,40 @@
from .q3dconst import LayerType, Script
from .q3dcontroller import Q3DController
from .q3dinterface import Q3DInterface
from . import q3dview
from .q3dview import WEBENGINE_AVAILABLE, WEBKIT_AVAILABLE, WEBVIEWTYPE_NONE, WEBVIEWTYPE_WEBKIT, WEBVIEWTYPE_WEBENGINE
from .utils import createUid, hex_color, js_bool, logMessage, pluginDir
from .ui.propertiesdialog import Ui_PropertiesDialog
from .ui import q3dwindow as ui_wnd
from .ui.q3dwindow import Ui_Q3DWindow


def switchWebView(webViewType):

if webViewType is q3dview.currentWebViewType:
return

if webViewType == WEBVIEWTYPE_WEBKIT:
from .q3dwebkitview import Q3DWebKitView, Q3DWebKitPage
ui_wnd.Q3DView = Q3DWebKitView
q3dview.Q3DView = Q3DWebKitView
q3dview.Q3DWebPage = Q3DWebKitPage

elif webViewType == WEBVIEWTYPE_WEBENGINE:
from .q3dwebengineview import Q3DWebEngineView, Q3DWebEnginePage
ui_wnd.Q3DView = Q3DWebEngineView
q3dview.Q3DView = Q3DWebEngineView
q3dview.Q3DWebPage = Q3DWebEnginePage

else:
from .q3ddummyview import Q3DDummyView, Q3DDummyPage
ui_wnd.Q3DView = Q3DDummyView
q3dview.Q3DView = Q3DDummyView
q3dview.Q3DWebPage = Q3DDummyPage

q3dview.currentWebViewType = webViewType


class Q3DViewerInterface(Q3DInterface):

abortRequest = pyqtSignal(bool) # param: cancel all requests in queue
Expand Down Expand Up @@ -94,7 +123,7 @@ def quit(self, controller):

class Q3DWindow(QMainWindow):

def __init__(self, qgisIface, settings, preview=True):
def __init__(self, qgisIface, settings, webViewType=WEBVIEWTYPE_WEBENGINE, previewEnabled=True):
QMainWindow.__init__(self, parent=qgisIface.mainWindow())
self.setAttribute(Qt.WA_DeleteOnClose)

Expand All @@ -108,24 +137,27 @@ def __init__(self, qgisIface, settings, preview=True):

self.setWindowIcon(QIcon(pluginDir("Qgis2threejs.png")))

# web view
switchWebView(webViewType)

self.ui = Ui_Q3DWindow()
self.ui.setupUi(self)

self.webPage = self.ui.webView._page
viewName = ""

if self.webPage:
settings.jsonSerializable = self.webPage.isWebEnginePage
viewName = "WebEngine" if self.webPage.isWebEnginePage else "WebKit"
else:
preview = False
previewEnabled = False
viewName = ""

self.iface = Q3DViewerInterface(settings, self.webPage, self, self.ui.treeView, parent=self)

self.thread = QThread(self) if RUN_CNTLR_IN_BKGND else None

self.controller = Q3DController(settings, self.thread)
self.controller.enabled = preview
self.controller.enabled = previewEnabled

if self.thread:
self.thread.finished.connect(self.controller.deleteLater)
Expand All @@ -138,12 +170,12 @@ def __init__(self, qgisIface, settings, preview=True):

self.setupMenu()
self.setupConsole()
self.setupStatusBar(self.iface, preview, viewName)
self.setupStatusBar(self.iface, previewEnabled, viewName)
self.ui.treeView.setup(self.iface, self.icons)
self.ui.treeView.addLayers(settings.layers())

if self.webPage:
self.ui.webView.setup(self.iface, settings, self, preview)
self.ui.webView.setup(self.iface, settings, self, previewEnabled)
else:
self.ui.webView.disableWidgetsAndMenus(self)

Expand Down Expand Up @@ -221,8 +253,14 @@ def setupMenu(self):

# signal-slot connections
self.ui.actionExportToWeb.triggered.connect(self.exportToWeb)
self.ui.actionSaveAsImage.triggered.connect(self.saveAsImage)
self.ui.actionSaveAsGLTF.triggered.connect(self.saveAsGLTF)

if WEBENGINE_AVAILABLE or WEBKIT_AVAILABLE:
self.ui.actionSaveAsImage.triggered.connect(self.saveAsImage)
self.ui.actionSaveAsGLTF.triggered.connect(self.saveAsGLTF)
else:
self.ui.actionSaveAsImage.setEnabled(False)
self.ui.actionSaveAsGLTF.setEnabled(False)

self.ui.actionLoadSettings.triggered.connect(self.loadSettings)
self.ui.actionSaveSettings.triggered.connect(self.saveSettings)
self.ui.actionClearSettings.triggered.connect(self.clearSettings)
Expand Down
92 changes: 68 additions & 24 deletions qgis2threejs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import os

from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import QAction
from PyQt5.QtGui import QIcon
from qgis.core import QgsApplication, QgsProject
Expand All @@ -14,6 +15,7 @@
from .procprovider import Qgis2threejsProvider
from .utils import logMessage, pluginDir, removeTemporaryOutputDir, settingsFilePath
from .q3dwindow import Q3DWindow
from .q3dview import WEBENGINE_AVAILABLE, WEBKIT_AVAILABLE, WEBVIEWTYPE_NONE, WEBVIEWTYPE_WEBKIT, WEBVIEWTYPE_WEBENGINE, currentWebViewType


class Qgis2threejs:
Expand All @@ -28,51 +30,82 @@ def __init__(self, iface):
self.previewEnabled = True # last preview state

def initGui(self):
# create actions
# add a toolbar button and web menu items
icon = QIcon(pluginDir("Qgis2threejs.png"))
self.action = QAction(icon, "Qgis2threejs Exporter", self.iface.mainWindow())
self.action.setObjectName("Qgis2threejsExporter")
self.actionNP = QAction(icon, "Qgis2threejs Exporter with Preview Off", self.iface.mainWindow())
self.actionNP.setObjectName("Qgis2threejsExporterNoPreview")
title = "Qgis2threejs Exporter"
wnd = self.iface.mainWindow()
objName = "Qgis2threejsExporter"

self.action = QAction(icon, title, wnd)
self.action.setObjectName(objName)
self.action.triggered.connect(self.openExporter)

# add toolbar button and web menu items
self.iface.addWebToolBarIcon(self.action)
self.iface.addPluginToWebMenu(PLUGIN_NAME, self.action)
self.iface.addPluginToWebMenu(PLUGIN_NAME, self.actionNP)

# register processing provider
QgsApplication.processingRegistry().addProvider(self.pprovider)
if WEBENGINE_AVAILABLE:
self.actionWebEng = QAction(icon, title + " (Web Engine)", wnd)
self.actionWebEng.setObjectName(objName + "WebEng")
self.actionWebEng.triggered.connect(self.openExporterWebEng)

# connect signal-slot
self.action.triggered.connect(self.openExporter)
self.actionNP.triggered.connect(self.openExporterWithPreviewDisabled)
self.iface.addPluginToWebMenu(PLUGIN_NAME, self.actionWebEng)

if WEBKIT_AVAILABLE:
self.actionWebKit = QAction(icon, title + " (WebKit)", wnd)
self.actionWebKit.setObjectName(objName + "WebKit")
self.actionWebKit.triggered.connect(self.openExporterWebKit)

self.iface.addPluginToWebMenu(PLUGIN_NAME, self.actionWebKit)

# connect signal-slot
QgsProject.instance().removeAll.connect(self.allLayersRemoved)

# register processing provider
QgsApplication.processingRegistry().addProvider(self.pprovider)

def unload(self):
# disconnect signal-slot
self.action.triggered.disconnect(self.openExporter)
self.actionNP.triggered.disconnect(self.openExporterWithPreviewDisabled)

QgsProject.instance().removeAll.disconnect(self.allLayersRemoved)

# remove the web menu items and icon
self.action.triggered.disconnect(self.openExporter)
self.iface.removeWebToolBarIcon(self.action)
self.iface.removePluginWebMenu(PLUGIN_NAME, self.action)
self.iface.removePluginWebMenu(PLUGIN_NAME, self.actionNP)

if WEBENGINE_AVAILABLE:
self.actionWebEng.triggered.disconnect(self.openExporterWebEng)
self.iface.removePluginWebMenu(PLUGIN_NAME, self.actionWebEng)

if WEBKIT_AVAILABLE:
self.actionWebKit.triggered.disconnect(self.openExporterWebKit)
self.iface.removePluginWebMenu(PLUGIN_NAME, self.actionWebKit)

# remove provider from processing registry
QgsApplication.processingRegistry().removeProvider(self.pprovider)

# remove temporary output directory
removeTemporaryOutputDir()

def openExporter(self, _, no_preview=False):
def openExporter(self, _=False, webViewType=None):
"""
webViewType: WEBVIEWTYPE_NONE, WEBVIEWTYPE_WEBKIT, WEBVIEWTYPE_WEBENGINE or None. None means last used web view type.
"""
if self.liveExporter:
logMessage("Qgis2threejs Exporter is already open.", False)
self.liveExporter.activateWindow()
return

if webViewType is None:
if WEBKIT_AVAILABLE and QSettings().value("/Qgis2threejs/preferWebKit", False, type=bool):
webViewType = WEBVIEWTYPE_WEBKIT

elif WEBENGINE_AVAILABLE:
webViewType = WEBVIEWTYPE_WEBENGINE

elif WEBKIT_AVAILABLE:
webViewType = WEBVIEWTYPE_WEBKIT

else:
webViewType = WEBVIEWTYPE_NONE

layersUpdated = False
proj_path = QgsProject.instance().fileName()
if proj_path and proj_path != self.currentProjectPath:
Expand All @@ -91,20 +124,31 @@ def openExporter(self, _, no_preview=False):
logMessage("Opening Qgis2threejs Exporter...", False)
self.liveExporter = Q3DWindow(self.iface,
self.exportSettings,
preview=self.previewEnabled and not no_preview)
webViewType=webViewType,
previewEnabled=self.previewEnabled)
self.liveExporter.show()
self.liveExporter.destroyed.connect(self.exporterDestroyed)

self.currentProjectPath = proj_path

def openExporterWithPreviewDisabled(self):
self.openExporter(False, True)
def openExporterWebEng(self):
self.openExporter(webViewType=WEBVIEWTYPE_WEBENGINE)

QSettings().remove("/Qgis2threejs/preferWebKit")

def openExporterWebKit(self):
self.openExporter(webViewType=WEBVIEWTYPE_WEBKIT)

QSettings().setValue("/Qgis2threejs/preferWebKit", True)

def exporterDestroyed(self, obj):
logMessage("Qgis2threejs Exporter has closed.", False)
self.previewEnabled = self.liveExporter.controller.enabled # remember preview state
if currentWebViewType != WEBVIEWTYPE_NONE:
self.previewEnabled = self.liveExporter.controller.enabled # remember preview state

self.liveExporter = None

logMessage("Qgis2threejs Exporter has closed.", False)

def allLayersRemoved(self):
self.currentProjectPath = ""
self.exportSettings = None

0 comments on commit 7677c03

Please sign in to comment.