From 5499319fa66d677d2ec0d39b077c4f42af4d1296 Mon Sep 17 00:00:00 2001 From: Matt Singleton Date: Fri, 14 Jan 2022 09:32:10 -0600 Subject: replace QTextBrowser with QWebEngineView --- browser.py | 103 ++++++++++++++++++++++++++++--------------------------------- 1 file changed, 47 insertions(+), 56 deletions(-) diff --git a/browser.py b/browser.py index e77b31d..5eda3b8 100755 --- a/browser.py +++ b/browser.py @@ -2,55 +2,36 @@ import sys -from PySide6 import QtCore, QtWidgets, QtGui +from PySide6 import QtCore, QtWidgets, QtGui, QtWebEngineWidgets, QtWebEngineCore import gemini -class GViewport(QtWidgets.QTextBrowser): - - hoverUrlChanged = QtCore.Signal(str) - resourceLoadedStatus = QtCore.Signal(str) - - def __init__(self, address_bar): - self.address_bar = address_bar - self._hover_url = None - QtWidgets.QTextBrowser.__init__(self) - - def mouseMoveEvent(self, event): - cur = self.cursorForPosition(event.localPos().toPoint()) - hover_url = cur.charFormat().anchorHref() - if hover_url: - hover_url = gemini.urljoin(self.address_bar.text(), hover_url) - if hover_url != self._hover_url: - self._hover_url = hover_url - self.hoverUrlChanged.emit(self._hover_url) - return super().mouseMoveEvent(event) - - def loadResource(self, type_, url): - gem = gemini.get(url.toString()) - print(gem['body']) - if 'body' in gem: - html = gemini.gem2html(gem['body']) - print(html) - else: - html = '

{} {}

'.format(gem['status'], gem['meta']) - self.resourceLoadedStatus.emit( - '{status} {meta}'.format(status=gem['status'], meta=gem['meta']) - ) - return html - def setSource(self, url, type_=None): +class GeminiPage(QtWebEngineCore.QWebEnginePage): + def acceptNavigationRequest(self, url, navtype, mainframe): """ - send all unsupported urls to the OS + Block non-gemini page navigation and + send the url to the os instead """ if url.scheme() == 'gemini': - if type_ is None: - return super().setSource(url) - return super().setSource(url, type_) - return QtGui.QDesktopServices().openUrl(url) + return True + else: + QtGui.QDesktopServices().openUrl(url) + return False + + +class GeminiSchemeHandler(QtWebEngineCore.QWebEngineUrlSchemeHandler): + def requestStarted(self, request): + print(request.requestUrl().toString()) + gem = gemini.get(request.requestUrl().toString()) + print(gem['status'], gem['meta']) + buf = QtCore.QBuffer(parent=request) + buf.open(QtCore.QIODevice.WriteOnly) + buf.write(gemini.gem2html(gem['body']).encode('utf8')) + buf.seek(0) + buf.close() + request.reply(b'text/html', buf) - def setRawSource(self): - return self.setSource(QtCore.QUrl(self.address_bar.text())) class GUrlBar(QtWidgets.QLineEdit): @@ -60,13 +41,16 @@ class GUrlBar(QtWidgets.QLineEdit): def setUrl(self, url): return self.setText(url.toDisplayString()) + class GBrowser(QtWidgets.QMainWindow): - def __init__(self, initial_url=None): + def __init__(self, initial_url=None, profile=None): + if initial_url is None: + initial_url = 'gemini://gemini.circumlunar.space/' + if profile is None: + profile = QtWebEngineCore.QWebEngineProfile.defaultProfile() QtWidgets.QMainWindow.__init__(self) - ## Create widgets - # Navigation Toolbar back = QtWidgets.QPushButton("back") forward = QtWidgets.QPushButton("forward") @@ -79,7 +63,9 @@ class GBrowser(QtWidgets.QMainWindow): self.addToolBar(toolbar) # Main Viewport - browser = GViewport(address) + browser = QtWebEngineWidgets.QWebEngineView() + page = GeminiPage(profile, browser) + browser.setPage(page) self.setCentralWidget(browser) # Status Bar @@ -87,17 +73,13 @@ class GBrowser(QtWidgets.QMainWindow): self.statusBar().addWidget(request_status) # Connect signals - back.clicked.connect(browser.backward) + back.clicked.connect(browser.back) forward.clicked.connect(browser.forward) - browser.sourceChanged.connect(address.setUrl) - address.returnPressed.connect(browser.setRawSource) - browser.hoverUrlChanged.connect(self.set_status_url) - browser.resourceLoadedStatus.connect(request_status.setText) + browser.urlChanged.connect(address.setUrl) + address.returnPressed.connect(browser.load) + browser.page().linkHovered.connect(self.set_status_url) - # - browser.document().setDefaultStyleSheet(open('style.css').read()) - - browser.setSource(QtCore.QUrl(initial_url or 'gemini://gemini.circumlunar.space/')) + browser.load(QtCore.QUrl(initial_url)) settings = QtCore.QSettings("xcolour.net", "GeminiBrowser") self.restoreGeometry(settings.value("geometry")) @@ -117,6 +99,15 @@ class GBrowser(QtWidgets.QMainWindow): settings.setValue("windowState", self.saveState()) super().closeEvent(event) + +scheme = QtWebEngineCore.QWebEngineUrlScheme(b'gemini') +scheme.setDefaultPort(1965) +scheme.setFlags(QtWebEngineCore.QWebEngineUrlScheme.SecureScheme) +QtWebEngineCore.QWebEngineUrlScheme.registerScheme(scheme) app = QtWidgets.QApplication(sys.argv) -ex = GBrowser(sys.argv[1] if len(sys.argv) > 1 else None) -sys.exit(app.exec_()) +gem_handler = GeminiSchemeHandler() +profile = QtWebEngineCore.QWebEngineProfile() +profile.removeAllUrlSchemeHandlers() +profile.installUrlSchemeHandler(b'gemini', gem_handler) +ex = GBrowser(sys.argv[1] if len(sys.argv) > 1 else None, profile) +sys.exit(app.exec()) -- cgit v1.2.3