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

Move actions and menus

parent 1ff67947
No related branches found
No related tags found
No related merge requests found
...@@ -80,7 +80,7 @@ class BaseGraph(QObject): ...@@ -80,7 +80,7 @@ class BaseGraph(QObject):
:rtype: str :rtype: str
""" """
try: try:
current_confirmations = min(max(block_number - self.blockchain_service.current_buid().number, 0), 6) current_confirmations = min(max(self.blockchain_service.current_buid().number - block_number, 0), 6)
if MAX_CONFIRMATIONS > current_confirmations: if MAX_CONFIRMATIONS > current_confirmations:
if self.app.parameters.expert_mode: if self.app.parameters.expert_mode:
......
...@@ -97,7 +97,7 @@ class IdentitiesProcessor: ...@@ -97,7 +97,7 @@ class IdentitiesProcessor:
:rtype: sakia.data.entities.Identity :rtype: sakia.data.entities.Identity
""" """
return self._identities_repo.get_written(currency=currency, pubkey=pubkey) return self._identities_repo.get_all(currency=currency, pubkey=pubkey, ms_written_on=0)
def get_identity(self, currency, pubkey, uid=""): def get_identity(self, currency, pubkey, uid=""):
""" """
......
...@@ -64,39 +64,6 @@ class IdentitiesRepo: ...@@ -64,39 +64,6 @@ class IdentitiesRepo:
if data: if data:
return Identity(*data) return Identity(*data)
def get_written(self, offset=0, limit=1000, sort_by="currency", sort_order="ASC", **search):
"""
Get an identity in the database written in the blockchain
and corresponding to the search
:param dict search: the criterions of the lookup
:rtype: List[sakia.data.entities.Identity]
"""
filters = []
values = []
for k, v in search.items():
if isinstance(v, bool):
v = int(v)
filters.append("{k}=?".format(k=k))
values.append(v)
request = """SELECT * FROM identities WHERE {filters}
AND ms_written_on!="{empty_buid}"
ORDER BY {sort_by} {sort_order}
LIMIT {limit} OFFSET {offset}""" \
.format(filters=" AND ".join(filters),
empty_buid=str(BlockUID.empty()),
offset=offset,
limit=limit,
sort_by=sort_by,
sort_order=sort_order
)
c = self._conn.execute(request, tuple(values))
datas = c.fetchall()
if datas:
return [Identity(*data) for data in datas]
return []
def get_all(self, **search): def get_all(self, **search):
""" """
Get all existing identity in the database corresponding to the search Get all existing identity in the database corresponding to the search
......
from sakia.gui.component.model import ComponentModel
from duniterpy.documents.certification import Revocation from duniterpy.documents.certification import Revocation
from duniterpy.api import bma, errors from duniterpy.api import bma, errors
from sakia.core.net import Node from PyQt5.QtCore import QObject
import aiohttp import aiohttp
......
...@@ -4,10 +4,12 @@ from PyQt5.QtWidgets import QDialog, QMessageBox ...@@ -4,10 +4,12 @@ from PyQt5.QtWidgets import QDialog, QMessageBox
from sakia.decorators import asyncify from sakia.decorators import asyncify
from sakia.gui.dialogs.connection_cfg.controller import ConnectionConfigController from sakia.gui.dialogs.connection_cfg.controller import ConnectionConfigController
from sakia.gui.dialogs.certification.controller import CertificationController from sakia.gui.dialogs.certification.controller import CertificationController
from sakia.gui.dialogs.revocation.controller import RevocationController
from sakia.gui.dialogs.transfer.controller import TransferController from sakia.gui.dialogs.transfer.controller import TransferController
from sakia.gui.widgets import toast from sakia.gui.widgets import toast
from sakia.gui.widgets.dialogs import QAsyncMessageBox, QAsyncFileDialog, dialog_async_exec from sakia.gui.widgets.dialogs import QAsyncMessageBox, QAsyncFileDialog, dialog_async_exec
from sakia.gui.password_asker import PasswordAskerDialog from sakia.gui.password_asker import PasswordAskerDialog
from sakia.gui.preferences import PreferencesDialog
from .model import ToolbarModel from .model import ToolbarModel
from .view import ToolbarView from .view import ToolbarView
...@@ -28,9 +30,9 @@ class ToolbarController(QObject): ...@@ -28,9 +30,9 @@ class ToolbarController(QObject):
self.model = model self.model = model
self.view.button_certification.clicked.connect(self.open_certification_dialog) self.view.button_certification.clicked.connect(self.open_certification_dialog)
self.view.button_send_money.clicked.connect(self.open_transfer_money_dialog) self.view.button_send_money.clicked.connect(self.open_transfer_money_dialog)
self.view.action_publish_uid.triggered.connect(self.publish_uid) self.view.button_membership.clicked.connect(self.send_join_demand)
self.view.button_membership.clicked.connect(self.send_membership_demand)
self.view.action_add_connection.triggered.connect(self.open_add_connection_dialog) self.view.action_add_connection.triggered.connect(self.open_add_connection_dialog)
self.view.action_parameters.triggered.connect(self.open_settings_dialog)
@classmethod @classmethod
def create(cls, app, navigation): def create(cls, app, navigation):
...@@ -52,11 +54,12 @@ class ToolbarController(QObject): ...@@ -52,11 +54,12 @@ class ToolbarController(QObject):
self.view.button_membership.setEnabled(enabled) self.view.button_membership.setEnabled(enabled)
@asyncify @asyncify
async def send_membership_demand(self, checked=False): async def send_join_demand(self, checked=False):
password = await self.password_asker.async_exec() connection = self.model.navigation_model.navigation.current_connection()
if self.password_asker.result() == QDialog.Rejected: password = PasswordAskerDialog(connection).async_exec()
if not password:
return return
result = await self.account.send_membership(password, self.community, 'IN') result = await self.model.send_join(connection, password)
if result[0]: if result[0]:
if self.app.preferences['notifications']: if self.app.preferences['notifications']:
toast.display(self.tr("Membership"), self.tr("Success sending Membership demand")) toast.display(self.tr("Membership"), self.tr("Success sending Membership demand"))
...@@ -70,61 +73,19 @@ class ToolbarController(QObject): ...@@ -70,61 +73,19 @@ class ToolbarController(QObject):
await QAsyncMessageBox.critical(self, self.tr("Membership"), await QAsyncMessageBox.critical(self, self.tr("Membership"),
result[1]) result[1])
@asyncify
async def send_membership_leaving(self):
reply = await QAsyncMessageBox.warning(self, self.tr("Warning"),
self.tr("""Are you sure ?
Sending a leaving demand cannot be canceled.
The process to join back the community later will have to be done again.""")
.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
if reply == QMessageBox.Ok:
password = self.password_asker.exec_()
if self.password_asker.result() == QDialog.Rejected:
return
result = await self.account.send_membership(password, self.community, 'OUT')
if result[0]:
if self.app.preferences['notifications']:
toast.display(self.tr("Revoke"), self.tr("Success sending Revoke demand"))
else:
await QAsyncMessageBox.information(self, self.tr("Revoke"),
self.tr("Success sending Revoke demand"))
else:
if self.app.preferences['notifications']:
toast.display(self.tr("Revoke"), result[1])
else:
await QAsyncMessageBox.critical(self, self.tr("Revoke"),
result[1])
@asyncify
async def publish_uid(self, checked=False):
password = await self.password_asker.async_exec()
if self.password_asker.result() == QDialog.Rejected:
return
result = await self.account.send_selfcert(password, self.community)
if result[0]:
if self.app.preferences['notifications']:
toast.display(self.tr("UID"), self.tr("Success publishing your UID"))
else:
await QAsyncMessageBox.information(self, self.tr("Membership"),
self.tr("Success publishing your UID"))
else:
if self.app.preferences['notifications']:
toast.display(self.tr("UID"), result[1])
else:
await QAsyncMessageBox.critical(self, self.tr("UID"),
result[1])
def open_certification_dialog(self): def open_certification_dialog(self):
CertificationController.open_dialog(self, self.model.app, CertificationController.open_dialog(self, self.model.app,
self.model.navigation_model.current_connection()) self.model.navigation_model.current_connection())
def open_revocation_dialog(self): def open_revocation_dialog(self):
RevocationDialog.open_dialog(self.app, RevocationController.open_dialog(self.app, self.model.navigation_model.current_connection())
self.account)
def open_transfer_money_dialog(self): def open_transfer_money_dialog(self):
TransferController.open_dialog(self, self.model.app, self.model.navigation_model.current_connection()) TransferController.open_dialog(self, self.model.app, self.model.navigation_model.current_connection())
def open_settings_dialog(self):
PreferencesDialog(self.model.app).exec()
def open_add_connection_dialog(self): def open_add_connection_dialog(self):
connection_config = ConnectionConfigController.create_connection(self, self.model.app) connection_config = ConnectionConfigController.create_connection(self, self.model.app)
connection_config.exec() connection_config.exec()
......
...@@ -6,6 +6,9 @@ import attr ...@@ -6,6 +6,9 @@ import attr
class ToolbarModel(QObject): class ToolbarModel(QObject):
""" """
The model of Navigation component The model of Navigation component
:param sakia.app.Application app: the application
:param sakia.gui.navigation.model.NavigationModel navigation_model: The navigation model
""" """
app = attr.ib() app = attr.ib()
...@@ -13,3 +16,6 @@ class ToolbarModel(QObject): ...@@ -13,3 +16,6 @@ class ToolbarModel(QObject):
def __attrs_post_init__(self): def __attrs_post_init__(self):
super().__init__() super().__init__()
async def send_join(self, connection, password):
return await self.app.documents_service.send_membership(connection, password, "IN")
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
<string>Send money</string> <string>Send money</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../../res/icons/icons.qrc"> <iconset resource="../../../../../res/icons/icons.qrc">
<normaloff>:/icons/payment_icon</normaloff>:/icons/payment_icon</iconset> <normaloff>:/icons/payment_icon</normaloff>:/icons/payment_icon</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
<string>Certification</string> <string>Certification</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../../res/icons/icons.qrc"> <iconset resource="../../../../../res/icons/icons.qrc">
<normaloff>:/icons/certification_icon</normaloff>:/icons/certification_icon</iconset> <normaloff>:/icons/certification_icon</normaloff>:/icons/certification_icon</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
<string>Renew membership</string> <string>Renew membership</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../../res/icons/icons.qrc"> <iconset resource="../../../../../res/icons/icons.qrc">
<normaloff>:/icons/renew_membership</normaloff>:/icons/renew_membership</iconset> <normaloff>:/icons/renew_membership</normaloff>:/icons/renew_membership</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../../res/icons/icons.qrc"> <iconset resource="../../../../../res/icons/icons.qrc">
<normaloff>:/icons/menu_icon</normaloff>:/icons/menu_icon</iconset> <normaloff>:/icons/menu_icon</normaloff>:/icons/menu_icon</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
...@@ -119,7 +119,7 @@ ...@@ -119,7 +119,7 @@
</layout> </layout>
</widget> </widget>
<resources> <resources>
<include location="../../../../res/icons/icons.qrc"/> <include location="../../../../../res/icons/icons.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>
...@@ -18,15 +18,14 @@ class ToolbarView(QFrame, Ui_SakiaToolbar): ...@@ -18,15 +18,14 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
tool_menu = QMenu(self.tr("Tools"), self.toolbutton_menu) tool_menu = QMenu(self.tr("Tools"), self.toolbutton_menu)
self.toolbutton_menu.setMenu(tool_menu) self.toolbutton_menu.setMenu(tool_menu)
self.action_publish_uid = QAction(self.tr(ToolbarView._action_publish_uid_text), self)
self.action_revoke_uid = QAction(self.tr(ToolbarView._action_revoke_uid_text), self) self.action_revoke_uid = QAction(self.tr(ToolbarView._action_revoke_uid_text), self)
tool_menu.addAction(self.action_publish_uid)
tool_menu.addAction(self.action_revoke_uid) tool_menu.addAction(self.action_revoke_uid)
menu_options = QMenu(self.tr("Options"), self.toolbutton_menu) self.action_add_connection = QAction(self.tr("Add a connection"), tool_menu)
self.action_add_connection = QAction(self.tr("Add a connection"), menu_options) tool_menu.addAction(self.action_add_connection)
menu_options.addAction(self.action_add_connection)
tool_menu.addMenu(menu_options) self.action_parameters = QAction(self.tr("Settings"), tool_menu)
tool_menu.addAction(self.action_parameters)
self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum) self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum)
self.setMaximumHeight(60) self.setMaximumHeight(60)
...@@ -13,7 +13,8 @@ from PyQt5.QtWidgets import QMenu, QAction, QMessageBox, QDialog ...@@ -13,7 +13,8 @@ from PyQt5.QtWidgets import QMenu, QAction, QMessageBox, QDialog
from PyQt5.QtGui import QCursor from PyQt5.QtGui import QCursor
from sakia.decorators import asyncify from sakia.decorators import asyncify
from sakia.gui.password_asker import PasswordAskerDialog from sakia.gui.password_asker import PasswordAskerDialog
from sakia.gui.widgets.dialogs import QAsyncFileDialog, dialog_async_exec from sakia.gui.widgets.dialogs import QAsyncFileDialog, QAsyncMessageBox
from sakia.gui.widgets import toast
class NavigationController(QObject): class NavigationController(QObject):
...@@ -109,9 +110,66 @@ class NavigationController(QObject): ...@@ -109,9 +110,66 @@ class NavigationController(QObject):
action_gen_revokation.triggered.connect(lambda c: action_gen_revokation.triggered.connect(lambda c:
self.action_save_revokation(raw_data['misc']['connection'])) self.action_save_revokation(raw_data['misc']['connection']))
action_publish_uid = QAction(self.tr("Publish UID"), menu)
menu.addAction(action_publish_uid)
action_publish_uid.triggered.connect(lambda c:
self.publish_uid(raw_data['misc']['connection']))
action_publish_uid.setEnabled(self.model.identity_published(raw_data['misc']['connection']))
# Show the context menu.
action_publish_uid = QAction(self.tr("Leave the currency"), menu)
menu.addAction(action_publish_uid)
action_publish_uid.triggered.connect(lambda c:
self.leave_currency(raw_data['misc']['connection']))
action_publish_uid.setEnabled(self.model.identity_is_member(raw_data['misc']['connection']))
# Show the context menu. # Show the context menu.
menu.popup(QCursor.pos()) menu.popup(QCursor.pos())
@asyncify
async def publish_uid(self, connection):
password = await self.password_asker.async_exec()
if self.password_asker.result() == QDialog.Rejected:
return
result = await self.account.send_selfcert(password, self.community)
if result[0]:
if self.app.preferences['notifications']:
toast.display(self.tr("UID"), self.tr("Success publishing your UID"))
else:
await QAsyncMessageBox.information(self, self.tr("Membership"),
self.tr("Success publishing your UID"))
else:
if self.app.preferences['notifications']:
toast.display(self.tr("UID"), result[1])
else:
await QAsyncMessageBox.critical(self, self.tr("UID"),
result[1])
@asyncify
async def send_leave(self):
reply = await QAsyncMessageBox.warning(self, self.tr("Warning"),
self.tr("""Are you sure ?
Sending a leaving demand cannot be canceled.
The process to join back the community later will have to be done again.""")
.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
if reply == QMessageBox.Ok:
password = PasswordAskerDialog(self.model.navigation_model.navigation.current_connection()).async_exec()
if not password:
return
result = await self.model.send_leave(password)
if result[0]:
if self.app.preferences['notifications']:
toast.display(self.tr("Revoke"), self.tr("Success sending Revoke demand"))
else:
await QAsyncMessageBox.information(self, self.tr("Revoke"),
self.tr("Success sending Revoke demand"))
else:
if self.app.preferences['notifications']:
toast.display(self.tr("Revoke"), result[1])
else:
await QAsyncMessageBox.critical(self, self.tr("Revoke"),
result[1])
def action_save_revokation(self, connection): def action_save_revokation(self, connection):
password = PasswordAskerDialog(connection).exec() password = PasswordAskerDialog(connection).exec()
if not password: if not password:
......
...@@ -127,3 +127,14 @@ class NavigationModel(QObject): ...@@ -127,3 +127,14 @@ class NavigationModel(QObject):
def generate_revokation(self, connection, password): def generate_revokation(self, connection, password):
return self.app.documents_service.generate_revokation(connection, password) return self.app.documents_service.generate_revokation(connection, password)
def identity_published(self, connection):
identities_services = self.app.identities_services[connection.currency]
return identities_services.get_identity(connection.pubkey, connection.uid).written_on != 0
def identity_is_member(self, connection):
identities_services = self.app.identities_services[connection.currency]
return identities_services.get_identity(connection.pubkey, connection.uid).member
async def send_leave(self, connection, password):
return await self.app.documents_service.send_membership(connection, password, "OUT")
...@@ -93,7 +93,7 @@ class DocumentsService: ...@@ -93,7 +93,7 @@ class DocumentsService:
return result, identity return result, identity
async def send_membership(self, currency, identity, salt, password, mstype): async def send_membership(self, connection, password, mstype):
""" """
Send a membership document to a target community. Send a membership document to a target community.
Signal "document_broadcasted" is emitted at the end. Signal "document_broadcasted" is emitted at the end.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment