Beispiel #1
0
    def __init__(self, parent, plugin, wallet_name, password, manager):
        QDialog.__init__(self, parent)
        print("Creating")
        self.main_window = parent
        self.wallet = parent.wallet
        self.plugin = plugin
        self.wallet_name = wallet_name
        self.config = parent.config
        self.password = None
        self.contract = None
        if self.wallet.has_password():
            self.main_window.show_error(
                _("Last Will requires password. It will get access to your private keys."
                  ))
            self.password = parent.password_dialog()
            if not self.password:
                print("no password")
                self.plugin.switch_to(Intro, self.wallet_name, None, None)
        self.fund_domain = None
        self.fund_change_address = None
        self.refresh_address = self.wallet.get_unused_address()
        self.inheritor_address = None
        self.cold_address = None
        self.value = 0
        index = self.wallet.get_address_index(self.refresh_address)
        key = self.wallet.keystore.get_private_key(index, self.password)
        self.privkey = int.from_bytes(key[0], 'big')

        if isinstance(self.wallet, Multisig_Wallet):
            self.main_window.show_error(
                "Last Will is designed for single signature wallet only right now"
            )

        vbox = QVBoxLayout()
        self.setLayout(vbox)
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        l = QLabel("<b>%s</b>" % (_("Creatin Last Will contract:")))
        hbox.addWidget(l)
        hbox.addStretch(1)
        b = QPushButton(_("Home"))
        b.clicked.connect(
            lambda: self.plugin.switch_to(Intro, self.wallet_name, None, None))
        hbox.addWidget(b)
        l = QLabel(
            _("Refreshing address") +
            ": auto (this wallet)")  # self.refreshing_address.to_ui_string())
        vbox.addWidget(l)

        grid = QGridLayout()
        vbox.addLayout(grid)

        l = QLabel(_("Inheritor address: "))
        grid.addWidget(l, 0, 0)

        l = QLabel(_("Value"))
        grid.addWidget(l, 0, 1)

        self.inheritor_address_wid = QLineEdit()
        self.inheritor_address_wid.textEdited.connect(
            self.inheritance_info_changed)
        grid.addWidget(self.inheritor_address_wid, 1, 0)

        self.inheritance_value_wid = BTCAmountEdit(
            self.main_window.get_decimal_point)
        self.inheritance_value_wid.textEdited.connect(
            self.inheritance_info_changed)
        grid.addWidget(self.inheritance_value_wid, 1, 1)
        l = QLabel(_("My cold wallet address: "))
        grid.addWidget(l, 2, 0)
        self.cold_address_wid = QLineEdit()
        self.cold_address_wid.textEdited.connect(self.inheritance_info_changed)
        grid.addWidget(self.cold_address_wid, 3, 0)
        b = QPushButton(_("Create Last Will"))
        b.clicked.connect(lambda: self.create_last_will())
        self.notification = NotificationWidget(self)
        vbox.addWidget(self.notification)
        vbox.addStretch(1)
        vbox.addWidget(b)
        self.create_button = b
        self.create_button.setDisabled(True)
        vbox.addStretch(1)
Beispiel #2
0
    def __init__(self, window, plugin, payment_data):
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)

        #print("PaymentDialog", "payment_data =", payment_data)
        self.payment_data = payment_data

        self.plugin = plugin

        # WARNING: Copying some attributes so PayToEdit() will work.
        self.main_window = window
        self.contacts = self.main_window.contacts
        self.is_max = self.main_window.is_max  # Unused, as we do not use max.
        self.completions = self.main_window.completions

        self.count_labels = [
            "Disabled",
            "Once",
            "Always",
        ]
        self.display_count_labels = [
            "Always",
        ]
        run_always_index = self.count_labels.index("Always")

        # NOTE: User entered data, for verification purposes (enabling save/create), and subsequent dispatch on button press.

        self.value_description = ""
        self.value_amount = None
        self.value_payto_outputs = []
        self.value_run_occurrences = self.count_labels.index("Always")
        self.set_flags(0 if self.payment_data is None else self.
                       payment_data[PAYMENT_FLAGS])

        if self.payment_data is not None:
            self.value_description = self.payment_data[PAYMENT_DESCRIPTION]
            self.value_amount = self.payment_data[PAYMENT_AMOUNT]
            self.value_run_occurrences = self.payment_data[PAYMENT_COUNT0]

        # NOTE: Set up the UI for this dialog.
        self.setMinimumWidth(350)
        if payment_data is None:
            self.setWindowTitle(_("Create New Scheduled Payment"))
        else:
            self.setWindowTitle(_("Edit Existing Scheduled Payment"))

        formLayout = QFormLayout()
        self.setLayout(formLayout)

        # Input fields.
        msg = _('Description of the payment (not mandatory).') + '\n\n' + _(
            'The description is not sent to the recipient of the funds. It is stored in your wallet file, and displayed in the \'History\' tab.'
        )
        self.description_label = HelpLabel(_('Description'), msg)
        self.description_edit = MyLineEdit()
        self.description_edit.setText(self.value_description)
        formLayout.addRow(self.description_label, self.description_edit)

        msg = _('How much to pay.') + '\n\n' + _('Unhelpful descriptive text')
        self.amount_label = HelpLabel(_('Amount'), msg)
        self.amount_e = BTCAmountEdit(
            window.get_decimal_point
        )  # WARNING: This has to be named this, as PayToEdit accesses it.
        self.amount_e.setAmount(self.value_amount)
        # WARNING: This needs to be present before PayToEdit is constructed (as that accesses it's attribute on this object),
        # but added to the layout after in order to try and reduce the "cleared amount" problem that happens when an address
        # is entered (perhaps on a selected completion, i.e. of a contact).

        # WARNING: This will clear the amount when an address is set, see PayToEdit.check_text.
        self.payto_edit = PayToEdit(self)
        msg = _('Recipient of the funds.') + '\n\n' + _(
            'You may enter a Bitcoin Cash address, a label from your list of contacts (a list of completions will be proposed), or an alias (email-like address that forwards to a Bitcoin Cash address)'
        )
        payto_label = HelpLabel(_('Pay to'), msg)
        formLayout.addRow(payto_label, self.payto_edit)

        def set_payment_address(address):
            self.payto_edit.payto_address = bitcoin.TYPE_ADDRESS, Address.from_string(
                address)
            self.value_payto_outputs = self.payto_edit.get_outputs(False)
            contact_name = None
            if address in window.wallet.contacts.keys():
                contact_type, contact_name = window.wallet.contacts[address]
            if contact_name is not None:
                self.payto_edit.setText(contact_name + ' <' + address + '>')
            else:
                self.payto_edit.setText(address)

        if payment_data is not None:
            set_payment_address(payment_data[PAYMENT_ADDRESS])

        completer = QCompleter()
        completer.setCaseSensitivity(False)
        self.payto_edit.setCompleter(completer)
        completer.setModel(self.completions)

        # WARNING: We created this before PayToEdit and add it to the layout after, due to the dependency issues with PayToEdit accessing `self.amount_e`.
        formLayout.addRow(self.amount_label, self.amount_e)

        if payment_data is not None:
            text = _("No payments made.")
            if payment_data[PAYMENT_DATELASTPAID] is not None:
                text = datetime.datetime.fromtimestamp(
                    payment_data[PAYMENT_DATELASTPAID]).strftime("%c")
            textLabel = QLabel(text)
            label = HelpLabel(
                _('Last Paid'),
                _('Date last paid.') + '\n\n' +
                _('The date at which this scheduled payment was last meant to send a transaction to the network, which the user acted on'
                  ))
            formLayout.addRow(label, textLabel)

        count_combo = QComboBox()
        count_combo.addItems(self.display_count_labels)
        count_combo.setCurrentIndex(
            self.display_count_labels.index(
                self.count_labels[self.value_run_occurrences]))
        msg = _('Repeat') + '\n\n' + _(
            'The number of times the payment should be made.')
        label = HelpLabel(_('Repeat'), msg)
        formLayout.addRow(label, count_combo)

        # The setting will be cleared if the wallet somehow becomes unencrypted, and will only be available for unencrypted wallets.
        isEnabled = not self.main_window.wallet.has_password(
        ) and window.config.fee_per_kb() is not None
        self.value_autopayment = self.value_autopayment and isEnabled
        # Will show it for now, for encrypted wallets.  Might be less confusing not to show it.
        self.autoPaymentCheckbox = QCheckBox(
            _("Make this payment automatically."))
        self.autoPaymentCheckbox.setToolTip(
            _("Requirements") + ":\n" +
            _("1. The wallet must not have a password.") + "\n" +
            _("2. There must be a default fee/kb configured for the wallet." +
              "\n" +
              _("If this checkbox is interactive and not disabled, these requirements are met."
                )))
        self.autoPaymentCheckbox.setChecked(self.value_autopayment)
        self.autoPaymentCheckbox.setEnabled(isEnabled)
        formLayout.addRow(_("Options"), self.autoPaymentCheckbox)

        import importlib
        from . import when_widget
        importlib.reload(when_widget)
        self.whenWidget = when_widget.WhenWidget(_("When"))
        self.whenWidget.setWhen(
            None if payment_data is None else payment_data[PAYMENT_WHEN])
        formLayout.addRow(self.whenWidget)

        # NOTE: Hook up value events and provide handlers.

        def validate_input_values():
            allow_commit = True
            allow_commit = allow_commit and len(self.value_description) > 0
            allow_commit = allow_commit and self.value_amount is not None and self.value_amount > 0
            allow_commit = allow_commit and len(self.value_payto_outputs) > 0
            allow_commit = allow_commit and self.value_run_occurrences == run_always_index
            # allow_commit = allow_commit and self.value_run_occurrences > -1 and self.value_run_occurrences < len(count_labels)
            self.save_button.setEnabled(allow_commit)

        def on_run_occurrences_changed(unknown):
            self.value_run_occurrences = self.count_labels.index(
                self.display_count_labels[count_combo.currentIndex()])
            validate_input_values()

        count_combo.currentIndexChanged.connect(on_run_occurrences_changed)

        def on_recipient_changed():
            self.value_payto_outputs = self.payto_edit.get_outputs(False)
            validate_input_values()

        self.payto_edit.textChanged.connect(on_recipient_changed)

        def on_amount_changed():
            self.value_amount = self.amount_e.get_amount()
            validate_input_values()

        self.amount_e.textChanged.connect(on_amount_changed)

        def on_description_changed():
            self.value_description = self.description_edit.text().strip()
            validate_input_values()

        self.description_edit.textChanged.connect(on_description_changed)

        def on_autopayment_toggled(v):
            self.value_autopayment = v == Qt.Checked

        self.autoPaymentCheckbox.stateChanged.connect(on_autopayment_toggled)

        # Buttons at bottom right.
        save_button_text = _("Save")
        if payment_data is None:
            save_button_text = _("Create")
        self.save_button = b = QPushButton(save_button_text)
        b.clicked.connect(self.save)

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

        self.buttons = [self.save_button, self.cancel_button]

        hbox = QHBoxLayout()
        #hbox.addLayout(Buttons(*self.sharing_buttons))
        hbox.addStretch(1)
        hbox.addLayout(Buttons(*self.buttons))
        formLayout.addRow(hbox)

        validate_input_values()
        self.update()
