mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-07 09:25:33 +00:00
228 lines
10 KiB
Python
228 lines
10 KiB
Python
#!/usr/bin/python3
|
|
|
|
import logging
|
|
import os
|
|
import pathlib
|
|
|
|
import gi
|
|
|
|
gi.require_version('Gtk', '3.0')
|
|
|
|
from gi.repository import Gtk
|
|
|
|
from keyman_config import _
|
|
from keyman_config.get_kmp import (InstallLocation, get_keyboard_dir,
|
|
get_keyman_dir)
|
|
from keyman_config.keyboard_details import KeyboardDetailsView
|
|
from keyman_config.keyboard_layouts_model import Model
|
|
from keyman_config.kmpmetadata import get_fonts, parsemetadata
|
|
from keyman_config.keyboard_options_view import KeyboardOptionsView
|
|
from keyman_config.uninstall_kmp import uninstall_kmp
|
|
from keyman_config.welcome import WelcomeView
|
|
|
|
|
|
class KeyboardLayoutsWidget(Gtk.Box):
|
|
def __init__(self, parent, store, restart_func) -> None:
|
|
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
|
|
self.restart = restart_func
|
|
self.parent = parent
|
|
|
|
scrolledWindow = Gtk.ScrolledWindow()
|
|
self.pack_start(scrolledWindow, True, True, 0)
|
|
|
|
self.tree = Gtk.TreeView(store)
|
|
|
|
renderer = Gtk.CellRendererPixbuf()
|
|
# i18n: column header in table displaying installed keyboards
|
|
column = Gtk.TreeViewColumn(_("Icon"), renderer, pixbuf=Model.ICON)
|
|
self.tree.append_column(column)
|
|
renderer = Gtk.CellRendererText()
|
|
# i18n: column header in table displaying installed keyboards
|
|
column = Gtk.TreeViewColumn(_("Name"), renderer, text=Model.NAME)
|
|
self.tree.append_column(column)
|
|
# i18n: column header in table displaying installed keyboards
|
|
column = Gtk.TreeViewColumn(_("Version"), renderer, text=Model.VERSION)
|
|
self.tree.append_column(column)
|
|
# i18n: column header in table displaying installed keyboards
|
|
column = Gtk.TreeViewColumn(_("Area"), renderer, text=Model.AREA)
|
|
self.tree.append_column(column)
|
|
|
|
self.tree.set_tooltip_column(column=Model.INSTALLPATH)
|
|
|
|
select = self.tree.get_selection()
|
|
select.connect("changed", self.on_tree_selection_changed)
|
|
|
|
scrolledWindow.add(self.tree)
|
|
|
|
self.pack_start(self._add_keyboard_buttons(), False, False, 12)
|
|
|
|
def _add_keyboard_buttons(self):
|
|
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
|
|
|
|
bbox_top = Gtk.ButtonBox(spacing=12, orientation=Gtk.Orientation.VERTICAL)
|
|
bbox_top.set_layout(Gtk.ButtonBoxStyle.START)
|
|
|
|
self.uninstall_button = Gtk.Button.new_with_mnemonic(_("_Uninstall"))
|
|
self.uninstall_button.set_tooltip_text(_("Uninstall keyboard"))
|
|
self.uninstall_button.connect("clicked", self.on_uninstall_clicked)
|
|
self.uninstall_button.set_sensitive(False)
|
|
bbox_top.add(self.uninstall_button)
|
|
|
|
self.about_button = Gtk.Button.new_with_mnemonic(_("_About"))
|
|
self.about_button.set_tooltip_text(_("About keyboard"))
|
|
self.about_button.connect("clicked", self.on_about_clicked)
|
|
self.about_button.set_sensitive(False)
|
|
bbox_top.add(self.about_button)
|
|
|
|
self.help_button = Gtk.Button.new_with_mnemonic(_("_Help"))
|
|
self.help_button.set_tooltip_text(_("Help for keyboard"))
|
|
self.help_button.connect("clicked", self.on_kbd_help_clicked)
|
|
self.help_button.set_sensitive(False)
|
|
bbox_top.add(self.help_button)
|
|
|
|
self.options_button = Gtk.Button.new_with_mnemonic(_("_Options"))
|
|
self.options_button.set_tooltip_text(_("Settings for keyboard"))
|
|
self.options_button.connect("clicked", self.on_options_clicked)
|
|
self.options_button.set_sensitive(False)
|
|
bbox_top.add(self.options_button)
|
|
|
|
vbox.pack_start(bbox_top, False, False, 12)
|
|
return vbox
|
|
|
|
def on_tree_selection_changed(self, selection):
|
|
model, treeiter = selection.get_selected()
|
|
if treeiter is not None:
|
|
# sourcery skip: extract-method
|
|
self.uninstall_button.set_tooltip_text(
|
|
_("Uninstall keyboard {package}").format(package=model[treeiter][Model.NAME]))
|
|
self.help_button.set_tooltip_text(
|
|
_("Help for keyboard {package}").format(package=model[treeiter][Model.NAME]))
|
|
self.about_button.set_tooltip_text(
|
|
_("About keyboard {package}").format(package=model[treeiter][Model.NAME]))
|
|
self.options_button.set_tooltip_text(
|
|
_("Settings for keyboard {package}").format(package=model[treeiter][Model.NAME]))
|
|
logging.debug("You selected %s version %s", model[treeiter][Model.NAME], model[treeiter][Model.VERSION])
|
|
self.about_button.set_sensitive(True)
|
|
if model[treeiter][Model.LOCATION] == InstallLocation.User:
|
|
logging.debug("Enabling uninstall button for %s in %s",
|
|
model[treeiter][Model.PACKAGEID], model[treeiter][Model.LOCATION])
|
|
self.uninstall_button.set_sensitive(True)
|
|
else:
|
|
self.uninstall_button.set_sensitive(False)
|
|
logging.debug("Disabling uninstall button for %s in %s",
|
|
model[treeiter][Model.PACKAGEID], model[treeiter][Model.LOCATION])
|
|
# welcome file if it exists
|
|
if model[treeiter][Model.WELCOMEFILE]:
|
|
self.help_button.set_sensitive(True)
|
|
else:
|
|
self.help_button.set_sensitive(False)
|
|
# options file if it exists
|
|
if model[treeiter][Model.OPTIONSFILE]:
|
|
self.options_button.set_sensitive(True)
|
|
else:
|
|
self.options_button.set_sensitive(False)
|
|
else:
|
|
self.uninstall_button.set_tooltip_text(_("Uninstall keyboard"))
|
|
self.help_button.set_tooltip_text(_("Help for keyboard"))
|
|
self.about_button.set_tooltip_text(_("About keyboard"))
|
|
self.options_button.set_tooltip_text(_("Settings for keyboard"))
|
|
self.uninstall_button.set_sensitive(False)
|
|
self.about_button.set_sensitive(False)
|
|
self.help_button.set_sensitive(False)
|
|
self.options_button.set_sensitive(False)
|
|
|
|
def on_uninstall_clicked(self, button):
|
|
model, treeiter = self.tree.get_selection().get_selected()
|
|
if treeiter is None:
|
|
return
|
|
|
|
logging.info(f"Uninstall keyboard {model[treeiter][Model.PACKAGEID]}?")
|
|
dialog = Gtk.MessageDialog(self.parent, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO,
|
|
_("Uninstall keyboard package?"))
|
|
msg = _("Are you sure that you want to uninstall the {keyboard} keyboard?").format(
|
|
keyboard=model[treeiter][Model.NAME])
|
|
kbdir = get_keyboard_dir(InstallLocation.User, model[treeiter][Model.PACKAGEID])
|
|
kmpjson = os.path.join(kbdir, "kmp.json")
|
|
if os.path.isfile(kmpjson):
|
|
info, system, options, keyboards, files = parsemetadata(kmpjson, False)
|
|
if fontlist := self._get_font_list(files):
|
|
msg += "\n\n" + _("The following fonts will also be uninstalled:\n") + fontlist
|
|
dialog.format_secondary_text(msg)
|
|
response = dialog.run()
|
|
dialog.destroy()
|
|
if response == Gtk.ResponseType.YES:
|
|
logging.info(f"Uninstalling keyboard{model[treeiter][Model.NAME]}")
|
|
# can only uninstall with the gui from user area
|
|
msg = uninstall_kmp(model[treeiter][Model.PACKAGEID])
|
|
if msg != '':
|
|
md = Gtk.MessageDialog(self.parent, 0, Gtk.MessageType.ERROR,
|
|
Gtk.ButtonsType.OK,
|
|
_("Uninstalling keyboard failed.\n\nError message: ") + msg)
|
|
md.run()
|
|
md.destroy()
|
|
logging.info("need to restart window after uninstalling a keyboard")
|
|
self.restart()
|
|
elif response == Gtk.ResponseType.NO:
|
|
logging.info(f"Not uninstalling keyboard {model[treeiter][Model.NAME]}")
|
|
|
|
def _get_font_list(self, files):
|
|
if not (fonts := get_fonts(files)):
|
|
return None
|
|
fontlist = ""
|
|
for font in fonts:
|
|
if 'description' in font:
|
|
if fontlist != "":
|
|
fontlist = fontlist + "\n"
|
|
if font['description'][:5] == "Font ":
|
|
fontdesc = font['description'][5:]
|
|
else:
|
|
fontdesc = font['description']
|
|
fontlist = fontlist + fontdesc
|
|
return fontlist
|
|
|
|
def on_about_clicked(self, button):
|
|
model, treeiter = self.tree.get_selection().get_selected()
|
|
if treeiter is not None and model[treeiter] is not None:
|
|
logging.info(f"Show keyboard details of {model[treeiter][Model.NAME]}")
|
|
areapath = get_keyman_dir(model[treeiter][Model.LOCATION])
|
|
kmp = {
|
|
"name": model[treeiter][Model.NAME],
|
|
"version": model[treeiter][Model.VERSION],
|
|
"packageID": model[treeiter][Model.PACKAGEID],
|
|
"areapath": areapath
|
|
}
|
|
w = KeyboardDetailsView(self.parent, kmp)
|
|
w.run()
|
|
w.destroy()
|
|
|
|
def on_kbd_help_clicked(self, button):
|
|
model, treeiter = self.tree.get_selection().get_selected()
|
|
if treeiter is not None:
|
|
logging.info("Open welcome.htm for %s if available", model[treeiter][Model.NAME])
|
|
welcome_file = model[treeiter][Model.WELCOMEFILE]
|
|
if welcome_file and os.path.isfile(welcome_file):
|
|
uri_path = pathlib.Path(welcome_file).as_uri()
|
|
logging.info(f"opening {uri_path}")
|
|
w = WelcomeView(self.parent, uri_path, model[treeiter][Model.PACKAGEID])
|
|
w.run()
|
|
w.destroy()
|
|
else:
|
|
logging.info("welcome.htm not available")
|
|
|
|
def on_options_clicked(self, button):
|
|
model, treeiter = self.tree.get_selection().get_selected()
|
|
if treeiter is not None:
|
|
logging.info("Open options.htm for %s if available", model[treeiter][Model.NAME])
|
|
options_file = model[treeiter][Model.OPTIONSFILE]
|
|
if options_file and os.path.isfile(options_file):
|
|
# sourcery skip: extract-method
|
|
uri_path = pathlib.Path(options_file).as_uri()
|
|
logging.info(f"opening {uri_path}")
|
|
# TODO: Determine keyboardID
|
|
info = {"optionurl": uri_path, "packageID": model[treeiter]
|
|
[Model.PACKAGEID], "keyboardID": model[treeiter][Model.PACKAGEID]}
|
|
w = KeyboardOptionsView(info)
|
|
w.resize(800, 600)
|
|
w.show_all()
|
|
else:
|
|
logging.info("options.htm not available")
|