def qr_input(self): from electroncash import qrscanner, get_config try: data = qrscanner.scan_barcode(get_config().get_video_device()) except BaseException as e: self.show_error(str(e)) data = '' self.setText(data) return data
def qr_input(self): from electroncash import qrscanner, get_config try: data = qrscanner.scan_barcode(get_config().get_video_device()) except BaseException as e: self.show_error(str(e)) data = '' if not data: data = '' if self.allow_multi: new_text = self.text() + data + '\n' else: new_text = data self.setText(new_text) return data
def warn_if_no_secp(self, parent=None, message=None, icon=QMessageBox.Warning, relaxed=False): ''' Returns True if it DID warn: ie if there's no secp and ecc operations are slow, otherwise returns False if we have secp. Pass message (rich text) to provide a custom message. Note that the URL link to the HOWTO will always be appended to the custom message.''' from electroncash import ecc_fast has_secp = ecc_fast.is_using_fast_ecc() if has_secp: return False # When relaxwarn is set return True without showing the warning from electroncash import get_config if relaxed and get_config().cmdline_options["relaxwarn"]: return True # else.. howto_url = 'https://github.com/Electron-Cash/Electron-Cash/blob/master/contrib/secp_HOWTO.md#libsecp256k1-0-for-electron-cash' template = ''' <html><body> <p> {message} <p> {url_blurb} </p> <p><a href="{url}">Electron Cash Secp Mini-HOWTO</a></p> </body></html> ''' msg = template.format( message=message or _("Electron Cash was unable to find the secp256k1 library on this system. Elliptic curve cryptography operations will be performed in slow Python-only mode." ), url=howto_url, url_blurb= _("Please visit this page for instructions on how to correct the situation:" )) self.warning(parent=parent, title=_("Missing libsecp256k1"), message=msg, rich_text=True) return True
def __init__(self, data, parent=None, title="", show_text=False): WindowModalDialog.__init__(self, parent, title) vbox = QVBoxLayout() qrw = QRCodeWidget(data) p = QPixmap.grabWindow(qrw.winId()) qscreen = QApplication.primaryScreen() vbox.addWidget(qrw, 1) if show_text: text = QTextEdit() text.setText(data) text.setReadOnly(True) vbox.addWidget(text) hbox = QHBoxLayout() hbox.addStretch(1) config = get_config() if config: filename = os.path.join(config.path, "qrcode.png") def print_qr(): p = QPixmap.grabWindow(qrw.winId()) p.save(filename, 'png') self.show_message(_("QR code saved to file") + " " + filename) def copy_to_clipboard(): p = QPixmap.grabWindow(qrw.winId()) p.save(filename, 'png') QApplication.clipboard().setImage(QImage(filename)) self.show_message(_("QR code copied to clipboard")) b = QPushButton(_("Copy")) hbox.addWidget(b) b.clicked.connect(copy_to_clipboard) b = QPushButton(_("Save")) hbox.addWidget(b) b.clicked.connect(print_qr) b = QPushButton(_("Close")) hbox.addWidget(b) b.clicked.connect(self.accept) b.setDefault(True) vbox.addLayout(hbox) self.setLayout(vbox)
def qr_input(self, callback=None): if self.qr_dialog: # Re-entrancy prevention -- there is some lag between when the user # taps the QR button and the modal dialog appears. We want to # prevent multiple instances of the dialog from appearing, so we # must do this. util.print_error( "[ScanQRTextEdit] Warning: QR dialog is already presented, ignoring." ) return from . import ElectrumGui if ElectrumGui.instance.warn_if_cant_import_qrreader(self): return from electroncash import get_config from .qrreader import QrReaderCameraDialog try: self.qr_dialog = QrReaderCameraDialog( parent=self.top_level_window()) def _on_qr_reader_finished(success: bool, error: str, result): if self.qr_dialog: self.qr_dialog.deleteLater() self.qr_dialog = None if not success: if error: self.show_error(error) return if not result: result = '' if self.allow_multi: new_text = self.text() + result + '\n' else: new_text = result self.setText(new_text) if callback and success: callback(result) self.qr_dialog.qr_finished.connect(_on_qr_reader_finished) self.qr_dialog.start_scan(get_config().get_video_device()) except Exception as e: if util.is_verbose: import traceback traceback.print_exc() self.qr_dialog = None self.show_error(str(e))
def __init__(self, parent): ''' Note: make sure parent is a "top_level_window()" as per MessageBoxMixin API else bad things can happen on macOS. ''' QtWidgets.QDialog.__init__(self, parent=parent) self.validator: AbstractQrReaderValidator = None self.frame_id: int = 0 self.qr_crop: QRect = None self.qrreader_res: List[QrCodeResult] = [] self.validator_res: QrReaderValidatorResult = None self.last_stats_time: float = 0.0 self.frame_counter: int = 0 self.qr_frame_counter: int = 0 self.last_qr_scan_ts: float = 0.0 self.camera: QCamera = None self._error_message: str = None self._ok_done: bool = False self.camera_sc_conn = None self.resolution: QSize = None self.config = get_config() # Try to get the QR reader for this system self.qrreader = get_qr_reader() if not self.qrreader: raise MissingQrDetectionLib( _("The platform QR detection library is not available.")) # Set up the window, add the maximize button flags = self.windowFlags() flags = flags | Qt.WindowMaximizeButtonHint self.setWindowFlags(flags) self.setWindowTitle(_("Scan QR Code")) self.setWindowModality( Qt.WindowModal if parent else Qt.ApplicationModal) # Create video widget and fixed aspect ratio layout to contain it self.video_widget = QrReaderVideoWidget() self.video_overlay = QrReaderVideoOverlay() self.video_layout = FixedAspectRatioLayout() self.video_layout.addWidget(self.video_widget) self.video_layout.addWidget(self.video_overlay) # Create root layout and add the video widget layout to it vbox = QtWidgets.QVBoxLayout() self.setLayout(vbox) vbox.setContentsMargins(0, 0, 0, 0) vbox.addLayout(self.video_layout) self.lowres_label = QtWidgets.QLabel( _("Note: This camera generates frames of relatively low resolution; QR scanning accuracy may be affected" )) self.lowres_label.setWordWrap(True) self.lowres_label.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) vbox.addWidget(self.lowres_label) self.lowres_label.setHidden(True) # Create a layout for the controls controls_layout = QtWidgets.QHBoxLayout() controls_layout.addStretch(2) controls_layout.setContentsMargins(10, 10, 10, 10) controls_layout.setSpacing(10) vbox.addLayout(controls_layout) # Flip horizontally checkbox with default coming from global config self.flip_x = QtWidgets.QCheckBox() self.flip_x.setText(_("&Flip horizontally")) self.flip_x.setChecked(bool(self.config.get('qrreader_flip_x', True))) self.flip_x.stateChanged.connect(self._on_flip_x_changed) controls_layout.addWidget(self.flip_x) close_but = QtWidgets.QPushButton(_("&Close")) close_but.clicked.connect(self.reject) controls_layout.addWidget(close_but) # Create the video surface and receive events when new frames arrive self.video_surface = QrReaderVideoSurface(self) self.video_surface.frame_available.connect(self._on_frame_available) # Create the crop blur effect self.crop_blur_effect = QrReaderCropBlurEffect(self) self.image_effect = ImageGraphicsEffect(self, self.crop_blur_effect) # Note these should stay as queued connections becasue we use the idiom # self.reject() and self.accept() in this class to kill the scan -- # and we do it from within callback functions. If you don't use # queued connections here, bad things can happen. self.finished.connect(self._boilerplate_cleanup, Qt.QueuedConnection) self.finished.connect(self._on_finished, Qt.QueuedConnection)
def pay(self, tips: list): """constructs and broadcasts transaction paying the given tips. No questions asked.""" if not self.network: return False if len(tips) <= 0: return False # (re)check wether tips qualify for autopay tips = [tip for tip in tips if self.qualifiesForAutopay(tip)] if len(tips) <= 0: return # label desc = "chaintip " desc_separator = "" for tip in tips: if tip.recipient_address and tip.amount_bch and isinstance( tip.recipient_address, Address) and isinstance( tip.amount_bch, Decimal): desc += f"{desc_separator}{tip.amount_bch} BCH to u/{tip.username} ({tip.chaintip_message_id})" desc_separator = ", " self.print_error("label for tx: ", desc) # construct transaction outputs = [] #outputs.append(OPReturn.output_for_stringdata(op_return)) for tip in tips: address = tip.recipient_address amount = int(COIN * tip.amount_bch) outputs.append((TYPE_ADDRESS, address, amount)) self.print_error("address: ", address, "amount:", amount) try: for tip in tips: tip.payment_status = "autopaying..." tx = self.wallet.mktx(outputs, password=None, config=get_config()) self.print_error("txid:", tx.txid()) self.print_error("tx:", tx) status, msg = self.network.broadcast_transaction(tx) self.print_error("status: ", status, "msg: ", msg) self.resetTimer() if status: # success # set tx label for history self.wallet.set_label(tx.txid(), text=desc, save=True) # this is a half-baked workaround for utxo set not being up-to-date on next payment #self.wallet.wait_until_synchronized() # should give some time #sleep(3) # my god, where have I gone? else: for tip in tips: tip.payment_status = "autopay error: " + msg self.tiplist.updateTip(tip) return status except Exception as e: self.print_error("error creating/sending tx: ", e) if isinstance(e, NotEnoughFunds): error = "not enough funds" else: error = "tx create/send error: " + str(e).partition('\n')[0] for tip in tips: tip.payment_status = error self.tiplist.updateTip(tip) return False