From 41970ce440c84259dad9103f76234e4c029939b1 Mon Sep 17 00:00:00 2001
From: vtexier <vit@free.fr>
Date: Thu, 2 Apr 2020 11:17:41 +0200
Subject: [PATCH] [enh] #798 add send as source menu for all transactions and
 dividend in expert mode

Check is source exists before display menu
---
 src/sakia/gui/widgets/context_menu.py | 83 +++++++++++++++++++++------
 1 file changed, 66 insertions(+), 17 deletions(-)

diff --git a/src/sakia/gui/widgets/context_menu.py b/src/sakia/gui/widgets/context_menu.py
index d7f6709f..084ac3c2 100644
--- a/src/sakia/gui/widgets/context_menu.py
+++ b/src/sakia/gui/widgets/context_menu.py
@@ -7,7 +7,7 @@ from duniterpy.constants import PUBKEY_REGEX
 from duniterpy.documents.crc_pubkey import CRCPubkey
 
 from sakia.app import Application
-from sakia.data.entities import Identity, Transaction, Dividend, Connection
+from sakia.data.entities import Identity, Transaction, Dividend, Connection, Source
 from sakia.data.processors import BlockchainProcessor, TransactionsProcessor
 from sakia.decorators import asyncify
 from sakia.gui.sub.certification.controller import CertificationController
@@ -106,7 +106,7 @@ class ContextMenu(QObject):
             menu.qmenu.addAction(copy_selfcert)
 
     @staticmethod
-    def _add_transfers_actions(menu, transfer):
+    def _add_transfer_actions(menu, transfer):
         """
         :param ContextMenu menu: the qmenu to add actions to
         :param Transfer transfer: the transfer
@@ -132,16 +132,26 @@ class ContextMenu(QObject):
             )
             menu.qmenu.addAction(cancel)
 
-        # if special lock condition on transaction...
-        if transfer.conditions is not None:
-            send_as_source = QAction(
-                QCoreApplication.translate("ContextMenu", "Send as source"),
-                menu.qmenu.parent(),
-            )
-            send_as_source.triggered.connect(
-                lambda checked, tr=transfer: menu.send_as_source(tr)
+        # if special lock condition on transaction or
+        # all transaction received in expert mode...
+        if transfer.conditions is not None or (
+            transfer.pubkey in transfer.receivers and menu._app.parameters.expert_mode
+        ):
+            # get source from conditions and transaction hash
+            source = menu._app.sources_service.get_one(
+                identifier=transfer.sha_hash, conditions=transfer.conditions
             )
-            menu.qmenu.addAction(send_as_source)
+            if source:
+                # add send as source menu
+                send_as_source = QAction(
+                    QCoreApplication.translate("ContextMenu", "Send as source"),
+                    menu.qmenu.parent(),
+                )
+                send_as_source.triggered.connect(
+                    lambda checked, src=source: menu.send_as_source(src)
+                )
+                menu.qmenu.addAction(send_as_source)
+
         if menu._app.parameters.expert_mode:
             copy_doc = QAction(
                 QCoreApplication.translate(
@@ -168,6 +178,32 @@ class ContextMenu(QObject):
                 )
                 menu.qmenu.addAction(copy_doc)
 
+    @staticmethod
+    def _add_dividend_actions(menu, dividend):
+        """
+        :param ContextMenu menu: the qmenu to add actions to
+        :param Transfer transfer: the transfer
+        """
+        menu.qmenu.addSeparator().setText(
+            QCoreApplication.translate("ContextMenu", "Dividend")
+        )
+
+        if menu._app.parameters.expert_mode:
+            # get dividend source from block number and type
+            source = menu._app.sources_service.get_one(
+                noffset=dividend.block_number, type=Source.TYPE_DIVIDEND
+            )
+            if source:
+                # add send as source menu
+                send_as_source = QAction(
+                    QCoreApplication.translate("ContextMenu", "Send as source"),
+                    menu.qmenu.parent(),
+                )
+                send_as_source.triggered.connect(
+                    lambda checked, src=source: menu.send_dividend_as_source(src)
+                )
+                menu.qmenu.addAction(send_as_source)
+
     @staticmethod
     def _add_string_actions(menu, str_value):
         if re.match(PUBKEY_REGEX, str_value):
@@ -219,8 +255,8 @@ class ContextMenu(QObject):
         menu = cls(QMenu(parent), app, connection)
         build_actions = {
             Identity: ContextMenu._add_identity_actions,
-            Transaction: ContextMenu._add_transfers_actions,
-            Dividend: lambda m, d: None,
+            Transaction: ContextMenu._add_transfer_actions,
+            Dividend: ContextMenu._add_dividend_actions,
             str: ContextMenu._add_string_actions,
             dict: lambda m, d: None,
             type(None): lambda m, d: None,
@@ -298,11 +334,24 @@ This money transfer will be removed and not sent.""",
             self._app.db.commit()
             self._app.transaction_state_changed.emit(transfer)
 
-    def send_as_source(self, transfer: Transaction):
-        # get source from conditions and transaction hash
-        source = self._app.sources_service.get_one(
-            identifier=transfer.sha_hash, conditions=transfer.conditions
+    def send_as_source(self, source: Source):
+        """
+        Open transfer dialog with a transaction as source
+
+        :param Source source: Source entity to send
+        :return:
+        """
+        TransferController.send_money_to_pubkey(
+            None, self._app, self._connection, None, source
         )
+
+    def send_dividend_as_source(self, source: Source):
+        """
+        Open transfer dialog with a dividend as source
+
+        :param Source source: Source entity to send
+        :return:
+        """
         TransferController.send_money_to_pubkey(
             None, self._app, self._connection, None, source
         )
-- 
GitLab