Beispiel #3
0
    def __init__(self, parent, plugin, wallet_name, password, tab):
        QDialog.__init__(self, parent)
        self.main_window = parent
        self.password = password
        self.wallet = parent.wallet
        self.plugin = plugin
        self.network = parent.network
        self.wallet_name = wallet_name
        self.distributions = [
            "Regular Distribution", "TF Distribution", "TF-100", "TF-1000",
            "TF-N"
        ]
        vbox = QVBoxLayout()
        self.setLayout(vbox)
        self.tab = Weak.ref(tab)
        self.total_amount = 0
        self.values = []
        self.distributions_combo = QComboBox()
        self.distributions_combo.addItems(self.distributions)
        self.distributions_combo.setCurrentIndex(0)
        self.selected_distribution = 0

        self.distributions_combo.currentIndexChanged.connect(
            self.on_distribution)

        l = QLabel("<b>%s</b>" % (_("Fund Biletoj (preview)")))
        vbox.addWidget(l)
        vbox.addWidget(self.distributions_combo)
        self.total_amount_wid = BTCAmountEdit(
            self.main_window.get_decimal_point)

        self.total_amount_wid.textEdited.connect(self.fund_parameters_changed)
        vbox.addWidget(self.total_amount_wid)
        self.total_amount_wid.setMaximumWidth(70)

        grid = QGridLayout()
        vbox.addLayout(grid)

        grid.addWidget(QLabel("Average: "), 0, 0)
        grid.addWidget(QLabel("Standard deviation: "), 1, 0)
        grid.addWidget(QLabel("Max: "), 2, 0)
        grid.addWidget(QLabel("Min: "), 3, 0)
        grid.addWidget(QLabel("Sum: "), 4, 0)
        self.stats = [QLabel('') for r in range(5)]
        #print(self.stats)
        for i, lab in enumerate(self.stats):
            grid.addWidget(lab, i, 1)
        tab = self.tab()
        self.selected = tab.tu.selectedItems()
        selected = self.selected
        if not selected:
            print("nothing was selected")
            self.closeEvent()
            return
        if isinstance(selected[0].data(1, Qt.UserRole), Address):
            self.addresses = [s.data(1, Qt.UserRole) for s in selected]
        else:
            self.addresses = selected[0].data(1, Qt.UserRole)

        self.p = QPushButton(_("Preview"))
        self.p.clicked.connect(lambda: self.do_fund(preview=True))
        hbox = QHBoxLayout()
        hbox.addWidget(self.p)
        self.b = QPushButton(_("Fund"))
        self.b.clicked.connect(self.do_fund)
        hbox.addWidget(self.b)
        vbox.addLayout(hbox)
        self.b.setDisabled(True)
        self.p.setDisabled(True)
        vbox.addStretch(1)
Beispiel #4
0
    def __init__(self, parent, plugin, wallet_name, password, manager):
        QDialog.__init__(self, parent)
        self.main_window = parent
        self.wallet = parent.wallet
        self.plugin = plugin
        self.wallet_name = wallet_name
        self.config = parent.config
        self.password = None
        self.contract = None
        self.version = 1
        if self.wallet.has_password():
            self.main_window.show_error(
                _("Plugin requires password. It will get access to your private keys."
                  ))
            self.password = parent.password_dialog()
            if not self.password:
                print("no password")
                self.plugin.switch_to(Intro, self.wallet_name, None, None)
        self.fund_domain = None
        self.fund_change_address = None
        self.sender_address = self.wallet.get_unused_address()
        self.receiver_address = None
        self.arbiter_address = None
        self.total_value = 0
        index = self.wallet.get_address_index(self.sender_address)
        key = self.wallet.keystore.get_private_key(index, self.password)
        self.privkey = int.from_bytes(key[0], 'big')

        if isinstance(self.wallet, Multisig_Wallet):
            self.main_window.show_error(
                "Simple Escrow Plugin is designed for single signature wallets."
            )

        vbox = QVBoxLayout()
        self.setLayout(vbox)
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        l = QLabel("<b>%s</b>" % (_("Creatin 2-of-3 Multisig contract:")))
        hbox.addWidget(l)
        hbox.addStretch(1)
        b = QPushButton(_("Home"))
        b.clicked.connect(
            lambda: self.plugin.switch_to(Intro, self.wallet_name, None, None))
        hbox.addWidget(b)
        l = QLabel(
            _("Refund address") +
            ": auto (this wallet)")  # self.refreshing_address.to_ui_string())
        vbox.addWidget(l)
        l = QLabel(_("Receiver address: "))
        vbox.addWidget(l)

        self.receiver_address_wid = QLineEdit()
        self.receiver_address_wid.textEdited.connect(
            self.new_contract_info_changed)
        vbox.addWidget(self.receiver_address_wid)

        l = QLabel(_("Arbiter address: "))
        vbox.addWidget(l)

        self.arbiter_address_wid = QLineEdit()
        self.arbiter_address_wid.textEdited.connect(
            self.new_contract_info_changed)
        vbox.addWidget(self.arbiter_address_wid)

        self.value_wid = BTCAmountEdit(self.main_window.get_decimal_point)
        self.value_wid.setAmount(1000000)
        self.value_wid.textEdited.connect(self.new_contract_info_changed)
        vbox.addWidget(self.value_wid)
        b = QPushButton(_("Create Escrow Contract"))
        b.clicked.connect(self.create_new_contract)
        vbox.addStretch(1)
        vbox.addWidget(b)
        self.create_button = b
        self.create_button.setDisabled(True)
        vbox.addStretch(1)
Beispiel #5
0
    def __init__(self, parent, plugin, wallet_name, password, manager):
        QDialog.__init__(self, parent)
        self.main_window = parent
        self.wallet = parent.wallet
        self.plugin = plugin
        self.wallet_name = wallet_name
        self.config = parent.config
        self.password = None
        self.contract = None
        self.version = 1
        if self.wallet.has_password():
            self.main_window.show_error(
                _("Plugin requires password. It will get access to your private keys."
                  ))
            self.password = parent.password_dialog()
            if not self.password:
                print("no password")
                self.plugin.switch_to(Intro, self.wallet_name, None, None)
        self.fund_domain = None
        self.fund_change_address = None
        self.mecenas_address = self.wallet.get_unused_address()
        self.protege_address = None
        self.escrow_address = None
        self.addresses = []
        self.total_value = 0
        self.rpayment_value = 0
        self.rpayment_time = 0
        self.reps = 0
        index = self.wallet.get_address_index(self.mecenas_address)
        key = self.wallet.keystore.get_private_key(index, self.password)
        self.privkey = int.from_bytes(key[0], 'big')

        if isinstance(self.wallet, Multisig_Wallet):
            self.main_window.show_error(
                "Mecenas is designed for single signature wallet only right now"
            )

        vbox = QVBoxLayout()
        self.setLayout(vbox)
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        l = QLabel("<b>%s</b>" % (_("Creatin Mecenas contract:")))
        hbox.addWidget(l)
        hbox.addStretch(1)
        b = QPushButton(_("Home"))
        b.clicked.connect(
            lambda: self.plugin.switch_to(Intro, self.wallet_name, None, None))
        hbox.addWidget(b)
        l = QLabel(
            _("Redeem address") +
            ": auto (this wallet)")  # self.refreshing_address.to_ui_string())
        vbox.addWidget(l)

        l = QLabel(_("Protege address: "))
        vbox.addWidget(l)

        self.protege_address_wid = QLineEdit()
        self.protege_address_wid.textEdited.connect(self.mecenate_info_changed)
        vbox.addWidget(self.protege_address_wid)

        grid = QGridLayout()
        vbox.addLayout(grid)

        l = QLabel(_("Recurring payment value: "))
        grid.addWidget(l, 0, 0)
        l = QLabel(_("Repetitions:"))
        grid.addWidget(l, 0, 1)

        l = QLabel(_("Period (days): "))
        grid.addWidget(l, 0, 2)

        self.rpayment_value_wid = BTCAmountEdit(
            self.main_window.get_decimal_point)
        self.rpayment_value_wid.setAmount(1000000)
        self.rpayment_value_wid.textEdited.connect(self.mecenate_info_changed)

        self.repetitions = QLineEdit()
        self.repetitions.textEdited.connect(self.mecenate_info_changed)
        grid.addWidget(self.repetitions, 1, 1)

        self.rpayment_time_wid = QLineEdit()
        self.rpayment_time_wid.setText("30")
        self.rpayment_time_wid.textEdited.connect(self.mecenate_info_changed)
        grid.addWidget(self.rpayment_value_wid, 1, 0)
        grid.addWidget(self.rpayment_time_wid, 1, 2)
        grid.addWidget(QLabel("Total contract value:"), 2, 0)
        self.total_label = QLabel("0")
        hbox = QHBoxLayout()
        hbox.addWidget(self.total_label)
        hbox.addStretch(1)
        hbox.addWidget(QLabel("Total time:"))
        #grid.addWidget(self.total_label,2,1)
        grid.addLayout(hbox, 2, 1)
        self.total_time_label = QLabel("0")
        grid.addWidget(self.total_time_label, 2, 2)
        self.advanced_wid = AdvancedWid(self)
        self.advanced_wid.toggle_sig.connect(self.mecenate_info_changed)
        vbox.addWidget(self.advanced_wid)
        b = QPushButton(_("Create Mecenas Contract"))
        b.clicked.connect(self.create_mecenat)
        vbox.addStretch(1)
        vbox.addWidget(b)
        self.create_button = b
        self.create_button.setDisabled(True)
        vbox.addStretch(1)
    def __init__(self, window, plugin, payment_data):
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)

        #print("PaymentDialog", "payment_data =", payment_data)
        self.payment_data = payment_data

        self.plugin = plugin

        # WARNING: Copying some attributes so PayToEdit() will work.
        self.main_window = window
        self.contacts = self.main_window.contacts
        self.completions = self.main_window.completions

        self.count_labels = [
            "Disabled",
            "Once",
            "Always",
        ]
        self.display_count_labels = [
            "Always",
        ]
        run_always_index = self.count_labels.index("Always")

        # NOTE: User entered data, for verification purposes (enabling save/create), and subsequent dispatch on button press.

        self.value_description = ""
        self.value_amount = None
        self.value_payto_outputs = []
        self.value_run_occurrences = self.count_labels.index("Always")
        self.set_flags(0 if self.payment_data is None else self.
                       payment_data[PAYMENT_FLAGS])
        payment_was_fiat = False

        if self.payment_data is not None:
            self.value_description = self.payment_data[PAYMENT_DESCRIPTION]
            self.value_amount = abs(self.payment_data[PAYMENT_AMOUNT])
            payment_was_fiat = self.payment_data[
                PAYMENT_FLAGS] & PAYMENT_FLAG_AMOUNT_IS_FIAT
            self.value_run_occurrences = self.payment_data[PAYMENT_COUNT0]

        # NOTE: Set up the UI for this dialog.
        self.setMinimumWidth(500)
        if payment_data is None:
            self.setWindowTitle(_("Create New Scheduled Payment"))
        else:
            self.setWindowTitle(_("Edit Existing Scheduled Payment"))

        formLayout = QFormLayout()
        self.setLayout(formLayout)
        formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)

        # Input fields.
        msg = _('Description of the payment (not mandatory).') + '\n\n' + _(
            'The description is not sent to the recipient of the funds. It is stored in your wallet file, and displayed in the \'History\' tab.'
        )
        self.description_label = HelpLabel(_('Description'), msg)
        self.description_edit = MyLineEdit()
        self.description_edit.setText(self.value_description)
        formLayout.addRow(self.description_label, self.description_edit)

        msg = _('How much to pay.') + '\n\n' + _('Unhelpful descriptive text')
        self.amount_label = HelpLabel(_('Amount'), msg)
        self.amount_e = BTCAmountEdit(
            window.get_decimal_point
        )  # WARNING: This has to be named this, as PayToEdit accesses it.
        if not payment_was_fiat:
            self.amount_e.setAmount(self.value_amount)
        else:
            self.amount_e.setHidden(True)
        # WARNING: This needs to be present before PayToEdit is constructed (as that accesses it's attribute on this object),
        # but added to the layout after in order to try and reduce the "cleared amount" problem that happens when an address
        # is entered (perhaps on a selected completion, i.e. of a contact).

        # WARNING: This will clear the amount when an address is set, see PayToEdit.check_text.
        self.payto_edit = PayToEdit(self)
        self.payto_edit.setSizePolicy(QSizePolicy.MinimumExpanding,
                                      QSizePolicy.Preferred)
        msg = _('Recipient of the funds.') + '\n\n' + _(
            'You may enter a Bitcoin Cash address, a label from your list of contacts (a list of completions will be proposed), or an alias (email-like address that forwards to a Bitcoin Cash address)'
        )
        payto_label = HelpLabel(_('Pay to'), msg)
        formLayout.addRow(payto_label, self.payto_edit)

        def set_payment_address(address):
            self.payto_edit.payto_address = bitcoin.TYPE_ADDRESS, Address.from_string(
                address)
            self.value_payto_outputs = self.payto_edit.get_outputs(False)
            contact_name = None
            contacts = window.wallet.contacts
            if isinstance(contacts, dict):
                # old contacts API
                if address in contacts.keys():
                    _ign, contact_name = contacts[address]
            else:
                # new contacts API - find the contact, extract type & name
                try:
                    for c in contacts.find(address=address):
                        contact_name = c.name
                except Exception as e:
                    print_error("Could not determine contacts API, giving up:",
                                repr(e))
            if contact_name is not None:
                self.payto_edit.setText(contact_name + ' <' + address + '>')
            else:
                if Address.is_valid(address):
                    address = Address.from_string(address).to_ui_string()
                self.payto_edit.setText(address)

        if payment_data is not None:
            set_payment_address(payment_data[PAYMENT_ADDRESS])

        completer = QCompleter()
        completer.setCaseSensitivity(False)
        self.payto_edit.setCompleter(completer)
        completer.setModel(self.completions)

        amount_hbox = QHBoxLayout()
        self.useFiatCheckbox = QCheckBox(
            _("Denomiate payment in FIAT rather than BCH"))
        self.useFiatCheckbox.setToolTip(
            _("If you elect to denomiate the payment in FIAT, then the BCH transaction\nuses the FIAT price at the time of payment to determine how much\nactual BCH is transmitted to your payee."
              ) + "\n\n" + _("Requirements") + ":\n" +
            _("1. You must have a fiat currency defined and a server enabled in settings."
              ) + "\n" +
            _("2. The fiat spot price quote must but be available from the FX server."
              + "\n" +
              _("If this checkbox is interactive and not disabled, these requirements are met."
                )))
        isFiatEnabled = self.plugin.can_do_fiat(self.main_window)
        self.useFiatCheckbox.setChecked(payment_was_fiat)
        self.useFiatCheckbox.setEnabled(isFiatEnabled)

        self.fiat_amount_e = AmountEdit(
            self.main_window.fx.get_currency if isFiatEnabled else '')
        self.fiat_amount_e.setHidden(not payment_was_fiat)
        if payment_was_fiat:
            self.fiat_amount_e.setText(str(self.value_amount))

        amount_hbox.addWidget(
            self.amount_e
        )  # either this or fiat_amount_e are visible at any 1 time
        amount_hbox.addWidget(
            self.fiat_amount_e
        )  # either this or amoune_e are visible at any 1 time
        amount_hbox.addWidget(self.useFiatCheckbox)

        def useFiatToggled(b):
            # Note we do it this explicit way because the order matters to avoid quick visual glitches as widgets
            # pop into and out of existence.  Hiding the visible one then revealing the invisible one is the best way
            # to avoid glitches.  The reverse causes a slight detectable spastication of the UI. :/  -Calin
            if b:
                self.amount_e.setHidden(True)
                self.fiat_amount_e.setHidden(False)
            else:
                self.fiat_amount_e.setHidden(True)
                self.amount_e.setHidden(False)

        self.useFiatCheckbox.toggled.connect(useFiatToggled)

        # WARNING: We created this before PayToEdit and add it to the layout after, due to the dependency issues with PayToEdit accessing `self.amount_e`.
        formLayout.addRow(self.amount_label, amount_hbox)

        if payment_data is not None:
            text = _("No payments made.")
            if payment_data[PAYMENT_DATELASTPAID] is not None:
                text = datetime.datetime.fromtimestamp(
                    payment_data[PAYMENT_DATELASTPAID]).strftime("%c")
            textLabel = QLabel(text)
            label = HelpLabel(
                _('Last Paid'),
                _('Date last paid.') + '\n\n' +
                _('The date at which this scheduled payment was last meant to send a transaction to the network, which the user acted on'
                  ))
            formLayout.addRow(label, textLabel)

        count_combo = QComboBox()
        count_combo.addItems(self.display_count_labels)
        count_combo.setCurrentIndex(
            self.display_count_labels.index(
                self.count_labels[self.value_run_occurrences]))
        msg = _('Repeat') + '\n\n' + _(
            'The number of times the payment should be made.')
        label = HelpLabel(_('Repeat'), msg)
        formLayout.addRow(label, count_combo)

        # The setting will be cleared if the wallet somehow becomes unencrypted, and will only be available for unencrypted wallets.
        isEnabled = not self.main_window.wallet.has_password(
        ) and window.config.fee_per_kb() is not None
        self.value_autopayment = self.value_autopayment and isEnabled
        # Will show it for now, for encrypted wallets.  Might be less confusing not to show it.
        options_hbox = QHBoxLayout()
        self.autoPaymentCheckbox = QCheckBox(
            _("Make this payment automatically"))
        self.autoPaymentCheckbox.setToolTip(
            _("Requirements") + ":\n" +
            _("1. The wallet must not have a password.") + "\n" +
            _("2. There must be a default fee/kb configured for the wallet." +
              "\n" +
              _("If this checkbox is interactive and not disabled, these requirements are met."
                )))
        self.autoPaymentCheckbox.setChecked(self.value_autopayment)
        self.autoPaymentCheckbox.setEnabled(isEnabled)
        options_hbox.addWidget(self.autoPaymentCheckbox)

        formLayout.addRow(_("Options"), options_hbox)

        import importlib
        from . import when_widget
        importlib.reload(when_widget)
        self.whenWidget = when_widget.WhenWidget(_("When"))
        self.whenWidget.setWhen(
            None if payment_data is None else payment_data[PAYMENT_WHEN])
        formLayout.addRow(self.whenWidget)

        # NOTE: Hook up value events and provide handlers.

        def validate_input_values():
            allow_commit = True
            allow_commit = allow_commit and len(self.value_description) > 0
            allow_commit = allow_commit and self.value_amount is not None and self.value_amount > 0
            allow_commit = allow_commit and len(self.value_payto_outputs) > 0
            allow_commit = allow_commit and self.value_run_occurrences == run_always_index
            # allow_commit = allow_commit and self.value_run_occurrences > -1 and self.value_run_occurrences < len(count_labels)
            self.save_button.setEnabled(allow_commit)

        def on_run_occurrences_changed(unknown):
            self.value_run_occurrences = self.count_labels.index(
                self.display_count_labels[count_combo.currentIndex()])
            validate_input_values()

        count_combo.currentIndexChanged.connect(on_run_occurrences_changed)

        def on_recipient_changed():
            self.value_payto_outputs = self.payto_edit.get_outputs(False)
            validate_input_values()

        self.payto_edit.textChanged.connect(on_recipient_changed)

        def on_amount_changed():
            self.value_amount = self.amount_e.get_amount(
            ) if not self.useFiatCheckbox.isChecked() else float(
                self.fiat_amount_e.get_amount() or 0.00)
            validate_input_values()

        self.amount_e.textChanged.connect(on_amount_changed)
        self.fiat_amount_e.textChanged.connect(on_amount_changed)
        self.useFiatCheckbox.toggled.connect(on_amount_changed)

        def on_description_changed():
            self.value_description = self.description_edit.text().strip()
            validate_input_values()

        self.description_edit.textChanged.connect(on_description_changed)

        def on_autopayment_toggled(v):
            self.value_autopayment = v == Qt.Checked

        self.autoPaymentCheckbox.stateChanged.connect(on_autopayment_toggled)

        # Buttons at bottom right.
        save_button_text = _("Save")
        if payment_data is None:
            save_button_text = _("Create")
        self.save_button = b = QPushButton(save_button_text)
        b.clicked.connect(self.save)

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

        # pet peeve -- on macOS it's customary to have cancel on left, action-on-right in dialogs
        if sys.platform == 'darwin':
            self.buttons = [self.cancel_button, self.save_button]
        else:
            self.buttons = [self.save_button, self.cancel_button]

        hbox = QHBoxLayout()
        #hbox.addLayout(Buttons(*self.sharing_buttons))
        hbox.addStretch(1)
        hbox.addLayout(Buttons(*self.buttons))
        formLayout.addRow(hbox)

        validate_input_values()
        self.update()