2019-02-05 04:59:03 +01:00
|
|
|
# Copyright: Ankitects Pty Ltd and contributors
|
2012-12-21 08:51:59 +01:00
|
|
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
2021-04-14 10:22:02 +02:00
|
|
|
|
2019-12-21 07:53:17 +01:00
|
|
|
import platform
|
2020-02-03 02:17:10 +01:00
|
|
|
import time
|
2012-12-21 08:51:59 +01:00
|
|
|
|
|
|
|
import aqt.forms
|
2020-12-18 21:34:42 +01:00
|
|
|
from anki.lang import without_unicode_isolation
|
2021-10-25 06:50:13 +02:00
|
|
|
from anki.utils import version_with_build
|
2020-02-04 02:46:57 +01:00
|
|
|
from aqt.addons import AddonManager, AddonMeta
|
2019-12-20 10:19:03 +01:00
|
|
|
from aqt.qt import *
|
2021-03-26 05:38:15 +01:00
|
|
|
from aqt.utils import disable_help_button, supportText, tooltip, tr
|
2019-12-20 10:19:03 +01:00
|
|
|
|
2017-06-26 05:05:11 +02:00
|
|
|
|
|
|
|
class ClosableQDialog(QDialog):
|
2021-02-01 14:28:21 +01:00
|
|
|
def reject(self) -> None:
|
2017-08-16 04:45:33 +02:00
|
|
|
aqt.dialogs.markClosed("About")
|
2017-06-26 05:05:11 +02:00
|
|
|
QDialog.reject(self)
|
|
|
|
|
2021-02-01 14:28:21 +01:00
|
|
|
def accept(self) -> None:
|
2017-08-16 04:45:33 +02:00
|
|
|
aqt.dialogs.markClosed("About")
|
2017-06-26 05:05:11 +02:00
|
|
|
QDialog.accept(self)
|
2012-12-21 08:51:59 +01:00
|
|
|
|
2021-02-02 15:00:29 +01:00
|
|
|
def closeWithCallback(self, callback: Callable[[], None]) -> None:
|
2017-08-16 04:45:33 +02:00
|
|
|
self.reject()
|
|
|
|
callback()
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2021-02-02 15:00:29 +01:00
|
|
|
def show(mw: aqt.AnkiQt) -> QDialog:
|
2017-06-26 05:05:11 +02:00
|
|
|
dialog = ClosableQDialog(mw)
|
2021-01-07 05:24:49 +01:00
|
|
|
disable_help_button(dialog)
|
2021-03-05 04:07:52 +01:00
|
|
|
mw.garbage_collect_on_dialog_finish(dialog)
|
2012-12-21 08:51:59 +01:00
|
|
|
abt = aqt.forms.about.Ui_About()
|
|
|
|
abt.setupUi(dialog)
|
2019-02-24 14:55:55 +01:00
|
|
|
|
|
|
|
# Copy debug info
|
|
|
|
######################################################################
|
2020-02-04 08:06:50 +01:00
|
|
|
|
|
|
|
def addon_fmt(addmgr: AddonManager, addon: AddonMeta) -> str:
|
|
|
|
if addon.installed_at:
|
|
|
|
installed = time.strftime(
|
|
|
|
"%Y-%m-%dT%H:%M", time.localtime(addon.installed_at)
|
|
|
|
)
|
2020-02-03 02:17:10 +01:00
|
|
|
else:
|
2020-02-04 08:06:50 +01:00
|
|
|
installed = "0"
|
|
|
|
if addon.provided_name:
|
|
|
|
name = addon.provided_name
|
2020-02-03 02:17:10 +01:00
|
|
|
else:
|
2020-02-04 08:06:50 +01:00
|
|
|
name = "''"
|
|
|
|
user = addmgr.getConfig(addon.dir_name)
|
|
|
|
default = addmgr.addonConfigDefaults(addon.dir_name)
|
2020-02-03 02:17:10 +01:00
|
|
|
if user == default:
|
2020-02-04 08:06:50 +01:00
|
|
|
modified = "''"
|
2020-02-03 02:17:10 +01:00
|
|
|
else:
|
2020-02-04 08:06:50 +01:00
|
|
|
modified = "mod"
|
|
|
|
return f"{name} ['{addon.dir_name}', {installed}, '{addon.human_version}', {modified}]"
|
2020-02-03 02:17:10 +01:00
|
|
|
|
2021-02-01 14:28:21 +01:00
|
|
|
def onCopy() -> None:
|
2019-02-24 14:55:55 +01:00
|
|
|
addmgr = mw.addonManager
|
2020-02-03 02:17:10 +01:00
|
|
|
active = []
|
|
|
|
activeids = []
|
|
|
|
inactive = []
|
2020-02-04 08:06:50 +01:00
|
|
|
for addon in addmgr.all_addon_meta():
|
|
|
|
if addon.enabled:
|
|
|
|
active.append(addon_fmt(addmgr, addon))
|
|
|
|
if addon.ankiweb_id():
|
|
|
|
activeids.append(addon.dir_name)
|
2020-02-03 02:17:10 +01:00
|
|
|
else:
|
2020-02-04 08:06:50 +01:00
|
|
|
inactive.append(addon_fmt(addmgr, addon))
|
2020-02-03 02:17:10 +01:00
|
|
|
newline = "\n"
|
|
|
|
info = f"""
|
|
|
|
{supportText()}
|
|
|
|
|
|
|
|
===Add-ons (active)===
|
|
|
|
(add-on provided name [Add-on folder, installed at, version, is config changed])
|
|
|
|
{newline.join(sorted(active))}
|
|
|
|
|
2020-02-04 08:06:41 +01:00
|
|
|
===IDs of active AnkiWeb add-ons===
|
2020-02-03 02:17:10 +01:00
|
|
|
{" ".join(activeids)}
|
|
|
|
|
|
|
|
===Add-ons (inactive)===
|
|
|
|
(add-on provided name [Add-on folder, installed at, version, is config changed])
|
|
|
|
{newline.join(sorted(inactive))}
|
|
|
|
"""
|
2021-02-11 01:09:06 +01:00
|
|
|
info = f" {' '.join(info.splitlines(True))}"
|
2019-02-24 14:55:55 +01:00
|
|
|
QApplication.clipboard().setText(info)
|
2021-03-26 04:48:26 +01:00
|
|
|
tooltip(tr.about_copied_to_clipboard(), parent=dialog)
|
2019-02-24 14:55:55 +01:00
|
|
|
|
2021-03-26 04:48:26 +01:00
|
|
|
btn = QPushButton(tr.about_copy_debug_info())
|
2020-05-04 05:23:08 +02:00
|
|
|
qconnect(btn.clicked, onCopy)
|
2021-10-05 05:53:01 +02:00
|
|
|
abt.buttonBox.addButton(btn, QDialogButtonBox.ButtonRole.ActionRole)
|
|
|
|
abt.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setFocus()
|
2019-02-24 14:55:55 +01:00
|
|
|
|
2021-11-29 03:31:37 +01:00
|
|
|
# WebView cleanup
|
|
|
|
######################################################################
|
|
|
|
|
|
|
|
def on_dialog_destroyed() -> None:
|
|
|
|
abt.label.cleanup()
|
|
|
|
abt.label = None
|
|
|
|
|
|
|
|
qconnect(dialog.destroyed, on_dialog_destroyed)
|
|
|
|
|
2019-02-24 14:55:55 +01:00
|
|
|
# WebView contents
|
|
|
|
######################################################################
|
2018-10-25 07:43:17 +02:00
|
|
|
abouttext = "<center><img src='/_anki/imgs/anki-logo-thin.png'></center>"
|
2021-03-26 04:48:26 +01:00
|
|
|
abouttext += f"<p>{tr.about_anki_is_a_friendly_intelligent_spaced()}"
|
|
|
|
abouttext += f"<p>{tr.about_anki_is_licensed_under_the_agpl3()}"
|
2021-10-25 06:50:13 +02:00
|
|
|
abouttext += f"<p>{tr.about_version(val=version_with_build())}<br>"
|
2019-12-23 01:34:10 +01:00
|
|
|
abouttext += ("Python %s Qt %s PyQt %s<br>") % (
|
|
|
|
platform.python_version(),
|
|
|
|
QT_VERSION_STR,
|
|
|
|
PYQT_VERSION_STR,
|
|
|
|
)
|
2020-12-18 21:34:42 +01:00
|
|
|
abouttext += (
|
2021-03-26 05:21:04 +01:00
|
|
|
without_unicode_isolation(tr.about_visit_website(val=aqt.appWebsite))
|
2020-12-18 21:34:42 +01:00
|
|
|
+ "</span>"
|
|
|
|
)
|
2017-06-26 05:05:11 +02:00
|
|
|
|
|
|
|
# automatically sorted; add new lines at the end
|
2019-12-23 01:34:10 +01:00
|
|
|
allusers = sorted(
|
|
|
|
(
|
|
|
|
"Aaron Harsh",
|
|
|
|
"Alex Fraser",
|
|
|
|
"Andreas Klauer",
|
|
|
|
"Andrew Wright",
|
|
|
|
"Aristotelis P.",
|
|
|
|
"Bernhard Ibertsberger",
|
|
|
|
"C. van Rooyen",
|
|
|
|
"Charlene Barina",
|
|
|
|
"Christian Krause",
|
|
|
|
"Christian Rusche",
|
|
|
|
"Dave Druelinger",
|
|
|
|
"David Smith",
|
|
|
|
"Dmitry Mikheev",
|
|
|
|
"Dotan Cohen",
|
|
|
|
"Emilio Wuerges",
|
|
|
|
"Emmanuel Jarri",
|
|
|
|
"Frank Harper",
|
|
|
|
"Gregor Skumavc",
|
|
|
|
"Guillem Palau Salvà",
|
|
|
|
"H. Mijail",
|
|
|
|
"Henrik Enggaard Hansen",
|
|
|
|
"Houssam Salem",
|
|
|
|
"Ian Lewis",
|
|
|
|
"Immanuel Asmus",
|
|
|
|
"Iroiro",
|
|
|
|
"Jarvik7",
|
|
|
|
"Jin Eun-Deok",
|
|
|
|
"Jo Nakashima",
|
|
|
|
"Johanna Lindh",
|
|
|
|
"Joseph Lorimer",
|
|
|
|
"Julien Baley",
|
|
|
|
"Jussi Määttä",
|
|
|
|
"Kieran Clancy",
|
|
|
|
"LaC",
|
|
|
|
"Laurent Steffan",
|
|
|
|
"Luca Ban",
|
|
|
|
"Luciano Esposito",
|
|
|
|
"Marco Giancotti",
|
|
|
|
"Marcus Rubeus",
|
|
|
|
"Mari Egami",
|
|
|
|
"Mark Wilbur",
|
|
|
|
"Matthew Duggan",
|
|
|
|
"Matthew Holtz",
|
|
|
|
"Meelis Vasser",
|
|
|
|
"Michael Jürges",
|
|
|
|
"Michael Keppler",
|
|
|
|
"Michael Montague",
|
|
|
|
"Michael Penkov",
|
|
|
|
"Michal Čadil",
|
|
|
|
"Morteza Salehi",
|
|
|
|
"Nathanael Law",
|
|
|
|
"Nguyễn Hào Khôi",
|
|
|
|
"Nick Cook",
|
|
|
|
"Niklas Laxström",
|
|
|
|
"Norbert Nagold",
|
|
|
|
"Ole Guldberg",
|
|
|
|
"Pcsl88",
|
|
|
|
"Petr Michalec",
|
|
|
|
"Piotr Kubowicz",
|
|
|
|
"Richard Colley",
|
|
|
|
"Roland Sieker",
|
|
|
|
"Samson Melamed",
|
|
|
|
"Silja Ijas",
|
|
|
|
"Snezana Lukic",
|
|
|
|
"Soren Bjornstad",
|
|
|
|
"Stefaan De Pooter",
|
|
|
|
"Susanna Björverud",
|
|
|
|
"Sylvain Durand",
|
|
|
|
"Tacutu",
|
|
|
|
"Timm Preetz",
|
|
|
|
"Timo Paulssen",
|
|
|
|
"Ursus",
|
|
|
|
"Victor Suba",
|
|
|
|
"Volker Jansen",
|
|
|
|
"Volodymyr Goncharenko",
|
|
|
|
"Xtru",
|
|
|
|
"Ádám Szegi",
|
|
|
|
"赵金鹏",
|
|
|
|
"黃文龍",
|
|
|
|
"David Bailey",
|
|
|
|
"Arman High",
|
|
|
|
"Arthur Milchior",
|
2019-12-25 01:25:57 +01:00
|
|
|
"Rai (Michael Pokorny)",
|
2020-01-03 18:37:50 +01:00
|
|
|
"AMBOSS MD Inc.",
|
2020-01-15 09:33:32 +01:00
|
|
|
"Erez Volk",
|
2020-02-24 09:36:37 +01:00
|
|
|
"Tobias Predel",
|
2020-05-31 21:50:03 +02:00
|
|
|
"Thomas Kahn",
|
|
|
|
"zjosua",
|
|
|
|
"Ijgnd",
|
|
|
|
"Evandro Coan",
|
|
|
|
"Alan Du",
|
2020-08-27 03:24:13 +02:00
|
|
|
"ANH",
|
|
|
|
"Junseo Park",
|
2020-10-06 06:36:11 +02:00
|
|
|
"Gustavo Costa",
|
2020-11-29 03:00:00 +01:00
|
|
|
"余时行",
|
2020-12-05 07:11:47 +01:00
|
|
|
"叶峻峣",
|
2021-03-10 11:34:28 +01:00
|
|
|
"RumovZ",
|
2021-04-14 03:03:17 +02:00
|
|
|
"学习骇客",
|
2021-10-14 13:02:21 +02:00
|
|
|
"ready-research",
|
2021-12-07 00:01:30 +01:00
|
|
|
"Henrik Giesel",
|
|
|
|
"Yoonchae Lee",
|
|
|
|
"Hikaru Yoshiga",
|
|
|
|
"Matthias Metelka",
|
|
|
|
"Sergio Quintero",
|
|
|
|
"Nicholas Flint",
|
2019-12-23 01:34:10 +01:00
|
|
|
)
|
|
|
|
)
|
2017-06-26 05:05:11 +02:00
|
|
|
|
2021-03-26 05:38:15 +01:00
|
|
|
abouttext += "<p>" + tr.about_written_by_damien_elmes_with_patches(
|
|
|
|
cont=", ".join(allusers)
|
2020-11-22 05:57:53 +01:00
|
|
|
)
|
2021-03-26 04:48:26 +01:00
|
|
|
abouttext += f"<p>{tr.about_if_you_have_contributed_and_are()}"
|
|
|
|
abouttext += f"<p>{tr.about_a_big_thanks_to_all_the()}"
|
2018-10-25 07:47:17 +02:00
|
|
|
abt.label.setMinimumWidth(800)
|
|
|
|
abt.label.setMinimumHeight(600)
|
|
|
|
dialog.show()
|
2020-02-12 22:20:30 +01:00
|
|
|
abt.label.stdHtml(abouttext, js=[])
|
2017-06-26 05:05:11 +02:00
|
|
|
return dialog
|