diff --git a/res/ui/toast.ui b/res/ui/toast.ui new file mode 100644 index 0000000000000000000000000000000000000000..73ebaaed438fc6f70d68489ca5d59030cb6d3a5c --- /dev/null +++ b/res/ui/toast.ui @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Toast</class> + <widget class="QMainWindow" name="Toast"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>358</width> + <height>87</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="display"> + <property name="styleSheet"> + <string notr="true"/> + </property> + <property name="text"> + <string/> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py index dd87965787a959291bd3f8c54a3708dd841f57c0..95c7ef9d6fbbf33b34e9616941809d6b1f321b81 100644 --- a/src/cutecoin/core/account.py +++ b/src/cutecoin/core/account.py @@ -184,7 +184,7 @@ class Account(QObject): for w in self.wallets: w.refresh_progressed.connect(progressing, type=Qt.DirectConnection) for c in self.communities: - w.refresh_cache(c) + w.refresh_cache(c, []) loaded_wallets = loaded_wallets + 1 def set_display_referential(self, index): diff --git a/src/cutecoin/core/wallet.py b/src/cutecoin/core/wallet.py index 5479d48b5c79e2e3fb294b42c9aacbcbf787300d..6064f39536bf65f5da8da655acd92718fc96f223 100644 --- a/src/cutecoin/core/wallet.py +++ b/src/cutecoin/core/wallet.py @@ -60,7 +60,7 @@ class Cache(): def transfers(self): return [t for t in self._transfers if t.state != Transfer.DROPPED] - def _parse_transaction(self, community, tx, block_number, mediantime): + def _parse_transaction(self, community, tx, block_number, mediantime, received_list): logging.debug(tx) receivers = [o.pubkey for o in tx.outputs if o.pubkey != tx.issuers[0]] @@ -113,11 +113,12 @@ class Cache(): for o in outputs: amount += o.amount metadata['amount'] = amount + received = Received(tx, metadata.copy()) + received_list.append(received) + self._transfers.append(received) - self._transfers.append(Received(tx, - metadata.copy())) - def _parse_block(self, community, block_number): + def _parse_block(self, community, block_number, received_list): block = community.request(bma.blockchain.Block, req_args={'number': block_number}) signed_raw = "{0}{1}\n".format(block['raw'], @@ -128,7 +129,8 @@ class Cache(): logging.debug("Error in {0}".format(block_number)) raise for tx in block_doc.transactions: - self._parse_transaction(community, tx, block_number, block_doc.mediantime) + self._parse_transaction(community, tx, block_number, + block_doc.mediantime, received_list) awaiting = [t for t in self._transfers if t.state == Transfer.AWAITING] @@ -139,8 +141,9 @@ class Cache(): transfer.check_registered(tx, block_number, block_doc.mediantime) - def refresh(self, community): + def refresh(self, community, received_list): current_block = 0 + received_list = [] try: block_data = community.current_blockid() current_block = block_data['number'] @@ -160,7 +163,7 @@ class Cache(): self.wallet.refresh_progressed.emit(self.latest_block, current_block) for block_number in parsed_blocks: - self._parse_block(community, block_number) + self._parse_block(community, block_number, received_list) self.wallet.refresh_progressed.emit(current_block - block_number, current_block - self.latest_block) @@ -249,7 +252,7 @@ class Wallet(QObject): data[currency] = self.caches[currency].jsonify() return data - def refresh_cache(self, community): + def refresh_cache(self, community, received_list): ''' Refresh the cache of this wallet for the specified community. @@ -257,7 +260,7 @@ class Wallet(QObject): ''' if community.currency not in self.caches: self.caches[community.currency] = Cache(self) - self.caches[community.currency].refresh(community) + self.caches[community.currency].refresh(community, received_list) def check_password(self, salt, password): ''' diff --git a/src/cutecoin/core/watching/blockchain.py b/src/cutecoin/core/watching/blockchain.py index 0e20aab46894304720a6b890c9270f93126fcad7..af9e1aaefb44958edb9b1cd26644980f9d47f353 100644 --- a/src/cutecoin/core/watching/blockchain.py +++ b/src/cutecoin/core/watching/blockchain.py @@ -9,9 +9,12 @@ import time from requests.exceptions import RequestException from ...tools.exceptions import NoPeerAvailable from .watcher import Watcher +from PyQt5.QtCore import pyqtSignal class BlockchainWatcher(Watcher): + + new_transfers = pyqtSignal(list) def __init__(self, account, community): super().__init__() self.account = account @@ -22,17 +25,20 @@ class BlockchainWatcher(Watcher): def watch(self): try: + received_list = [] block_number = self.community.network.latest_block if self.last_block != block_number: if not self.exiting: self.community.refresh_cache() for w in self.account.wallets: if not self.exiting: - w.refresh_cache(self.community) + w.refresh_cache(self.community, received_list) logging.debug("New block, {0} mined in {1}".format(block_number, self.community.currency)) self.last_block = block_number + if len(received_list) > 0: + self.new_transfers.emit(received_list) except NoPeerAvailable: pass except RequestException as e: diff --git a/src/cutecoin/gui/currency_tab.py b/src/cutecoin/gui/currency_tab.py index e247604680bccb2b559e2ae834eb49b953c4121c..1cc3f3f847c6e6911da54c6b69bd6a524e002cb4 100644 --- a/src/cutecoin/gui/currency_tab.py +++ b/src/cutecoin/gui/currency_tab.py @@ -16,6 +16,7 @@ from .wallets_tab import WalletsTabWidget from .transactions_tab import TransactionsTabWidget from .network_tab import NetworkTabWidget from .informations_tab import InformationsTabWidget +from .toast import Toast from ..tools.exceptions import MembershipNotFoundError from ..core.person import Person @@ -56,6 +57,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): bc_watcher = self.app.monitor.blockchain_watcher(self.community) bc_watcher.error.connect(self.display_error) bc_watcher.watching_stopped.connect(self.refresh_data) + bc_watcher.new_transfers.connect(self.notify_transfers) person = Person.lookup(self.app.current_account.pubkey, self.community) try: @@ -176,6 +178,18 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): icon = '<img src=":/icons/disconnected" width="12" height="12"/>' self.status_label.setText("{0}{1}".format(icon, text)) + @pyqtSlot(list) + def notify_transfers(self, transfers_list): + text = self.tr("Received {0} {1}") + amount = 0 + currency = self.community.name + for t in transfers_list: + amount += t.metadata['amount'] + text += """{0} +""".format(t.metadata['uid']) + text.format(amount, currency) + Toast(text) + def refresh_wallets(self): if self.app.current_account: self.tab_wallets.refresh() diff --git a/src/cutecoin/gui/toast.py b/src/cutecoin/gui/toast.py new file mode 100644 index 0000000000000000000000000000000000000000..f3903a69ae42b182b4ff837582f3972255cc46d8 --- /dev/null +++ b/src/cutecoin/gui/toast.py @@ -0,0 +1,37 @@ +''' +Created on 1 mai 2015 + +@author: inso +''' +import sys, time +from PyQt5.QtCore import Qt, QThread +from PyQt5.QtWidgets import QMainWindow +from ..gen_resources.toast_uic import Ui_Toast + +window = None # global + +class Toast(QMainWindow, Ui_Toast): + def __init__(self, msg): + global window # some space outside the local stack + window = self # save pointer till killed to avoid GC + super().__init__() + self.setWindowFlags(Qt.FramelessWindowHint) + self.setupUi(self) + + self.display.setText(msg) + + self.toastThread = ToastThread() # start thread to remove display + self.toastThread.finished.connect(self.toastDone) + self.toastThread.start() + self.show() + + def toastDone(self): + global window + window = None # kill pointer to window object to close it and GC + +class ToastThread(QThread): + def __init__(self): + QThread.__init__(self) + + def run(self): + time.sleep(2.0) \ No newline at end of file