示例#1
0
    def switch_to(self, mode, wallet_name, recipient_wallet, time, password):
        window = self.wallet_windows[wallet_name]
        try:
            l = mode(window,
                     self,
                     wallet_name,
                     recipient_wallet,
                     time,
                     password=password)

            tab = window.create_list_tab(l)
            destroyed_print_error(tab)  # track object lifecycle
            finalization_print_error(tab)  # track object lifecycle

            old_tab = self.lw_tabs.get(wallet_name)
            i = window.tabs.indexOf(old_tab)

            self.lw_tabs[wallet_name] = tab
            self.lw_tab[wallet_name] = l
            window.tabs.addTab(tab, self.icon(), _('Bitcoin Bileto'))
            if old_tab:
                window.tabs.removeTab(i)
                old_tab.searchable_list.deleteLater()
                old_tab.deleteLater(
                )  # Qt (and Python) will proceed to delete this widget
        except Exception as e:
            self.print_error(repr(e))
            return
示例#2
0
 def create_window_for_wallet(self, wallet):
     w = ElectrumWindow(self, wallet)
     self.windows.append(w)
     finalization_print_error(w, "[{}] finalized".format(w.diagnostic_name()))
     self.build_tray_menu()
     run_hook('on_new_window', w)
     return w
示例#3
0
    def __init__(self,
                 config,
                 app,
                 plugins,
                 storage,
                 partial_title='Install Wizard'):
        BaseWizard.__init__(self, config, storage)
        QDialog.__init__(self, None)
        self.setWindowTitle('Electron Cash SLP Edition -  ' + _(partial_title))
        self.app = app
        self.config = config
        # Set for base base class
        self.plugins = plugins
        self.setMinimumSize(600, 450)
        self.accept_signal.connect(self.accept)
        self.title = QLabel()
        self.main_widget = QWidget()
        self.back_button = QPushButton(_("Back"), self)
        self.back_button.setText(
            _('Back') if self.can_go_back() else _('Cancel'))
        self.next_button = QPushButton(_("Next"), self)
        self.next_button.setDefault(True)
        self.logo = QLabel()
        self.please_wait = QLabel(_("Please wait..."))
        self.please_wait.setAlignment(Qt.AlignCenter)
        self.icon_filename = None
        self.loop = QEventLoop()
        self.rejected.connect(lambda: self.loop.exit(0))
        self.back_button.clicked.connect(lambda: self.loop.exit(1))
        self.next_button.clicked.connect(lambda: self.loop.exit(2))
        outer_vbox = QVBoxLayout(self)
        inner_vbox = QVBoxLayout()
        inner_vbox.addWidget(self.title)
        inner_vbox.addWidget(self.main_widget)
        inner_vbox.addStretch(1)
        inner_vbox.addWidget(self.please_wait)
        inner_vbox.addStretch(1)
        scroll_widget = QWidget()
        scroll_widget.setLayout(inner_vbox)
        scroll = QScrollArea()
        scroll.setWidget(scroll_widget)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setWidgetResizable(True)
        icon_vbox = QVBoxLayout()
        icon_vbox.addWidget(self.logo)
        icon_vbox.addStretch(1)
        hbox = QHBoxLayout()
        hbox.addLayout(icon_vbox)
        hbox.addSpacing(5)
        hbox.addWidget(scroll)
        hbox.setStretchFactor(scroll, 1)
        outer_vbox.addLayout(hbox)
        outer_vbox.addLayout(Buttons(self.back_button, self.next_button))
        self.set_icon(':icons/electron-cash.svg')
        self.show()
        self.raise_()

        # Track object lifecycle
        finalization_print_error(self)
示例#4
0
 def __init__(self, config):
     super().__init__(None) # Top-level Object
     if Exception_Hook._instance: return # This is ok, we will be GC'd later.
     Exception_Hook._instance = self # strong reference to self should keep us alive until uninstall() is called
     self.config = config
     sys.excepthook = self.handler # yet another strong reference. We really won't die unless uninstall() is called
     self._report_exception.connect(_show_window)
     print_error("[{}] Installed.".format(__class__.__qualname__))
     finalization_print_error(self, "[{}] Finalized.".format(__class__.__qualname__))
     destroyed_print_error(self)
示例#5
0
 def _cleanup_keystore_extra(self, keystore):
     # awkward cleanup code for the keystore 'thread' object (qt.util.TaskThread object)
     # we have to do it this way so as to avoid relying on and/or importing gui.qt
     finalization_print_error(keystore)  # track object lifecycle
     thread = getattr(keystore, 'thread', None)
     if thread and all(
             hasattr(thread, attr)
             for attr in ('isRunning', 'stop')) and thread.isRunning():
         # was a Qt TaskThread, kill it, and wait up to 5 seconds for it to stop
         thread.stop(waitTime=5.0)
