#!/usr/bin/python3

# Keyboard details window

import logging
import json
from os import path
import qrcode
import tempfile

import gi
from gi.repository import Gtk

from keyman_config import KeymanComUrl, _, secure_lookup
from keyman_config.accelerators import init_accel
from keyman_config.kmpmetadata import parsemetadata

gi.require_version('Gtk', '3.0')

# basics: keyboard name, package version, description
# other things: filename (of kmx), ,
#    OSK availability, documentation availability, package copyright
# also: supported languages, fonts
# from kmx?: keyboard version, encoding, layout type

# there is data in kmp.inf/kmp.json
# there is possibly data in kbid.json (downloaded from api)


class KeyboardDetailsView(Gtk.Dialog):
    # TODO Display all the information that is available
    #    especially what is displayed for Keyman on Windows
    # TODO clean up file once have what we want
    def __init__(self, parent, kmp):
        # kmp has name, version, packageID, area
        if "keyboard" in kmp["name"].lower():
            wintitle = kmp["name"]
        else:
            wintitle = _("{name} keyboard").format(name=kmp["name"])
        Gtk.Dialog.__init__(self, wintitle, parent)
        init_accel(self)

        self.set_border_width(6)

        packageDir = path.join(kmp['areapath'], kmp['packageID'])
        kmp_json = path.join(packageDir, "kmp.json")
        info, system, options, keyboards, files = parsemetadata(kmp_json)

        if info is None:
            # Dialog when invalid metadata
            self.add_button(_("_Close"), Gtk.ResponseType.CLOSE)
            grid = Gtk.Grid()
            self.get_content_area().pack_start(grid, True, True, 12)
            lbl_invalid_metadata = Gtk.Label()
            lbl_invalid_metadata.set_text(_("ERROR: Keyboard metadata is damaged.\nPlease \"Uninstall\" and then \"Install\" the keyboard."))
            lbl_invalid_metadata.set_halign(Gtk.Align.END)
            grid.add(lbl_invalid_metadata)
            self.resize(700, 200)
            self.show_all()
            return

        kbdata = None
        jsonfile = path.join(packageDir, kmp['packageID'] + ".json")
        if path.isfile(jsonfile):
            try:
                with open(jsonfile, "r") as read_file:
                    kbdata = json.load(read_file)
            except Exception as e:
                logging.warning('Exception %s reading %s %s', type(e), jsonfile, e.args)

        grid = Gtk.Grid()
        # grid.set_column_homogeneous(True)

        # kbdatapath = path.join("/usr/local/share/keyman", kmp["id"], kmp["id"] + ".json")

        # Package info

        lbl_pkg_name = Gtk.Label()
        lbl_pkg_name.set_text(_("Package name:   "))
        lbl_pkg_name.set_halign(Gtk.Align.END)
        grid.add(lbl_pkg_name)
        prevlabel = lbl_pkg_name
        label = Gtk.Label()
        if secure_lookup(info, 'name', 'description'):
            label.set_text(secure_lookup(info, 'name', 'description'))
        label.set_halign(Gtk.Align.START)
        label.set_selectable(True)
        grid.attach_next_to(label, lbl_pkg_name, Gtk.PositionType.RIGHT, 1, 1)

        lbl_pkg_id = Gtk.Label()
        lbl_pkg_id.set_text(_("Package id:   "))
        lbl_pkg_id.set_halign(Gtk.Align.END)
        grid.attach_next_to(lbl_pkg_id, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
        prevlabel = lbl_pkg_id
        label = Gtk.Label()
        if secure_lookup(kmp, 'packageID'):
            label.set_text(kmp['packageID'])
        label.set_halign(Gtk.Align.START)
        label.set_selectable(True)
        grid.attach_next_to(label, lbl_pkg_id, Gtk.PositionType.RIGHT, 1, 1)

        lbl_pkg_vrs = Gtk.Label()
        lbl_pkg_vrs.set_text(_("Package version:   "))
        lbl_pkg_vrs.set_halign(Gtk.Align.END)
        grid.attach_next_to(lbl_pkg_vrs, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
        prevlabel = lbl_pkg_vrs
        label = Gtk.Label()
        if secure_lookup(info, 'version', 'description'):
            label.set_text(secure_lookup(info, 'version', 'description'))
        label.set_halign(Gtk.Align.START)
        label.set_selectable(True)
        grid.attach_next_to(label, lbl_pkg_vrs, Gtk.PositionType.RIGHT, 1, 1)

        if secure_lookup(kbdata, 'description'):
            lbl_pkg_desc = Gtk.Label()
            lbl_pkg_desc.set_text(_("Package description:   "))
            lbl_pkg_desc.set_halign(Gtk.Align.END)
            grid.attach_next_to(lbl_pkg_desc, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
            prevlabel = lbl_pkg_desc
            label = Gtk.Label()
            label.set_text(kbdata['description'])
            label.set_halign(Gtk.Align.START)
            label.set_selectable(True)
            label.set_line_wrap(80)
            grid.attach_next_to(label, lbl_pkg_desc, Gtk.PositionType.RIGHT, 1, 1)

        if secure_lookup(info, "author"):
            lbl_pkg_auth = Gtk.Label()
            lbl_pkg_auth.set_text(_("Package author:   "))
            lbl_pkg_auth.set_halign(Gtk.Align.END)
            grid.attach_next_to(lbl_pkg_auth, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
            prevlabel = lbl_pkg_auth
            label = Gtk.Label()
            if secure_lookup(info, 'author', 'description'):
                label.set_text(secure_lookup(info, 'author', 'description'))
            label.set_halign(Gtk.Align.START)
            label.set_selectable(True)
            grid.attach_next_to(label, lbl_pkg_auth, Gtk.PositionType.RIGHT, 1, 1)

        if secure_lookup(info, "copyright"):
            lbl_pkg_cpy = Gtk.Label()
            lbl_pkg_cpy.set_text(_("Package copyright:   "))
            lbl_pkg_cpy.set_halign(Gtk.Align.END)
            grid.attach_next_to(lbl_pkg_cpy, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
            prevlabel = lbl_pkg_cpy
            label = Gtk.Label()
            if secure_lookup(info, 'copyright', 'description'):
                label.set_text(secure_lookup(info, 'copyright', 'description'))
            label.set_halign(Gtk.Align.START)
            label.set_selectable(True)
            grid.attach_next_to(label, lbl_pkg_cpy, Gtk.PositionType.RIGHT, 1, 1)

        # Padding and full width horizontal divider
        lbl_pad = Gtk.Label()
        lbl_pad.set_text("")
        lbl_pad.set_halign(Gtk.Align.END)
        grid.attach_next_to(lbl_pad, prevlabel, Gtk.PositionType.BOTTOM, 2, 1)
        prevlabel = lbl_pad

        divider_pkg = Gtk.HSeparator()
        grid.attach_next_to(divider_pkg, prevlabel, Gtk.PositionType.BOTTOM, 2, 1)
        prevlabel = divider_pkg

        # Keyboard info for each keyboard

        if keyboards:
            for kbd in keyboards:
                kbdata = None
                jsonfile = path.join(packageDir, kbd['id'] + ".json")
                if path.isfile(jsonfile):
                    try:
                        with open(jsonfile, "r") as read_file:
                            kbdata = json.load(read_file)
                    except Exception as e:
                        logging.warning('Exception %s reading %s %s', type(e), jsonfile, e.args)

                # start with padding
                lbl_pad = Gtk.Label()
                lbl_pad.set_text("")
                lbl_pad.set_halign(Gtk.Align.END)
                grid.attach_next_to(lbl_pad, prevlabel, Gtk.PositionType.BOTTOM, 2, 1)
                prevlabel = lbl_pad

                # show the icon somewhere

                lbl_kbd_file = Gtk.Label()
                lbl_kbd_file.set_text(_("Keyboard filename:   "))
                lbl_kbd_file.set_halign(Gtk.Align.END)
                grid.attach_next_to(lbl_kbd_file, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                prevlabel = lbl_kbd_file
                label = Gtk.Label()
                label.set_text(path.join(packageDir, kbd['id'] + ".kmx"))
                label.set_halign(Gtk.Align.START)
                label.set_selectable(True)
                grid.attach_next_to(label, lbl_kbd_file, Gtk.PositionType.RIGHT, 1, 1)

                if kbdata and secure_lookup(kbdata, 'id') != secure_lookup(kmp, 'packageID'):
                    lbl_kbd_name = Gtk.Label()
                    lbl_kbd_name.set_text(_("Keyboard name:   "))
                    lbl_kbd_name.set_halign(Gtk.Align.END)
                    grid.attach_next_to(lbl_kbd_name, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                    prevlabel = lbl_kbd_name
                    label = Gtk.Label()
                    if secure_lookup(kbdata, 'name'):
                        label.set_text(kbdata['name'])
                    label.set_halign(Gtk.Align.START)
                    label.set_selectable(True)
                    grid.attach_next_to(label, lbl_kbd_name, Gtk.PositionType.RIGHT, 1, 1)

                    lbl_kbd_id = Gtk.Label()
                    lbl_kbd_id.set_text(_("Keyboard id:   "))
                    lbl_kbd_id.set_halign(Gtk.Align.END)
                    grid.attach_next_to(lbl_kbd_id, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                    prevlabel = lbl_kbd_id
                    label = Gtk.Label()
                    if secure_lookup(kbdata, 'id'):
                        label.set_text(kbdata['id'])
                    label.set_halign(Gtk.Align.START)
                    label.set_selectable(True)
                    grid.attach_next_to(label, lbl_kbd_id, Gtk.PositionType.RIGHT, 1, 1)

                    lbl_kbd_vrs = Gtk.Label()
                    lbl_kbd_vrs.set_text(_("Keyboard version:   "))
                    lbl_kbd_vrs.set_halign(Gtk.Align.END)
                    grid.attach_next_to(lbl_kbd_vrs, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                    prevlabel = lbl_kbd_vrs
                    label = Gtk.Label()
                    if secure_lookup(kbdata, 'version'):
                        label.set_text(kbdata['version'])
                    label.set_halign(Gtk.Align.START)
                    label.set_selectable(True)
                    grid.attach_next_to(label, lbl_kbd_vrs, Gtk.PositionType.RIGHT, 1, 1)

                    if secure_lookup(info, "author"):
                        lbl_kbd_auth = Gtk.Label()
                        lbl_kbd_auth.set_text(_("Keyboard author:   "))
                        lbl_kbd_auth.set_halign(Gtk.Align.END)
                        grid.attach_next_to(lbl_kbd_auth, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                        prevlabel = lbl_kbd_auth
                        label = Gtk.Label()
                        if secure_lookup(kbdata, 'authorName'):
                            label.set_text(kbdata['authorName'])
                        label.set_halign(Gtk.Align.START)
                        label.set_selectable(True)
                        grid.attach_next_to(label, lbl_kbd_auth, Gtk.PositionType.RIGHT, 1, 1)

                    lbl_kbd_lic = Gtk.Label()
                    lbl_kbd_lic.set_text(_("Keyboard license:   "))
                    lbl_kbd_lic.set_halign(Gtk.Align.END)
                    grid.attach_next_to(lbl_kbd_lic, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                    prevlabel = lbl_kbd_lic
                    label = Gtk.Label()
                    if secure_lookup(kbdata, 'license'):
                        label.set_text(kbdata['license'])
                    label.set_halign(Gtk.Align.START)
                    label.set_selectable(True)
                    grid.attach_next_to(label, lbl_kbd_lic, Gtk.PositionType.RIGHT, 1, 1)

                    lbl_kbd_desc = Gtk.Label()
                    lbl_kbd_desc.set_text(_("Keyboard description:   "))
                    lbl_kbd_desc.set_halign(Gtk.Align.END)
                    grid.attach_next_to(lbl_kbd_desc, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                    prevlabel = lbl_kbd_desc
                    label = Gtk.Label()
                    if secure_lookup(kbdata, 'description'):
                        label.set_text(kbdata['description'])
                    label.set_halign(Gtk.Align.START)
                    label.set_selectable(True)
                    label.set_line_wrap(80)
                    grid.attach_next_to(label, lbl_kbd_desc, Gtk.PositionType.RIGHT, 1, 1)

                    # Padding and full width horizontal divider
                    lbl_pad = Gtk.Label()
                    lbl_pad.set_text("")
                    lbl_pad.set_halign(Gtk.Align.END)
                    grid.attach_next_to(lbl_pad, prevlabel, Gtk.PositionType.BOTTOM, 2, 1)
                    prevlabel = lbl_pad

                    divider_pkg = Gtk.HSeparator()
                    grid.attach_next_to(divider_pkg, prevlabel, Gtk.PositionType.BOTTOM, 2, 1)

                    # label7 = Gtk.Label()
                    # label7.set_text(_("On Screen Keyboard:   "))
                    # label7.set_halign(Gtk.Align.END)
                    # grid.attach_next_to(label7, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                    # prevlabel = label7
                    # # label = Gtk.Label()
                    # # label.set_text(secure_lookup(info, 'version', 'description'))
                    # # label.set_halign(Gtk.Align.START)
                    # # label.set_selectable(True)
                    # # grid.attach_next_to(label, label7, Gtk.PositionType.RIGHT, 1, 1)

                    # label8 = Gtk.Label()
                    # label8.set_text(_("Documentation:   "))
                    # label8.set_halign(Gtk.Align.END)
                    # grid.attach_next_to(label8, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                    # prevlabel = label8
                    # #TODO need to know which area keyboard is installed in to show this
                    # # label = Gtk.Label()
                    # # welcome_file = path.join("/usr/local/share/doc/keyman", kmp["id"], "welcome.htm")
                    # # if path.isfile(welcome_file):
                    # #     label.set_text(_("Installed"))
                    # # else:
                    # #     label.set_text(_("Not installed"))
                    # # label.set_halign(Gtk.Align.START)
                    # # label.set_selectable(True)
                    # # grid.attach_next_to(label, label8, Gtk.PositionType.RIGHT, 1, 1)

                    # label9 = Gtk.Label()
                    # # stored in kmx
                    # label9.set_text(_("Message:   "))
                    # label9.set_halign(Gtk.Align.END)
                    # grid.attach_next_to(label9, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
                    # prevlabel = label9
                    # label = Gtk.Label()
                    # label.set_line_wrap(True)
                    # label.set_text(
                    #     "This keyboard is distributed under the MIT license (MIT) as described somewhere")
                    # #label.set_text(kmp["description"])
                    # label.set_halign(Gtk.Align.START)
                    # label.set_selectable(True)
                    # grid.attach_next_to(label, label9, Gtk.PositionType.RIGHT, 1, 1)

        # Add an entire row of padding
        lbl_pad = Gtk.Label()
        lbl_pad.set_text("")
        lbl_pad.set_halign(Gtk.Align.END)
        grid.attach_next_to(lbl_pad, prevlabel, Gtk.PositionType.BOTTOM, 2, 1)
        prevlabel = lbl_pad

        # If it doesn't exist, generate QR code to share keyboard package
        path_qr = path.join(tempfile.gettempdir(), kmp['packageID'] + '_qrcode.png')
        url = KeymanComUrl + "/go/keyboard/" + kmp['packageID'] + "/share"
        if not path.isfile(path_qr):
            qr = qrcode.QRCode(
                version=1,
                error_correction=qrcode.constants.ERROR_CORRECT_H,
                box_size=4,
                border=4)
            qr.add_data(url)
            qr.make(fit=True)

            img = qr.make_image()
            img.save(path_qr)

        # Display QR Code, spanning 2 columns so it will be centered
        image = Gtk.Image()
        image.set_from_file(path_qr)
        grid.attach_next_to(image, prevlabel, Gtk.PositionType.BOTTOM, 2, 1)

        lbl_share_kbd = Gtk.Label()
        lbl_share_kbd.set_markup(_("Scan this code to load this keyboard\non another device or <a href='{uri}'>share online</a>").format(uri=url))
        lbl_share_kbd.set_halign(Gtk.Align.CENTER)
        lbl_share_kbd.set_line_wrap(True)
        grid.attach_next_to(lbl_share_kbd, image, Gtk.PositionType.BOTTOM, 2, 1)
        prevlabel = lbl_share_kbd

        self.add_button(_("_Close"), Gtk.ResponseType.CLOSE)

        self.get_content_area().pack_start(grid, True, True, 12)
        self.resize(800, 450)
        self.show_all()

[(18, 'gi.require_version', 'gi.require_version', False, 'import gi\n'), (40, 'gi.repository.Gtk.Dialog.__init__', 'Gtk.Dialog.__init__', False, 'from gi.repository import Gtk\n'), (41, 'keyman_config.accelerators.init_accel', 'init_accel', False, 'from keyman_config.accelerators import init_accel\n'), (45, 'os.path.join', 'path.join', False, 'from os import path\n'), (46, 'os.path.join', 'path.join', False, 'from os import path\n'), (47, 'keyman_config.kmpmetadata.parsemetadata', 'parsemetadata', False, 'from keyman_config.kmpmetadata import parsemetadata\n'), (63, 'os.path.join', 'path.join', False, 'from os import path\n'), (64, 'os.path.isfile', 'path.isfile', False, 'from os import path\n'), (71, 'gi.repository.Gtk.Grid', 'Gtk.Grid', False, 'from gi.repository import Gtk\n'), (78, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (83, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (84, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (90, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (95, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (96, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (102, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (107, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (108, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (114, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (127, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (140, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (154, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (160, 'gi.repository.Gtk.HSeparator', 'Gtk.HSeparator', False, 'from gi.repository import Gtk\n'), (325, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (347, 'gi.repository.Gtk.Image', 'Gtk.Image', False, 'from gi.repository import Gtk\n'), (351, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (52, 'gi.repository.Gtk.Grid', 'Gtk.Grid', False, 'from gi.repository import Gtk\n'), (54, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (79, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (91, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (103, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (115, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (120, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (128, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (133, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (134, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (141, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (146, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (147, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (332, 'tempfile.gettempdir', 'tempfile.gettempdir', False, 'import tempfile\n'), (334, 'os.path.isfile', 'path.isfile', False, 'from os import path\n'), (335, 'qrcode.QRCode', 'qrcode.QRCode', False, 'import qrcode\n'), (358, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (51, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (55, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (85, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (109, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (116, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (129, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (142, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (169, 'os.path.join', 'path.join', False, 'from os import path\n'), (170, 'os.path.isfile', 'path.isfile', False, 'from os import path\n'), (178, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (186, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (191, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (39, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (67, 'json.load', 'json.load', False, 'import json\n'), (135, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (148, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (187, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (192, 'os.path.join', 'path.join', False, 'from os import path\n'), (198, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (203, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (204, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (210, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (215, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (216, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (222, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (227, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (228, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (234, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (247, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (252, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (253, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (259, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (264, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (265, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (273, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (279, 'gi.repository.Gtk.HSeparator', 'Gtk.HSeparator', False, 'from gi.repository import Gtk\n'), (352, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (197, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (197, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (199, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (211, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (223, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (235, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (240, 'gi.repository.Gtk.Label', 'Gtk.Label', False, 'from gi.repository import Gtk\n'), (241, 'keyman_config.secure_lookup', 'secure_lookup', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (248, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (260, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n'), (173, 'json.load', 'json.load', False, 'import json\n'), (236, 'keyman_config._', '_', False, 'from keyman_config import KeymanComUrl, _, secure_lookup\n')]