def __init__(self, parent, welcomeurl, keyboardname, newlyInstalled=False): self.accelerators = None if newlyInstalled: kbtitle = _("{name} installed").format(name=keyboardname) else: kbtitle = keyboardname self.welcomeurl = welcomeurl Gtk.Dialog.__init__(self, kbtitle, parent) init_accel(self) s = Gtk.ScrolledWindow() self.webview = WebKit2.WebView() self.webview.connect("decide-policy", self.doc_policy) self.webview.load_uri(welcomeurl) s.add(self.webview) self.get_content_area().pack_start(s, True, True, 0) hbox = Gtk.Box(spacing=12) self.get_content_area().pack_start(hbox, False, False, 6) button = Gtk.Button.new_with_mnemonic(_("Open in _Web browser")) button.connect("clicked", self.on_openweb_clicked) button.set_tooltip_text( _("Open in the default web browser to do things like printing")) hbox.pack_start(button, False, False, 12) button = Gtk.Button.new_with_mnemonic(_("_OK")) button.connect("clicked", self.on_ok_clicked) hbox.pack_end(button, False, False, 12) bind_accelerator(self.accelerators, button, '<Control>w') self.resize(800, 600) self.show_all()
def __init__(self, info): self.accelerators = None self.optionurl = info["optionurl"] self.packageID = info["packageID"] self.keyboardID = info["keyboardID"] kbtitle = _("{packageId} Settings").format(packageId=self.packageID) Gtk.Window.__init__(self, title=kbtitle) init_accel(self) vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) # Keyman Desktop gets current option settings from the registry. # Similarly, we'll read Keyman options from DConf and update optionurl info = {"packageID": self.packageID, "keyboardID": self.keyboardID} self.options = get_option(info) params = "" if self.options: # Convert dictionary to query params = "?" + urlencode(self.options) s = Gtk.ScrolledWindow() self.webview = WebKit2.WebView() self.webview.connect("decide-policy", self.doc_policy) self.webview.load_uri(self.optionurl + params) s.add(self.webview) vbox.pack_start(s, True, True, 0) hbox = Gtk.Box(spacing=12) vbox.pack_start(hbox, False, False, 6) self.add(vbox)
def on_installfile_clicked(self, button): logging.debug("Install from file clicked") dlg = Gtk.FileChooserDialog(_("Choose a kmp file..."), self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dlg.resize(640, 480) filter_text = Gtk.FileFilter() # i18n: file type in file selection dialog filter_text.set_name(_("KMP files")) filter_text.add_pattern("*.kmp") dlg.add_filter(filter_text) response = dlg.run() if response != Gtk.ResponseType.OK: dlg.destroy() return file = dlg.get_filename() dlg.destroy() self.restart(self.install_file(file))
def on_uninstall_clicked(self, button): model, treeiter = self.tree.get_selection().get_selected() if treeiter is not None: logging.info("Uninstall keyboard " + model[treeiter][3] + "?") dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Uninstall keyboard package?")) dialog.format_secondary_text( _("Are you sure that you want to uninstall the {keyboard} keyboard and its fonts?" ).format(keyboard=model[treeiter][1])) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: logging.info("Uninstalling keyboard" + model[treeiter][1]) # can only uninstall with the gui from user area uninstall_kmp(model[treeiter][3]) logging.info( "need to restart window after uninstalling a keyboard") self.restart() elif response == Gtk.ResponseType.NO: logging.info("Not uninstalling keyboard " + model[treeiter][1])
def __init__(self, parent=None): self.accelerators = None Gtk.Dialog.__init__(self, _("Download Keyman keyboards"), parent) self.parentWindow = parent self.downloadfile = None init_accel(self) s = Gtk.ScrolledWindow() self.webview = WebKit2.WebView() self.webview.connect("decide-policy", self._keyman_policy) url = KeymanComUrl + "/go/linux/" + __releaseversion__ + "/download-keyboards" self.webview.load_uri(url) s.add(self.webview) self.get_content_area().pack_start(s, True, True, 0) self.add_button(_("_Close"), Gtk.ResponseType.CLOSE) if self.parentWindow is not None: self.getinfo = GetInfo(self.parentWindow.incomplete_kmp) self.resize(800, 450) self.show_all()
def on_install_clicked(self, button): logging.info("Installing keyboard") try: install_kmp(self.kmpfile, self.online, language=self.language) if self.viewwindow: self.viewwindow.refresh_installed_kmp() keyboardid = os.path.basename(os.path.splitext(self.kmpfile)[0]) welcome_file = os.path.join(user_keyboard_dir(keyboardid), "welcome.htm") if os.path.isfile(welcome_file): uri_path = pathlib.Path(welcome_file).as_uri() logging.debug(uri_path) w = WelcomeView(self, uri_path, self.kbname, True) w.run() w.destroy() else: dialog = Gtk.MessageDialog( self, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, _("Keyboard {name} installed").format(name=self.kbname)) dialog.run() dialog.destroy() except InstallError as e: if e.status == InstallStatus.Abort: message = _("Keyboard {name} could not be installed.").format(name=self.kbname) \ + "\n\n" + _("Error Message:") + "\n %s" % (e.message) logging.error(message) message_type = Gtk.MessageType.ERROR else: message = _("Keyboard {name} could not be installed.").format(name=self.kbname) \ + "\n\n" + _("Warning Message:") + "\n %s" % (e.message) logging.warning(message) message_type = Gtk.MessageType.WARNING dialog = Gtk.MessageDialog(self, 0, message_type, Gtk.ButtonsType.OK, message) dialog.run() dialog.destroy() self.close()
def on_tree_selection_changed(self, selection): model, treeiter = selection.get_selected() if treeiter is not None: self.uninstall_button.set_tooltip_text( _("Uninstall keyboard {package}").format( package=model[treeiter][1])) self.help_button.set_tooltip_text( _("Help for keyboard {package}").format( package=model[treeiter][1])) self.about_button.set_tooltip_text( _("About keyboard {package}").format( package=model[treeiter][1])) self.options_button.set_tooltip_text( _("Settings for keyboard {package}").format( package=model[treeiter][1])) logging.debug("You selected %s version %s", model[treeiter][1], model[treeiter][2]) self.about_button.set_sensitive(True) if model[treeiter][4] == InstallArea.IA_USER: logging.debug("Enabling uninstall button for %s in %s", model[treeiter][3], model[treeiter][4]) self.uninstall_button.set_sensitive(True) else: self.uninstall_button.set_sensitive(False) logging.debug("Disabling uninstall button for %s in %s", model[treeiter][3], model[treeiter][4]) # welcome file if it exists if model[treeiter][5]: self.help_button.set_sensitive(True) else: self.help_button.set_sensitive(False) # options file if it exists if model[treeiter][6]: 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 install_kmp_shared(inputfile, online=False, language=None): """ Install a kmp file to /usr/local/share/keyman Args: inputfile (str): path to kmp file online (bool, default=False): whether to attempt to get online keyboard data """ check_keyman_dir( '/usr/local/share', _("You do not have permissions to install the keyboard files to the shared area " "/usr/local/share/keyman")) check_keyman_dir( '/usr/local/share/doc', _("You do not have permissions to install the documentation to the shared " "documentation area /usr/local/share/doc/keyman")) check_keyman_dir( '/usr/local/share/fonts', _("You do not have permissions to install the font files to the shared font area " "/usr/local/share/fonts")) packageID = extract_package_id(inputfile) packageDir = os.path.join('/usr/local/share/keyman', packageID) kmpdocdir = os.path.join('/usr/local/share/doc/keyman', packageID) kmpfontdir = os.path.join('/usr/local/share/fonts/keyman', packageID) if not os.path.isdir(packageDir): os.makedirs(packageDir) extract_kmp(inputfile, packageDir) # restart IBus so it knows about the keyboards being installed logging.debug("restarting IBus") restart_ibus() info, system, options, keyboards, files = get_metadata(packageDir) if keyboards: logging.info("Installing %s", info['name']['description']) if online: process_keyboard_data(packageID, packageDir) if len(keyboards) > 1: for kb in keyboards: if kb['id'] != packageID: process_keyboard_data(kb['id'], packageDir) for f in files: fpath = os.path.join(packageDir, f['name']) ftype = f['type'] if ftype == KMFileTypes.KM_DOC or ftype == KMFileTypes.KM_IMAGE: # Special handling of doc and images to hard link them into doc dir logging.info("Installing %s as documentation", f['name']) if not os.path.isdir(kmpdocdir): os.makedirs(kmpdocdir) os.link(fpath, os.path.join(kmpdocdir, f['name'])) elif ftype == KMFileTypes.KM_FONT: # Special handling of font to hard link it into font dir logging.info("Installing %s as font", f['name']) if not os.path.isdir(kmpfontdir): os.makedirs(kmpfontdir) os.link(fpath, os.path.join(kmpfontdir, f['name'])) elif ftype == KMFileTypes.KM_SOURCE: # TODO for the moment just leave it for ibus-kmfl to ignore if it doesn't load logging.info("Installing %s as keyman file", f['name']) elif ftype == KMFileTypes.KM_OSK: # Special handling to convert kvk into LDML logging.info( "Converting %s to LDML and installing both as as keyman file", f['name']) ldml = convert_kvk_to_ldml(fpath) name, ext = os.path.splitext(f['name']) ldmlfile = os.path.join(packageDir, name + ".ldml") output_ldml(ldmlfile, ldml) elif ftype == KMFileTypes.KM_ICON: # Special handling of icon to convert to PNG logging.info( "Converting %s to PNG and installing both as keyman files", f['name']) checkandsaveico(fpath) elif ftype == KMFileTypes.KM_KMX: # Sanitize keyboard filename if not lower case kmx_id, ext = os.path.splitext(os.path.basename(f['name'])) for kb in keyboards: if kmx_id.lower() == kb['id'] and kmx_id != kb['id']: os.rename(os.path.join(packageDir, f['name']), os.path.join(packageDir, kb['id'] + '.kmx')) fpath = os.path.join(packageDir, kb['id'] + '.kmx') extractico(fpath) install_keyboards_to_ibus(keyboards, packageDir, language) else: logging.error( "install_kmp.py: error: No kmp.json or kmp.inf found in %s", inputfile) logging.info("Contents of %s:", inputfile) for o in os.listdir(packageDir): logging.info(o) rmtree(packageDir) message = _( "install_kmp.py: error: No kmp.json or kmp.inf found in {package}" ).format(package=inputfile) raise InstallError(InstallStatus.Abort, message)
def install_kmp_user(inputfile, online=False, language=None): packageID = extract_package_id(inputfile) packageDir = user_keyboard_dir(packageID) if not os.path.isdir(packageDir): os.makedirs(packageDir) extract_kmp(inputfile, packageDir) restart_ibus() info, system, options, keyboards, files = get_metadata(packageDir) if keyboards: logging.info("Installing %s", info['name']['description']) if online: process_keyboard_data(packageID, packageDir) if len(keyboards) > 1: for kb in keyboards: if kb['id'] != packageID: process_keyboard_data(kb['id'], packageDir) for f in files: fpath = os.path.join(packageDir, f['name']) ftype = f['type'] if ftype == KMFileTypes.KM_FONT: # Special handling of font to hard link it into font dir fontsdir = os.path.join(user_keyman_font_dir(), packageID) if not os.path.isdir(fontsdir): os.makedirs(fontsdir) os.link(fpath, os.path.join(fontsdir, f['name'])) logging.info("Installing %s as font", f['name']) elif ftype == KMFileTypes.KM_OSK: # Special handling to convert kvk into LDML logging.info( "Converting %s to LDML and installing both as as keyman file", f['name']) ldml = convert_kvk_to_ldml(fpath) name, ext = os.path.splitext(f['name']) ldmlfile = os.path.join(packageDir, name + ".ldml") output_ldml(ldmlfile, ldml) elif ftype == KMFileTypes.KM_ICON: # Special handling of icon to convert to PNG logging.info( "Converting %s to PNG and installing both as keyman files", f['name']) checkandsaveico(fpath) elif ftype == KMFileTypes.KM_SOURCE: # TODO for the moment just leave it for ibus-kmfl to ignore if it doesn't load pass elif ftype == KMFileTypes.KM_KMX: # Sanitize keyboard filename if not lower case kmx_id, ext = os.path.splitext(os.path.basename(f['name'])) for kb in keyboards: if kmx_id.lower() == kb['id'] and kmx_id != kb['id']: os.rename(os.path.join(packageDir, f['name']), os.path.join(packageDir, kb['id'] + '.kmx')) fpath = os.path.join(packageDir, kb['id'] + '.kmx') extractico(fpath) install_keyboards(keyboards, packageDir, language) else: logging.error( "install_kmp.py: error: No kmp.json or kmp.inf found in %s", inputfile) logging.info("Contents of %s:", inputfile) for o in os.listdir(packageDir): logging.info(o) rmtree(packageDir) message = _( "install_kmp.py: error: No kmp.json or kmp.inf found in {packageFile}" ).format(packageFile=inputfile) raise InstallError(InstallStatus.Abort, message)
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 = os.path.join(kmp['areapath'], kmp['packageID']) kmp_json = os.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 = os.path.join(packageDir, kmp['packageID'] + ".json") if os.path.isfile(jsonfile): with open(jsonfile, "r") as read_file: kbdata = json.load(read_file) grid = Gtk.Grid() # grid.set_column_homogeneous(True) # kbdatapath = os.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() label.set_text(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() 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() label.set_text(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 kbdata: 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 "author" in info: 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() label.set_text(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 "copyright" in info: 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() label.set_text(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 = os.path.join(packageDir, kbd['id'] + ".json") if os.path.isfile(jsonfile): with open(jsonfile, "r") as read_file: kbdata = json.load(read_file) # 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(os.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: if kbdata['id'] != 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() 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() 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() 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 "author" in info: 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() 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() 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() 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(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 = os.path.join("/usr/local/share/doc/keyman", kmp["id"], "welcome.htm") # # if os.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 = packageDir + "/qrcode.png" url = KeymanComUrl + "/go/keyboard/" + kmp['packageID'] + "/share" if not os.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()
def __init__(self, kmpfile, online=False, viewkmp=None, language=None): logging.debug("InstallKmpWindow: kmpfile: %s", kmpfile) self.kmpfile = kmpfile self.online = online self.viewwindow = viewkmp self.accelerators = None self.language = language keyboardid = os.path.basename(os.path.splitext(kmpfile)[0]) installed_kmp_ver = get_kmp_version(keyboardid) if installed_kmp_ver: logging.info("installed kmp version %s", installed_kmp_ver) windowtitle = _("Installing keyboard/package {keyboardid}").format( keyboardid=keyboardid) Gtk.Dialog.__init__(self, windowtitle, viewkmp) init_accel(self) self.set_border_width(12) mainhbox = Gtk.Box() with tempfile.TemporaryDirectory() as tmpdirname: extract_kmp(kmpfile, tmpdirname) info, system, options, keyboards, files = get_metadata(tmpdirname) self.kbname = keyboards[0]['name'] self.checkcontinue = True if installed_kmp_ver: if info['version']['description'] == installed_kmp_ver: dialog = Gtk.MessageDialog( viewkmp, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Keyboard is installed already")) dialog.format_secondary_text( _("The {name} keyboard is already installed at version {version}. " "Do you want to uninstall then reinstall it?"). format(name=self.kbname, version=installed_kmp_ver)) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: logging.debug( "QUESTION dialog closed by clicking YES button") uninstall_kmp(keyboardid) elif response == Gtk.ResponseType.NO: logging.debug( "QUESTION dialog closed by clicking NO button") self.checkcontinue = False return else: try: logging.info("package version %s", info['version']['description']) logging.info("installed kmp version %s", installed_kmp_ver) if StrictVersion(info['version']['description'] ) <= StrictVersion(installed_kmp_ver): dialog = Gtk.MessageDialog( viewkmp, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Keyboard is installed already")) dialog.format_secondary_text( _("The {name} keyboard is already installed with a newer version {installedversion}. " "Do you want to uninstall it and install the older version {version}?" ).format( name=self.kbname, installedversion=installed_kmp_ver, version=info['version']['description'])) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: logging.debug( "QUESTION dialog closed by clicking YES button" ) uninstall_kmp(keyboardid) elif response == Gtk.ResponseType.NO: logging.debug( "QUESTION dialog closed by clicking NO button" ) self.checkcontinue = False return except: # noqa: E722 logging.warning( "Exception uninstalling an old kmp, continuing") pass image = Gtk.Image() if options and "graphicFile" in options: image.set_from_file( os.path.join(tmpdirname, options['graphicFile'])) else: img_default = find_keyman_image("defaultpackage.gif") image.set_from_file(img_default) mainhbox.pack_start(image, False, False, 0) self.page1 = Gtk.Box() self.page1.set_border_width(12) grid = Gtk.Grid() self.page1.add(grid) label1 = Gtk.Label() label1.set_text(_("Keyboard layouts: ")) label1.set_halign(Gtk.Align.END) grid.add(label1) prevlabel = label1 label = Gtk.Label() keyboardlayout = "" for kb in keyboards: if keyboardlayout != "": keyboardlayout = keyboardlayout + "\n" keyboardlayout = keyboardlayout + kb['name'] label.set_text(keyboardlayout) label.set_halign(Gtk.Align.START) label.set_selectable(True) grid.attach_next_to(label, label1, Gtk.PositionType.RIGHT, 1, 1) fonts = get_fonts(files) if fonts: label2 = Gtk.Label() # Fonts are optional label2.set_text(_("Fonts: ")) label2.set_halign(Gtk.Align.END) grid.attach_next_to(label2, prevlabel, Gtk.PositionType.BOTTOM, 1, 1) prevlabel = label2 label = Gtk.Label() fontlist = "" for font in fonts: if fontlist != "": fontlist = fontlist + "\n" if font['description'][:5] == "Font ": fontdesc = font['description'][5:] else: fontdesc = font['description'] fontlist = fontlist + fontdesc label.set_text(fontlist) label.set_halign(Gtk.Align.START) label.set_selectable(True) grid.attach_next_to(label, label2, Gtk.PositionType.RIGHT, 1, 1) label3 = Gtk.Label() label3.set_text(_("Package version: ")) label3.set_halign(Gtk.Align.END) grid.attach_next_to(label3, prevlabel, Gtk.PositionType.BOTTOM, 1, 1) prevlabel = label3 label = Gtk.Label() label.set_text(info['version']['description']) label.set_halign(Gtk.Align.START) label.set_selectable(True) grid.attach_next_to(label, label3, Gtk.PositionType.RIGHT, 1, 1) if info and 'author' in info: label4 = Gtk.Label() label4.set_text(_("Author: ")) label4.set_halign(Gtk.Align.END) grid.attach_next_to(label4, prevlabel, Gtk.PositionType.BOTTOM, 1, 1) prevlabel = label4 label = Gtk.Label() if 'url' in info['author']: label.set_markup("<a href=\"" + info['author']['url'] + "\" title=\"" + info['author']['url'] + "\">" + info['author']['description'] + "</a>") else: label.set_text(info['author']['description']) label.set_halign(Gtk.Align.START) label.set_selectable(True) grid.attach_next_to(label, label4, Gtk.PositionType.RIGHT, 1, 1) if info and 'website' in info: label5 = Gtk.Label() # Website is optional and may be a mailto for the author label5.set_text(_("Website: ")) label5.set_halign(Gtk.Align.END) grid.attach_next_to(label5, prevlabel, Gtk.PositionType.BOTTOM, 1, 1) prevlabel = label5 label = Gtk.Label() label.set_markup("<a href=\"" + info['website']['description'] + "\">" + info['website']['description'] + "</a>") label.set_halign(Gtk.Align.START) label.set_selectable(True) grid.attach_next_to(label, label5, Gtk.PositionType.RIGHT, 1, 1) if info and 'copyright' in info: label6 = Gtk.Label() label6.set_text(_("Copyright: ")) label6.set_halign(Gtk.Align.END) grid.attach_next_to(label6, prevlabel, Gtk.PositionType.BOTTOM, 1, 1) label = Gtk.Label() label.set_text(info['copyright']['description']) label.set_halign(Gtk.Align.START) label.set_selectable(True) grid.attach_next_to(label, label6, Gtk.PositionType.RIGHT, 1, 1) self.page2 = Gtk.Box() webview = WebKit2.WebView() webview.connect("decide-policy", self.doc_policy) if options and "readmeFile" in options: self.readme = options['readmeFile'] else: self.readme = "noreadme" readme_file = os.path.join(tmpdirname, self.readme) if os.path.isfile(readme_file): with open(readme_file, "r") as read_file: readme_data = read_file.read() readme_uri = pathlib.Path(readme_file).as_uri() logging.debug(readme_data) webview.load_html(readme_data, readme_uri) s = Gtk.ScrolledWindow() s.add(webview) self.page2.pack_start(s, True, True, 0) self.notebook = Gtk.Notebook() self.notebook.set_tab_pos(Gtk.PositionType.BOTTOM) mainhbox.pack_start(self.notebook, True, True, 0) self.notebook.append_page(self.page1, Gtk.Label(_('Details'))) self.notebook.append_page(self.page2, Gtk.Label(_('README'))) else: mainhbox.pack_start(self.page1, True, True, 0) self.get_content_area().pack_start(mainhbox, True, True, 0) hbox = Gtk.Box(spacing=6) self.get_content_area().pack_start(hbox, False, False, 0) button = Gtk.Button.new_with_mnemonic(_("_Install")) button.connect("clicked", self.on_install_clicked) hbox.pack_start(button, False, False, 0) button = Gtk.Button.new_with_mnemonic(_("_Cancel")) button.connect("clicked", self.on_cancel_clicked) hbox.pack_end(button, False, False, 0) bind_accelerator(self.accelerators, button, '<Control>w') self.resize(800, 450) self.show_all()
def __init__(self): ViewInstalledWindowBase.__init__(self) # window is split left/right hbox # right is ButtonBox # possibly 2 ButtonBox in a vbox # top one with _Remove, _About, ?_Welcome? or ?Read_Me?, _Options # bottom one with _Download, _Install, Re_fresh, _Close # left is GtkTreeView - does it need to be inside anything else apart from the hbox? # with liststore which defines columns # GdkPixbuf icon # gchararray name # gchararray version # gchararray packageID (hidden) # enum? area (user, shared, system) (icon or hidden?) # gchararray welcomefile (hidden) (or just use area and packageID?) # changing selected item in treeview changes what buttons are activated # on selected_item_changed signal set the data that the buttons will use in their callbacks # see https://developer.gnome.org/gtk3/stable/TreeWidget.html#TreeWidget hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) s = Gtk.ScrolledWindow() hbox.pack_start(s, True, True, 0) self.store = Gtk.ListStore( GdkPixbuf.Pixbuf, # icon str, # name str, # version str, # packageID int, # enum InstallArea (KmpArea is GObject version) str, # path to welcome file if it exists or None str) # path to options file if it exists or None # add installed keyboards to the the store e.g. # treeiter = store.append([GdkPixbuf.Pixbuf.new_from_file_at_size( # "/usr/local/share/keyman/libtralo/libtralo.ico.png", 16, 16), \ # "LIBTRALO", "1.6.1", \ # "libtralo", KmpArea.SHARED, True]) self.refresh_installed_kmp() self.tree = Gtk.TreeView(self.store) renderer = Gtk.CellRendererPixbuf() # i18n: column header in table displaying installed keyboards column = Gtk.TreeViewColumn(_("Icon"), renderer, pixbuf=0) self.tree.append_column(column) renderer = Gtk.CellRendererText() # i18n: column header in table displaying installed keyboards column = Gtk.TreeViewColumn(_("Name"), renderer, text=1) self.tree.append_column(column) # i18n: column header in table displaying installed keyboards column = Gtk.TreeViewColumn(_("Version"), renderer, text=2) self.tree.append_column(column) select = self.tree.get_selection() select.connect("changed", self.on_tree_selection_changed) s.add(self.tree) 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_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) bbox_bottom = Gtk.ButtonBox(spacing=12, orientation=Gtk.Orientation.VERTICAL) bbox_bottom.set_layout(Gtk.ButtonBoxStyle.END) button = Gtk.Button.new_with_mnemonic(_("_Refresh")) button.set_tooltip_text(_("Refresh keyboard list")) button.connect("clicked", self.on_refresh_clicked) bbox_bottom.add(button) button = Gtk.Button.new_with_mnemonic(_("_Download")) button.set_tooltip_text( _("Download and install a keyboard from the Keyman website")) button.connect("clicked", self.on_download_clicked) bbox_bottom.add(button) button = Gtk.Button.new_with_mnemonic(_("_Install")) button.set_tooltip_text(_("Install a keyboard from a file")) button.connect("clicked", self.on_installfile_clicked) bbox_bottom.add(button) button = Gtk.Button.new_with_mnemonic(_("_Close")) button.set_tooltip_text(_("Close window")) button.connect("clicked", self.on_close_clicked) bind_accelerator(self.accelerators, button, '<Control>q') bind_accelerator(self.accelerators, button, '<Control>w') bbox_bottom.add(button) vbox.pack_end(bbox_bottom, False, False, 12) hbox.pack_start(vbox, False, False, 12) self.add(hbox)
def __init__(self): self.accelerators = None Gtk.Window.__init__(self, title=_("Keyman Configuration")) init_accel(self)