text: from functools import partial
  import threading
  
  from PyQt5.QtWidgets import (QVBoxLayout, QLabel, QGridLayout,
                               QWidget, QTabWidget)
  
  from electrum_axe.gui.qt.util import WindowModalDialog, Buttons, CloseButton
  from electrum_axe.i18n import _
  from electrum_axe.plugin import hook
  from electrum_axe.util import bh2u
  
  from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
  from ..hw_wallet.plugin import only_hook_if_libraries_available
  from .hideez import (HideezPlugin, TIM_NEW, TIM_RECOVER, TIM_MNEMONIC,
                       RECOVERY_TYPE_SCRAMBLED_WORDS)
  
  
  PASSPHRASE_HELP_SHORT = _(
      "Passphrases allow you to access new wallets, each "
      "hidden behind a particular case-sensitive passphrase.")
  PASSPHRASE_HELP = PASSPHRASE_HELP_SHORT + "  " + _(
      "You need to create a separate Axe-Electrum wallet for each passphrase "
      "you use as they each generate different addresses.  Changing "
      "your passphrase does not lose other wallets, each is still "
      "accessible behind its own passphrase.")
  RECOMMEND_PIN = _(
      "You should enable PIN protection.  Your PIN is the only protection "
      "for your Axe coins if your device is lost or stolen.")
  PASSPHRASE_NOT_PIN = _(
      "If you forget a passphrase you will be unable to access any "
      "Axe coins in the wallet behind it.  A passphrase is not a PIN. "
      "Only change this if you are sure you understand it.")
  
  
  class QtHandler(QtHandlerBase):
  
      def __init__(self, win, device):
          super(QtHandler, self).__init__(win, device)
  
  
  class QtPlugin(QtPluginBase):
      # Derived classes must provide the following class-static variables:
      #   icon_file
  
      def create_handler(self, window):
          return QtHandler(window, self.device)
  
      @only_hook_if_libraries_available
      @hook
      def receive_menu(self, menu, addrs, wallet):
          if len(addrs) != 1:
              return
          for keystore in wallet.get_keystores():
              if type(keystore) == self.keystore_class:
                  def show_address(keystore=keystore):
                      keystore.thread.add(partial(self.show_address, wallet,
                                                  addrs[0], keystore))
                  device_name = "{} ({})".format(self.device, keystore.label)
                  menu.addAction(_("Show on {}").format(device_name),
                                 show_address)
  
      def show_settings_dialog(self, window, keystore):
          device_id = self.choose_device(window, keystore)
          if device_id:
              SettingsDialog(window, self, keystore, device_id).exec_()
  
  
  class Plugin(HideezPlugin, QtPlugin):
      icon_unpaired = "hideez_unpaired.png"
      icon_paired = "hideez.png"
  
  
  class SettingsDialog(WindowModalDialog):
      '''This dialog doesn't require a device be paired with a wallet.
      We want users to be able to wipe a device even if they've forgotten
      their PIN.'''
  
      def __init__(self, window, plugin, keystore, device_id):
          title = _("{} Settings").format(plugin.device)
          super(SettingsDialog, self).__init__(window, title)
          self.setMaximumWidth(540)
          self.setMinimumWidth(540)
          self.setMinimumHeight(450)
  
          devmgr = plugin.device_manager()
          config = devmgr.config
          handler = keystore.handler
          thread = keystore.thread
  
          def invoke_client(method, *args, **kw_args):
              unpair_after = kw_args.pop('unpair_after', False)
  
              def task():
                  client = devmgr.client_by_id(device_id)
                  if not client:
                      raise RuntimeError("Device not connected")
                  if method:
                      getattr(client, method)(*args, **kw_args)
                  if unpair_after:
                      devmgr.unpair_id(device_id)
                  return client.features
  
              thread.add(task, on_success=update)
  
          def update(features):
              self.features = features
              if features.bootloader_hash:
                  bl_hash = bh2u(features.bootloader_hash)
                  bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]])
              else:
                  bl_hash = "N/A"
              noyes = [_("No"), _("Yes")]
              endis = [_("Enable Passphrases"), _("Disable Passphrases")]
              disen = [_("Disabled"), _("Enabled")]
              setchange = [_("Change PIN")]
  
              version = "%d.%d.%d" % (features.major_version,
                                      features.minor_version,
                                      features.patch_version)
  
              device_label.setText(features.label)
              pin_set_label.setText(noyes[features.pin_protection])
              passphrases_label.setText(disen[features.passphrase_protection])
              bl_hash_label.setText(bl_hash)
              device_id_label.setText(features.device_id)
              initialized_label.setText(noyes[features.initialized])
              version_label.setText(version)
              language_label.setText(features.language)
  
          # Information tab
          info_tab = QWidget()
          info_layout = QVBoxLayout(info_tab)
          info_glayout = QGridLayout()
          info_glayout.setColumnStretch(2, 1)
          device_label = QLabel()
          pin_set_label = QLabel()
          passphrases_label = QLabel()
          version_label = QLabel()
          device_id_label = QLabel()
          bl_hash_label = QLabel()
          bl_hash_label.setWordWrap(True)
          language_label = QLabel()
          initialized_label = QLabel()
          rows = [
              (_("Device Label"), device_label),
              (_("PIN set"), pin_set_label),
              (_("Passphrases"), passphrases_label),
              (_("Firmware Version"), version_label),
              (_("Device ID"), device_id_label),
              (_("Bootloader Hash"), bl_hash_label),
              (_("Language"), language_label),
              (_("Initialized"), initialized_label),
          ]
          for row_num, (label, widget) in enumerate(rows):
              info_glayout.addWidget(QLabel(label), row_num, 0)
              info_glayout.addWidget(widget, row_num, 1)
          info_layout.addLayout(info_glayout)
  
          tabs = QTabWidget(self)
          tabs.addTab(info_tab, _("Information"))
          dialog_vbox = QVBoxLayout(self)
          dialog_vbox.addWidget(tabs)
          dialog_vbox.addLayout(Buttons(CloseButton(self)))
  
          # Update information
          invoke_client(None)
  