diff --git a/src/cutecoin/gui/views/wot.py b/src/cutecoin/gui/views/wot.py index e5f64c9176376a659b9aa8a488f7937b178aaea0..42d684065dbe52e944beb856d3147e36631a3479 100644 --- a/src/cutecoin/gui/views/wot.py +++ b/src/cutecoin/gui/views/wot.py @@ -55,9 +55,11 @@ class WotView(QGraphicsView): class Scene(QGraphicsScene): - # This defines a signal called 'nodeSigned' that takes on string argument - node_signed = pyqtSignal(str, name='nodeSigned') + # This defines signals taking string arguments node_clicked = pyqtSignal(str, name='nodeClicked') + node_signed = pyqtSignal(dict, name='nodeSigned') + node_transaction = pyqtSignal(dict, name='nodeTransaction') + node_contact = pyqtSignal(dict, name='nodeContact') def __init__(self, parent=None): """ @@ -74,21 +76,20 @@ class Scene(QGraphicsScene): # self.addLine(-100, 0, 100, 0) # self.addLine(0, -100, 0, 100) - def add_node(self, _id, node, pos): + def add_node(self, metadata, pos): """ Add a node item in the graph - :param str _id: Node id - :param dict node: Node data + :param dict metadata: Node metadata :param tuple pos: Position (x,y) of the node :return: Node """ - node = Node(_id, node, pos) + node = Node(metadata, pos) self.addItem(node) return node - def add_arc(self, source_node, destination_node, arc): + def add_arc(self, source_node, destination_node, metadata): """ Add an arc between two nodes @@ -98,7 +99,7 @@ class Scene(QGraphicsScene): :return: Arc """ - arc = Arc(source_node, destination_node, arc) + arc = Arc(source_node, destination_node, metadata) self.addItem(arc) return arc @@ -117,7 +118,7 @@ class Scene(QGraphicsScene): selected_id = _id selected_node = node - root_node = self.add_node(selected_id, selected_node, (0, 0)) + root_node = self.add_node(selected_node, (0, 0)) #Â add certified by selected node y = 0 @@ -130,7 +131,7 @@ class Scene(QGraphicsScene): nodes = ((k, v) for (k, v) in sorted(nodes.items(), key=lambda kv: kv[1]['node']['text'].lower())) # add nodes and arcs for _id, items in nodes: - node = self.add_node(_id, items['node'], (x, y)) + node = self.add_node(items['node'], (x, y)) self.add_arc(root_node, node, items['arc']) y += 50 @@ -141,7 +142,7 @@ class Scene(QGraphicsScene): nodes = ((k, v) for (k, v) in sorted(graph.items(), key=lambda kv: kv[1]['text'].lower()) if selected_id in (arc['id'] for arc in v['arcs'])) # add nodes and arcs for _id, certifier_node in nodes: - node = self.add_node(_id, certifier_node, (x, y)) + node = self.add_node(certifier_node, (x, y)) for arc in certifier_node['arcs']: if arc['id'] == selected_id: self.add_arc(node, root_node, arc) @@ -151,24 +152,27 @@ class Scene(QGraphicsScene): class Node(QGraphicsEllipseItem): - def __init__(self, _id, data, x_y): + def __init__(self, metadata, x_y): """ Create node in the graph scene - :param dict data: Node data + :param dict metadata: Node metadata :param x_y: Position of the node """ # unpack tuple x, y = x_y super(Node, self).__init__() - self.id = _id - self.status_wallet = data['status'] & NODE_STATUS_HIGHLIGHTED - self.text = data['text'] - self.setToolTip(data['tooltip']) + + self.metadata = metadata + self.status_wallet = self.metadata['status'] & NODE_STATUS_HIGHLIGHTED + self.text = self.metadata['text'] + self.setToolTip(self.metadata['tooltip']) self.arcs = [] self.menu = None self.action_sign = None + self.action_transaction = None + self.action_contact = None # color around ellipse outline_color = QColor('grey') @@ -216,7 +220,7 @@ class Node(QGraphicsEllipseItem): """ if event.button() == Qt.LeftButton: # trigger scene signal - self.scene().node_clicked.emit(self.id) + self.scene().node_clicked.emit(self.metadata['id']) def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent): """ @@ -238,6 +242,15 @@ class Node(QGraphicsEllipseItem): self.action_sign = QAction('Sign identity', self.scene()) self.menu.addAction(self.action_sign) self.action_sign.triggered.connect(self.sign_action) + #Â action transaction toward identity + self.action_transaction = QAction('Send money to identity', self.scene()) + self.menu.addAction(self.action_transaction) + self.action_transaction.triggered.connect(self.transaction_action) + #Â action add identity as contact + self.action_contact = QAction('Add identity as contact', self.scene()) + self.menu.addAction(self.action_contact) + self.action_contact.triggered.connect(self.contact_action) + # run menu self.menu.exec(event.screenPos()) def add_arc(self, arc): @@ -253,26 +266,40 @@ class Node(QGraphicsEllipseItem): Sign identity node """ # trigger scene signal - self.scene().node_signed.emit(self.id) + self.scene().node_signed.emit(self.metadata) + + def transaction_action(self): + """ + Transaction action to identity node + """ + # trigger scene signal + self.scene().node_transaction.emit(self.metadata) + def contact_action(self): + """ + Transaction action to identity node + """ + # trigger scene signal + self.scene().node_contact.emit(self.metadata) class Arc(QGraphicsLineItem): - def __init__(self, source_node, destination_node, data): + def __init__(self, source_node, destination_node, metadata): """ Create an arc between two nodes :param Node source_node: Source node of the arc :param Node destination_node: Destination node of the arc - :param dict data: Arc data + :param dict metadata: Arc metadata """ super(Arc, self).__init__() + self.metadata = metadata self.source = source_node self.destination = destination_node - self.setToolTip(data['tooltip']) + self.setToolTip(self.metadata['tooltip']) self.source.add_arc(self) - self.status = data['status'] + self.status = self.metadata['status'] self.source_point = None self.destination_point = None diff --git a/src/cutecoin/gui/wot_tab.py b/src/cutecoin/gui/wot_tab.py index 50b4a448647bbf3573d16ed138e49f86d267b6f8..ebc4eeabe0b4cbcd339842474dbfb8ada5abb1cd 100644 --- a/src/cutecoin/gui/wot_tab.py +++ b/src/cutecoin/gui/wot_tab.py @@ -2,11 +2,15 @@ import time import datetime +import logging from PyQt5.QtWidgets import QWidget from ..gen_resources.wot_tab_uic import Ui_WotTabWidget from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_SELECTED, ARC_STATUS_STRONG, ARC_STATUS_WEAK from ucoinpy.api import bma +from .certification import CertificationDialog +from .add_contact import AddContactDialog +from .transfer import TransferMoneyDialog class WotTabWidget(QWidget, Ui_WotTabWidget): @@ -28,8 +32,10 @@ class WotTabWidget(QWidget, Ui_WotTabWidget): self.comboBoxSearch.lineEdit().returnPressed.connect(self.combobox_return_pressed) #Â add scene events - self.graphicsView.scene().node_signed.connect(self.sign_node) self.graphicsView.scene().node_clicked.connect(self.draw_graph) + self.graphicsView.scene().node_signed.connect(self.sign_node) + self.graphicsView.scene().node_transaction.connect(self.send_money_to_node) + self.graphicsView.scene().node_contact.connect(self.add_node_as_contact) self.account = account self.community = community @@ -47,13 +53,21 @@ class WotTabWidget(QWidget, Ui_WotTabWidget): :param public_key: Public key of the identity """ + try: + certifiers = self.community.request(bma.wot.CertifiersOf, {'search': public_key}) + except ValueError as e: + logging.debug('bma.wot.CertifiersOf request error : ' + str(e)) + return False + + # reset graph graph = dict() + #Â add wallet node node_status = (NODE_STATUS_HIGHLIGHTED and (public_key == self.account.pubkey)) or 0 node_status += NODE_STATUS_SELECTED - certifiers = self.community.request(bma.wot.CertifiersOf, {'search': public_key}) - graph[public_key] = {'arcs': [], 'text': certifiers['uid'], 'tooltip': public_key, 'status': node_status} + # highlighted node (wallet) + graph[public_key] = {'id': public_key, 'arcs': [], 'text': certifiers['uid'], 'tooltip': public_key, 'status': node_status} #Â add certifiers of uid for certifier in certifiers['certifications']: @@ -71,6 +85,7 @@ class WotTabWidget(QWidget, Ui_WotTabWidget): if certifier['pubkey'] not in graph.keys(): node_status = (NODE_STATUS_HIGHLIGHTED and (certifier['pubkey'] == self.account.pubkey)) or 0 graph[certifier['pubkey']] = { + 'id': certifier['pubkey'], 'arcs': [arc], 'text': certifier['uid'], 'tooltip': certifier['pubkey'], @@ -94,6 +109,7 @@ class WotTabWidget(QWidget, Ui_WotTabWidget): if certified['pubkey'] not in graph.keys(): node_status = (NODE_STATUS_HIGHLIGHTED and (certified['pubkey'] == self.account.pubkey)) or 0 graph[certified['pubkey']] = { + 'id': certified['pubkey'], 'arcs': list(), 'text': certified['uid'], 'tooltip': certified['pubkey'], @@ -150,5 +166,29 @@ class WotTabWidget(QWidget, Ui_WotTabWidget): node['pubkey'] ) - def sign_node(self, public_key): - print('sign node {} not implemented'.format(public_key)) + def sign_node(self, metadata): + # check if identity already certified... + for certified in self.community.request(bma.wot.CertifiedBy, {'search': self.account.pubkey})['certifications']: + if metadata['id'] == certified['pubkey']: + return False + # open certify dialog + dialog = CertificationDialog(self.account) + dialog.edit_pubkey.setText(metadata['id']) + dialog.radio_pubkey.setChecked(True) + dialog.exec_() + + def send_money_to_node(self, metadata): + dialog = TransferMoneyDialog(self.account) + dialog.edit_pubkey.setText(metadata['id']) + dialog.combo_community.setCurrentText(self.community.name()) + dialog.radio_pubkey.setChecked(True) + dialog.exec_() + + def add_node_as_contact(self, metadata): + # check if contact already exists... + if metadata['id'] == self.account.pubkey or metadata['id'] in [contact.pubkey for contact in self.account.contacts]: + return False + dialog = AddContactDialog(self.account, self.window()) + dialog.edit_name.setText(metadata['text']) + dialog.edit_pubkey.setText(metadata['id']) + dialog.exec_()