diff --git a/src/sakia/gui/main_window/toolbar/about_money.ui b/src/sakia/gui/main_window/toolbar/about_money.ui new file mode 100644 index 0000000000000000000000000000000000000000..21432be2ced327e84f19684a3b58e11f0be6606e --- /dev/null +++ b/src/sakia/gui/main_window/toolbar/about_money.ui @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>509</width> + <height>406</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="group_general"> + <property name="styleSheet"> + <string notr="true"/> + </property> + <property name="title"> + <string>General</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="label_general"> + <property name="text"> + <string/> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="group_rules"> + <property name="title"> + <string>Rules</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <widget class="QLabel" name="label_rules"> + <property name="text"> + <string/> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="group_referentials"> + <property name="title"> + <string>Referentials</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label_referentials"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="group_money"> + <property name="title"> + <string>Money</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QLabel" name="label_money"> + <property name="text"> + <string/> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="group_wot"> + <property name="title"> + <string>WoT</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QLabel" name="label_wot"> + <property name="text"> + <string/> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/sakia/gui/main_window/toolbar/controller.py b/src/sakia/gui/main_window/toolbar/controller.py index 015d8f01440bb30574c156d3389733d016215212..cb8e5db5f960487d3f2b3aa7e0f06bbbcb06009b 100644 --- a/src/sakia/gui/main_window/toolbar/controller.py +++ b/src/sakia/gui/main_window/toolbar/controller.py @@ -1,6 +1,5 @@ from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog -from sakia.gui.dialogs.certification.controller import CertificationController from sakia.gui.dialogs.connection_cfg.controller import ConnectionConfigController from sakia.gui.dialogs.revocation.controller import RevocationController from sakia.gui.dialogs.contact.controller import ContactController @@ -46,10 +45,6 @@ class ToolbarController(QObject): toolbar = cls(view, model) return toolbar - def open_certification_dialog(self): - CertificationController.open_dialog(self, self.model.app, - self.model.navigation_model.current_connection()) - def open_contacts_dialog(self): ContactController.open_dialog(self, self.model.app) diff --git a/src/sakia/gui/navigation/controller.py b/src/sakia/gui/navigation/controller.py index c91023e6d92264279befb1f93dfd42b682762acb..f052c954c79ad2d37e7ba03228d8b6ad87b1b64b 100644 --- a/src/sakia/gui/navigation/controller.py +++ b/src/sakia/gui/navigation/controller.py @@ -12,7 +12,7 @@ from sakia.models.generic_tree import GenericTreeModel from .graphs.wot.controller import WotController from .homescreen.controller import HomeScreenController from .identities.controller import IdentitiesController -from .informations.controller import InformationsController +from .identity.controller import IdentityController from .model import NavigationModel from .network.controller import NetworkController from .txhistory.controller import TxHistoryController @@ -41,7 +41,7 @@ class NavigationController(QObject): 'HomeScreen': HomeScreenController, 'Network': NetworkController, 'Identities': IdentitiesController, - 'Informations': InformationsController, + 'Informations': IdentityController, 'Wot': WotController } self.view.current_view_changed.connect(self.handle_view_change) diff --git a/src/sakia/gui/dialogs/certification/__init__.py b/src/sakia/gui/navigation/identity/__init__.py similarity index 100% rename from src/sakia/gui/dialogs/certification/__init__.py rename to src/sakia/gui/navigation/identity/__init__.py diff --git a/src/sakia/gui/navigation/informations/controller.py b/src/sakia/gui/navigation/identity/controller.py similarity index 68% rename from src/sakia/gui/navigation/informations/controller.py rename to src/sakia/gui/navigation/identity/controller.py index 402c9618127ad704b31091959c9a22b7df5945f3..186f1e2e21898d46789de74e1a55cd179edbebe9 100644 --- a/src/sakia/gui/navigation/informations/controller.py +++ b/src/sakia/gui/navigation/identity/controller.py @@ -4,16 +4,17 @@ from PyQt5.QtCore import QObject from sakia.errors import NoPeerAvailable from sakia.constants import ROOT_SERVERS from duniterpy.api import errors -from .model import InformationsModel -from .view import InformationsView +from .model import IdentityModel +from .view import IdentityView from sakia.decorators import asyncify +from sakia.gui.sub.certification.controller import CertificationController from sakia.gui.sub.password_input import PasswordInputController from sakia.gui.widgets import toast from sakia.gui.widgets.dialogs import QAsyncMessageBox, QMessageBox -class InformationsController(QObject): +class IdentityController(QObject): """ The informations component """ @@ -31,13 +32,6 @@ class InformationsController(QObject): self._logger = logging.getLogger('sakia') self.view.button_membership.clicked.connect(self.send_join_demand) - @property - def informations_view(self): - """ - :rtype: sakia.gui.informations.view.InformationsView - """ - return self.view - @classmethod def create(cls, parent, app, connection, blockchain_service, identities_service, sources_service): """ @@ -50,32 +44,23 @@ class InformationsController(QObject): :param sources_service: :return: """ - view = InformationsView(parent.view) - model = InformationsModel(None, app, connection, blockchain_service, identities_service, sources_service) - informations = cls(parent, view, model) - model.setParent(informations) - informations.init_view_text() - view.retranslate_required.connect(informations.refresh_localized_data) - app.identity_changed.connect(informations.handle_identity_change) - app.new_transfer.connect(informations.refresh_localized_data) - app.new_dividend.connect(informations.refresh_localized_data) - app.referential_changed.connect(informations.refresh_localized_data) - app.sources_refreshed.connect(informations.refresh_localized_data) - return informations + certification = CertificationController.integrate_to_main_view(None, app, connection) + view = IdentityView(parent.view, certification.view) + model = IdentityModel(None, app, connection, blockchain_service, identities_service, sources_service) + identity = cls(parent, view, model) + certification.accepted.connect(view.clear) + certification.rejected.connect(view.clear) + identity.refresh_localized_data() + return identity @asyncify async def init_view_text(self): """ Initialization of text in informations view """ - referentials = self.model.referentials() - self.view.set_rules_text_no_dividend() - self.view.set_general_text_no_dividend() - self.view.set_text_referentials(referentials) params = self.model.parameters() if params: self.view.set_money_text(params, ROOT_SERVERS[self.model.connection.currency]["display"]) - self.view.set_wot_text(params) self.refresh_localized_data() def handle_identity_change(self, identity): @@ -90,19 +75,16 @@ class InformationsController(QObject): try: simple_data = self.model.get_identity_data() all_data = {**simple_data, **localized_data} - self.view.set_simple_informations(all_data, InformationsView.CommunityState.READY) + self.view.set_simple_informations(all_data, IdentityView.CommunityState.READY) except NoPeerAvailable as e: self._logger.debug(str(e)) - self.view.set_simple_informations(all_data, InformationsView.CommunityState.OFFLINE) + self.view.set_simple_informations(all_data, IdentityView.CommunityState.OFFLINE) except errors.DuniterError as e: if e.ucode == errors.BLOCK_NOT_FOUND: - self.view.set_simple_informations(all_data, InformationsView.CommunityState.NOT_INIT) + self.view.set_simple_informations(all_data, IdentityView.CommunityState.NOT_INIT) else: self._logger.debug(str(e)) - self.view.set_general_text(localized_data) - self.view.set_rules_text(localized_data) - @asyncify async def send_join_demand(self, checked=False): if not self.model.connection: diff --git a/src/sakia/gui/navigation/identity/identity.ui b/src/sakia/gui/navigation/identity/identity.ui new file mode 100644 index 0000000000000000000000000000000000000000..2943dab63cc4d5b0748eb49f2f3ca166e7627f27 --- /dev/null +++ b/src/sakia/gui/navigation/identity/identity.ui @@ -0,0 +1,155 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>IdentityWidget</class> + <widget class="QWidget" name="IdentityWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>538</width> + <height>737</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="styleSheet"> + <string notr="true">QGroupBox { + border: 1px solid gray; + border-radius: 9px; + margin-top: 0.5em; +} + +QGroupBox::title { + subcontrol-origin: margin; + left: 10px; + padding: 0 3px 0 3px; + font-weight: bold; +}</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="2" column="0"> + <widget class="QStackedWidget" name="stacked_widget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="page_empty"> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QWidget" name="widget" native="true"/> + </item> + </layout> + </widget> + </widget> + </item> + <item row="1" column="0"> + <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="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="button_certify"> + <property name="text"> + <string>Certify an identity</string> + </property> + <property name="icon"> + <iconset resource="../../../../../res/icons/icons.qrc"> + <normaloff>:/icons/certification_icon</normaloff>:/icons/certification_icon</iconset> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="QGroupBox" name="group_uid_state"> + <property name="title"> + <string>Identity</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label_currency"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_identity"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>6</number> + </property> + <item> + <widget class="QLabel" name="label_membership"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="button_membership"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Renew membership</string> + </property> + <property name="icon"> + <iconset resource="../../../../../res/icons/icons.qrc"> + <normaloff>:/icons/renew_membership</normaloff>:/icons/renew_membership</iconset> + </property> + <property name="iconSize"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </widget> + </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> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../../../../res/icons/icons.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/sakia/gui/navigation/informations/model.py b/src/sakia/gui/navigation/identity/model.py similarity index 94% rename from src/sakia/gui/navigation/informations/model.py rename to src/sakia/gui/navigation/identity/model.py index 2ba9cd9083be6ae926e11c878b3644fb624016a2..ffc8d3561de7454da8334f6a3149575521d2bd69 100644 --- a/src/sakia/gui/navigation/informations/model.py +++ b/src/sakia/gui/navigation/identity/model.py @@ -9,7 +9,7 @@ from sakia.data.processors import BlockchainProcessor from duniterpy.api import errors -class InformationsModel(QObject): +class IdentityModel(QObject): """ An component """ @@ -19,7 +19,7 @@ class InformationsModel(QObject): """ Constructor of an component - :param sakia.gui.informations.controller.InformationsController parent: the controller + :param sakia.gui.identity.controller.IdentityController parent: the controller :param sakia.app.Application app: the app :param sakia.data.entities.Connection connection: the user connection of this node :param sakia.services.BlockchainService blockchain_service: the service watching the blockchain state @@ -172,17 +172,6 @@ class InformationsModel(QObject): """ return self.blockchain_service.parameters() - def referentials(self): - """ - Get referentials - :return: The list of instances of all referentials - :rtype: list - """ - refs_instances = [] - for ref_class in Referentials: - refs_instances.append(ref_class(0, self.connection.currency, self.app, None)) - return refs_instances - def notifications(self): return self.app.parameters.notifications diff --git a/src/sakia/gui/navigation/identity/view.py b/src/sakia/gui/navigation/identity/view.py new file mode 100644 index 0000000000000000000000000000000000000000..a9585d05e5ed8925899d4c7506083ab750a4ef69 --- /dev/null +++ b/src/sakia/gui/navigation/identity/view.py @@ -0,0 +1,210 @@ +from PyQt5.QtWidgets import QWidget, QMessageBox +from PyQt5.QtCore import QEvent, QLocale, pyqtSignal +from .identity_uic import Ui_IdentityWidget +from enum import Enum +from sakia.helpers import timestamp_to_dhms +from sakia.constants import ROOT_SERVERS +from sakia.gui.widgets.dialogs import dialog_async_exec + + +class IdentityView(QWidget, Ui_IdentityWidget): + """ + The view of navigation panel + """ + retranslate_required = pyqtSignal() + + class CommunityState(Enum): + NOT_INIT = 0 + OFFLINE = 1 + READY = 2 + + def __init__(self, parent, certification_view): + super().__init__(parent) + self.certification_view = certification_view + self.setupUi(self) + self.stacked_widget.insertWidget(1, certification_view) + self.button_certify.clicked.connect(lambda c: self.stacked_widget.setCurrentWidget(self.certification_view)) + + def clear(self): + self.stacked_widget.setCurrentWidget(self.page_empty) + + def set_simple_informations(self, data, state): + if state in (IdentityView.CommunityState.NOT_INIT, IdentityView.CommunityState.OFFLINE): + self.label_currency.setText("""<html> + <body> + <p> + <span style=" font-size:16pt; font-weight:600;">{currency}</span> + </p> + <p>{message}</p> + </body> + </html>""".format(currency=data['currency'], + message=IdentityView.simple_message[state])) + self.button_membership.hide() + else: + status_value = self.tr("Member") if data['membership_state'] else self.tr("Non-Member") + if data['mstime'] > 0: + membership_action_value = self.tr("Renew membership") + status_info = "" + membership_action_enabled = True + elif data['membership_state']: + membership_action_value = self.tr("Renew membership") + status_info = "Your membership expired" + membership_action_enabled = True + else: + membership_action_value = self.tr("Request membership") + if data['nb_certs'] > data['nb_certs_required']: + status_info = self.tr("Registration ready") + membership_action_enabled = True + else: + status_info = self.tr("{0} more certifications required")\ + .format(data['nb_certs_required'] - data['nb_certs']) + membership_action_enabled = True + + if data['mstime'] > 0: + days, hours, minutes, seconds = timestamp_to_dhms(data['mstime']) + mstime_remaining_text = self.tr("Expires in ") + if days > 0: + mstime_remaining_text += "{days} days".format(days=days) + else: + mstime_remaining_text += "{hours} hours and {min} min.".format(hours=hours, + min=minutes) + else: + mstime_remaining_text = self.tr("Expired or never published") + + status_color = '#00AA00' if data['membership_state'] else self.tr('#FF0000') + description_currency = """<html> +<body> + <p> + <span style=" font-size:16pt; font-weight:600;">{currency}</span> + </p> + <p>{nb_members} {members_label}</p> + <p><span style="font-weight:600;">{monetary_mass_label}</span> : {monetary_mass}</p> + <p><span style="font-weight:600;">{balance_label}</span> : {balance}</p> +</body> +</html>""".format(currency=data['currency'], + nb_members=data['members_count'], + members_label=self.tr("members"), + monetary_mass_label=self.tr("Monetary mass"), + monetary_mass=data['mass'], + balance_label=self.tr("Balance"), + balance=data['amount']) + + description_membership = """<html> +<body> + <p><span style="font-weight:600;">{status_label}</span> + : <span style="color:{status_color};">{status}</span> + - <span>{status_info}</span></p> +</body> +</html>""".format(status_color=status_color, + status_label=self.tr("Status"), + status=status_value, + status_info=status_info) + description_identity = """<html> +<body> + <p><span style="font-weight:600;">{nb_certs_label}</span> : {nb_certs} ({outdistanced_text})</p> + <p><span style="font-weight:600;">{mstime_remaining_label}</span> : {mstime_remaining}</p> +</body> +</html>""".format(nb_certs_label=self.tr("Certs. received"), + nb_certs=data['nb_certs'], + outdistanced_text=data['outdistanced'], + mstime_remaining_label=self.tr("Membership"), + mstime_remaining=mstime_remaining_text) + + self.label_currency.setText(description_currency) + + if data['is_identity']: + self.label_membership.setText(description_membership) + self.label_identity.setText(description_identity) + self.button_membership.setText(membership_action_value) + self.button_membership.setEnabled(membership_action_enabled) + else: + self.label_membership.hide() + self.label_identity.hide() + self.button_membership.hide() + + async def licence_dialog(self, currency, params): + dt_dhms = timestamp_to_dhms(params.dt) + if dt_dhms[0] > 0: + dt_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_dhms) + else: + dt_as_str = self.tr("{:} hour(s)").format(dt_dhms[1]) + if dt_dhms[2] > 0 or dt_dhms[3] > 0: + dt_dhms += ", {:} minute(s) and {:} second(s)".format(*dt_dhms[1:]) + dt_reeval_dhms = timestamp_to_dhms(params.dt_reeval) + dt_reeval_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_reeval_dhms) + + message_box = QMessageBox(self) + + message_box.setText("Do you recognize the terms of the following licence :") + message_box.setInformativeText(""" +{:} is being produced by a Universal Dividend (UD) for any human member, which is :<br/> +<br/> +<table cellpadding="5"> + <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> +</table> +<br/> +<br/> + +The parameters of the Web of Trust of {:} are :<br/> +<table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> +</table> +<br/> +<br/> + +<b>By asking to join as member, you recognize that this is your unique account, +and that you will only certify persons that you know well enough.</b> + """.format( + ROOT_SERVERS[currency]["display"], + params.c, + QLocale().toString(params.dt / 86400, 'f', 2), + self.tr('Fundamental growth (c)'), + params.ud0, + self.tr('Initial Universal Dividend UD(0) in'), + ROOT_SERVERS[currency]["display"], + dt_as_str, + self.tr('Time period between two UD'), + dt_reeval_as_str, + self.tr('Time period between two UD reevaluation'), + ROOT_SERVERS[currency]["display"], + QLocale().toString(params.sig_period / 86400, 'f', 2), + self.tr('Minimum delay between 2 certifications (in days)'), + QLocale().toString(params.sig_validity / 86400, 'f', 2), + self.tr('Maximum age of a valid signature (in days)'), + params.sig_qty, + self.tr('Minimum quantity of signatures to be part of the WoT'), + params.sig_stock, + self.tr('Maximum quantity of active certifications made by member.'), + params.sig_window, + self.tr('Maximum delay a certification can wait before being expired for non-writing.'), + params.xpercent, + self.tr('Minimum percent of sentries to reach to match the distance rule'), + params.ms_validity / 86400, + self.tr('Maximum age of a valid membership (in days)'), + params.step_max, + self.tr('Maximum distance between each WoT member and a newcomer'), + ) + ) + message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No ) + message_box.setDefaultButton(QMessageBox.No) + return await dialog_async_exec(message_box) + + def changeEvent(self, event): + """ + Intercepte LanguageChange event to translate UI + :param QEvent QEvent: Event + :return: + """ + if event.type() == QEvent.LanguageChange: + self.retranslateUi(self) + return super().changeEvent(event) diff --git a/src/sakia/gui/navigation/informations/informations.ui b/src/sakia/gui/navigation/informations/informations.ui deleted file mode 100644 index 4aa82113f6bcdecb962fa6f9316dbc1605b33a75..0000000000000000000000000000000000000000 --- a/src/sakia/gui/navigation/informations/informations.ui +++ /dev/null @@ -1,277 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>InformationsWidget</class> - <widget class="QWidget" name="InformationsWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>538</width> - <height>737</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <property name="styleSheet"> - <string notr="true">QGroupBox { - border: 1px solid gray; - border-radius: 9px; - margin-top: 0.5em; -} - -QGroupBox::title { - subcontrol-origin: margin; - left: 10px; - padding: 0 3px 0 3px; - font-weight: bold; -}</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="3" column="0"> - <widget class="QScrollArea" name="scrollarea"> - <property name="styleSheet"> - <string notr="true"/> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>522</width> - <height>272</height> - </rect> - </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QGroupBox" name="group_general"> - <property name="styleSheet"> - <string notr="true"/> - </property> - <property name="title"> - <string>General</string> - </property> - <property name="flat"> - <bool>false</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QLabel" name="label_general"> - <property name="text"> - <string/> - </property> - <property name="scaledContents"> - <bool>false</bool> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="group_rules"> - <property name="title"> - <string>Rules</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> - <widget class="QLabel" name="label_rules"> - <property name="text"> - <string/> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="group_referentials"> - <property name="title"> - <string>Referentials</string> - </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0"> - <widget class="QLabel" name="label_referentials"> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="group_money"> - <property name="title"> - <string>Money</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QLabel" name="label_money"> - <property name="text"> - <string/> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="group_wot"> - <property name="title"> - <string>WoT</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <widget class="QLabel" name="label_wot"> - <property name="text"> - <string/> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item row="1" column="0"> - <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="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="button_certify"> - <property name="text"> - <string>Certify an identity</string> - </property> - <property name="icon"> - <iconset resource="../../../../../res/icons/icons.qrc"> - <normaloff>:/icons/certification_icon</normaloff>:/icons/certification_icon</iconset> - </property> - </widget> - </item> - </layout> - </item> - <item row="0" column="0"> - <widget class="QGroupBox" name="group_uid_state"> - <property name="title"> - <string>UID</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label_currency"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_identity"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <property name="topMargin"> - <number>6</number> - </property> - <item> - <widget class="QLabel" name="label_membership"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="button_membership"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Renew membership</string> - </property> - <property name="icon"> - <iconset resource="../../../../../res/icons/icons.qrc"> - <normaloff>:/icons/renew_membership</normaloff>:/icons/renew_membership</iconset> - </property> - <property name="iconSize"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </widget> - </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> - </layout> - </item> - </layout> - </widget> - </item> - <item row="2" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <resources> - <include location="../../../../../res/icons/icons.qrc"/> - </resources> - <connections/> -</ui> diff --git a/src/sakia/gui/navigation/informations/view.py b/src/sakia/gui/navigation/informations/view.py deleted file mode 100644 index 631567a1036600204cee6d92b8f11049600bd4c0..0000000000000000000000000000000000000000 --- a/src/sakia/gui/navigation/informations/view.py +++ /dev/null @@ -1,420 +0,0 @@ -from PyQt5.QtWidgets import QWidget, QMessageBox -from PyQt5.QtCore import QEvent, QLocale, pyqtSignal -from .informations_uic import Ui_InformationsWidget -from enum import Enum -from sakia.helpers import timestamp_to_dhms -from sakia.constants import ROOT_SERVERS -from sakia.gui.widgets.dialogs import dialog_async_exec - - -class InformationsView(QWidget, Ui_InformationsWidget): - """ - The view of navigation panel - """ - retranslate_required = pyqtSignal() - - class CommunityState(Enum): - NOT_INIT = 0 - OFFLINE = 1 - READY = 2 - - def __init__(self, parent): - super().__init__(parent) - self.setupUi(self) - self.scrollarea.hide() - #self.button_details.clicked.connect(self.handle_details_click) - - def handle_details_click(self): - if self.button_details.isChecked(): - self.scrollarea.show() - else: - self.scrollarea.hide() - - def set_simple_informations(self, data, state): - if state in (InformationsView.CommunityState.NOT_INIT, InformationsView.CommunityState.OFFLINE): - self.label_currency.setText("""<html> - <body> - <p> - <span style=" font-size:16pt; font-weight:600;">{currency}</span> - </p> - <p>{message}</p> - </body> - </html>""".format(currency=data['currency'], - message=InformationsView.simple_message[state])) - self.button_membership.hide() - else: - status_value = self.tr("Member") if data['membership_state'] else self.tr("Non-Member") - if data['mstime'] > 0: - membership_action_value = self.tr("Renew membership") - status_info = "" - membership_action_enabled = True - elif data['membership_state']: - membership_action_value = self.tr("Renew membership") - status_info = "Your membership expired" - membership_action_enabled = True - else: - membership_action_value = self.tr("Request membership") - if data['nb_certs'] > data['nb_certs_required']: - status_info = self.tr("Registration ready") - membership_action_enabled = True - else: - status_info = self.tr("{0} more certifications required")\ - .format(data['nb_certs_required'] - data['nb_certs']) - membership_action_enabled = True - - if data['mstime'] > 0: - days, hours, minutes, seconds = timestamp_to_dhms(data['mstime']) - mstime_remaining_text = self.tr("Expires in ") - if days > 0: - mstime_remaining_text += "{days} days".format(days=days) - else: - mstime_remaining_text += "{hours} hours and {min} min.".format(hours=hours, - min=minutes) - else: - mstime_remaining_text = self.tr("Expired or never published") - - status_color = '#00AA00' if data['membership_state'] else self.tr('#FF0000') - description_currency = """<html> -<body> - <p> - <span style=" font-size:16pt; font-weight:600;">{currency}</span> - </p> - <p>{nb_members} {members_label}</p> - <p><span style="font-weight:600;">{monetary_mass_label}</span> : {monetary_mass}</p> - <p><span style="font-weight:600;">{balance_label}</span> : {balance}</p> -</body> -</html>""".format(currency=data['currency'], - nb_members=data['members_count'], - members_label=self.tr("members"), - monetary_mass_label=self.tr("Monetary mass"), - monetary_mass=data['mass'], - balance_label=self.tr("Balance"), - balance=data['amount']) - - description_membership = """<html> -<body> - <p><span style="font-weight:600;">{status_label}</span> - : <span style="color:{status_color};">{status}</span> - - <span>{status_info}</span></p> -</body> -</html>""".format(status_color=status_color, - status_label=self.tr("Status"), - status=status_value, - status_info=status_info) - description_identity = """<html> -<body> - <p><span style="font-weight:600;">{nb_certs_label}</span> : {nb_certs} ({outdistanced_text})</p> - <p><span style="font-weight:600;">{mstime_remaining_label}</span> : {mstime_remaining}</p> -</body> -</html>""".format(nb_certs_label=self.tr("Certs. received"), - nb_certs=data['nb_certs'], - outdistanced_text=data['outdistanced'], - mstime_remaining_label=self.tr("Membership"), - mstime_remaining=mstime_remaining_text) - - self.label_currency.setText(description_currency) - - if data['is_identity']: - self.label_membership.setText(description_membership) - self.label_identity.setText(description_identity) - self.button_membership.setText(membership_action_value) - self.button_membership.setEnabled(membership_action_enabled) - else: - self.label_membership.hide() - self.label_identity.hide() - self.button_membership.hide() - - def set_general_text_no_dividend(self): - """ - Set the general text when there is no dividend - """ - self.label_general.setText(self.tr('No Universal Dividend created yet.')) - - def set_general_text(self, localized_data): - """ - Fill the general text with given informations - :return: - """ - # set infos in label - self.label_general.setText( - self.tr(""" - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> - <tr><td align="right"><b>{:2.2%} / {:} days</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - """).format( - localized_data.get('ud', '####'), - self.tr('Universal Dividend UD(t) in'), - localized_data['diff_units'], - localized_data.get('mass_minus_1', "###"), - self.tr('Monetary Mass M(t-1) in'), - localized_data['units'], - localized_data.get('members_count', '####'), - self.tr('Members N(t)'), - localized_data.get('mass_minus_1_per_member', '####'), - self.tr('Monetary Mass per member M(t-1)/N(t) in'), - localized_data['diff_units'], - localized_data.get('actual_growth', 0), - localized_data.get('days_per_dividend', '####'), - self.tr('Actual growth c = UD(t)/[M(t-1)/N(t)]'), - localized_data.get('ud_median_time_minus_1', '####'), - self.tr('Penultimate UD date and time (t-1)'), - localized_data.get('ud_median_time', '####'), - self.tr('Last UD date and time (t)'), - localized_data.get('next_ud_median_time', '####'), - self.tr('Next UD date and time (t+1)'), - localized_data.get('next_ud_reeaval', '####'), - self.tr('Next UD reevaluation (t+1)') - ) - ) - - def set_rules_text_no_dividend(self): - """ - Set text when no dividends was generated yet - """ - self.label_rules.setText(self.tr('No Universal Dividend created yet.')) - - def set_rules_text(self, localized_data): - """ - Set text in rules - :param dict localized_data: - :return: - """ - # set infos in label - self.label_rules.setText( - self.tr(""" - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - """).format( - self.tr('{:2.0%} / {:} days').format(localized_data['growth'], localized_data['days_per_dividend']), - self.tr('Fundamental growth (c) / Delta time (dt)'), - self.tr('UDĞ(t) = UDĞ(t-1) + c²*M(t-1)/N(t-1)'), - self.tr('Universal Dividend (formula)'), - self.tr('{:} = {:} + {:2.0%}²* {:} / {:}').format( - localized_data.get('ud_plus_1', '####'), - localized_data.get('ud', '####'), - localized_data.get('growth', '####'), - localized_data.get('mass', '####'), - localized_data.get('members_count', '####') - ), - self.tr('Universal Dividend (computed)') - ) - ) - - def set_text_referentials(self, referentials): - """ - Set text from referentials - :param list referentials: list of referentials - """ - # set infos in label - ref_template = """ - <table cellpadding="5"> - <tr><th>{:}</th><td>{:}</td></tr> - <tr><th>{:}</th><td>{:}</td></tr> - <tr><th>{:}</th><td>{:}</td></tr> - <tr><th>{:}</th><td>{:}</td></tr> - </table> - """ - templates = [] - for ref in referentials: - # print(ref_class.__class__.__name__) - # if ref_class.__class__.__name__ == 'RelativeToPast': - # continue - templates.append(ref_template.format(self.tr('Name'), ref.translated_name(), - self.tr('Units'), ref.units, - self.tr('Formula'), ref.formula, - self.tr('Description'), ref.description - ) - ) - - self.label_referentials.setText('<hr>'.join(templates)) - - def set_money_text(self, params, currency): - """ - Set text from money parameters - :param sakia.data.entities.BlockchainParameters params: Parameters of the currency - :param str currency: The currency - """ - - dt_dhms = timestamp_to_dhms(params.dt) - if dt_dhms[0] > 0: - dt_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_dhms) - else: - dt_as_str = self.tr("{:} hour(s)").format(dt_dhms[1]) - if dt_dhms[2] > 0 or dt_dhms[3] > 0: - dt_dhms += ", {:} minute(s) and {:} second(s)".format(*dt_dhms[1:]) - dt_reeval_dhms = timestamp_to_dhms(params.dt_reeval) - dt_reeval_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_reeval_dhms) - - - # set infos in label - self.label_money.setText( - self.tr(""" - <table cellpadding="5"> - <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr> - </table> - """).format( - params.c, - QLocale().toString(params.dt / 86400, 'f', 2), - self.tr('Fundamental growth (c)'), - params.ud0, - self.tr('Initial Universal Dividend UD(0) in'), - currency, - dt_as_str, - self.tr('Time period between two UD'), - dt_reeval_as_str, - self.tr('Time period between two UD reevaluation'), - params.median_time_blocks, - self.tr('Number of blocks used for calculating median time'), - params.avg_gen_time, - self.tr('The average time in seconds for writing 1 block (wished time)'), - params.dt_diff_eval, - self.tr('The number of blocks required to evaluate again PoWMin value'), - params.percent_rot, - self.tr('The percent of previous issuers to reach for personalized difficulty') - ) - ) - - def set_wot_text(self, params): - """ - Set wot text from currency parameters - :param sakia.data.entities.BlockchainParameters params: Parameters of the currency - :return: - """ - - # set infos in label - self.label_wot.setText( - self.tr(""" - <table cellpadding="5"> -<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -</table> -""").format( - QLocale().toString(params.sig_period / 86400, 'f', 2), - self.tr('Minimum delay between 2 certifications (in days)'), - QLocale().toString(params.sig_validity / 86400, 'f', 2), - self.tr('Maximum age of a valid signature (in days)'), - params.sig_qty, - self.tr('Minimum quantity of signatures to be part of the WoT'), - params.sig_stock, - self.tr('Maximum quantity of active certifications made by member.'), - params.sig_window, - self.tr('Maximum delay a certification can wait before being expired for non-writing.'), - params.xpercent, - self.tr('Minimum percent of sentries to reach to match the distance rule'), - params.ms_validity / 86400, - self.tr('Maximum age of a valid membership (in days)'), - params.step_max, - self.tr('Maximum distance between each WoT member and a newcomer'), - ) - ) - - async def licence_dialog(self, currency, params): - dt_dhms = timestamp_to_dhms(params.dt) - if dt_dhms[0] > 0: - dt_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_dhms) - else: - dt_as_str = self.tr("{:} hour(s)").format(dt_dhms[1]) - if dt_dhms[2] > 0 or dt_dhms[3] > 0: - dt_dhms += ", {:} minute(s) and {:} second(s)".format(*dt_dhms[1:]) - dt_reeval_dhms = timestamp_to_dhms(params.dt_reeval) - dt_reeval_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_reeval_dhms) - - message_box = QMessageBox(self) - - message_box.setText("Do you recognize the terms of the following licence :") - message_box.setInformativeText(""" -{:} is being produced by a Universal Dividend (UD) for any human member, which is :<br/> -<br/> -<table cellpadding="5"> - <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -</table> -<br/> -<br/> - -The parameters of the Web of Trust of {:} are :<br/> -<table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> -</table> -<br/> -<br/> - -<b>By asking to join as member, you recognize that this is your unique account, -and that you will only certify persons that you know well enough.</b> - """.format( - ROOT_SERVERS[currency]["display"], - params.c, - QLocale().toString(params.dt / 86400, 'f', 2), - self.tr('Fundamental growth (c)'), - params.ud0, - self.tr('Initial Universal Dividend UD(0) in'), - ROOT_SERVERS[currency]["display"], - dt_as_str, - self.tr('Time period between two UD'), - dt_reeval_as_str, - self.tr('Time period between two UD reevaluation'), - ROOT_SERVERS[currency]["display"], - QLocale().toString(params.sig_period / 86400, 'f', 2), - self.tr('Minimum delay between 2 certifications (in days)'), - QLocale().toString(params.sig_validity / 86400, 'f', 2), - self.tr('Maximum age of a valid signature (in days)'), - params.sig_qty, - self.tr('Minimum quantity of signatures to be part of the WoT'), - params.sig_stock, - self.tr('Maximum quantity of active certifications made by member.'), - params.sig_window, - self.tr('Maximum delay a certification can wait before being expired for non-writing.'), - params.xpercent, - self.tr('Minimum percent of sentries to reach to match the distance rule'), - params.ms_validity / 86400, - self.tr('Maximum age of a valid membership (in days)'), - params.step_max, - self.tr('Maximum distance between each WoT member and a newcomer'), - ) - ) - message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No ) - message_box.setDefaultButton(QMessageBox.No) - return await dialog_async_exec(message_box) - - def changeEvent(self, event): - """ - Intercepte LanguageChange event to translate UI - :param QEvent QEvent: Event - :return: - """ - if event.type() == QEvent.LanguageChange: - self.retranslateUi(self) - return super().changeEvent(event) diff --git a/src/sakia/gui/navigation/txhistory/controller.py b/src/sakia/gui/navigation/txhistory/controller.py index d9022dba1edd0c4054e19d110b5d5e9d962c3ccc..acf2ee357ec8309b239fef0e35c1d55d9d27bebd 100644 --- a/src/sakia/gui/navigation/txhistory/controller.py +++ b/src/sakia/gui/navigation/txhistory/controller.py @@ -42,8 +42,7 @@ class TxHistoryController(QObject): def create(cls, parent, app, connection, identities_service, blockchain_service, transactions_service, sources_service): - transfer = TransferController.create(None, app) - transfer.integrate_to_main_view(connection) + transfer = TransferController.integrate_to_main_view(None, app, connection) view = TxHistoryView(parent.view, transfer.view) model = TxHistoryModel(None, app, connection, blockchain_service, identities_service, transactions_service, sources_service) diff --git a/src/sakia/gui/navigation/informations/__init__.py b/src/sakia/gui/sub/certification/__init__.py similarity index 100% rename from src/sakia/gui/navigation/informations/__init__.py rename to src/sakia/gui/sub/certification/__init__.py diff --git a/src/sakia/gui/dialogs/certification/certification.ui b/src/sakia/gui/sub/certification/certification.ui similarity index 84% rename from src/sakia/gui/dialogs/certification/certification.ui rename to src/sakia/gui/sub/certification/certification.ui index dc03f7bcc9728695cbfcbb86321d40d8f6fbfc71..626e4130ab3229feaae6b4ac4457431793cc524a 100644 --- a/src/sakia/gui/dialogs/certification/certification.ui +++ b/src/sakia/gui/sub/certification/certification.ui @@ -1,21 +1,21 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>CertificationDialog</class> - <widget class="QDialog" name="CertificationDialog"> + <class>CertificationWidget</class> + <widget class="QWidget" name="CertificationWidget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>517</width> - <height>441</height> + <width>629</width> + <height>620</height> </rect> </property> <property name="windowTitle"> - <string>Certification</string> + <string>Form</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QGroupBox" name="groupBox_2"> + <widget class="QGroupBox" name="groupbox_identity"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> @@ -27,7 +27,7 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <widget class="QComboBox" name="combo_connection"/> + <widget class="QComboBox" name="combo_connections"/> </item> <item> <widget class="QGroupBox" name="groupBox_3"> @@ -123,13 +123,4 @@ </widget> <resources/> <connections/> - <slots> - <slot>open_manage_wallet_coins()</slot> - <slot>change_displayed_wallet(int)</slot> - <slot>transfer_mode_changed(bool)</slot> - <slot>recipient_mode_changed(bool)</slot> - <slot>change_current_community(int)</slot> - <slot>amount_changed()</slot> - <slot>relative_amount_changed()</slot> - </slots> </ui> diff --git a/src/sakia/gui/dialogs/certification/controller.py b/src/sakia/gui/sub/certification/controller.py similarity index 87% rename from src/sakia/gui/dialogs/certification/controller.py rename to src/sakia/gui/sub/certification/controller.py index 84bbd89703c2fcb154f3c7bfa17b597944bef45c..d63e1db1ace3968e63fc38f61b0816dafe8302e5 100644 --- a/src/sakia/gui/dialogs/certification/controller.py +++ b/src/sakia/gui/sub/certification/controller.py @@ -1,7 +1,7 @@ import asyncio -from PyQt5.QtCore import Qt, QObject -from PyQt5.QtWidgets import QApplication +from PyQt5.QtCore import Qt, QObject, pyqtSignal +from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout from sakia.constants import ROOT_SERVERS from sakia.decorators import asyncify @@ -20,6 +20,8 @@ class CertificationController(QObject): """ The Certification view """ + accepted = pyqtSignal() + rejected = pyqtSignal() view = attr.ib() model = attr.ib() @@ -31,7 +33,7 @@ class CertificationController(QObject): super().__init__() self.view.button_box.accepted.connect(self.accept) self.view.button_box.rejected.connect(self.reject) - self.view.combo_connection.currentIndexChanged.connect(self.change_connection) + self.view.combo_connections.currentIndexChanged.connect(self.change_connection) @classmethod def create(cls, parent, app): @@ -61,6 +63,13 @@ class CertificationController(QObject): view.identity_document_imported.connect(certification.load_identity_document) return certification + @classmethod + def integrate_to_main_view(cls, parent, app, connection): + certification = cls.create(parent, app) + certification.view.combo_connections.setCurrentText(connection.title()) + certification.view.groupbox_identity.hide() + return certification + @classmethod def open_dialog(cls, parent, app, connection): """ @@ -71,10 +80,17 @@ class CertificationController(QObject): :param sakia.core.Community community: the community :return: """ - dialog = cls.create(parent, app) - dialog.set_connection(connection) - dialog.refresh() - return dialog.exec() + + dialog = QDialog(parent) + dialog.setWindowTitle(dialog.tr("Certification")) + dialog.setLayout(QVBoxLayout(dialog)) + certification = cls.create(parent, app) + certification.set_connection(connection) + certification.refresh() + dialog.layout().addWidget(certification.view) + certification.accepted.connect(dialog.accept) + certification.rejected.connect(dialog.reject) + return certification.exec() @classmethod async def certify_identity(cls, parent, app, connection, identity): @@ -87,7 +103,7 @@ class CertificationController(QObject): :return: """ dialog = cls.create(parent, app) - dialog.view.combo_connection.setCurrentText(connection.title()) + dialog.view.combo_connections.setCurrentText(connection.title()) dialog.user_information.change_identity(identity) dialog.refresh() return await dialog.async_exec() @@ -99,7 +115,7 @@ class CertificationController(QObject): def set_connection(self, connection): if connection: - self.view.combo_connection.setCurrentText(connection.title()) + self.view.combo_connections.setCurrentText(connection.title()) self.password_input.set_connection(connection) @asyncify diff --git a/src/sakia/gui/dialogs/certification/model.py b/src/sakia/gui/sub/certification/model.py similarity index 100% rename from src/sakia/gui/dialogs/certification/model.py rename to src/sakia/gui/sub/certification/model.py diff --git a/src/sakia/gui/dialogs/certification/view.py b/src/sakia/gui/sub/certification/view.py similarity index 96% rename from src/sakia/gui/dialogs/certification/view.py rename to src/sakia/gui/sub/certification/view.py index b5bd687b877146286832568bdfbb95f4d4bf8918..00753c97f53a58cee6f4c87238b875d2bd64b048 100644 --- a/src/sakia/gui/dialogs/certification/view.py +++ b/src/sakia/gui/sub/certification/view.py @@ -1,6 +1,6 @@ from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFileDialog, QMessageBox from PyQt5.QtCore import QT_TRANSLATE_NOOP, Qt, pyqtSignal -from .certification_uic import Ui_CertificationDialog +from .certification_uic import Ui_CertificationWidget from sakia.gui.widgets import toast from sakia.gui.widgets.dialogs import QAsyncMessageBox from sakia.constants import ROOT_SERVERS @@ -8,7 +8,7 @@ from duniterpy.documents import Identity, MalformedDocumentError from enum import Enum -class CertificationView(QDialog, Ui_CertificationDialog): +class CertificationView(QDialog, Ui_CertificationWidget): """ The view of the certification component """ @@ -56,15 +56,15 @@ class CertificationView(QDialog, Ui_CertificationDialog): self.button_import_identity.clicked.connect(self.import_identity_document) def set_keys(self, connections): - self.combo_connection.clear() + self.combo_connections.clear() for c in connections: - self.combo_connection.addItem(c.title()) + self.combo_connections.addItem(c.title()) def set_selected_key(self, connection): """ :param sakia.data.entities.Connection connection: """ - self.combo_connection.setCurrentText(connection.title()) + self.combo_connections.setCurrentText(connection.title()) def pubkey_value(self): return self.edit_pubkey.text() diff --git a/src/sakia/gui/sub/transfer/controller.py b/src/sakia/gui/sub/transfer/controller.py index 8f76eae7f262518cf935e605722b184ed5ddfbdb..ee4839a533f6fe957ef551bf56d8b6b4aecded88 100644 --- a/src/sakia/gui/sub/transfer/controller.py +++ b/src/sakia/gui/sub/transfer/controller.py @@ -71,6 +71,14 @@ class TransferController(QObject): return transfer + @classmethod + def integrate_to_main_view(cls, parent, app, connection): + transfer = cls.create(parent, app) + transfer.view.combo_connections.setCurrentText(connection.title()) + transfer.view.groupbox_connection.hide() + transfer.view.label_total.hide() + return transfer + @classmethod def open_transfer_with_pubkey(cls, parent, app, connection, pubkey): transfer = cls.create(parent, app) @@ -140,11 +148,6 @@ class TransferController(QObject): transfer.rejected.connect(dialog.reject) return dialog.exec() - def integrate_to_main_view(self, connection): - self.view.combo_connections.setCurrentText(connection.title()) - self.view.groupbox_connection.hide() - self.view.label_total.hide() - def selected_pubkey(self): """ Get selected pubkey in the widgets of the window diff --git a/src/sakia/gui/widgets/context_menu.py b/src/sakia/gui/widgets/context_menu.py index fa260abb287a65db7aaa29cd38ddb99201903890..5a6c107ea01ba1644ed868936917c4478c78ccc1 100644 --- a/src/sakia/gui/widgets/context_menu.py +++ b/src/sakia/gui/widgets/context_menu.py @@ -7,7 +7,7 @@ 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 -from sakia.gui.dialogs.certification.controller import CertificationController +from sakia.gui.sub.certification.controller import CertificationController from sakia.gui.sub.transfer.controller import TransferController from sakia.gui.sub.user_information.controller import UserInformationController