示例#6
0
    def __init__(
        self,
        bip38_keys,
        *,
        parent=None,
        title=None,
        message=None,  # The message to display as a label up top
        show_count=True,  # If false, don't show 'Key 1/n:' in UI instead just say: 'Key: '
        on_success=None,  # Callback will be called with a dict of bip38key -> (decoded_wif_str, Address) objects
        on_cancel=None):  # Callback will be called if user hits cancel
        ''' bip38_keys should be a list of '6P' strings, representing bip38
        keys. The user will be prompted for each key to enter a password
        and will be shown the decoded address and WIF key. Note that this
        method will raise RuntimeError if not bitcion.is_bip38_available().

        on_success: if specified, will be called after the window has closed
                    (exec_ has finished) with a single argument: a dict of
                    bip38key -> (decoded_wif, Address).
        on_cancel:  if specified, will be called after the window was closed
                    (exec_ has finished) with no arguments.

        If you don't specify any callbacks, results are still available in
        the self.decoded_keys dict.

        The dialog will always terminate with either all keys successfully
        decrypted or a user cancel.
        '''
        if not title:
            title = f'{PROJECT_NAME} - ' + _('BIP38 Import')
        WindowModalDialog.__init__(self, parent=parent, title=title)
        if not bitcoin.is_bip38_available():
            raise RuntimeError(
                'Bip38Importer: bip38 decoding is not available')
        self.bip38_keys = tuple(bip38_keys)
        assert self.bip38_keys and all(
            bitcoin.is_bip38_key(k) for k in self.bip38_keys)
        if not parent:
            self.setWindowModality(Qt.ApplicationModal)

        self.decoded_keys = dict()  # results are placed here on success
        self.success_cb, self.cancel_cb = on_success, on_cancel
        self.cur, self.decoded_wif, self.decoded_address = 0, None, None
        self.decrypter = None
        self.show_count = show_count

        self.decrypted_sig.connect(self.on_decrypted)

        self._setup_ui(message)

        util.finalization_print_error(self)
示例#7
0
 def __init__(self, config):
     super().__init__()
     self.dialog: Optional[ExceptionDialog] = None
     if ExceptionHook._instance is not None:
         # This is ok, we will be GC'd later.
         return
     # strong reference to self keeps us alive until uninstall() is called
     ExceptionHook._instance = self
     self.config = config
     sys.excepthook = self.handler
     self._report_exception.connect(self._show_window)
     print_error(f"[{__class__.__qualname__}] Installed.")
     finalization_print_error(self,
                              f"[{__class__.__qualname__}] Finalized.")
     destroyed_print_error(self)
示例#8
0
def ShowPopupLabel(text, target, timeout, name="Global", pointer_position=PopupWidget.RightSide, opacity=0.9, onClick=None, onRightClick=None,
                   activation_hides=True, track_target=True, dark_mode=False):
    assert isinstance(name, str) and isinstance(text, str) and isinstance(target, QWidget) and isinstance(timeout, (float, int)), "Invalid parameters"
    window = target.window()
    if not window.isActiveWindow():
        return False
    KillPopupLabel(name)
    popup = PopupLabel(text, window, timeout=timeout, delete_on_hide=True, activation_hides=activation_hides, dark_mode=dark_mode)
    popup.setPointerPosition(pointer_position)
    popup.final_opacity = opacity
    popup.setObjectName(str(id(popup)))
    def onDestroyed(x):
        # NB: even though x and popup are the same object, they will have different id() at this point (I think this is because Qt destructed the python object stub and is passing us a reference to the QWidget base here.)
        xid = None
        try:
            xid = int(x.objectName())
        except (ValueError,TypeError):
            pass
        if xid == id(_extant_popups.get(name, None)):
            # Clean up the dict entry
            _extant_popups.pop(name, None)
            #print("----> Destroyed and cleaned up:",name)
        else:
            # Stale object or already removed from dict. No need to clean up the dict entry
            pass
            #print("----> Not found!!")
    if track_target:
        class MyEventFilter(QObject):
            ''' Traps target move events and moves the popup to line up with the target '''
            def eventFilter(self, obj, e):
                lbl = self.parent()
                if e.type() in (QEvent.Move, QEvent.Resize) and isinstance(lbl, PopupLabel):
                    # track the target, moving us along with it if its geometry changes
                    lbl.moveRelativeTo(obj)
                return False
        popup.my_e_filter = MyEventFilter(popup)
        target.installEventFilter(popup.my_e_filter)
    popup.destroyed.connect(onDestroyed)
    destroyed_print_error(popup, "[PopupLabel/{}] destroyed".format(name))
    finalization_print_error(popup, "[PopupLabel/{}] finalized".format(name))
    _extant_popups[name] = popup
    if onClick:
        popup.onClick.connect(onClick, Qt.QueuedConnection)
    if onRightClick:
        popup.onRightClick.connect(onRightClick, Qt.QueuedConnection)
    popup.showRelativeTo(target)
    return True
def ShowPopupLabel(text,
                   target,
                   timeout,
                   name="Global",
                   pointer_position=PopupWidget.RightSide,
                   opacity=0.9,
                   onClick=None,
                   onRightClick=None):
    assert isinstance(name, str) and isinstance(text, str) and isinstance(
        target, QWidget) and isinstance(timeout,
                                        (float, int)), "Invalid parameters"
    window = target.window()
    if not window.isActiveWindow():
        return False
    KillPopupLabel(name)
    popup = PopupLabel(text, window, timeout=timeout, delete_on_hide=True)
    popup.setPointerPosition(pointer_position)
    popup.final_opacity = opacity
    popup.setObjectName(str(id(popup)))

    def onDestroyed(x):
        # NB: even though x and popup are the same object, they will have different id() at this point (I think this is because Qt destructed the python object stub and is passing us a reference to the QWidget base here.)
        xid = None
        try:
            xid = int(x.objectName())
        except (ValueError, TypeError):
            pass
        if xid == id(_extant_popups.get(name, None)):
            # Clean up the dict entry
            _extant_popups.pop(name, None)
            #print("----> Destroyed and cleaned up:",name)
        else:
            # Stale object or already removed from dict. No need to clean up the dict entry
            pass
            #print("----> Not found!!")

    popup.destroyed.connect(onDestroyed)
    destroyed_print_error(popup, "[PopupLabel/{}] destroyed".format(name))
    finalization_print_error(popup, "[PopupLabel/{}] finalized".format(name))
    _extant_popups[name] = popup
    if onClick:
        popup.onClick.connect(onClick, Qt.QueuedConnection)
    if onRightClick:
        popup.onRightClick.connect(onRightClick, Qt.QueuedConnection)
    popup.showRelativeTo(target)
    return True
示例#10
0
def multiple_result_picker(parent,
                           results,
                           wallet=None,
                           msg=None,
                           title=None,
                           gbtext=None):
    ''' Pops up a modal dialog telling you to pick a results. Used by the
    Contacts tab edit function, etc. '''
    assert parent
    from .main_window import ElectrumWindow
    if isinstance(parent, ElectrumWindow) and not wallet:
        wallet = parent.wallet
    assert isinstance(wallet, Abstract_Wallet)

    msg = msg or _(
        'Multiple results were found, please select an option from the items below:'
    )
    title = title or _("Select Cash Account")

    d = WindowModalDialog(parent, title)
    util.finalization_print_error(d)  # track object lifecycle
    destroyed_print_error(d)

    vbox = QVBoxLayout(d)
    lbl = WWLabel(msg)
    vbox.addWidget(lbl)

    gb = InfoGroupBox(d, parent, results)
    vbox.addWidget(gb)

    ok_but = OkButton(d)
    buts = Buttons(CancelButton(d), ok_but)
    vbox.addLayout(buts)
    ok_but.setEnabled(False)

    but_grp = gb.buttonGroup()
    but_grp.buttonClicked.connect(
        lambda x=None: ok_but.setEnabled(gb.selectedItem() is not None))

    code = d.exec_()

    if code == QDialog.Accepted:
        item = gb.selectedItem()
        if item:
            return item[:-1]
示例#11
0
文件: util.py 项目: proteanx/DeLight
 def __init__(self, parent, message, task, on_success=None, on_error=None, auto_cleanup=True,
              *, auto_show=True, auto_exec=False, title=None, disable_escape_key=False):
     assert parent
     if isinstance(parent, MessageBoxMixin):
         parent = parent.top_level_window()
     WindowModalDialog.__init__(self, parent, title or _("Please wait"))
     self.auto_cleanup = auto_cleanup
     self.disable_escape_key = disable_escape_key
     self._vbox = vbox = QVBoxLayout(self)
     self._label = label = QLabel(message)
     vbox.addWidget(label)
     self.accepted.connect(self.on_accepted)
     self.rejected.connect(self.on_rejected)
     if auto_show and not auto_exec:
         self.open()
     self.thread = TaskThread(self)
     self.thread.add(task, on_success, self.accept, on_error)
     if auto_exec:
         self.exec_()
     finalization_print_error(self)  # track object lifecycle
示例#12
0
    def switch_to(self, mode, wallet_name, password, manager):
        window=self.wallet_windows[wallet_name]
        try:
            l = mode(window, self, wallet_name, password=password, manager=manager)
            tab = window.create_list_tab(l)
            destroyed_print_error(tab)  # track object lifecycle
            finalization_print_error(tab)  # track object lifecycle

            old_tab = self.mecenas_tabs.get(wallet_name, None)
            i = window.tabs.indexOf(old_tab)

            self.mecenas_tabs[wallet_name] = tab
            self.mecenas_tab[wallet_name] = l
            if old_tab:
                window.tabs.removeTab(i)
                old_tab.searchable_list.deleteLater()
                old_tab.deleteLater()
            window.tabs.insertTab(i,tab, self._get_icon(), _('Mecenas'))
            window.tabs.setCurrentIndex(i)
        except Exception as e:
            self.print_error(repr(e))
            return
示例#13
0
    def __init__(self,
                 main_window,
                 token_id_hex=None,
                 token_name=None,
                 allow_overwrite=False):
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)
        from .main_window import ElectrumWindow

        assert isinstance(main_window, ElectrumWindow)
        main_window._slp_dialogs.add(self)
        finalization_print_error(self)  # Track object lifecycle

        self.provided_token_name = token_name
        self.allow_overwrite = allow_overwrite
        self.main_window = main_window
        self.wallet = main_window.wallet
        self.network = main_window.network
        self.app = main_window.app

        if self.main_window.gui_object.warn_if_no_network(self.main_window):
            return

        if self.provided_token_name:
            self.setWindowTitle(_("SLP Token Details"))
        else:
            self.setWindowTitle(_("Add SLP Token"))

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        vbox.addWidget(QLabel(_('Token ID:')))

        self.token_id_e = ButtonsLineEdit()
        if token_id_hex is not None:
            self.token_id_e.addCopyButton()
        vbox.addWidget(self.token_id_e)

        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        hbox.addWidget(QLabel(_('Genesis transaction information:')))

        self.get_info_button = b = QPushButton(_("Download"))
        b.clicked.connect(self.download_info)
        hbox.addWidget(b)

        self.load_tx_menu_button = b = QPushButton(_("Load..."))
        menu = QMenu()
        menu.addAction(_("&From file"), self.do_process_from_file)
        menu.addAction(_("&From text"), self.do_process_from_text)
        menu.addAction(_("&From QR code"), self.read_tx_from_qrcode)
        b.setMenu(menu)
        hbox.addWidget(b)

        self.view_tx_button = b = QPushButton(_("View Tx"))
        b.clicked.connect(self.view_tx)
        b.setDisabled(True)
        hbox.addWidget(b)

        hbox.addStretch(1)

        self.token_info_e = QTextBrowser()
        self.token_info_e.setOpenExternalLinks(True)
        self.token_info_e.setMinimumHeight(100)
        vbox.addWidget(self.token_info_e)

        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        warnpm = QIcon(":icons/warning.png").pixmap(20, 20)

        l = QLabel()
        l.setPixmap(warnpm)
        hbox.addWidget(l)
        hbox.addWidget(
            QLabel(
                _('Avoid counterfeits—carefully compare the token ID with a trusted source.'
                  )))
        l = QLabel()
        l.setPixmap(warnpm)
        hbox.addWidget(l)

        if self.provided_token_name is None:
            namelabel = QLabel(
                _('To use tokens with this ID, assign it a name.'))
            namelabel.setAlignment(Qt.AlignRight)
            vbox.addWidget(namelabel)

        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        self.cancel_button = b = QPushButton(_("Cancel"))
        self.cancel_button.setAutoDefault(False)
        self.cancel_button.setDefault(False)
        b.clicked.connect(self.close)
        b.setDefault(True)
        hbox.addWidget(self.cancel_button)

        hbox.addStretch(1)

        hbox.addWidget(QLabel(_('Name in wallet:')))
        self.token_name_e = QLineEdit()
        self.token_name_e.setFixedWidth(200)
        if self.provided_token_name is not None:
            self.token_name_e.setText(self.provided_token_name)
        hbox.addWidget(self.token_name_e)

        self.add_button = b = QPushButton(
            _("Add") if self.provided_token_name is None else _("Change"))
        b.clicked.connect(self.add_token)
        self.add_button.setAutoDefault(True)
        self.add_button.setDefault(True)
        b.setDisabled(True)
        hbox.addWidget(self.add_button)

        if token_id_hex is not None:
            self.token_id_e.setText(token_id_hex)
            self.download_info()

        self.got_network_response_sig.connect(self.got_network_response_slot,
                                              Qt.QueuedConnection)
        self.update()

        dialogs.append(self)
        self.show()

        self.token_name_e.setFocus()
示例#14
0
 def _cleanup_keystore_extra(self, keystore):
     # awkward cleanup code for the keystore 'thread' object (see qt.py)
     finalization_print_error(keystore)  # track object lifecycle
     if callable(getattr(keystore.thread, 'stop', None)):
         keystore.thread.stop()
    def __init__(self, main_window, token_id_hex, token_name):
        QDialog.__init__(self, parent=None)
        from .main_window import ElectrumWindow

        assert isinstance(main_window, ElectrumWindow)
        main_window._slp_dialogs.add(self)
        finalization_print_error(self)  # Track object lifecycle

        self.main_window = main_window
        self.wallet = main_window.wallet
        self.network = main_window.network
        self.app = main_window.app

        if self.main_window.gui_object.warn_if_no_network(self.main_window):
            return
        
        self.baton_txo = None
        try:
            self.baton_txo = self.main_window.wallet.get_slp_token_baton(token_id_hex)
        except SlpNoMintingBatonFound:
            pass

        self.setWindowTitle(_("Burn Tokens"))

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        grid = QGridLayout()
        grid.setColumnStretch(1, 1)
        vbox.addLayout(grid)
        row = 0

        grid.addWidget(QLabel(_('Name:')), row, 0)

        self.token_name = QLineEdit()
        self.token_name.setFixedWidth(490)
        self.token_name.setText(token_name)
        self.token_name.setDisabled(True)
        grid.addWidget(self.token_name, row, 1)
        row += 1

        msg = _('Unique identifier for the token.')
        grid.addWidget(HelpLabel(_('Token ID:'), msg), row, 0)

        self.token_id_e = QLineEdit()
        self.token_id_e.setFixedWidth(490)
        self.token_id_e.setText(token_id_hex)
        self.token_id_e.setDisabled(True)
        grid.addWidget(self.token_id_e, row, 1)
        row += 1

        msg = _('The number of decimal places used in the token quantity.')
        grid.addWidget(HelpLabel(_('Decimals:'), msg), row, 0)
        self.token_dec = QDoubleSpinBox()
        decimals = self.main_window.wallet.token_types.get(token_id_hex)['decimals']
        self.token_dec.setRange(0, 9)
        self.token_dec.setValue(decimals)
        self.token_dec.setDecimals(0)
        self.token_dec.setFixedWidth(50)
        self.token_dec.setDisabled(True)
        grid.addWidget(self.token_dec, row, 1)
        row += 1

        hbox = QHBoxLayout()
        msg = _('The number of tokens to be destroyed for this token.')
        grid.addWidget(HelpLabel(_('Burn Amount:'), msg), row, 0)
        name = self.main_window.wallet.token_types.get(token_id_hex)['name']
        self.token_qty_e = SLPAmountEdit(name, int(decimals))
        self.token_qty_e.setFixedWidth(200)
        #self.token_qty_e.textChanged.connect(self.check_token_qty)
        hbox.addWidget(self.token_qty_e)

        self.max_button = EnterButton(_("Max"), self.burn_max)
        self.max_button.setFixedWidth(140)
        #self.max_button.setCheckable(True)
        hbox.addWidget(self.max_button)
        hbox.addStretch(1)
        grid.addLayout(hbox, row, 1)
        row += 1

        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        self.token_burn_baton_cb = cb = QCheckBox(_("Burn Minting Baton"))
        self.token_burn_baton_cb.setChecked(False)
        self.token_burn_baton_cb.setDisabled(True)
        grid.addWidget(self.token_burn_baton_cb, row, 0)
        if self.baton_txo != None:
            self.token_burn_baton_cb.setDisabled(False)

        self.token_burn_invalid_cb = cb = QCheckBox(_("Burn invalid SLP transactions for this token"))
        self.token_burn_invalid_cb.setChecked(True)
        grid.addWidget(self.token_burn_invalid_cb, row, 1)
        row += 1

        self.cancel_button = b = QPushButton(_("Cancel"))
        self.cancel_button.setAutoDefault(True)
        self.cancel_button.setDefault(True)
        b.clicked.connect(self.close)
        b.setDefault(True)
        hbox.addWidget(self.cancel_button)

        hbox.addStretch(1)

        self.preview_button = EnterButton(_("Preview"), self.do_preview)
        self.burn_button = b = QPushButton(_("Burn Tokens"))
        b.clicked.connect(self.burn_token)
        self.burn_button.setAutoDefault(False)
        self.burn_button.setDefault(False)
        hbox.addWidget(self.preview_button)
        hbox.addWidget(self.burn_button)

        dialogs.append(self)
        self.show()
        self.token_qty_e.setFocus()
示例#16
0
    def __init__(self, parent):
        super().__init__(parent)

        util.finalization_print_error(self)

        warning_fmt = '<h1 align="center">{0}</h1><p align=center><font size=-1>{1} {2}</font></p><p align=center><font size=-1><a href="{3}" {5}>{3}</a></font></p><p align="center">{4}</p>'
        warning_text = warning_fmt.format(
            _('WARNING'),
            _('Do not enter code here that you don\'t understand. Executing the wrong code could '
              'lead to your coins being irreversibly lost.'),
            _("If someone you do not trust wants you to enter something here, that person might "
              "be attempting a social engineering / phishing attack on you."),
            'https://en.wikipedia.org/wiki/Social_engineering_(security)',
            _("Type: '{}' below to proceed").format('<b>' + self.CONFIRM_TEXT + '</b>'),
            'style="color: #3399ff;"' if ColorScheme.dark_scheme else '',
        )

        style_sheet = self.STYLESHEET_DARK if ColorScheme.dark_scheme else self.STYLESHEET
        style_sheet = style_sheet + self.STYLESHEET_COMMON
        style_sheet = style_sheet + self.STYLESHEET_BORDER_RADIUS
        self.setStyleSheet(style_sheet)

        layout = QtWidgets.QVBoxLayout()
        layout.setContentsMargins(35,35,35,35)
        self.setLayout(layout)

        warning_label = QtWidgets.QLabel(warning_text)
        warning_label.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                    QtWidgets.QSizePolicy.MinimumExpanding)
        warning_label.setWordWrap(True)
        warning_label.setOpenExternalLinks(True)
        layoutLbl = QtWidgets.QVBoxLayout()
        layoutLbl.addWidget(warning_label)
        layout.addLayout(layoutLbl, 1)

        if not ColorScheme.dark_scheme:
            drop_shadow_effect = QtWidgets.QGraphicsDropShadowEffect()
            drop_shadow_effect.setBlurRadius(5.0)
            drop_shadow_effect.setOffset(2.0, 2.0)
            drop_shadow_effect.setColor(QtGui.QColor(63,63,63,100))
            warning_label.setGraphicsEffect(drop_shadow_effect)

        hbox_layout = QtWidgets.QHBoxLayout()
        layout.addLayout(hbox_layout)

        fixed = QtWidgets.QSizePolicy.Fixed
        hbox_layout.addSpacerItem(QtWidgets.QSpacerItem(self.BORDER_RADIUS, 0, fixed, fixed))

        self.input_edit = QtWidgets.QLineEdit()
        self.input_edit.textChanged.connect(self.on_text_changed)
        self.input_edit.returnPressed.connect(self.on_confirm)
        hbox_layout.addWidget(self.input_edit)

        self.confirm_btn = QtWidgets.QPushButton(_("&Confirm"))
        self.confirm_btn.setEnabled(False)
        self.confirm_btn.clicked.connect(self.on_confirm)
        hbox_layout.addWidget(self.confirm_btn)

        self.dontaskagain_cbx = QtWidgets.QCheckBox(_("&Don't ask again"))
        hbox_layout.addWidget(self.dontaskagain_cbx)

        hbox_layout.addSpacerItem(QtWidgets.QSpacerItem(self.BORDER_RADIUS, 0, fixed, fixed))
    def __init__(self, main_window, token_id_hex):
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)
        from .main_window import ElectrumWindow

        assert isinstance(main_window, ElectrumWindow)
        main_window._slp_dialogs.add(self)
        finalization_print_error(self)  # Track object lifecycle

        self.main_window = main_window
        self.wallet = main_window.wallet
        self.network = main_window.network
        self.app = main_window.app

        if self.main_window.gui_object.warn_if_no_network(self.main_window):
            return

        self.setWindowTitle(_("Mint Additional Tokens"))

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        grid = QGridLayout()
        grid.setColumnStretch(1, 1)
        vbox.addLayout(grid)
        row = 0

        msg = _('Unique identifier for the token.')
        grid.addWidget(HelpLabel(_('Token ID:'), msg), row, 0)

        self.token_id_e = QLineEdit()
        self.token_id_e.setFixedWidth(490)
        self.token_id_e.setText(token_id_hex)
        self.token_id_e.setDisabled(True)
        grid.addWidget(self.token_id_e, row, 1)
        row += 1

        msg = _('The number of decimal places used in the token quantity.')
        grid.addWidget(HelpLabel(_('Decimals:'), msg), row, 0)
        self.token_dec = QDoubleSpinBox()
        decimals = self.main_window.wallet.token_types.get(
            token_id_hex)['decimals']
        self.token_dec.setRange(0, 9)
        self.token_dec.setValue(decimals)
        self.token_dec.setDecimals(0)
        self.token_dec.setFixedWidth(50)
        self.token_dec.setDisabled(True)
        grid.addWidget(self.token_dec, row, 1)
        row += 1

        msg = _(
            'The number of tokens created during token minting transaction, send to the receiver address provided below.'
        )
        grid.addWidget(HelpLabel(_('Additional Token Quantity:'), msg), row, 0)
        name = self.main_window.wallet.token_types.get(token_id_hex)['name']
        self.token_qty_e = SLPAmountEdit(name, int(decimals))
        self.token_qty_e.setFixedWidth(200)
        self.token_qty_e.textChanged.connect(self.check_token_qty)
        grid.addWidget(self.token_qty_e, row, 1)
        row += 1

        msg = _(
            'The simpleledger formatted bitcoin address for the genesis receiver of all genesis tokens.'
        )
        grid.addWidget(HelpLabel(_('Token Receiver Address:'), msg), row, 0)
        self.token_pay_to_e = ButtonsLineEdit()
        self.token_pay_to_e.setFixedWidth(490)
        grid.addWidget(self.token_pay_to_e, row, 1)
        row += 1

        msg = _(
            'The simpleledger formatted bitcoin address for the genesis baton receiver.'
        )
        self.token_baton_label = HelpLabel(_('Mint Baton Address:'), msg)
        grid.addWidget(self.token_baton_label, row, 0)
        self.token_baton_to_e = ButtonsLineEdit()
        self.token_baton_to_e.setFixedWidth(490)
        grid.addWidget(self.token_baton_to_e, row, 1)
        row += 1

        try:
            slpAddr = self.wallet.get_unused_address().to_slpaddr()
            self.token_pay_to_e.setText(
                Address.prefix_from_address_string(slpAddr) + ":" + slpAddr)
            self.token_baton_to_e.setText(
                Address.prefix_from_address_string(slpAddr) + ":" + slpAddr)
        except Exception as e:
            pass

        self.token_fixed_supply_cb = cb = QCheckBox(
            _('Permanently end issuance'))
        self.token_fixed_supply_cb.setChecked(False)
        grid.addWidget(self.token_fixed_supply_cb, row, 0)
        cb.clicked.connect(self.show_mint_baton_address)
        row += 1

        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        self.cancel_button = b = QPushButton(_("Cancel"))
        self.cancel_button.setAutoDefault(False)
        self.cancel_button.setDefault(False)
        b.clicked.connect(self.close)
        b.setDefault(True)
        hbox.addWidget(self.cancel_button)

        hbox.addStretch(1)

        self.preview_button = EnterButton(_("Preview"), self.do_preview)
        self.mint_button = b = QPushButton(_("Create Additional Tokens"))
        b.clicked.connect(self.mint_token)
        self.mint_button.setAutoDefault(True)
        self.mint_button.setDefault(True)
        hbox.addWidget(self.preview_button)
        hbox.addWidget(self.mint_button)

        dialogs.append(self)
        self.show()
        self.token_qty_e.setFocus()
    def __init__(self, main_window, *, nft_parent_id=None):
        #self.provided_token_name = token_name
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)
        from .main_window import ElectrumWindow

        assert isinstance(main_window, ElectrumWindow)
        main_window._slp_dialogs.add(self)
        finalization_print_error(self)  # track object lifecycle

        self.main_window = main_window
        self.wallet = main_window.wallet
        self.config = main_window.config
        self.network = main_window.network
        self.app = main_window.app
        self.nft_parent_id = nft_parent_id
        if nft_parent_id != None:
            self.token_type = 65
        else:
            self.token_type = 1

        if self.main_window.gui_object.warn_if_no_network(self.main_window):
            return

        self.setWindowTitle(_("Create a New Token"))

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        grid = QGridLayout()
        grid.setColumnStretch(1, 1)
        vbox.addLayout(grid)
        row = 0

        msg = _(
            'An optional name string embedded in the token genesis transaction.'
        )
        grid.addWidget(HelpLabel(_('Token Name (optional):'), msg), row, 0)
        self.token_name_e = QLineEdit()
        grid.addWidget(self.token_name_e, row, 1)
        row += 1

        msg = _(
            'An optional ticker symbol string embedded into the token genesis transaction.'
        )
        grid.addWidget(HelpLabel(_('Ticker Symbol (optional):'), msg), row, 0)
        self.token_ticker_e = QLineEdit()
        self.token_ticker_e.setFixedWidth(110)
        self.token_ticker_e.textChanged.connect(self.upd_token)
        grid.addWidget(self.token_ticker_e, row, 1)
        row += 1

        msg = _(
            'An optional URL string embedded into the token genesis transaction.'
        )
        grid.addWidget(HelpLabel(_('Document URL (optional):'), msg), row, 0)
        self.token_url_e = QLineEdit()
        self.token_url_e.setFixedWidth(560)
        self.token_url_e.textChanged.connect(self.upd_token)
        grid.addWidget(self.token_url_e, row, 1)
        row += 1

        msg = _('An optional hash hexidecimal bytes embedded into the token genesis transaction for hashing') \
                                                    + 'the document file contents at the URL provided above.'
        grid.addWidget(HelpLabel(_('Document Hash (optional):'), msg), row, 0)
        self.token_dochash_e = QLineEdit()
        self.token_dochash_e.setInputMask(
            "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH")
        self.token_dochash_e.setFixedWidth(560)
        self.token_dochash_e.textChanged.connect(self.upd_token)
        grid.addWidget(self.token_dochash_e, row, 1)
        row += 1

        msg = _('Sets the number of decimals of divisibility for this token (embedded into genesis).') \
                + '\n\n' \
                + _('Each 1 token is divisible into 10^(decimals) base units, and internally in the protocol') \
                + _('the token amounts are represented as 64-bit integers measured in these base units.')
        grid.addWidget(HelpLabel(_('Decimal Places:'), msg), row, 0)
        self.token_ds_e = QDoubleSpinBox()
        self.token_ds_e.setRange(0, 9)
        self.token_ds_e.setDecimals(0)
        self.token_ds_e.setFixedWidth(50)
        self.token_ds_e.valueChanged.connect(self.upd_token)
        grid.addWidget(self.token_ds_e, row, 1)
        row += 1

        msg = _('The number of tokens created during token genesis transaction,') \
                                    + _('send to the receiver address provided below.')
        if nft_parent_id == None:
            self.token_qty_label = HelpLabel(_('Token Quantity:'), msg)
        else:
            self.token_qty_label = HelpLabel(_('Number of Child NFTs:'), msg)
        grid.addWidget(self.token_qty_label, row, 0)
        self.token_qty_e = SLPAmountEdit('', 0)
        self.token_qty_e.setFixedWidth(200)
        self.token_qty_e.textChanged.connect(self.check_token_qty)
        grid.addWidget(self.token_qty_e, row, 1)
        row += 1

        msg = _(
            'The \'simpleledger:\' formatted bitcoin address for the genesis receiver of all genesis tokens.'
        )
        grid.addWidget(HelpLabel(_('Token Receiver Address:'), msg), row, 0)
        self.token_pay_to_e = ButtonsLineEdit()
        self.token_pay_to_e.setFixedWidth(560)
        grid.addWidget(self.token_pay_to_e, row, 1)
        row += 1

        self.token_fixed_supply_cb = cb = QCheckBox(_('Fixed Supply'))
        self.token_fixed_supply_cb.setChecked(True)
        grid.addWidget(self.token_fixed_supply_cb, row, 1)
        cb.clicked.connect(self.show_mint_baton_address)
        row += 1

        self.token_nft_parent_cb = cb = QCheckBox(_('Is NFT Parent?'))
        self.token_nft_parent_cb.setChecked(False)
        grid.addWidget(self.token_nft_parent_cb, row, 1)
        cb.clicked.connect(self.token_nft_parent_cb_update)
        row += 1

        if self.nft_parent_id:
            self.token_nft_parent_cb.setDisabled(True)
            self.token_fixed_supply_cb.setDisabled(True)
            self.token_qty_e.setAmount(1)
            self.token_qty_e.setDisabled(True)
            self.token_ds_e.setDisabled(True)

        msg = _('The \'simpleledger:\' formatted bitcoin address for the "minting baton" receiver.') + '\n\n' \
                + _('After the genesis transaction, further unlimited minting operations can be performed by the owner of') \
                + ' the "minting baton" transaction output. This baton can be repeatedly used for minting operations but' \
                + ' it cannot be duplicated.'
        self.token_baton_label = HelpLabel(_('Address for Baton:'), msg)
        self.token_baton_label.setHidden(True)
        grid.addWidget(self.token_baton_label, row, 0)
        self.token_baton_to_e = ButtonsLineEdit()
        self.token_baton_to_e.setFixedWidth(560)
        self.token_baton_to_e.setHidden(True)
        grid.addWidget(self.token_baton_to_e, row, 1)
        row += 1

        try:
            slpAddr = self.wallet.get_unused_address().to_slpaddr()
            self.token_pay_to_e.setText(
                Address.prefix_from_address_string(slpAddr) + ":" + slpAddr)
            self.token_baton_to_e.setText(
                Address.prefix_from_address_string(slpAddr) + ":" + slpAddr)
        except Exception as e:
            pass

        if nft_parent_id:
            nft_parent_coin = get_nft_parent_coin(nft_parent_id, main_window)
            if not get_nft_parent_coin(nft_parent_id, main_window):
                hbox2 = QHBoxLayout()
                vbox.addLayout(hbox2)
                warnpm = QIcon(":icons/warning.png").pixmap(20, 20)
                self.warn1 = l = QLabel()
                l.setPixmap(warnpm)
                hbox2.addWidget(l)
                self.warn_msg = msg = QLabel(
                    _("     NOTE: The parent token needs to be split before a new NFT can be created, click 'Prepare Group Parent'."
                      ))
                hbox2.addWidget(msg)
                self.warn2 = l = QLabel()
                l.setPixmap(warnpm)
                hbox2.addStretch(1)
                hbox2.addWidget(l)

        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        self.cancel_button = b = QPushButton(_("Cancel"))
        self.cancel_button.setAutoDefault(False)
        self.cancel_button.setDefault(False)
        b.clicked.connect(self.close)
        hbox.addWidget(self.cancel_button)

        hbox.addStretch(1)

        # self.hash_button = b = QPushButton(_("Compute Document Hash..."))
        # self.hash_button.setAutoDefault(False)
        # self.hash_button.setDefault(False)
        # b.clicked.connect(self.hash_file)
        # b.setDefault(True)
        # hbox.addWidget(self.hash_button)

        self.tok_doc_button = b = QPushButton(_("Upload a Token Document..."))
        self.tok_doc_button.setAutoDefault(False)
        self.tok_doc_button.setDefault(False)
        b.clicked.connect(self.show_upload)
        b.setDefault(True)
        hbox.addWidget(self.tok_doc_button)

        if nft_parent_id:
            self.import_burn_tx_file_button = EnterButton(
                _("Import file..."), self.do_process_from_file)
            self.import_burn_tx_text_button = EnterButton(
                _("Import hex..."), self.do_process_from_text)
            hbox.addWidget(self.import_burn_tx_file_button)
            hbox.addWidget(self.import_burn_tx_text_button)

        self.preview_button = EnterButton(_("Preview"), self.do_preview)
        hbox.addWidget(self.preview_button)

        self.create_button = b = QPushButton(
            _("Create New Token"
              ))  #if self.provided_token_name is None else _("Change"))
        b.clicked.connect(self.create_token)
        self.create_button.setAutoDefault(True)
        self.create_button.setDefault(True)
        hbox.addWidget(self.create_button)

        if nft_parent_id:
            self.create_button.setText("Create NFT")
            if not nft_parent_coin:
                self.create_button.setHidden(True)
                self.prepare_parent_bttn = QPushButton(
                    _("Prepare Group Parent"))
                self.prepare_parent_bttn.clicked.connect(
                    self.prepare_nft_parent)
                self.prepare_parent_bttn.setAutoDefault(True)
                self.prepare_parent_bttn.setDefault(True)
                hbox.addWidget(self.prepare_parent_bttn)
                self.token_name_e.setDisabled(True)
                self.token_ticker_e.setDisabled(True)
                self.token_url_e.setDisabled(True)
                self.token_dochash_e.setDisabled(True)
                self.token_pay_to_e.setDisabled(True)
                self.token_baton_to_e.setDisabled(True)

        dialogs.append(self)
        self.show()
        self.token_name_e.setFocus()