2019-06-13 18:27:53 +02:00
|
|
|
# Readability - plugin for Falkon
|
2019-06-20 18:22:03 +02:00
|
|
|
# Copyright (C) 2019 Juraj Oravec <sgd.orava@gmail.com>
|
2019-06-13 18:27:53 +02:00
|
|
|
#
|
|
|
|
# This program 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.
|
|
|
|
#
|
|
|
|
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2019-06-10 22:24:42 +02:00
|
|
|
import Falkon
|
2019-06-11 00:08:05 +02:00
|
|
|
import os
|
|
|
|
from PySide2 import QtCore, QtGui
|
2019-06-11 22:41:49 +02:00
|
|
|
from readability.settingsDialog import SettingsDialog
|
2019-06-13 18:26:48 +02:00
|
|
|
from readability.button import Button
|
2019-06-13 19:03:23 +02:00
|
|
|
from readability.str2bool import str2bool
|
2019-06-10 22:24:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
class Readability(Falkon.PluginInterface, QtCore.QObject):
|
2019-06-11 22:41:49 +02:00
|
|
|
config = None
|
2019-06-13 18:26:48 +02:00
|
|
|
view = None
|
|
|
|
buttons = None
|
2019-06-11 00:08:05 +02:00
|
|
|
|
2019-06-20 18:51:14 +02:00
|
|
|
style = ""
|
|
|
|
scriptReadability = ""
|
|
|
|
scriptToolbar = ""
|
|
|
|
scriptCall = ""
|
|
|
|
|
2019-06-10 22:24:42 +02:00
|
|
|
def init(self, state, settingsPath):
|
2019-06-11 22:41:49 +02:00
|
|
|
self.config = {
|
|
|
|
"settingsFile": os.path.join(settingsPath, "readability", "settings.ini"),
|
2019-06-13 19:03:23 +02:00
|
|
|
"icon": "dark",
|
2019-06-20 21:41:29 +02:00
|
|
|
"contextMenu": False,
|
|
|
|
"colorTheme": "sepia",
|
|
|
|
"font": "sans-serif",
|
|
|
|
"fontSize": 5
|
2019-06-11 22:41:49 +02:00
|
|
|
}
|
2019-06-13 18:26:48 +02:00
|
|
|
self.buttons = {}
|
2019-06-11 22:41:49 +02:00
|
|
|
self.loadSettings()
|
2019-06-13 18:26:48 +02:00
|
|
|
self.onConfigUpdate()
|
2019-06-11 22:41:49 +02:00
|
|
|
|
2019-06-10 22:24:42 +02:00
|
|
|
plugins = Falkon.MainApplication.instance().plugins()
|
|
|
|
|
|
|
|
plugins.mainWindowCreated.connect(self.onMainWindowCreated)
|
2019-06-11 00:08:05 +02:00
|
|
|
plugins.mainWindowDeleted.connect(self.onMainWindowDeleted)
|
2019-06-10 22:24:42 +02:00
|
|
|
|
|
|
|
if state == Falkon.PluginInterface.LateInitState:
|
|
|
|
for window in Falkon.MainApplication.instance().windows():
|
|
|
|
self.onMainWindowCreated(window)
|
|
|
|
|
|
|
|
def unload(self):
|
|
|
|
for window in Falkon.MainApplication.instance().windows():
|
2019-06-11 00:08:05 +02:00
|
|
|
self.onMainWindowDeleted(window)
|
2019-06-10 22:24:42 +02:00
|
|
|
|
|
|
|
def testPlugin(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def onMainWindowCreated(self, window):
|
2019-06-13 18:26:48 +02:00
|
|
|
button = Button(self.config["icon"])
|
|
|
|
button.clicked.connect(lambda: self.makeReadability(button.webView()))
|
|
|
|
|
|
|
|
window.navigationBar().addToolButton(button)
|
|
|
|
self.buttons[window] = button
|
2019-06-10 22:24:42 +02:00
|
|
|
|
2019-06-11 00:08:05 +02:00
|
|
|
def onMainWindowDeleted(self, window):
|
2019-06-20 12:47:03 +02:00
|
|
|
if window not in self.buttons:
|
|
|
|
return
|
|
|
|
|
|
|
|
button = self.buttons[window]
|
|
|
|
window.navigationBar().removeToolButton(button)
|
|
|
|
del self.buttons[window]
|
2019-06-10 22:24:42 +02:00
|
|
|
|
2019-06-11 00:08:05 +02:00
|
|
|
def populateWebViewMenu(self, menu, view, hitTestResult):
|
2019-06-13 19:03:23 +02:00
|
|
|
if not self.config["contextMenu"]:
|
|
|
|
return
|
|
|
|
|
2019-06-11 00:08:05 +02:00
|
|
|
self.view = view
|
|
|
|
|
|
|
|
if (hitTestResult.imageUrl().isEmpty()
|
|
|
|
and hitTestResult.linkUrl().isEmpty()
|
|
|
|
and hitTestResult.mediaUrl().isEmpty()
|
|
|
|
and not hitTestResult.isContentEditable()
|
|
|
|
and not hitTestResult.isContentSelected()):
|
2019-06-11 22:41:49 +02:00
|
|
|
icon = "icon-light.png" if self.config["icon"] == "light" else "icon-dark.png"
|
2019-06-11 00:08:05 +02:00
|
|
|
menu.addAction(
|
2019-06-11 22:41:49 +02:00
|
|
|
QtGui.QIcon(os.path.join(os.path.dirname(__file__), "data", icon)),
|
2019-06-11 00:08:05 +02:00
|
|
|
"Readability",
|
|
|
|
self.makeReadability
|
|
|
|
)
|
|
|
|
|
2019-06-20 18:51:14 +02:00
|
|
|
def loadStyle(self):
|
2019-06-11 00:08:05 +02:00
|
|
|
dataDir = os.path.join(os.path.dirname(__file__), "data")
|
|
|
|
|
|
|
|
iconClose = Falkon.QzTools.pixmapToDataUrl(
|
|
|
|
QtGui.QPixmap(os.path.join(dataDir, "RM-close.png"))
|
|
|
|
).toString()
|
|
|
|
iconCloseHover = Falkon.QzTools.pixmapToDataUrl(
|
|
|
|
QtGui.QPixmap(os.path.join(dataDir, "RM-close-hover.png"))
|
|
|
|
).toString()
|
|
|
|
iconDelete = Falkon.QzTools.pixmapToDataUrl(
|
|
|
|
QtGui.QPixmap(os.path.join(dataDir, "RM-Delete-24x24.png"))
|
|
|
|
).toString()
|
|
|
|
iconPlus = Falkon.QzTools.pixmapToDataUrl(
|
|
|
|
QtGui.QPixmap(os.path.join(dataDir, "RM-Plus-24x24.png"))
|
|
|
|
).toString()
|
|
|
|
iconMinus = Falkon.QzTools.pixmapToDataUrl(
|
|
|
|
QtGui.QPixmap(os.path.join(dataDir, "RM-Minus-24x24.png"))
|
|
|
|
).toString()
|
|
|
|
iconArrow = Falkon.QzTools.readAllFileContents(
|
|
|
|
os.path.join(dataDir, "RM-Type-Controls-Arrow.png")
|
|
|
|
)
|
|
|
|
iconControls = Falkon.QzTools.pixmapToDataUrl(
|
|
|
|
QtGui.QPixmap(os.path.join(dataDir, "RM-Type-Controls-24x24.png"))
|
|
|
|
).toString()
|
|
|
|
|
|
|
|
css = Falkon.QzTools.readAllFileContents(
|
|
|
|
os.path.join(dataDir, "style.css")
|
|
|
|
).replace("\n", "")
|
2019-06-20 18:17:12 +02:00
|
|
|
css = css.replace("{iconClose}", iconClose)
|
|
|
|
css = css.replace("{iconCloseHover}", iconCloseHover)
|
|
|
|
css = css.replace("{iconDelete}", iconDelete)
|
|
|
|
css = css.replace("{iconPlus}", iconPlus)
|
|
|
|
css = css.replace("{iconMinus}", iconMinus)
|
|
|
|
css = css.replace("{iconArrow}", iconArrow)
|
|
|
|
css = css.replace("{iconControls}", iconControls)
|
2019-06-11 00:08:05 +02:00
|
|
|
|
2019-06-20 18:51:14 +02:00
|
|
|
return css
|
|
|
|
|
|
|
|
def makeReadability(self, view=None):
|
|
|
|
if view:
|
|
|
|
self.view = view
|
|
|
|
|
|
|
|
dataDir = os.path.join(os.path.dirname(__file__), "data")
|
|
|
|
|
|
|
|
if not self.style:
|
|
|
|
self.style = self.loadStyle()
|
|
|
|
if not self.scriptReadability:
|
|
|
|
self.scriptReadability = Falkon.QzTools.readAllFileContents(
|
|
|
|
os.path.join(dataDir, "Readability.js")
|
|
|
|
)
|
|
|
|
if not self.scriptToolbar:
|
|
|
|
self.scriptToolbar = Falkon.QzTools.readAllFileContents(
|
|
|
|
os.path.join(dataDir, "Toolbar.js")
|
|
|
|
)
|
|
|
|
if not self.scriptCall:
|
|
|
|
self.scriptCall = Falkon.QzTools.readAllFileContents(
|
|
|
|
os.path.join(dataDir, "Call.js")
|
|
|
|
)
|
|
|
|
self.scriptCall = self.scriptCall.replace("{readability.js}", self.scriptReadability)
|
|
|
|
self.scriptCall = self.scriptCall.replace("{toolbar.js}", self.scriptToolbar)
|
|
|
|
self.scriptCall = self.scriptCall.replace("{style.css}", self.style)
|
2019-06-11 00:08:05 +02:00
|
|
|
|
2019-06-20 21:41:29 +02:00
|
|
|
initConfigScript = "initConfig('{}', '{}', {});".format(
|
|
|
|
self.config["colorTheme"],
|
|
|
|
self.config["font"],
|
|
|
|
self.config["fontSize"]
|
|
|
|
)
|
|
|
|
|
|
|
|
self.view.page().runJavaScript(
|
|
|
|
self.scriptCall + initConfigScript,
|
|
|
|
Falkon.WebPage.SafeJsWorld
|
|
|
|
)
|
2019-06-11 00:08:05 +02:00
|
|
|
|
2019-06-11 22:41:49 +02:00
|
|
|
def showSettings(self, parent):
|
|
|
|
settings = SettingsDialog(self.config, parent)
|
|
|
|
settings.accepted.connect(self.saveSettings)
|
2019-06-13 18:26:48 +02:00
|
|
|
settings.accepted.connect(self.onConfigUpdate)
|
2019-06-11 22:41:49 +02:00
|
|
|
settings.exec_()
|
|
|
|
|
|
|
|
def saveSettings(self):
|
|
|
|
settings = QtCore.QSettings(self.config["settingsFile"], QtCore.QSettings.IniFormat)
|
|
|
|
|
|
|
|
settings.beginGroup("Readability")
|
|
|
|
settings.setValue("icon", self.config["icon"])
|
2019-06-13 19:03:23 +02:00
|
|
|
settings.setValue("showInContextMenu", self.config["contextMenu"])
|
2019-06-20 21:41:29 +02:00
|
|
|
settings.setValue("colorTheme", self.config["colorTheme"])
|
|
|
|
settings.setValue("font", self.config["font"])
|
|
|
|
settings.setValue("fontSize", self.config["fontSize"])
|
2019-06-11 22:41:49 +02:00
|
|
|
settings.endGroup()
|
|
|
|
|
|
|
|
settings.sync()
|
|
|
|
|
|
|
|
def loadSettings(self):
|
|
|
|
settings = QtCore.QSettings(self.config["settingsFile"], QtCore.QSettings.IniFormat)
|
|
|
|
|
|
|
|
settings.beginGroup("Readability")
|
|
|
|
self.config["icon"] = str(settings.value("icon", self.config["icon"]))
|
2019-06-13 19:03:23 +02:00
|
|
|
self.config["contextMenu"] = str2bool(
|
|
|
|
settings.value("showInContextMenu", self.config["contextMenu"])
|
|
|
|
)
|
2019-06-20 21:41:29 +02:00
|
|
|
self.config["colorTheme"] = str(settings.value("colorTheme", self.config["colorTheme"]))
|
|
|
|
self.config["font"] = str(settings.value("font", self.config["font"]))
|
|
|
|
self.config["fontSize"] = int(settings.value("fontSize", self.config["fontSize"]))
|
2019-06-11 22:41:49 +02:00
|
|
|
settings.endGroup()
|
|
|
|
|
2019-06-13 18:26:48 +02:00
|
|
|
def onConfigUpdate(self):
|
|
|
|
for _, button in self.buttons.items():
|
|
|
|
button.updateIcon(self.config["icon"])
|
|
|
|
|
2019-06-10 22:24:42 +02:00
|
|
|
|
|
|
|
Falkon.registerPlugin(Readability())
|