def __init__(self, parent): QWidget.__init__(self, parent) l = QVBoxLayout() self.setLayout(l) l.addStretch(10) self.pi = ProgressIndicator(self, 128) l.addWidget(self.pi, alignment=Qt.AlignHCenter) self.dummy = QLabel('<h2>\xa0') l.addSpacing(10) l.addWidget(self.dummy, alignment=Qt.AlignHCenter) l.addStretch(10) self.text = _('Calculating differences, please wait...')
def __init__(self, parent): QWidget.__init__(self, parent) l = QVBoxLayout() self.setLayout(l) l.addStretch(10) self.pi = ProgressIndicator(self, 128) l.addWidget(self.pi, alignment=Qt.AlignHCenter) self.dummy = QLabel('<h2>\xa0') l.addSpacing(10) l.addWidget(self.dummy, alignment=Qt.AlignHCenter) l.addStretch(10) self.setVisible(False) self.text = ''
def __init__(self, plugin_action): QWidget.__init__(self) self.plugin_action = plugin_action layout = QVBoxLayout(self) self.setLayout(layout) keyboard_shortcuts_button = QPushButton('Keyboard shortcuts...', self) keyboard_shortcuts_button.setToolTip(_( 'Edit the keyboard shortcuts associated with this plugin')) keyboard_shortcuts_button.clicked.connect(self.edit_shortcuts) layout.addWidget(keyboard_shortcuts_button) reset_confirmation_button = QPushButton(_('Reset disabled &confirmation dialogs'), self) reset_confirmation_button.setToolTip(_( 'Reset all show me again dialogs for the Find Duplicates plugin')) reset_confirmation_button.clicked.connect(self.reset_dialogs) layout.addWidget(reset_confirmation_button) view_prefs_button = QPushButton('&View library preferences...', self) view_prefs_button.setToolTip(_( 'View data stored in the library database for this plugin')) view_prefs_button.clicked.connect(self.view_prefs) layout.addWidget(view_prefs_button) layout.addStretch(1)
def __init__(self, window, plugin, device_id): title = _("%s Settings") % plugin.device super(SettingsDialog, self).__init__(window, title) self.setMaximumWidth(540) devmgr = plugin.device_manager() config = devmgr.config keystore = window.wallet.get_keystore() handler = keystore.handler thread = keystore.thread # wallet can be None, needn't be window.wallet wallet = devmgr.wallet_by_id(device_id) hs_rows, hs_cols = (64, 128) def invoke_client(method, *args, **kw_args): unpair_after = kw_args.pop('unpair_after', False) def task(): client = devmgr.client_by_id(device_id, handler) 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 set_label_enabled() bl_hash = features.bootloader_hash.encode('hex') bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]]) noyes = [_("No"), _("Yes")] endis = [_("Enable Passphrases"), _("Disable Passphrases")] disen = [_("Disabled"), _("Enabled")] setchange = [_("Set a PIN"), _("Change PIN")] version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) coins = ", ".join(coin.coin_name for coin in features.coins) 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) label_edit.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) coins_label.setText(coins) clear_pin_button.setVisible(features.pin_protection) clear_pin_warning.setVisible(features.pin_protection) pin_button.setText(setchange[features.pin_protection]) pin_msg.setVisible(not features.pin_protection) passphrase_button.setText(endis[features.passphrase_protection]) language_label.setText(features.language) def set_label_enabled(): label_apply.setEnabled(label_edit.text() != self.features.label) def rename(): invoke_client('change_label', unicode(label_edit.text())) def toggle_passphrase(): title = _("Confirm Toggle Passphrase Protection") currently_enabled = self.features.passphrase_protection if currently_enabled: msg = _("After disabling passphrases, you can only pair this " "Electrum wallet if it had an empty passphrase. " "If its passphrase was not empty, you will need to " "create a new wallet with the install wizard. You " "can use this wallet again at any time by re-enabling " "passphrases and entering its passphrase.") else: msg = _("Your current Electrum wallet can only be used with " "an empty passphrase. You must create a separate " "wallet with the install wizard for other passphrases " "as each one generates a new set of addresses.") msg += "\n\n" + _("Are you sure you want to proceed?") if not self.question(msg, title=title): return invoke_client('toggle_passphrase', unpair_after=currently_enabled) def change_homescreen(): from PIL import Image # FIXME dialog = QFileDialog(self, _("Choose Homescreen")) filename = dialog.getOpenFileName() if filename: im = Image.open(str(filename)) if im.size != (hs_cols, hs_rows): raise Exception('Image must be 64 x 128 pixels') im = im.convert('1') pix = im.load() img = '' for j in range(hs_rows): for i in range(hs_cols): img += '1' if pix[i, j] else '0' img = ''.join( chr(int(img[i:i + 8], 2)) for i in range(0, len(img), 8)) invoke_client('change_homescreen', img) def clear_homescreen(): invoke_client('change_homescreen', '\x00') def set_pin(): invoke_client('set_pin', remove=False) def clear_pin(): invoke_client('set_pin', remove=True) def wipe_device(): if wallet and sum(wallet.get_balance()): title = _("Confirm Device Wipe") msg = _("Are you SURE you want to wipe the device?\n" "Your wallet still has bitcoins in it!") if not self.question( msg, title=title, icon=QMessageBox.Critical): return invoke_client('wipe_device', unpair_after=True) def slider_moved(): mins = timeout_slider.sliderPosition() timeout_minutes.setText(_("%2d minutes") % mins) def slider_released(): config.set_session_timeout(timeout_slider.sliderPosition() * 60) # 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) coins_label = QLabel() coins_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), (_("Supported Coins"), coins_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) # Settings tab settings_tab = QWidget() settings_layout = QVBoxLayout(settings_tab) settings_glayout = QGridLayout() # Settings tab - Label label_msg = QLabel( _("Name this %s. If you have mutiple devices " "their labels help distinguish them.") % plugin.device) label_msg.setWordWrap(True) label_label = QLabel(_("Device Label")) label_edit = QLineEdit() label_edit.setMinimumWidth(150) label_edit.setMaxLength(plugin.MAX_LABEL_LEN) label_apply = QPushButton(_("Apply")) label_apply.clicked.connect(rename) label_edit.textChanged.connect(set_label_enabled) settings_glayout.addWidget(label_label, 0, 0) settings_glayout.addWidget(label_edit, 0, 1, 1, 2) settings_glayout.addWidget(label_apply, 0, 3) settings_glayout.addWidget(label_msg, 1, 1, 1, -1) # Settings tab - PIN pin_label = QLabel(_("PIN Protection")) pin_button = QPushButton() pin_button.clicked.connect(set_pin) settings_glayout.addWidget(pin_label, 2, 0) settings_glayout.addWidget(pin_button, 2, 1) pin_msg = QLabel( _("PIN protection is strongly recommended. " "A PIN is your only protection against someone " "stealing your bitcoins if they obtain physical " "access to your %s.") % plugin.device) pin_msg.setWordWrap(True) pin_msg.setStyleSheet("color: red") settings_glayout.addWidget(pin_msg, 3, 1, 1, -1) # Settings tab - Homescreen if plugin.device != 'KeepKey': # Not yet supported by KK firmware homescreen_layout = QHBoxLayout() homescreen_label = QLabel(_("Homescreen")) homescreen_change_button = QPushButton(_("Change...")) homescreen_clear_button = QPushButton(_("Reset")) homescreen_change_button.clicked.connect(change_homescreen) homescreen_clear_button.clicked.connect(clear_homescreen) homescreen_msg = QLabel( _("You can set the homescreen on your " "device to personalize it. You must " "choose a %d x %d monochrome black and " "white image.") % (hs_rows, hs_cols)) homescreen_msg.setWordWrap(True) settings_glayout.addWidget(homescreen_label, 4, 0) settings_glayout.addWidget(homescreen_change_button, 4, 1) settings_glayout.addWidget(homescreen_clear_button, 4, 2) settings_glayout.addWidget(homescreen_msg, 5, 1, 1, -1) # Settings tab - Session Timeout timeout_label = QLabel(_("Session Timeout")) timeout_minutes = QLabel() timeout_slider = QSlider(Qt.Horizontal) timeout_slider.setRange(1, 60) timeout_slider.setSingleStep(1) timeout_slider.setTickInterval(5) timeout_slider.setTickPosition(QSlider.TicksBelow) timeout_slider.setTracking(True) timeout_msg = QLabel( _("Clear the session after the specified period " "of inactivity. Once a session has timed out, " "your PIN and passphrase (if enabled) must be " "re-entered to use the device.")) timeout_msg.setWordWrap(True) timeout_slider.setSliderPosition(config.get_session_timeout() // 60) slider_moved() timeout_slider.valueChanged.connect(slider_moved) timeout_slider.sliderReleased.connect(slider_released) settings_glayout.addWidget(timeout_label, 6, 0) settings_glayout.addWidget(timeout_slider, 6, 1, 1, 3) settings_glayout.addWidget(timeout_minutes, 6, 4) settings_glayout.addWidget(timeout_msg, 7, 1, 1, -1) settings_layout.addLayout(settings_glayout) settings_layout.addStretch(1) # Advanced tab advanced_tab = QWidget() advanced_layout = QVBoxLayout(advanced_tab) advanced_glayout = QGridLayout() # Advanced tab - clear PIN clear_pin_button = QPushButton(_("Disable PIN")) clear_pin_button.clicked.connect(clear_pin) clear_pin_warning = QLabel( _("If you disable your PIN, anyone with physical access to your " "%s device can spend your bitcoins.") % plugin.device) clear_pin_warning.setWordWrap(True) clear_pin_warning.setStyleSheet("color: red") advanced_glayout.addWidget(clear_pin_button, 0, 2) advanced_glayout.addWidget(clear_pin_warning, 1, 0, 1, 5) # Advanced tab - toggle passphrase protection passphrase_button = QPushButton() passphrase_button.clicked.connect(toggle_passphrase) passphrase_msg = WWLabel(PASSPHRASE_HELP) passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN) passphrase_warning.setStyleSheet("color: red") advanced_glayout.addWidget(passphrase_button, 3, 2) advanced_glayout.addWidget(passphrase_msg, 4, 0, 1, 5) advanced_glayout.addWidget(passphrase_warning, 5, 0, 1, 5) # Advanced tab - wipe device wipe_device_button = QPushButton(_("Wipe Device")) wipe_device_button.clicked.connect(wipe_device) wipe_device_msg = QLabel( _("Wipe the device, removing all data from it. The firmware " "is left unchanged.")) wipe_device_msg.setWordWrap(True) wipe_device_warning = QLabel( _("Only wipe a device if you have the recovery seed written down " "and the device wallet(s) are empty, otherwise the bitcoins " "will be lost forever.")) wipe_device_warning.setWordWrap(True) wipe_device_warning.setStyleSheet("color: red") advanced_glayout.addWidget(wipe_device_button, 6, 2) advanced_glayout.addWidget(wipe_device_msg, 7, 0, 1, 5) advanced_glayout.addWidget(wipe_device_warning, 8, 0, 1, 5) advanced_layout.addLayout(advanced_glayout) advanced_layout.addStretch(1) tabs = QTabWidget(self) tabs.addTab(info_tab, _("Information")) tabs.addTab(settings_tab, _("Settings")) tabs.addTab(advanced_tab, _("Advanced")) dialog_vbox = QVBoxLayout(self) dialog_vbox.addWidget(tabs) dialog_vbox.addLayout(Buttons(CloseButton(self))) # Update information invoke_client(None)
def __init__(self, window, plugin, device_id): title = _("%s Settings") % plugin.device super(SettingsDialog, self).__init__(window, title) self.setMaximumWidth(540) devmgr = plugin.device_manager() handler = window.wallet.handler thread = window.wallet.thread # wallet can be None, needn't be window.wallet wallet = devmgr.wallet_by_id(device_id) hs_rows, hs_cols = (64, 128) self.current_label=None def invoke_client(method, *args, **kw_args): unpair_after = kw_args.pop('unpair_after', False) def task(): client = devmgr.client_by_id(device_id, handler) 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.current_label = features.label set_label_enabled() bl_hash = features.bootloader_hash.encode('hex') bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]]) noyes = [_("No"), _("Yes")] endis = [_("Enable Passphrases"), _("Disable Passphrases")] disen = [_("Disabled"), _("Enabled")] setchange = [_("Set a PIN"), _("Change PIN")] version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) coins = ", ".join(coin.coin_name for coin in features.coins) 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) label_edit.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) coins_label.setText(coins) clear_pin_button.setVisible(features.pin_protection) clear_pin_warning.setVisible(features.pin_protection) pin_button.setText(setchange[features.pin_protection]) pin_msg.setVisible(not features.pin_protection) passphrase_button.setText(endis[features.passphrase_protection]) language_label.setText(features.language) def set_label_enabled(): label_apply.setEnabled(label_edit.text() != self.current_label) def rename(): invoke_client('change_label', unicode(label_edit.text())) def toggle_passphrase(): title = _("Confirm Toggle Passphrase Protection") msg = _("This will cause your Electrum wallet to be unpaired " "unless your passphrase was or will be empty.\n\n" "This is because addresses will no " "longer correspond to those used by your %s.\n\n" "You will need to create a new Electrum wallet " "with the install wizard so that they match.\n\n" "Are you sure you want to proceed?") % plugin.device if not self.question(msg, title=title): return invoke_client('toggle_passphrase', unpair_after=True) def change_homescreen(): from PIL import Image # FIXME dialog = QFileDialog(self, _("Choose Homescreen")) filename = dialog.getOpenFileName() if filename: im = Image.open(str(filename)) if im.size != (hs_cols, hs_rows): raise Exception('Image must be 64 x 128 pixels') im = im.convert('1') pix = im.load() img = '' for j in range(hs_rows): for i in range(hs_cols): img += '1' if pix[i, j] else '0' img = ''.join(chr(int(img[i:i + 8], 2)) for i in range(0, len(img), 8)) invoke_client('change_homescreen', img) def clear_homescreen(): invoke_client('change_homescreen', '\x00') def set_pin(): invoke_client('set_pin', remove=False) def clear_pin(): invoke_client('set_pin', remove=True) def wipe_device(): if wallet and sum(wallet.get_balance()): title = _("Confirm Device Wipe") msg = _("Are you SURE you want to wipe the device?\n" "Your wallet still has bitcoins in it!") if not self.question(msg, title=title, icon=QMessageBox.Critical): return invoke_client('wipe_device', unpair_after=True) def slider_moved(): mins = timeout_slider.sliderPosition() timeout_minutes.setText(_("%2d minutes") % mins) def slider_released(): seconds = timeout_slider.sliderPosition() * 60 wallet.set_session_timeout(seconds) # 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) coins_label = QLabel() coins_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), (_("Supported Coins"), coins_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) # Settings tab settings_tab = QWidget() settings_layout = QVBoxLayout(settings_tab) settings_glayout = QGridLayout() # Settings tab - Label label_msg = QLabel(_("Name this %s. If you have mutiple devices " "their labels help distinguish them.") % plugin.device) label_msg.setWordWrap(True) label_label = QLabel(_("Device Label")) label_edit = QLineEdit() label_edit.setMinimumWidth(150) label_edit.setMaxLength(plugin.MAX_LABEL_LEN) label_apply = QPushButton(_("Apply")) label_apply.clicked.connect(rename) label_edit.textChanged.connect(set_label_enabled) settings_glayout.addWidget(label_label, 0, 0) settings_glayout.addWidget(label_edit, 0, 1, 1, 2) settings_glayout.addWidget(label_apply, 0, 3) settings_glayout.addWidget(label_msg, 1, 1, 1, -1) # Settings tab - PIN pin_label = QLabel(_("PIN Protection")) pin_button = QPushButton() pin_button.clicked.connect(set_pin) settings_glayout.addWidget(pin_label, 2, 0) settings_glayout.addWidget(pin_button, 2, 1) pin_msg = QLabel(_("PIN protection is strongly recommended. " "A PIN is your only protection against someone " "stealing your bitcoins if they obtain physical " "access to your %s.") % plugin.device) pin_msg.setWordWrap(True) pin_msg.setStyleSheet("color: red") settings_glayout.addWidget(pin_msg, 3, 1, 1, -1) # Settings tab - Homescreen if plugin.device != 'KeepKey': # Not yet supported by KK firmware homescreen_layout = QHBoxLayout() homescreen_label = QLabel(_("Homescreen")) homescreen_change_button = QPushButton(_("Change...")) homescreen_clear_button = QPushButton(_("Reset")) homescreen_change_button.clicked.connect(change_homescreen) homescreen_clear_button.clicked.connect(clear_homescreen) homescreen_msg = QLabel(_("You can set the homescreen on your " "device to personalize it. You must " "choose a %d x %d monochrome black and " "white image.") % (hs_rows, hs_cols)) homescreen_msg.setWordWrap(True) settings_glayout.addWidget(homescreen_label, 4, 0) settings_glayout.addWidget(homescreen_change_button, 4, 1) settings_glayout.addWidget(homescreen_clear_button, 4, 2) settings_glayout.addWidget(homescreen_msg, 5, 1, 1, -1) # Settings tab - Session Timeout if wallet: timeout_label = QLabel(_("Session Timeout")) timeout_minutes = QLabel() timeout_slider = QSlider(Qt.Horizontal) timeout_slider.setRange(1, 60) timeout_slider.setSingleStep(1) timeout_slider.setTickInterval(5) timeout_slider.setTickPosition(QSlider.TicksBelow) timeout_slider.setTracking(True) timeout_msg = QLabel( _("Clear the session after the specified period " "of inactivity. Once a session has timed out, " "your PIN and passphrase (if enabled) must be " "re-entered to use the device.")) timeout_msg.setWordWrap(True) timeout_slider.setSliderPosition(wallet.session_timeout // 60) slider_moved() timeout_slider.valueChanged.connect(slider_moved) timeout_slider.sliderReleased.connect(slider_released) settings_glayout.addWidget(timeout_label, 6, 0) settings_glayout.addWidget(timeout_slider, 6, 1, 1, 3) settings_glayout.addWidget(timeout_minutes, 6, 4) settings_glayout.addWidget(timeout_msg, 7, 1, 1, -1) settings_layout.addLayout(settings_glayout) settings_layout.addStretch(1) # Advanced tab advanced_tab = QWidget() advanced_layout = QVBoxLayout(advanced_tab) advanced_glayout = QGridLayout() # Advanced tab - clear PIN clear_pin_button = QPushButton(_("Disable PIN")) clear_pin_button.clicked.connect(clear_pin) clear_pin_warning = QLabel( _("If you disable your PIN, anyone with physical access to your " "%s device can spend your bitcoins.") % plugin.device) clear_pin_warning.setWordWrap(True) clear_pin_warning.setStyleSheet("color: red") advanced_glayout.addWidget(clear_pin_button, 0, 2) advanced_glayout.addWidget(clear_pin_warning, 1, 0, 1, 5) # Advanced tab - toggle passphrase protection passphrase_button = QPushButton() passphrase_button.clicked.connect(toggle_passphrase) passphrase_msg = WWLabel(PASSPHRASE_HELP) passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN) passphrase_warning.setStyleSheet("color: red") advanced_glayout.addWidget(passphrase_button, 3, 2) advanced_glayout.addWidget(passphrase_msg, 4, 0, 1, 5) advanced_glayout.addWidget(passphrase_warning, 5, 0, 1, 5) # Advanced tab - wipe device wipe_device_button = QPushButton(_("Wipe Device")) wipe_device_button.clicked.connect(wipe_device) wipe_device_msg = QLabel( _("Wipe the device, removing all data from it. The firmware " "is left unchanged.")) wipe_device_msg.setWordWrap(True) wipe_device_warning = QLabel( _("Only wipe a device if you have the recovery seed written down " "and the device wallet(s) are empty, otherwise the bitcoins " "will be lost forever.")) wipe_device_warning.setWordWrap(True) wipe_device_warning.setStyleSheet("color: red") advanced_glayout.addWidget(wipe_device_button, 6, 2) advanced_glayout.addWidget(wipe_device_msg, 7, 0, 1, 5) advanced_glayout.addWidget(wipe_device_warning, 8, 0, 1, 5) advanced_layout.addLayout(advanced_glayout) advanced_layout.addStretch(1) tabs = QTabWidget(self) tabs.addTab(info_tab, _("Information")) tabs.addTab(settings_tab, _("Settings")) tabs.addTab(advanced_tab, _("Advanced")) dialog_vbox = QVBoxLayout(self) dialog_vbox.addWidget(tabs) dialog_vbox.addLayout(Buttons(CloseButton(self))) # Update information invoke_client(None)
def __init__(self, window, plugin): self.plugin = plugin self.window = window # The main electrum window title = _("%s Settings") % plugin.device super(SettingsDialog, self).__init__(window, title) self.setMaximumWidth(540) hs_rows, hs_cols = (64, 128) def get_client(lookup=DeviceMgr.PAIRED): return self.plugin.get_client(wallet, lookup) def update(): features = get_client(DeviceMgr.PAIRED).features self.features = features # The above was for outer scopes. Now the real logic. set_label_enabled() bl_hash = features.bootloader_hash.encode('hex') bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]]) noyes = [_("No"), _("Yes")] endis = [_("Enable Passphrases"), _("Disable Passphrases")] setchange = [_("Set a PIN"), _("Change PIN")] version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) coins = ", ".join(coin.coin_name for coin in features.coins) device_label.setText(features.label) pin_set_label.setText(noyes[features.pin_protection]) bl_hash_label.setText(bl_hash) label_edit.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) coins_label.setText(coins) clear_pin_button.setVisible(features.pin_protection) clear_pin_warning.setVisible(features.pin_protection) pin_button.setText(setchange[features.pin_protection]) pin_msg.setVisible(not features.pin_protection) passphrase_button.setText(endis[features.passphrase_protection]) language_label.setText(features.language) def set_label_enabled(): label_apply.setEnabled(label_edit.text() != self.features.label) def rename(): get_client().change_label(unicode(label_edit.text())) update() def toggle_passphrase(): title = _("Confirm Toggle Passphrase Protection") msg = _("This will cause your Electrum wallet to be unpaired " "unless your passphrase was or will be empty.\n\n" "This is because addresses will no " "longer correspond to those used by your %s.\n\n" "You will need to create a new Electrum wallet " "with the install wizard so that they match.\n\n" "Are you sure you want to proceed?") % plugin.device if not self.question(msg, title=title): return get_client().toggle_passphrase() self.device_manager().close_wallet(wallet) # Unpair update() def change_homescreen(): dialog = QFileDialog(self, _("Choose Homescreen")) filename = dialog.getOpenFileName() if filename: im = Image.open(str(filename)) if im.size != (hs_cols, hs_rows): raise Exception('Image must be 64 x 128 pixels') im = im.convert('1') pix = im.load() img = '' for j in range(hs_rows): for i in range(hs_cols): img += '1' if pix[i, j] else '0' img = ''.join(chr(int(img[i:i + 8], 2)) for i in range(0, len(img), 8)) get_client().change_homescreen(img) def clear_homescreen(): get_client().change_homescreen('\x00') def set_pin(remove=False): get_client().set_pin(remove=remove) update() def clear_pin(): set_pin(remove=True) def wipe_device(): # FIXME: cannot yet wipe a device that is only plugged in if sum(wallet.get_balance()): title = _("Confirm Device Wipe") msg = _("Are you SURE you want to wipe the device?\n" "Your wallet still has bitcoins in it!") if not self.question(msg, title=title, icon=QMessageBox.Critical): return # Note: we use PRESENT so that a user who has forgotten # their PIN is not prevented from wiping their device get_client(DeviceMgr.PRESENT).wipe_device() self.device_manager().close_wallet(wallet) update() def slider_moved(): mins = timeout_slider.sliderPosition() timeout_minutes.setText(_("%2d minutes") % mins) wallet = window.wallet handler = wallet.handler device = plugin.device dialog_vbox = QVBoxLayout(self) # 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() version_label = QLabel() device_id_label = QLabel() bl_hash_label = QLabel() bl_hash_label.setWordWrap(True) coins_label = QLabel() coins_label.setWordWrap(True) language_label = QLabel() initialized_label = QLabel() rows = [ (_("Device Label"), device_label), (_("PIN set"), pin_set_label), (_("Firmware Version"), version_label), (_("Serial Number"), device_id_label), (_("Bootloader Hash"), bl_hash_label), (_("Supported Coins"), coins_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) # Settings tab settings_tab = QWidget() settings_layout = QVBoxLayout(settings_tab) settings_glayout = QGridLayout() #settings_glayout.setColumnStretch(3, 1) # Settings tab - Label label_msg = QLabel(_("Name this %s. If you have mutiple devices " "their labels help distinguish them.") % plugin.device) label_msg.setWordWrap(True) label_label = QLabel(_("Device Label")) label_edit = QLineEdit() label_edit.setMinimumWidth(150) label_edit.setMaxLength(self.plugin.MAX_LABEL_LEN) label_apply = QPushButton(_("Apply")) label_apply.clicked.connect(rename) label_edit.textChanged.connect(set_label_enabled) settings_glayout.addWidget(label_label, 0, 0) settings_glayout.addWidget(label_edit, 0, 1, 1, 2) settings_glayout.addWidget(label_apply, 0, 3) settings_glayout.addWidget(label_msg, 1, 1, 1, -1) # Settings tab - PIN pin_label = QLabel(_("PIN Protection")) pin_button = QPushButton() pin_button.clicked.connect(set_pin) settings_glayout.addWidget(pin_label, 2, 0) settings_glayout.addWidget(pin_button, 2, 1) pin_msg = QLabel(_("PIN protection is strongly recommended. " "A PIN is your only protection against someone " "stealing your bitcoins if they obtain physical " "access to your %s.") % plugin.device) pin_msg.setWordWrap(True) pin_msg.setStyleSheet("color: red") settings_glayout.addWidget(pin_msg, 3, 1, 1, -1) settings_layout.addLayout(settings_glayout) # Settings tab - Homescreen homescreen_layout = QHBoxLayout() homescreen_label = QLabel(_("Homescreen")) homescreen_change_button = QPushButton(_("Change...")) homescreen_clear_button = QPushButton(_("Reset")) homescreen_change_button.clicked.connect(change_homescreen) homescreen_clear_button.clicked.connect(clear_homescreen) homescreen_msg = QLabel(_("You can set the homescreen on your device " "to personalize it. You must choose a " "%d x %d monochrome black and white image.") % (hs_rows, hs_cols)) homescreen_msg.setWordWrap(True) settings_glayout.addWidget(homescreen_label, 4, 0) settings_glayout.addWidget(homescreen_change_button, 4, 1) settings_glayout.addWidget(homescreen_clear_button, 4, 2) settings_glayout.addWidget(homescreen_msg, 5, 1, 1, -1) # Settings tab - Session Timeout timeout_label = QLabel(_("Session Timeout")) timeout_minutes = QLabel() timeout_slider = self.slider = QSlider(Qt.Horizontal) timeout_slider.setRange(1, 60) timeout_slider.setSingleStep(1) timeout_slider.setSliderPosition(wallet.session_timeout // 60) timeout_slider.setTickInterval(5) timeout_slider.setTickPosition(QSlider.TicksBelow) timeout_slider.setTracking(True) timeout_slider.valueChanged.connect(slider_moved) timeout_msg = QLabel(_("Clear the session after the specified period " "of inactivity. Once a session has timed out, " "your PIN and passphrase (if enabled) must be " "re-entered to use the device.")) timeout_msg.setWordWrap(True) settings_glayout.addWidget(timeout_label, 6, 0) settings_glayout.addWidget(timeout_slider, 6, 1, 1, 3) settings_glayout.addWidget(timeout_minutes, 6, 4) settings_glayout.addWidget(timeout_msg, 7, 1, 1, -1) # Advanced tab advanced_tab = QWidget() advanced_layout = QVBoxLayout(advanced_tab) advanced_glayout = QGridLayout() # Advanced tab - clear PIN clear_pin_button = QPushButton(_("Disable PIN")) clear_pin_button.clicked.connect(clear_pin) clear_pin_warning = QLabel(_("If you disable your PIN, anyone with " "physical access to your %s device can " "spend your bitcoins.") % plugin.device) clear_pin_warning.setWordWrap(True) clear_pin_warning.setStyleSheet("color: red") advanced_glayout.addWidget(clear_pin_button, 0, 2) advanced_glayout.addWidget(clear_pin_warning, 1, 0, 1, 5) # Advanced tab - toggle passphrase protection passphrase_button = QPushButton() passphrase_button.clicked.connect(toggle_passphrase) passphrase_msg = QLabel( _("Passphrases allow you to access new wallets, each " "hidden behind a particular case-sensitive passphrase. You " "need to create a separate 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.")) passphrase_msg.setWordWrap(True) passphrase_warning = QLabel( _("If you forget a passphrase you will be unable to access any " "bitcoins in the wallet behind it. A passphrase is not a PIN. " "Only change this if you are sure you understand it.")) passphrase_warning.setWordWrap(True) passphrase_warning.setStyleSheet("color: red") advanced_glayout.addWidget(passphrase_button, 3, 2) advanced_glayout.addWidget(passphrase_msg, 4, 0, 1, 5) advanced_glayout.addWidget(passphrase_warning, 5, 0, 1, 5) # Advanced tab - wipe device wipe_device_button = QPushButton(_("Wipe Device")) wipe_device_button.clicked.connect(wipe_device) wipe_device_msg = QLabel( _("Wipe the device, removing all data from it. The firmware " "is left unchanged.")) wipe_device_msg.setWordWrap(True) wipe_device_warning = QLabel( _("Only wipe a device if you have the recovery seed written down " "and the device wallet(s) are empty, otherwise the bitcoins " "will be lost forever.")) wipe_device_warning.setWordWrap(True) wipe_device_warning.setStyleSheet("color: red") advanced_glayout.addWidget(wipe_device_button, 6, 2) advanced_glayout.addWidget(wipe_device_msg, 7, 0, 1, 5) advanced_glayout.addWidget(wipe_device_warning, 8, 0, 1, 5) advanced_layout.addLayout(advanced_glayout) advanced_layout.addStretch(1) tabs = QTabWidget(self) tabs.addTab(info_tab, _("Information")) tabs.addTab(settings_tab, _("Settings")) tabs.addTab(advanced_tab, _("Advanced")) # Update information and then connect change slots update() slider_moved() dialog_vbox.addWidget(tabs) dialog_vbox.addLayout(Buttons(CloseButton(self)))
def request_trezor_init_settings(self, method, device): wizard = self.win vbox = QVBoxLayout() main_label = QLabel(_("Initialization settings for your %s:") % device) vbox.addWidget(main_label) OK_button = OkButton(wizard, _('Next')) def clean_text(widget): text = unicode(widget.toPlainText()).strip() return ' '.join(text.split()) if method in [TIM_NEW, TIM_RECOVER]: gb = QGroupBox() vbox1 = QVBoxLayout() gb.setLayout(vbox1) vbox.addWidget(gb) gb.setTitle(_("Select your seed length:")) choices = [ _("12 words"), _("18 words"), _("24 words"), ] bg = QButtonGroup() for i, choice in enumerate(choices): rb = QRadioButton(gb) rb.setText(choice) bg.addButton(rb) bg.setId(rb, i) vbox1.addWidget(rb) rb.setChecked(True) cb_pin = QCheckBox(_('Enable PIN protection')) cb_pin.setChecked(True) else: text = QTextEdit() text.setMaximumHeight(60) if method == TIM_MNEMONIC: msg = _("Enter your BIP39 mnemonic:") else: msg = _("Enter the master private key beginning with xprv:") def set_enabled(): OK_button.setEnabled(Wallet.is_xprv(clean_text(text))) text.textChanged.connect(set_enabled) OK_button.setEnabled(False) vbox.addWidget(QLabel(msg)) vbox.addWidget(text) pin = QLineEdit() pin.setValidator(QRegExpValidator(QRegExp('[1-9]{0,10}'))) pin.setMaximumWidth(100) hbox_pin = QHBoxLayout() hbox_pin.addWidget(QLabel(_("Enter your PIN (digits 1-9):"))) hbox_pin.addWidget(pin) hbox_pin.addStretch(1) label = QLabel(_("Enter a label to name your device:")) name = QLineEdit() hl = QHBoxLayout() hl.addWidget(label) hl.addWidget(name) hl.addStretch(1) vbox.addLayout(hl) if method in [TIM_NEW, TIM_RECOVER]: vbox.addWidget(cb_pin) else: vbox.addLayout(hbox_pin) cb_phrase = QCheckBox(_('Enable Passphrase protection')) cb_phrase.setChecked(False) vbox.addWidget(cb_phrase) vbox.addStretch(1) vbox.addLayout(Buttons(CancelButton(wizard), OK_button)) wizard.set_layout(vbox) if not wizard.exec_(): raise UserCancelled if method in [TIM_NEW, TIM_RECOVER]: item = bg.checkedId() pin = cb_pin.isChecked() else: item = ' '.join(str(clean_text(text)).split()) pin = str(pin.text()) return (item, unicode(name.text()), pin, cb_phrase.isChecked())
def __init__(self, plugin_action): QWidget.__init__(self) self.plugin_action = plugin_action layout = QVBoxLayout(self) self.setLayout(layout) c = plugin_prefs[STORE_NAME] avail_columns = self.get_custom_columns() library_config = get_library_config(self.plugin_action.gui.current_db) pages_algorithm = library_config.get(KEY_PAGES_ALGORITHM, DEFAULT_LIBRARY_VALUES[KEY_PAGES_ALGORITHM]) button_default = c.get(KEY_BUTTON_DEFAULT, DEFAULT_STORE_VALUES[KEY_BUTTON_DEFAULT]) # Fudge the button default to cater for the options no longer supported by plugin as of 1.5 if button_default in ['Estimate', 'EstimatePage', 'EstimateWord']: button_default = 'Estimate' else: button_default = 'Goodreads' overwrite_existing = c.get(KEY_OVERWRITE_EXISTING, DEFAULT_STORE_VALUES[KEY_OVERWRITE_EXISTING]) # --- Pages --- page_group_box = QGroupBox('Page count options:', self) layout.addWidget(page_group_box) page_group_box_layout = QGridLayout() page_group_box.setLayout(page_group_box_layout) page_column_label = QLabel('&Custom column:', self) page_column_label.setToolTip('Leave this blank if you do not want to count pages') page_col = library_config.get(KEY_PAGES_CUSTOM_COLUMN, '') self.page_column_combo = CustomColumnComboBox(self, avail_columns, page_col) page_column_label.setBuddy(self.page_column_combo) page_group_box_layout.addWidget(page_column_label, 0, 0, 1, 1) page_group_box_layout.addWidget(self.page_column_combo, 0, 1, 1, 2) page_algorithm_label = QLabel('&Algorithm:', self) page_algorithm_label.setToolTip('Choose which algorithm to use if you have specified a page count column') self.page_algorithm_combo = AlgorithmComboBox(self, PAGE_ALGORITHMS, pages_algorithm) page_algorithm_label.setBuddy(self.page_algorithm_combo) page_group_box_layout.addWidget(page_algorithm_label, 1, 0, 1, 1) page_group_box_layout.addWidget(self.page_algorithm_combo, 1, 1, 1, 2) # --- Words --- layout.addSpacing(5) word_group_box = QGroupBox('Word count options:', self) layout.addWidget(word_group_box) word_group_box_layout = QGridLayout() word_group_box.setLayout(word_group_box_layout) word_column_label = QLabel('C&ustom column:', self) word_column_label.setToolTip('Leave this blank if you do not want to count words') word_col = library_config.get(KEY_WORDS_CUSTOM_COLUMN, '') self.word_column_combo = CustomColumnComboBox(self, avail_columns, word_col) word_column_label.setBuddy(self.word_column_combo) word_group_box_layout.addWidget(word_column_label, 0, 0, 1, 1) word_group_box_layout.addWidget(self.word_column_combo, 0, 1, 1, 2) # --- Readability --- layout.addSpacing(5) readability_group_box = QGroupBox('Readability options:', self) layout.addWidget(readability_group_box) readability_layout = QGridLayout() readability_group_box.setLayout(readability_layout) readability_label = QLabel('Readability statistics available are <a href="http://en.wikipedia.org/wiki/Flesch–Kincaid_readability_test">Flesch-Kincaid</a> ' 'or <a href="http://en.wikipedia.org/wiki/Gunning_fog_index">Gunning Fog Index</a>.', self) readability_layout.addWidget(readability_label, 0, 0, 1, 3) readability_label.linkActivated.connect(self._link_activated) flesch_reading_column_label = QLabel('&Flesch Reading Ease:', self) flesch_reading_column_label.setToolTip('Specify the custom column to store a computed Flesch Reading Ease score.\n' 'Leave this blank if you do not want to calculate it') flesch_reading_col = library_config.get(KEY_FLESCH_READING_CUSTOM_COLUMN, '') self.flesch_reading_column_combo = CustomColumnComboBox(self, avail_columns, flesch_reading_col) flesch_reading_column_label.setBuddy(self.flesch_reading_column_combo) readability_layout.addWidget(flesch_reading_column_label, 1, 0, 1, 1) readability_layout.addWidget(self.flesch_reading_column_combo, 1, 1, 1, 2) flesch_grade_column_label = QLabel('Flesch-&Kincaid Grade:', self) flesch_grade_column_label.setToolTip('Specify the custom column to store a computed Flesch-Kincaid Grade Level score.\n' 'Leave this blank if you do not want to calculate it') flesch_grade_col = library_config.get(KEY_FLESCH_GRADE_CUSTOM_COLUMN, '') self.flesch_grade_column_combo = CustomColumnComboBox(self, avail_columns, flesch_grade_col) flesch_grade_column_label.setBuddy(self.flesch_grade_column_combo) readability_layout.addWidget(flesch_grade_column_label, 2, 0, 1, 1) readability_layout.addWidget(self.flesch_grade_column_combo, 2, 1, 1, 2) gunning_fog_column_label = QLabel('&Gunning Fox Index:', self) gunning_fog_column_label.setToolTip('Specify the custom column to store a computed Gunning Fog Index score.\n' 'Leave this blank if you do not want to calculate it') gunning_fog_col = library_config.get(KEY_GUNNING_FOG_CUSTOM_COLUMN, '') self.gunning_fog_column_combo = CustomColumnComboBox(self, avail_columns, gunning_fog_col) gunning_fog_column_label.setBuddy(self.gunning_fog_column_combo) readability_layout.addWidget(gunning_fog_column_label, 3, 0, 1, 1) readability_layout.addWidget(self.gunning_fog_column_combo, 3, 1, 1, 2) # --- Other options --- layout.addSpacing(5) other_group_box = QGroupBox('Other options:', self) layout.addWidget(other_group_box) other_group_box_layout = QGridLayout() other_group_box.setLayout(other_group_box_layout) button_default_label = QLabel('&Button default:', self) button_default_label.setToolTip('If plugin is placed as a toolbar button, choose a default action when clicked on') self.button_default_combo = KeyValueComboBox(self, BUTTON_DEFAULTS, button_default) button_default_label.setBuddy(self.button_default_combo) other_group_box_layout.addWidget(button_default_label, 0, 0, 1, 1) other_group_box_layout.addWidget(self.button_default_combo, 0, 1, 1, 2) self.overwrite_checkbox = QCheckBox('Always overwrite an existing word/page count', self) self.overwrite_checkbox.setToolTip('Uncheck this option if you have manually populated values in\n' 'either of your page/word custom columns, and never want the\n' 'plugin to overwrite it. Acts as a convenience option for users\n' 'who have the toolbar button configured to populate both page\n' 'and word count, but for some books have already assigned values\n' 'into a column and just want the zero/blank column populated.') self.overwrite_checkbox.setChecked(overwrite_existing) other_group_box_layout.addWidget(self.overwrite_checkbox, 1, 0, 1, 3) keyboard_shortcuts_button = QPushButton('Keyboard shortcuts...', self) keyboard_shortcuts_button.setToolTip(_( 'Edit the keyboard shortcuts associated with this plugin')) keyboard_shortcuts_button.clicked.connect(self.edit_shortcuts) view_prefs_button = QPushButton('&View library preferences...', self) view_prefs_button.setToolTip(_( 'View data stored in the library database for this plugin')) view_prefs_button.clicked.connect(self.view_prefs) layout.addWidget(keyboard_shortcuts_button) layout.addWidget(view_prefs_button) layout.addStretch(1)
def settings_dialog(self, window): handler = window.wallet.handler client = self.client(window.wallet) def rename(): title = _("Set Device Label") msg = _("Enter new label:") response = QInputDialog().getText(dialog, title, msg) if not response[1]: return new_label = str(response[0]) client.change_label(new_label) device_label.setText(new_label) def update_pin_info(): features = client.features pin_label.setText(noyes[features.pin_protection]) pin_button.setText(_("Change") if features.pin_protection else _("Set")) clear_pin_button.setVisible(features.pin_protection) def set_pin(remove): client.set_pin(remove=remove) update_pin_info() features = client.features noyes = [_("No"), _("Yes")] bl_hash = features.bootloader_hash.encode('hex').upper() bl_hash = "%s...%s" % (bl_hash[:10], bl_hash[-10:]) info_tab = QWidget() layout = QGridLayout(info_tab) device_label = QLabel(features.label) rename_button = QPushButton(_("Rename")) rename_button.clicked.connect(rename) pin_label = QLabel() pin_button = QPushButton() pin_button.clicked.connect(partial(set_pin, False)) clear_pin_button = QPushButton(_("Clear")) clear_pin_button.clicked.connect(partial(set_pin, True)) update_pin_info() version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) rows = [ (_("Bootloader Hash"), bl_hash), (_("Device ID"), features.device_id), (_("Device Label"), device_label, rename_button), (_("Firmware Version"), version), (_("Language"), features.language), (_("Has Passphrase"), noyes[features.passphrase_protection]), (_("Has PIN"), pin_label, pin_button, clear_pin_button) ] for row_num, items in enumerate(rows): for col_num, item in enumerate(items): widget = item if isinstance(item, QWidget) else QLabel(item) layout.addWidget(widget, row_num, col_num) dialog = WindowModalDialog(window, _("%s Settings") % self.device) vbox = QVBoxLayout() tabs = QTabWidget() tabs.addTab(info_tab, _("Information")) tabs.addTab(QWidget(), _("Advanced")) vbox.addWidget(tabs) vbox.addStretch(1) vbox.addLayout(Buttons(CloseButton(dialog))) dialog.setLayout(vbox) handler.exec_dialog(dialog)
def settings_dialog(self, window): def get_client(lookup=DeviceMgr.PAIRED): return self.get_client(wallet, lookup) def add_rows_to_layout(layout, rows): for row_num, items in enumerate(rows): for col_num, txt in enumerate(items): widget = txt if isinstance(txt, QWidget) else QLabel(txt) layout.addWidget(widget, row_num, col_num) def refresh(): features = get_client(DeviceMgr.PAIRED).features bl_hash = features.bootloader_hash.encode("hex").upper() bl_hash = "%s...%s" % (bl_hash[:10], bl_hash[-10:]) version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) coins = ", ".join(coin.coin_name for coin in features.coins) bl_hash_label.setText(bl_hash) device_label.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) coins_label.setText(coins) pin_label.setText(noyes[features.pin_protection]) passphrase_label.setText(noyes[features.passphrase_protection]) language_label.setText(features.language) pin_button.setText(_("Change") if features.pin_protection else _("Set")) clear_pin_button.setVisible(features.pin_protection) def rename(): title = _("Set Device Label") msg = _("Enter new label:") response = QInputDialog().getText(dialog, title, msg) if not response[1]: return get_client().change_label(str(response[0])) refresh() def toggle_passphrase(): title = _("Confirm Toggle Passphrase Protection") msg = ( _( "This will cause your Electrum wallet to be unpaired " "unless your passphrase was or will be empty.\n\n" "This is because addresses will no " "longer correspond to those used by your %s.\n\n" "If your passphrase is not or was not empty you will " "need to create a new Electrum wallet with the install " "wizard so that they match.\n\n" "Are you sure you want to proceed?" ) % device ) if not dialog.question(msg, title=title): return get_client().toggle_passphrase() self.device_manager().close_wallet(wallet) # Unpair refresh() def set_pin(): get_client().set_pin(remove=False) refresh() def clear_pin(): title = _("Confirm Clear PIN") msg = ( _( "WARNING: if your clear your PIN, anyone with physical " "access to your %s device can spend your bitcoins.\n\n" "Are you certain you want to remove your PIN?" ) % device ) if not dialog.question(msg, title=title): return get_client().set_pin(remove=True) refresh() def wipe_device(): # FIXME: cannot yet wipe a device that is only plugged in title = _("Confirm Device Wipe") msg = _( "Are you sure you want to wipe the device? " "You should make sure you have a copy of your recovery " "seed and that your wallet holds no bitcoins." ) if not dialog.question(msg, title=title): return if sum(wallet.get_balance()): title = _("Confirm Device Wipe") msg = _("Are you SURE you want to wipe the device?\n" "Your wallet still has bitcoins in it!") if not dialog.question(msg, title=title, icon=QMessageBox.Critical): return # Note: we use PRESENT so that a user who has forgotten # their PIN is not prevented from wiping their device get_client(DeviceMgr.PRESENT).wipe_device() wallet.wiped() self.device_manager().close_wallet(wallet) refresh() def slider_moved(): mins = timeout_slider.sliderPosition() timeout_label.setText(_("%2d minutes") % mins) wallet = window.wallet handler = wallet.handler device = self.device info_tab = QWidget() tab_layout = QVBoxLayout(info_tab) info_layout = QGridLayout() noyes = [_("No"), _("Yes")] bl_hash_label = QLabel() coins_label = QLabel() coins_label.setWordWrap(True) device_label = QLabel() passphrase_label = QLabel() initialized_label = QLabel() device_id_label = QLabel() version_label = QLabel() pin_label = QLabel() language_label = QLabel() rename_button = QPushButton(_("Rename")) rename_button.clicked.connect(rename) toggle_passphrase_button = QPushButton(_("Toggle")) toggle_passphrase_button.clicked.connect(toggle_passphrase) pin_button = QPushButton() pin_button.clicked.connect(set_pin) clear_pin_button = QPushButton(_("Clear")) clear_pin_button.clicked.connect(clear_pin) add_rows_to_layout( info_layout, [ (_("Device Label"), device_label, rename_button), (_("Has Passphrase"), passphrase_label, toggle_passphrase_button), (_("Has PIN"), pin_label, pin_button, clear_pin_button), (_("Initialized"), initialized_label), (_("Device ID"), device_id_label), (_("Bootloader Hash"), bl_hash_label), (_("Firmware Version"), version_label), (_("Supported Coins"), coins_label), (_("Language"), language_label), ], ) timeout_layout = QHBoxLayout() timeout_label = QLabel() timeout_slider = QSlider(Qt.Horizontal) timeout_slider.setRange(1, 60) timeout_slider.setSingleStep(1) timeout_slider.setSliderPosition(wallet.session_timeout // 60) timeout_slider.setTickInterval(5) timeout_slider.setTickPosition(QSlider.TicksBelow) timeout_slider.setTracking(True) timeout_slider.valueChanged.connect(slider_moved) timeout_layout.addWidget(QLabel(_("Session Timeout"))) timeout_layout.addWidget(timeout_slider) timeout_layout.addWidget(timeout_label) advanced_tab = QWidget() advanced_layout = QGridLayout(advanced_tab) wipe_device_button = QPushButton(_("Wipe Device")) wipe_device_button.clicked.connect(wipe_device) add_rows_to_layout(advanced_layout, [(wipe_device_button,)]) dialog = WindowModalDialog(window, _("%s Settings") % device) vbox = QVBoxLayout() tabs = QTabWidget() tabs.addTab(info_tab, _("Information")) tabs.addTab(advanced_tab, _("Advanced")) vbox.addWidget(tabs) vbox.addStretch(1) # Show values slider_moved() refresh() # QT on MacOSX is sensitive to layout ordering so these are last tab_layout.addLayout(info_layout) tab_layout.addLayout(timeout_layout) vbox.addLayout(Buttons(CloseButton(dialog))) dialog.setLayout(vbox) handler.exec_dialog(dialog) wallet.set_session_timeout(timeout_slider.sliderPosition() * 60)
def setup_ui(self): set_no_activate_on_click = plugins['progress_indicator'][0].set_no_activate_on_click self.setWindowIcon(QIcon(I('spell-check.png'))) self.l = l = QVBoxLayout(self) self.setLayout(l) self.stack = s = QStackedLayout() l.addLayout(s) l.addWidget(self.bb) self.bb.clear() self.bb.addButton(self.bb.Close) b = self.bb.addButton(_('&Refresh'), self.bb.ActionRole) b.setToolTip('<p>' + _('Re-scan the book for words, useful if you have edited the book since opening this dialog')) b.setIcon(QIcon(I('view-refresh.png'))) b.clicked.connect(self.refresh) self.progress = p = QWidget(self) s.addWidget(p) p.l = l = QVBoxLayout(p) l.setAlignment(Qt.AlignCenter) self.progress_indicator = pi = ProgressIndicator(self, 256) l.addWidget(pi, alignment=Qt.AlignHCenter), l.addSpacing(10) p.la = la = QLabel(_('Checking, please wait...')) la.setStyleSheet('QLabel { font-size: 30pt; font-weight: bold }') l.addWidget(la, alignment=Qt.AlignHCenter) self.main = m = QWidget(self) s.addWidget(m) m.l = l = QVBoxLayout(m) m.h1 = h = QHBoxLayout() l.addLayout(h) self.filter_text = t = QLineEdit(self) t.setPlaceholderText(_('Filter the list of words')) t.textChanged.connect(self.do_filter) m.fc = b = QToolButton(m) b.setIcon(QIcon(I('clear_left.png'))), b.setToolTip(_('Clear filter')) b.clicked.connect(t.clear) h.addWidget(t), h.addWidget(b) m.h2 = h = QHBoxLayout() l.addLayout(h) self.words_view = w = WordsView(m) set_no_activate_on_click(w) w.ignore_all.connect(self.ignore_all) w.add_all.connect(self.add_all) w.activated.connect(self.word_activated) w.change_to.connect(self.change_to) w.currentChanged = self.current_word_changed state = tprefs.get('spell-check-table-state', None) hh = self.words_view.horizontalHeader() h.addWidget(w) self.words_model = m = WordsModel(self) w.setModel(m) m.dataChanged.connect(self.current_word_changed) m.modelReset.connect(self.current_word_changed) if state is not None: hh.restoreState(state) # Sort by the restored state, if any w.sortByColumn(hh.sortIndicatorSection(), hh.sortIndicatorOrder()) m.show_only_misspelt = hh.isSectionHidden(3) self.ignore_button = b = QPushButton(_('&Ignore')) b.ign_text, b.unign_text = unicode(b.text()), _('Un&ignore') b.ign_tt = _('Ignore the current word for the rest of this session') b.unign_tt = _('Stop ignoring the current word') b.clicked.connect(self.toggle_ignore) l = QVBoxLayout() h.addLayout(l) h.setStretch(0, 1) l.addWidget(b), l.addSpacing(20) self.add_button = b = QPushButton(_('Add word to &dictionary:')) b.add_text, b.remove_text = unicode(b.text()), _('Remove from &dictionaries') b.add_tt = _('Add the current word to the specified user dictionary') b.remove_tt = _('Remove the current word from all active user dictionaries') b.clicked.connect(self.add_remove) self.user_dictionaries = d = QComboBox(self) self.user_dictionaries_missing_label = la = QLabel(_( 'You have no active user dictionaries. You must' ' choose at least one active user dictionary via' ' Preferences->Editor->Manage spelling dictionaries')) la.setWordWrap(True) self.initialize_user_dictionaries() d.setMinimumContentsLength(25) l.addWidget(b), l.addWidget(d), l.addWidget(la) self.next_occurrence = b = QPushButton(_('Show &next occurrence'), self) b.setToolTip('<p>' + _( 'Show the next occurrence of the selected word in the editor, so you can edit it manually')) b.clicked.connect(self.show_next_occurrence) l.addSpacing(20), l.addWidget(b) l.addStretch(1) self.change_button = b = QPushButton(_('&Change selected word to:'), self) b.clicked.connect(self.change_word) l.addWidget(b) self.suggested_word = sw = LineEdit(self) sw.set_separator(None) sw.setPlaceholderText(_('The replacement word')) sw.returnPressed.connect(self.change_word) l.addWidget(sw) self.suggested_list = sl = QListWidget(self) sl.currentItemChanged.connect(self.current_suggestion_changed) sl.itemActivated.connect(self.change_word) set_no_activate_on_click(sl) l.addWidget(sl) hh.setSectionHidden(3, m.show_only_misspelt) self.show_only_misspelled = om = QCheckBox(_('Show &only misspelled words')) om.setChecked(m.show_only_misspelt) om.stateChanged.connect(self.update_show_only_misspelt) self.case_sensitive_sort = cs = QCheckBox(_('Case &sensitive sort')) cs.setChecked(tprefs['spell_check_case_sensitive_sort']) cs.stateChanged.connect(self.sort_type_changed) self.hb = h = QHBoxLayout() self.summary = s = QLabel('') self.main.l.addLayout(h), h.addWidget(s), h.addWidget(om), h.addWidget(cs), h.addStretch(1)
def settings_dialog(self, window): def client(): return self.client(wallet) def add_rows_to_layout(layout, rows): for row_num, items in enumerate(rows): for col_num, txt in enumerate(items): widget = txt if isinstance(txt, QWidget) else QLabel(txt) layout.addWidget(widget, row_num, col_num) def refresh(): features = client().features bl_hash = features.bootloader_hash.encode('hex').upper() bl_hash = "%s...%s" % (bl_hash[:10], bl_hash[-10:]) version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) bl_hash_label.setText(bl_hash) device_label.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) pin_label.setText(noyes[features.pin_protection]) passphrase_label.setText(noyes[features.passphrase_protection]) language_label.setText(features.language) pin_button.setText(_("Change") if features.pin_protection else _("Set")) clear_pin_button.setVisible(features.pin_protection) def rename(): title = _("Set Device Label") msg = _("Enter new label:") response = QInputDialog().getText(dialog, title, msg) if not response[1]: return client().change_label(str(response[0])) refresh() def set_pin(): client().set_pin(remove=False) refresh() def clear_pin(): title = _("Confirm Clear PIN") msg = _("WARNING: if your clear your PIN, anyone with physical " "access to your %s device can spend your bitcoins.\n\n" "Are you certain you want to remove your PIN?") % device if not dialog.question(msg, title=title): return client().set_pin(remove=True) refresh() def wipe_device(): title = _("Confirm Device Wipe") msg = _("Are you sure you want to wipe the device? " "You should make sure you have a copy of your recovery " "seed and that your wallet holds no bitcoins.") if not dialog.question(msg, title=title): return if sum(wallet.get_balance()): title = _("Confirm Device Wipe") msg = _("Are you SURE you want to wipe the device?\n" "Your wallet still has bitcoins in it!") if not dialog.question(msg, title=title, icon=QMessageBox.Critical): return client().wipe_device() refresh() def slider_moved(): mins = timeout_slider.sliderPosition() timeout_label.setText(_("%2d minutes") % mins) wallet = window.wallet handler = wallet.handler device = self.device info_tab = QWidget() tab_layout = QVBoxLayout(info_tab) info_layout = QGridLayout() noyes = [_("No"), _("Yes")] bl_hash_label = QLabel() device_label = QLabel() passphrase_label = QLabel() initialized_label = QLabel() device_id_label = QLabel() version_label = QLabel() pin_label = QLabel() language_label = QLabel() rename_button = QPushButton(_("Rename")) rename_button.clicked.connect(rename) pin_button = QPushButton() pin_button.clicked.connect(set_pin) clear_pin_button = QPushButton(_("Clear")) clear_pin_button.clicked.connect(clear_pin) add_rows_to_layout(info_layout, [ (_("Device Label"), device_label, rename_button), (_("Has Passphrase"), passphrase_label), (_("Has PIN"), pin_label, pin_button, clear_pin_button), (_("Initialized"), initialized_label), (_("Device ID"), device_id_label), (_("Bootloader Hash"), bl_hash_label), (_("Firmware Version"), version_label), (_("Language"), language_label), ]) tab_layout.addLayout(info_layout) timeout_layout = QHBoxLayout() timeout_label = QLabel() timeout_slider = QSlider(Qt.Horizontal) timeout_slider.setRange(1, 60) timeout_slider.setSingleStep(1) timeout_slider.setSliderPosition(wallet.session_timeout // 60) timeout_slider.setTickInterval(5) timeout_slider.setTickPosition(QSlider.TicksBelow) timeout_slider.setTracking(True) timeout_slider.valueChanged.connect(slider_moved) timeout_layout.addWidget(QLabel(_("Session Timeout"))) timeout_layout.addWidget(timeout_slider) timeout_layout.addWidget(timeout_label) tab_layout.addLayout(timeout_layout) advanced_tab = QWidget() advanced_layout = QGridLayout(advanced_tab) wipe_device_button = QPushButton(_("Wipe Device")) wipe_device_button.clicked.connect(wipe_device) add_rows_to_layout(advanced_layout, [ (wipe_device_button, ), ]) dialog = WindowModalDialog(window, _("%s Settings") % device) vbox = QVBoxLayout() tabs = QTabWidget() tabs.addTab(info_tab, _("Information")) tabs.addTab(advanced_tab, _("Advanced")) vbox.addWidget(tabs) vbox.addStretch(1) vbox.addLayout(Buttons(CloseButton(dialog))) # Show values slider_moved() refresh() dialog.setLayout(vbox) handler.exec_dialog(dialog) wallet.set_session_timeout(timeout_slider.sliderPosition() * 60)