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

Refactored graph tabs to new context menu

parent 0dd6e3c3
Branches
Tags
No related merge requests found
......@@ -71,17 +71,17 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
super().setupUi(self)
self.tab_identities.view_in_wot.connect(self.tab_wot.draw_graph)
self.tab_identities.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot))
self.tab_identities.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot.widget))
self.tab_history.view_in_wot.connect(self.tab_wot.draw_graph)
self.tab_history.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot))
self.tab_identities.money_sent.connect(lambda: self.tab_history.table_history.model().sourceModel().refresh_transfers())
self.tab_wot.money_sent.connect(lambda: self.tab_history.table_history.model().sourceModel().refresh_transfers())
self.tab_history.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot.widget))
self.tab_identities.money_sent.connect(lambda: self.tab_history.widget.table_history.model().sourceModel().refresh_transfers())
self.tab_wot.money_sent.connect(lambda: self.tab_history.widget.table_history.model().sourceModel().refresh_transfers())
self.tabs.addTab(self.tab_history.widget,
QIcon(':/icons/tx_icon'),
self.tr(CommunityWidget._tab_history_label))
self.tabs.addTab(self.tab_wot,
self.tabs.addTab(self.tab_wot.widget,
QIcon(':/icons/wot_icon'),
self.tr(CommunityWidget._tab_wot_label))
......@@ -99,7 +99,7 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
self.toolbutton_menu.addAction(action_showinfo)
action_showexplorer = QAction(self.tr("Show explorer"), self.toolbutton_menu)
action_showexplorer.triggered.connect(lambda : self.show_closable_tab(self.tab_explorer,
action_showexplorer.triggered.connect(lambda : self.show_closable_tab(self.tab_explorer.widget,
QIcon(":/icons/explorer_icon"), self.tr("Explorer")))
self.toolbutton_menu.addAction(action_showexplorer)
......@@ -410,7 +410,7 @@ The process to join back the community later will have to be done again.""")
:param widget:
:return:
"""
self.tabs.setTabText(self.tabs.indexOf(self.tab_wot), self.tr(CommunityWidget._tab_wot_label))
self.tabs.setTabText(self.tabs.indexOf(self.tab_wot.widget), self.tr(CommunityWidget._tab_wot_label))
self.tabs.setTabText(self.tabs.indexOf(self.tab_network), self.tr(CommunityWidget._tab_network_label))
self.tabs.setTabText(self.tabs.indexOf(self.tab_informations), self.tr(CommunityWidget._tab_informations_label))
self.tabs.setTabText(self.tabs.indexOf(self.tab_history.widget), self.tr(CommunityWidget._tab_history_label))
......
import logging
from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP
from ucoinpy.api import bma
from PyQt5.QtCore import QEvent, pyqtSignal
from PyQt5.QtWidgets import QWidget
from ...tools.decorators import asyncify, once_at_a_time, cancel_once_task
from ...tools.exceptions import NoPeerAvailable
from ...core.graph import ExplorerGraph
from .graph_tab import GraphTabWidget
from ...gen_resources.explorer_tab_uic import Ui_ExplorerTabWidget
......@@ -15,20 +13,22 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
money_sent = pyqtSignal()
def __init__(self, app):
def __init__(self, app, account=None, community=None, password_asker=None,
widget=QWidget, view=Ui_ExplorerTabWidget):
"""
:param sakia.core.app.Application app: Application instance
:param sakia.core.app.Application app: Application instance
:param sakia.core.Account account: The account displayed in the widget
:param sakia.core.Community community: The community displayed in the widget
:param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
"""
# construct from qtDesigner
super().__init__(app)
self.setupUi(self)
self.search_user_widget.init(app)
self.set_scene(self.graphicsView.scene())
super().__init__(app, account, community, password_asker, widget)
self.ui = view()
self.ui.setupUi(self.widget)
self.ui.search_user_widget.init(app)
self.account = None
self.community = None
self.password_asker = None
self.set_scene(self.ui.graphicsView.scene())
self.graph = None
self.app = app
self.draw_task = None
......@@ -38,16 +38,16 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
# create node metadata from account
self._current_identity = None
self.button_go.clicked.connect(self.go_clicked)
self.search_user_widget.identity_selected.connect(self.draw_graph)
self.search_user_widget.reset.connect(self.reset)
self.ui.button_go.clicked.connect(self.go_clicked)
self.ui.search_user_widget.identity_selected.connect(self.draw_graph)
self.ui.search_user_widget.reset.connect(self.reset)
def cancel_once_tasks(self):
cancel_once_task(self, self.refresh_informations_frame)
cancel_once_task(self, self.reset)
def change_account(self, account, password_asker):
self.search_user_widget.change_account(account)
self.ui.search_user_widget.change_account(account)
self.account = account
self.password_asker = password_asker
......@@ -57,8 +57,8 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
self.graph.stop_exploration()
self.graph = ExplorerGraph(self.app, self.community)
self.graph.graph_changed.connect(self.refresh)
self.search_user_widget.change_community(community)
self.graph.current_identity_changed.connect(self.graphicsView.scene().update_current_identity)
self.ui.search_user_widget.change_community(community)
self.graph.current_identity_changed.connect(self.ui.graphicsView.scene().update_current_identity)
self.reset()
def go_clicked(self):
......@@ -79,11 +79,11 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
if self._current_identity != identity:
self._current_identity = identity
self.graph.start_exploration(identity, self.steps_slider.value())
self.graph.start_exploration(identity, self.ui.steps_slider.value())
# draw graph in qt scene
self.graphicsView.scene().clear()
self.graphicsView.scene().update_wot(self.graph.nx_graph, identity, self.steps_slider.maximum())
self.ui.graphicsView.scene().clear()
self.ui.graphicsView.scene().update_wot(self.graph.nx_graph, identity, self.ui.steps_slider.maximum())
def refresh(self):
"""
......@@ -91,7 +91,7 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
"""
if self._current_identity:
# draw graph in qt scene
self.graphicsView.scene().update_wot(self.graph.nx_graph, self._current_identity, self.steps_slider.maximum())
self.ui.graphicsView.scene().update_wot(self.graph.nx_graph, self._current_identity, self.ui.steps_slider.maximum())
else:
self.reset()
......@@ -103,8 +103,8 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
"""
if self.account and self.community:
parameters = await self.community.parameters()
self.steps_slider.setMaximum(parameters['stepMax'])
self.steps_slider.setValue(int(0.33 * parameters['stepMax']))
self.ui.steps_slider.setMaximum(parameters['stepMax'])
self.ui.steps_slider.setValue(int(0.33 * parameters['stepMax']))
identity = await self.account.identity(self.community)
self.draw_graph(identity)
......
from PyQt5.QtWidgets import QWidget, QDialog
from PyQt5.QtCore import pyqtSlot, QEvent, QLocale, QDateTime, pyqtSignal
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import pyqtSlot, QEvent, QLocale, QDateTime, pyqtSignal, QObject
from PyQt5.QtGui import QCursor
from ...tools.exceptions import MembershipNotFoundError
from ...tools.decorators import asyncify, once_at_a_time
from ...core.registry import BlockchainState
from ...gui.member import MemberDialog
from ...gui.certification import CertificationDialog
from ...gui.transfer import TransferMoneyDialog
from ...gui.contact import ConfigureContactDialog
from ..widgets import ContextMenu
class GraphTabWidget(QWidget):
class GraphTabWidget(QObject):
money_sent = pyqtSignal()
def __init__(self, app):
def __init__(self, app, account=None, community=None, password_asker=None, widget=QWidget):
"""
:param sakia.core.app.Application app: Application instance
:param sakia.core.app.Application app: Application instance
:param sakia.core.Account account: The account displayed in the widget
:param sakia.core.Community community: The community displayed in the widget
:param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
:param class widget: The class of the graph tab
"""
super().__init__()
self.password_asker = None
self.widget = widget()
self.account = account
self.community = community
self.password_asker = password_asker
self.app = app
def set_scene(self, scene):
# add scene events
scene.node_clicked.connect(self.handle_node_click)
scene.node_signed.connect(self.sign_node)
scene.node_transaction.connect(self.send_money_to_node)
scene.node_contact.connect(self.add_node_as_contact)
scene.node_member.connect(self.identity_informations)
scene.node_copy_pubkey.connect(self.copy_node_pubkey)
scene.node_context_menu_requested.connect(self.node_context_menu)
@once_at_a_time
@asyncify
......@@ -147,59 +150,18 @@ class GraphTabWidget(QWidget):
"""
pass
def identity_informations(self, pubkey, metadata):
identity = self.app.identities_registry.from_handled_data(
metadata['text'],
pubkey,
None,
BlockchainState.VALIDATED,
self.community
)
dialog = MemberDialog(self.app, self.account, self.community, identity)
dialog.exec_()
@asyncify
async def sign_node(self, pubkey, metadata):
identity = self.app.identities_registry.from_handled_data(
metadata['text'],
pubkey,
None,
BlockchainState.VALIDATED,
self.community
)
await CertificationDialog.certify_identity(self.app, self.account, self.password_asker,
self.community, identity)
async def node_context_menu(self, pubkey):
"""
Open the node context menu
:param str pubkey: the pubkey of the node to open
"""
identity = await self.app.identities_registry.future_find(pubkey, self.community)
menu = ContextMenu.from_data(self.widget, self.app, self.account, self.community, self.password_asker,
(identity,))
@asyncify
async def send_money_to_node(self, pubkey, metadata):
identity = self.app.identities_registry.from_handled_data(
metadata['text'],
pubkey,
None,
BlockchainState.VALIDATED,
self.community
)
result = await TransferMoneyDialog.send_money_to_identity(self.app, self.account, self.password_asker,
self.community, identity)
if result == QDialog.Accepted:
self.money_sent.emit()
def copy_node_pubkey(self, pubkey):
cb = self.app.qapp.clipboard()
cb.clear(mode=cb.Clipboard)
cb.setText(pubkey, mode=cb.Clipboard)
def add_node_as_contact(self, pubkey, metadata):
# check if contact already exists...
if pubkey == self.account.pubkey \
or pubkey in [contact['pubkey'] for contact in self.account.contacts]:
return False
dialog = ConfigureContactDialog(self.account, self.window(), {'name': metadata['text'],
'pubkey': pubkey,
})
result = dialog.exec_()
if result == QDialog.Accepted:
self.window().refresh_contacts()
# Show the context menu.
menu.qmenu.popup(QCursor.pos())
def changeEvent(self, event):
"""
......
import logging
import asyncio
from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP
from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP, QObject
from PyQt5.QtWidgets import QWidget
from ...tools.decorators import asyncify, once_at_a_time, cancel_once_task
from ...core.graph import WoTGraph
from ...gen_resources.wot_tab_uic import Ui_WotTabWidget
......@@ -9,31 +10,39 @@ from ...gui.widgets.busy import Busy
from .graph_tab import GraphTabWidget
class WotTabWidget(GraphTabWidget, Ui_WotTabWidget):
class WotTabWidget(GraphTabWidget):
money_sent = pyqtSignal()
def __init__(self, app):
def __init__(self, app, account=None, community=None, password_asker=None, widget=QWidget, view=Ui_WotTabWidget):
"""
:param sakia.core.app.Application app: Application instance
:param sakia.core.app.Application app: Application instance
:param sakia.core.Account account: The account displayed in the widget
:param sakia.core.Community community: The community displayed in the widget
:param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
:param class widget: The class of the PyQt5 widget used for this tab
:param class view: The class of the UI View for this tab
"""
super().__init__(app)
super().__init__(app, account, community, password_asker, widget)
# construct from qtDesigner
self.setupUi(self)
self.search_user_widget.init(app)
self.busy = Busy(self.graphicsView)
self.ui = view()
self.ui.setupUi(self.widget)
self.ui.search_user_widget.init(app)
self.busy = Busy(self.ui.graphicsView)
self.busy.hide()
self.set_scene(self.graphicsView.scene())
self.set_scene(self.ui.graphicsView.scene())
self.account = None
self.community = None
self.password_asker = None
self.account = account
self.community = community
self.password_asker = password_asker
self.app = app
self.draw_task = None
self.search_user_widget.identity_selected.connect(self.draw_graph)
self.search_user_widget.reset.connect(self.reset)
self.ui.search_user_widget.identity_selected.connect(self.draw_graph)
self.ui.search_user_widget.reset.connect(self.reset)
# create node metadata from account
self._current_identity = None
......@@ -45,13 +54,13 @@ class WotTabWidget(GraphTabWidget, Ui_WotTabWidget):
def change_account(self, account, password_asker):
self.cancel_once_tasks()
self.search_user_widget.change_account(account)
self.ui.search_user_widget.change_account(account)
self.account = account
self.password_asker = password_asker
def change_community(self, community):
self.cancel_once_tasks()
self.search_user_widget.change_community(community)
self.ui.search_user_widget.change_community(community)
self._auto_refresh(community)
self.community = community
self.reset()
......@@ -87,14 +96,14 @@ class WotTabWidget(GraphTabWidget, Ui_WotTabWidget):
graph = WoTGraph(self.app, self.community)
await graph.initialize(identity, identity_account)
# draw graph in qt scene
self.graphicsView.scene().update_wot(graph.nx_graph, identity)
self.ui.graphicsView.scene().update_wot(graph.nx_graph, identity)
# if selected member is not the account member...
if identity.pubkey != identity_account.pubkey:
# add path from selected member to account member
path = await graph.get_shortest_path_to_identity(identity_account, identity)
if path:
self.graphicsView.scene().update_path(graph.nx_graph, path)
self.ui.graphicsView.scene().update_path(graph.nx_graph, path)
self.busy.hide()
@once_at_a_time
......
......@@ -3,7 +3,7 @@ from PyQt5.QtWidgets import QGraphicsEllipseItem, \
QGraphicsSceneContextMenuEvent
from PyQt5.QtCore import Qt, QCoreApplication, QT_TRANSLATE_NOOP, pyqtSignal
from PyQt5.QtGui import QMouseEvent
from sakia.core.graph.constants import NodeStatus
from ....core.graph.constants import NodeStatus
class BaseNode(QGraphicsEllipseItem):
......@@ -65,68 +65,4 @@ class BaseNode(QGraphicsEllipseItem):
# no menu on the wallet node
if self.status_wallet:
return None
# create node context menus
self.menu = QMenu()
# action show member
QT_TRANSLATE_NOOP('WoT.Node', 'Informations')
self.action_show_member = QAction(QCoreApplication.translate('WoT.Node', 'Informations'), self.scene())
self.menu.addAction(self.action_show_member)
self.action_show_member.triggered.connect(self.member_action)
# action add identity as contact
QT_TRANSLATE_NOOP('WoT.Node', 'Add as contact')
self.action_contact = QAction(QCoreApplication.translate('WoT.Node', 'Add as contact'), self.scene())
self.menu.addAction(self.action_contact)
self.action_contact.triggered.connect(self.contact_action)
# action transaction toward identity
QT_TRANSLATE_NOOP('WoT.Node', 'Send money')
self.action_transaction = QAction(QCoreApplication.translate('WoT.Node', 'Send money'), self.scene())
self.menu.addAction(self.action_transaction)
self.action_transaction.triggered.connect(self.transaction_action)
# action sign identity
QT_TRANSLATE_NOOP('WoT.Node', 'Certify identity')
self.action_sign = QAction(QCoreApplication.translate('WoT.Node', 'Certify identity'), self.scene())
self.menu.addAction(self.action_sign)
self.action_sign.triggered.connect(self.sign_action)
# action copy identity pubkey
QT_TRANSLATE_NOOP('WoT.Node', 'Copy pubkey')
self.action_copy = QAction(QCoreApplication.translate('WoT.Node', 'Copy pubkey'), self.scene())
self.menu.addAction(self.action_copy)
self.action_copy.triggered.connect(self.copy_action)
# run menu
self.menu.exec(event.screenPos())
def member_action(self):
"""
Transaction action to identity node
"""
# trigger scene signal
self.scene().node_member.emit(self.id, self.metadata)
def contact_action(self):
"""
Transaction action to identity node
"""
# trigger scene signal
self.scene().node_contact.emit(self.id, self.metadata)
def sign_action(self):
"""
Sign identity node
"""
# trigger scene signal
self.scene().node_signed.emit(self.id, self.metadata)
def copy_action(self):
"""
Copy identity node pubkey
"""
# trigger scene signal
self.scene().node_copy_pubkey.emit(self.id)
def transaction_action(self):
"""
Transaction action to identity node
"""
# trigger scene signal
self.scene().node_transaction.emit(self.id, self.metadata)
self.scene().node_context_menu_requested.emit(self.id)
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QGraphicsScene
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsSceneContextMenuEvent
class BaseScene(QGraphicsScene):
# This defines signals taking string arguments
node_clicked = pyqtSignal(str, dict)
node_signed = pyqtSignal(str, dict)
node_transaction = pyqtSignal(str, dict)
node_contact = pyqtSignal(str, dict)
node_member = pyqtSignal(str, dict)
node_copy_pubkey = pyqtSignal(str)
node_context_menu_requested = pyqtSignal(str)
node_hovered = pyqtSignal(str)
def __init__(self, parent=None):
......
import networkx
from PyQt5.QtCore import Qt, QPoint, pyqtSignal
from PyQt5.QtGui import QPainter, QWheelEvent
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene
from .edges import WotEdge
from .nodes import WotNode
from PyQt5.QtWidgets import QGraphicsView, QGraphicsSceneContextMenuEvent
from .scenes import WotScene
from ..widgets import ContextMenu
class WotView(QGraphicsView):
......@@ -15,7 +13,7 @@ class WotView(QGraphicsView):
:param parent: [Optional, default=None] Parent widget
"""
super(WotView, self).__init__(parent)
super().__init__(parent)
self.setScene(WotScene(self))
......
......@@ -34,7 +34,7 @@ class ContextMenu(QObject):
:param ContextMenu menu: the qmenu to add actions to
:param Identity identity: the identity
"""
menu.qmenu.addSeparator().setText(menu.qmenu.tr("Identity"))
menu.qmenu.addSeparator().setText(identity.uid)
informations = QAction(menu.qmenu.tr("Informations"), menu.qmenu.parent())
informations.triggered.connect(lambda checked, i=identity: menu.informations(i))
......
......@@ -77,6 +77,15 @@ class SearchUserWidget(QWidget, Ui_SearchUserWidget):
self.combobox_search.addItem(uid)
self.blockSignals(False)
self.combobox_search.showPopup()
except ValueError as e:
if '404' in str(e):
self.nodes = list()
self.blockSignals(True)
self.combobox_search.clear()
self.blockSignals(False)
self.combobox_search.showPopup()
else:
pass
except NoPeerAvailable:
pass
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment