Skip to content
Snippets Groups Projects
Commit bc170dd8 authored by inso's avatar inso
Browse files

Fix context menu with pubkeys

parent 3bfa4629
Branches
Tags
No related merge requests found
......@@ -3,6 +3,7 @@ from .table_model import HistoryTableModel, TxFilterProxyModel
from PyQt5.QtCore import Qt, QDateTime, QTime, pyqtSignal, QModelIndex
from sakia.errors import NoPeerAvailable
from duniterpy.api import errors
from sakia.data.entities import Identity
import logging
......@@ -66,11 +67,15 @@ class TxHistoryModel(QObject):
pubkey_col = self.table_model.sourceModel().columns_types.index('pubkey')
pubkey_index = self.table_model.sourceModel().index(source_index.row(), pubkey_col)
pubkeys = self.table_model.sourceModel().data(pubkey_index, Qt.DisplayRole)
identities = []
identities_or_pubkeys = []
for pubkey in pubkeys:
identities.append(self.identities_service.get_identity(pubkey))
identity = self.identities_service.get_identity(pubkey)
if identity:
identities_or_pubkeys.append(identity)
else:
identities_or_pubkeys.append(pubkey)
transfer = self._model.transfers_data[source_index.row()][self._model.columns_types.index('raw_data')]
return True, identities, transfer
return True, identities_or_pubkeys, transfer
return False, [], None
def minimum_maximum_datetime(self):
......
......@@ -20,6 +20,37 @@
<string>Balance</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>6</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_balance">
<property name="font">
......@@ -37,16 +68,14 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>6</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
......
......@@ -2,7 +2,7 @@ import asyncio
import logging
from PyQt5.QtCore import Qt, QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout
from sakia.data.processors import ConnectionsProcessor
from sakia.decorators import asyncify
......@@ -10,6 +10,7 @@ from sakia.gui.sub.password_input import PasswordInputController
from sakia.gui.sub.search_user.controller import SearchUserController
from sakia.gui.sub.user_information.controller import UserInformationController
from sakia.money import Quantitative
from sakia.gui.widgets.dialogs import dialog_async_exec
from .model import TransferModel
from .view import TransferView
......@@ -71,41 +72,73 @@ class TransferController(QObject):
return transfer
@classmethod
async def send_money_to_identity(cls, parent, app, connection, identity):
dialog = cls.create(parent, app)
dialog.view.groupbox_connection.show()
dialog.view.combo_connections.setCurrentText(connection.title())
dialog.user_information.change_identity(identity)
dialog.view.edit_pubkey.setText(identity.pubkey)
dialog.view.radio_pubkey.setChecked(True)
dialog.refresh()
def open_transfer_with_pubkey(cls, parent, app, connection, pubkey):
transfer = cls.create(parent, app)
transfer.view.groupbox_connection.show()
transfer.view.combo_connections.setCurrentText(connection.title())
transfer.view.edit_pubkey.setText(pubkey)
transfer.view.radio_pubkey.setChecked(True)
transfer.refresh()
return transfer
@classmethod
def send_transfer_again(cls, parent, app, connection, resent_transfer):
dialog = cls.create(parent, app)
dialog.view.groupbox_connection.show()
dialog.view.label_total.show()
dialog.view.combo_connections.setCurrentText(connection.title())
dialog.view.edit_pubkey.setText(resent_transfer.receivers[0])
dialog.view.radio_pubkey.setChecked(True)
def send_money_to_pubkey(cls, parent, app, connection, pubkey):
dialog = QDialog(parent)
dialog.setWindowTitle(dialog.tr("Transfer"))
dialog.setLayout(QVBoxLayout(dialog))
transfer = cls.open_transfer_with_pubkey(parent, app, connection, pubkey)
dialog.refresh()
dialog.layout().addWidget(transfer.view)
transfer.accepted.connect(dialog.accept)
transfer.rejected.connect(dialog.reject)
return dialog.exec()
current_base = dialog.model.current_base()
@classmethod
def send_money_to_identity(cls, parent, app, connection, identity):
dialog = QDialog(parent)
dialog.setWindowTitle(dialog.tr("Transfer"))
dialog.setLayout(QVBoxLayout(dialog))
transfer = cls.open_transfer_with_pubkey(parent, app, connection, identity.pubkey)
transfer.user_information.change_identity(identity)
dialog.layout().addWidget(transfer.view)
transfer.accepted.connect(dialog.accept)
transfer.rejected.connect(dialog.reject)
return dialog.exec()
@classmethod
def send_transfer_again(cls, parent, app, connection, resent_transfer):
dialog = QDialog(parent)
dialog.setWindowTitle(dialog.tr("Transfer"))
dialog.setLayout(QVBoxLayout(dialog))
transfer = cls.create(parent, app)
transfer.view.groupbox_connection.show()
transfer.view.label_total.show()
transfer.view.combo_connections.setCurrentText(connection.title())
transfer.view.edit_pubkey.setText(resent_transfer.receivers[0])
transfer.view.radio_pubkey.setChecked(True)
transfer.refresh()
current_base = transfer.model.current_base()
current_base_amount = resent_transfer.amount / pow(10, resent_transfer.amount_base - current_base)
relative = dialog.model.quant_to_rel(current_base_amount / 100)
dialog.view.set_spinboxes_parameters(current_base_amount / 100, relative)
dialog.view.change_relative_amount(relative)
dialog.view.change_quantitative_amount(current_base_amount / 100)
relative = transfer.model.quant_to_rel(current_base_amount / 100)
transfer.view.set_spinboxes_parameters(current_base_amount / 100, relative)
transfer.view.change_relative_amount(relative)
transfer.view.change_quantitative_amount(current_base_amount / 100)
connections_processor = ConnectionsProcessor.instanciate(app)
wallet_index = connections_processor.connections().index(connection)
dialog.view.combo_connections.setCurrentIndex(wallet_index)
dialog.view.edit_pubkey.setText(resent_transfer.receivers[0])
dialog.view.radio_pubkey.setChecked(True)
dialog.view.edit_message.setText(resent_transfer.comment)
transfer.view.combo_connections.setCurrentIndex(wallet_index)
transfer.view.edit_pubkey.setText(resent_transfer.receivers[0])
transfer.view.radio_pubkey.setChecked(True)
transfer.view.edit_message.setText(resent_transfer.comment)
dialog.layout().addWidget(transfer.view)
transfer.accepted.connect(dialog.accept)
transfer.rejected.connect(dialog.reject)
return dialog.exec()
def integrate_to_main_view(self, connection):
self.view.combo_connections.setCurrentText(connection.title())
......@@ -210,14 +243,3 @@ class TransferController(QObject):
self.model.set_connection(index)
self.password_input.set_connection(self.model.connection)
self.refresh()
def async_exec(self):
future = asyncio.Future()
self.view.finished.connect(lambda r: future.set_result(r))
self.view.open()
self.refresh()
return future
def exec(self):
self.refresh()
self.view.exec()
import logging
import re
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QMenu, QAction, QApplication, QMessageBox
from duniterpy.documents.constants import pubkey_regex
from sakia.data.entities import Identity, Transaction, Dividend
from sakia.data.processors import BlockchainProcessor, TransactionsProcessor
from sakia.decorators import asyncify
......@@ -32,17 +33,12 @@ class ContextMenu(QObject):
:param ContextMenu menu: the qmenu to add actions to
:param Identity identity: the identity
"""
menu.qmenu.addSeparator().setText(identity.uid if identity.uid else "Pubkey")
menu.qmenu.addSeparator().setText(identity.uid if identity.uid else identity.pubkey[:7])
informations = QAction(menu.qmenu.tr("Informations"), menu.qmenu.parent())
informations.triggered.connect(lambda checked, i=identity: menu.informations(i))
menu.qmenu.addAction(informations)
if menu._connection.pubkey != identity.pubkey:
send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
send_money.triggered.connect(lambda checked, i=identity: menu.send_money(i))
menu.qmenu.addAction(send_money)
if identity.uid and menu._connection.pubkey != identity.pubkey:
certify = QAction(menu.tr("Certify identity"), menu.qmenu.parent())
certify.triggered.connect(lambda checked, i=identity: menu.certify_identity(i))
......@@ -52,6 +48,10 @@ class ContextMenu(QObject):
view_wot.triggered.connect(lambda checked, i=identity: menu.view_wot(i))
menu.qmenu.addAction(view_wot)
send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
send_money.triggered.connect(lambda checked, i=identity: menu.send_money(i))
menu.qmenu.addAction(send_money)
copy_pubkey = QAction(menu.qmenu.tr("Copy pubkey to clipboard"), menu.qmenu.parent())
copy_pubkey.triggered.connect(lambda checked, i=identity: ContextMenu.copy_pubkey_to_clipboard(i))
menu.qmenu.addAction(copy_pubkey)
......@@ -88,6 +88,19 @@ class ContextMenu(QObject):
menu.copy_block_to_clipboard(transfer.blockstamp.number))
menu.qmenu.addAction(copy_doc)
@staticmethod
def _add_string_actions(menu, str_value):
if re.match(pubkey_regex, str_value):
menu.qmenu.addSeparator().setText(str_value[:7])
copy_pubkey = QAction(menu.qmenu.tr("Copy pubkey to clipboard"), menu.qmenu.parent())
copy_pubkey.triggered.connect(lambda checked, p=str_value: ContextMenu.copy_pubkey_to_clipboard(p))
menu.qmenu.addAction(copy_pubkey)
if menu._connection.pubkey != str_value:
send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
send_money.triggered.connect(lambda checked, p=str_value: menu.send_money(p))
menu.qmenu.addAction(send_money)
@classmethod
def from_data(cls, parent, app, connection, data):
"""
......@@ -105,6 +118,7 @@ class ContextMenu(QObject):
Identity: ContextMenu._add_identity_actions,
Transaction: ContextMenu._add_transfers_actions,
Dividend: lambda m, d: None,
str: ContextMenu._add_string_actions,
dict: lambda m, d: None,
type(None): lambda m, d: None
}
......@@ -114,9 +128,12 @@ class ContextMenu(QObject):
return menu
@staticmethod
def copy_pubkey_to_clipboard(identity):
def copy_pubkey_to_clipboard(identity_or_pubkey):
clipboard = QApplication.clipboard()
clipboard.setText(identity.pubkey)
if isinstance(identity_or_pubkey, Identity):
clipboard.setText(identity_or_pubkey.pubkey)
else:
clipboard.setText(identity_or_pubkey)
def informations(self, identity):
if identity.uid:
......@@ -126,9 +143,11 @@ class ContextMenu(QObject):
UserInformationController.search_and_show_pubkey(self.parent(), self._app,
identity.pubkey)
@asyncify
async def send_money(self, identity):
await TransferController.send_money_to_identity(None, self._app, self._connection, identity)
def send_money(self, identity_or_pubkey):
if isinstance(identity_or_pubkey, Identity):
TransferController.send_money_to_identity(None, self._app, self._connection, identity_or_pubkey)
else:
TransferController.send_money_to_pubkey(None, self._app, self._connection, identity_or_pubkey)
def view_wot(self, identity):
self.view_identity_in_wot.emit(identity)
......
......@@ -73,6 +73,9 @@ class IdentitiesService(QObject):
identities.append(self._identities_processor.get_identity(self.currency, c.pubkey))
return identities
def is_identity_of_connection(self, identity):
return identity.pubkey in self._connections_processor.pubkeys()
async def load_memberships(self, identity):
"""
Request the identity data and save it to written identities
......@@ -97,14 +100,14 @@ class IdentitiesService(QObject):
identity.membership_written_on = ms["written"]
identity = await self.load_requirements(identity)
# We save connections pubkeys
if identity.pubkey in self._connections_processor.pubkeys():
identity.written = True
if self.is_identity_of_connection(identity):
self._identities_processor.insert_or_update_identity(identity)
except errors.DuniterError as e:
logging.debug(str(e))
if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
identity.written = False
if identity.pubkey in self._connections_processor.pubkeys():
if self.is_identity_of_connection(identity):
self._identities_processor.insert_or_update_identity(identity)
except NoPeerAvailable as e:
logging.debug(str(e))
......@@ -136,7 +139,7 @@ class IdentitiesService(QObject):
cert.block)
certifiers.append(cert)
# We save connections pubkeys
if identity.pubkey in self._connections_processor.pubkeys():
if self.is_identity_of_connection(identity):
self._certs_processor.insert_or_update_certification(cert)
for signed_data in result["signed"]:
cert = Certification(currency=self.currency,
......@@ -148,7 +151,7 @@ class IdentitiesService(QObject):
if cert not in certified:
certified.append(cert)
# We save connections pubkeys
if identity.pubkey in self._connections_processor.pubkeys():
if self.is_identity_of_connection(identity):
cert.timestamp = await self._blockchain_processor.timestamp(self.currency,
cert.block)
self._certs_processor.insert_or_update_certification(cert)
......@@ -183,7 +186,7 @@ class IdentitiesService(QObject):
self._certs_processor.insert_or_update_certification(cert)
identity.written = True
if identity.pubkey in self._connections_processor.pubkeys():
if self.is_identity_of_connection(identity):
self._identities_processor.insert_or_update_identity(identity)
except errors.DuniterError as e:
if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
......@@ -219,7 +222,7 @@ class IdentitiesService(QObject):
self._certs_processor.insert_or_update_certification(cert)
identity.written = True
if identity.pubkey in self._connections_processor.pubkeys():
if self.is_identity_of_connection(identity):
self._identities_processor.insert_or_update_identity(identity)
except errors.DuniterError as e:
if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment