diff --git a/Makefile b/Makefile index 4afec396e08904eb71d3deeb545f8a91d47ddf34..655556026ee27188d8f30a0810a3456e654c6ae8 100644 --- a/Makefile +++ b/Makefile @@ -6,11 +6,11 @@ RESOURCE_DIR = res/ui COMPILED_DIR = src/cutecoin/gen_resources #UI files to compile -UI_FILES = mainwindow.ui addAccountDialog.ui addCommunityDialog.ui communityTabWidget.ui issuanceDialog.ui +UI_FILES = mainwindow.ui addAccountDialog.ui addCommunityDialog.ui communityTabWidget.ui issuanceDialog.ui transferDialog.ui #Qt resource files to compile RESOURCES = -#pyuic4 and pyrcc4 binaries +#pyuic5 and pyrcc5 binaries PYUIC = pyuic5 PYRCC = pyrcc5 diff --git a/res/ui/mainwindow.ui b/res/ui/mainwindow.ui index f980d5dc26cdea5dd76edf5edcc6a83efaa903f2..3fc73a2798bfd9c2683c859a27fec5bc20c0ae18 100644 --- a/res/ui/mainwindow.ui +++ b/res/ui/mainwindow.ui @@ -139,8 +139,15 @@ <addaction name="separator"/> <addaction name="actionAdd_a_contact"/> </widget> + <widget class="QMenu" name="menuActions"> + <property name="title"> + <string>Actions</string> + </property> + <addaction name="actionTransfer_money"/> + </widget> <addaction name="menuTr_File"/> <addaction name="menuEdit"/> + <addaction name="menuActions"/> </widget> <widget class="QStatusBar" name="statusbar"/> <action name="actionManage_accounts"> @@ -208,6 +215,11 @@ <string>Account</string> </property> </action> + <action name="actionTransfer_money"> + <property name="text"> + <string>Transfer money</string> + </property> + </action> </widget> <resources/> <connections> @@ -259,9 +271,26 @@ </hint> </hints> </connection> + <connection> + <sender>actionTransfer_money</sender> + <signal>triggered()</signal> + <receiver>MainWindow</receiver> + <slot>openTransferMoneyDialog()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>248</x> + <y>218</y> + </hint> + </hints> + </connection> </connections> <slots> <slot>openAddAccountDialog()</slot> <slot>save()</slot> + <slot>openTransferMoneyDialog()</slot> </slots> </ui> diff --git a/res/ui/transferDialog.ui b/res/ui/transferDialog.ui index 1993bc8c4c1553e7850832077eaf76b71e23e7c4..76f411f5a21db20a17cc659629d577022497add9 100644 --- a/res/ui/transferDialog.ui +++ b/res/ui/transferDialog.ui @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>Dialog</class> - <widget class="QDialog" name="Dialog"> + <class>TransferMoneyDialog</class> + <widget class="QDialog" name="TransferMoneyDialog"> <property name="geometry"> <rect> <x>0</x> @@ -11,7 +11,7 @@ </rect> </property> <property name="windowTitle"> - <string>Dialog</string> + <string>Transfer money</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> @@ -31,6 +31,12 @@ </item> <item> <widget class="QLineEdit" name="edit_keyFingerprint"> + <property name="inputMask"> + <string>>NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN</string> + </property> + <property name="text"> + <string/> + </property> <property name="placeholderText"> <string>Key fingerprint</string> </property> @@ -66,12 +72,39 @@ <item> <widget class="QRadioButton" name="radio_nodeAddress"> <property name="text"> + <string>Node</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="edit_nodeAddress"> + <property name="inputMask"> + <string/> + </property> + <property name="placeholderText"> <string>Node address</string> </property> </widget> </item> <item> - <widget class="QLineEdit" name="edit_nodeAddress"/> + <widget class="QLabel" name="label"> + <property name="text"> + <string>:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="edit_port"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="placeholderText"> + <string>Port</string> + </property> + </widget> </item> </layout> </item> @@ -104,7 +137,17 @@ <number>5</number> </property> <item> - <widget class="QListView" name="listView_wallet"/> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <property name="leftMargin"> + <number>6</number> + </property> + <item> + <widget class="QComboBox" name="comboBox_wallets"/> + </item> + <item> + <widget class="QListView" name="listView_wallet"/> + </item> + </layout> </item> <item> <layout class="QVBoxLayout" name="verticalLayout_4"> @@ -135,7 +178,31 @@ </layout> </item> <item> - <widget class="QListView" name="listView_coinsSent"/> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <item> + <widget class="QLineEdit" name="lineEdit"> + <property name="placeholderText"> + <string>A message</string> + </property> + </widget> + </item> + <item> + <widget class="QListView" name="listView_coinsSent"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>8</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> </item> </layout> </item> @@ -186,7 +253,7 @@ <connection> <sender>buttonBox</sender> <signal>accepted()</signal> - <receiver>Dialog</receiver> + <receiver>TransferMoneyDialog</receiver> <slot>accept()</slot> <hints> <hint type="sourcelabel"> @@ -202,7 +269,7 @@ <connection> <sender>buttonBox</sender> <signal>rejected()</signal> - <receiver>Dialog</receiver> + <receiver>TransferMoneyDialog</receiver> <slot>reject()</slot> <hints> <hint type="sourcelabel"> @@ -215,5 +282,109 @@ </hint> </hints> </connection> + <connection> + <sender>button_add</sender> + <signal>clicked()</signal> + <receiver>TransferMoneyDialog</receiver> + <slot>addCoinsToTransfer()</slot> + <hints> + <hint type="sourcelabel"> + <x>201</x> + <y>327</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>244</y> + </hint> + </hints> + </connection> + <connection> + <sender>button_remove</sender> + <signal>clicked()</signal> + <receiver>TransferMoneyDialog</receiver> + <slot>removeCoinsFromTransfer()</slot> + <hints> + <hint type="sourcelabel"> + <x>201</x> + <y>373</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>244</y> + </hint> + </hints> + </connection> + <connection> + <sender>button_manageCoins</sender> + <signal>clicked()</signal> + <receiver>TransferMoneyDialog</receiver> + <slot>openManageWalletCoins()</slot> + <hints> + <hint type="sourcelabel"> + <x>201</x> + <y>281</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>244</y> + </hint> + </hints> + </connection> + <connection> + <sender>comboBox_wallets</sender> + <signal>currentIndexChanged(int)</signal> + <receiver>TransferMoneyDialog</receiver> + <slot>changeDisplayedWallet()</slot> + <hints> + <hint type="sourcelabel"> + <x>82</x> + <y>264</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>244</y> + </hint> + </hints> + </connection> + <connection> + <sender>radio_keyFingerprint</sender> + <signal>toggled(bool)</signal> + <receiver>TransferMoneyDialog</receiver> + <slot>recipientModeChanged(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>87</x> + <y>51</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>244</y> + </hint> + </hints> + </connection> + <connection> + <sender>radio_nodeAddress</sender> + <signal>toggled(bool)</signal> + <receiver>TransferMoneyDialog</receiver> + <slot>transferModeChanged(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>70</x> + <y>155</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>244</y> + </hint> + </hints> + </connection> </connections> + <slots> + <slot>addCoinsToTransfer()</slot> + <slot>removeCoinsFromTransfer()</slot> + <slot>openManageWalletCoins()</slot> + <slot>changeDisplayedWallet(int)</slot> + <slot>transferModeChanged(bool)</slot> + <slot>recipientModeChanged(bool)</slot> + </slots> </ui> diff --git a/src/cutecoin/gui/mainWindow.py b/src/cutecoin/gui/mainWindow.py index c56edffb9bd89b5afac3eb5aab3ff5897fb19263..1388d900996f0246d5df979c3046a23004ce7d3e 100644 --- a/src/cutecoin/gui/mainWindow.py +++ b/src/cutecoin/gui/mainWindow.py @@ -7,6 +7,7 @@ from cutecoin.gen_resources.mainwindow_uic import Ui_MainWindow from PyQt5.QtWidgets import QMainWindow, QAction, QErrorMessage from PyQt5.QtCore import QSignalMapper from cutecoin.gui.addAccountDialog import AddAccountDialog +from cutecoin.gui.transferMoneyDialog import TransferMoneyDialog from cutecoin.gui.communityTabWidget import CommunityTabWidget from cutecoin.models.account.wallets.listModel import WalletsListModel from cutecoin.models.wallet.listModel import WalletListModel @@ -55,6 +56,10 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.refreshMainWindow() + def openTransferMoneyDialog(self): + transferMoneyDialog = TransferMoneyDialog(self.core.currentAccount) + transferMoneyDialog.exec_() + ''' Refresh main window When the selected account changes, all the widgets diff --git a/src/cutecoin/gui/transferMoneyDialog.py b/src/cutecoin/gui/transferMoneyDialog.py new file mode 100644 index 0000000000000000000000000000000000000000..7af976b2f614bbdb699fcd348b96283e7a52bda4 --- /dev/null +++ b/src/cutecoin/gui/transferMoneyDialog.py @@ -0,0 +1,95 @@ +''' +Created on 2 févr. 2014 + +@author: inso +''' +import logging +from math import pow + +from PyQt5.QtWidgets import QDialog,QFrame, QSlider, QLabel, QDialogButtonBox +from PyQt5.QtCore import Qt, QSignalMapper + + +from cutecoin.models.coin import Coin +from cutecoin.models.person import Person +from cutecoin.models.node import Node +from cutecoin.models.coin.listModel import CoinsListModel + +from cutecoin.gen_resources.transferDialog_uic import Ui_TransferMoneyDialog + +class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): + ''' + classdocs + ''' + def __init__(self, sender): + ''' + Constructor + ''' + super(TransferMoneyDialog, self).__init__() + self.setupUi(self) + self.sender = sender + for wallet in sender.wallets.walletsList: + self.comboBox_wallets.addItem(wallet.getText()) + + self.refreshTransaction(sender.wallets.walletsList[0]) + + + def removeCoinsFromTransfer(self): + selection = self.listView_coinsSent.selectedIndexes() + walletCoins = self.listView_wallet.model().coins + sentCoins = self.listView_coinsSent.model().coins + newWallet = sentCoins + for selected in selection: + coin = sentCoins[selected.row()] + sentCoins.remove(coin) + walletCoins.append(coin) + self.listView_wallet.setModel(CoinsListModel(walletCoins)) + self.listView_coinsSent.setModel(CoinsListModel(newWallet)) + + def addCoinsToTransfer(self): + selection = self.listView_wallet.selectedIndexes() + walletCoins = self.listView_wallet.model().coins + sentCoins = self.listView_coinsSent.model().coins + newWallet = walletCoins + for selected in selection: + coin = walletCoins[selected.row()] + newWallet.remove(coin) + sentCoins.append(coin) + self.listView_wallet.setModel(CoinsListModel(newWallet)) + self.listView_coinsSent.setModel(CoinsListModel(sentCoins)) + + def openManageWalletCoins(self): + pass + + def accept(self): + sentCoins = self.listView_coinsSent.model().coins + receiver = None + + if self.radio_keyFingerprint.toggled(): + receiver = Person(self.edit_keyFingerprint.text(), "", "") + else: + #TODO: Manage contacts + receiver = Person(self.edit_keyFingerprint.text(), "", "") + + if self.radio_nodeAddress.toggled(): + node = Node(self.edit_nodeAddress, self.edit_port) + else: + #TODO: Manage trusted nodes + node = Node(self.edit_nodeAddress, self.edit_port) + + #TODO: Transfer money, and validate the window if no error happened + + self.sender.transferCoins(sentCoins) + + def changeDisplayedWallet(self, index): + wallet = self.sender.wallets.walletsList[index] + self.refreshTransaction(wallet) + + def refreshTransaction(self, wallet): + coinsSentModel = CoinsListModel([]) + self.listView_coinsSent.setModel(coinsSentModel) + walletCoinsModel = CoinsListModel(list(wallet.coins)) + self.listView_wallet.setModel(walletCoinsModel) + + + diff --git a/src/cutecoin/models/coin/__init__.py b/src/cutecoin/models/coin/__init__.py index 1cfc8c708307416954fe02d3b2c3dff47a9f8725..cd6bf8f7b11e828004fdfd9d411127a3f4ee1fa3 100644 --- a/src/cutecoin/models/coin/__init__.py +++ b/src/cutecoin/models/coin/__init__.py @@ -31,6 +31,9 @@ class Coin(object): origin = m.group(5) return cls(issuer, number, base, power, origin) + def __eq__(self, other): + return self.getId() == other.getId() + def value(self): return self.base*math.pow(10, self.power) diff --git a/src/cutecoin/models/community/__init__.py b/src/cutecoin/models/community/__init__.py index 1dbfbe854f0e51e2016f15c52208dcd06a0cf258..adab6a1a29c310cd6eabd4bedc1ebd723badff8f 100644 --- a/src/cutecoin/models/community/__init__.py +++ b/src/cutecoin/models/community/__init__.py @@ -42,11 +42,12 @@ class Community(object): community = cls(knownNodes) for walletsData in jsonData['wallets']: - account.wallets.walletsList.append(Wallet.load(walletsData, community)) + wallet = Wallet.load(walletsData, community) + wallet.refreshCoins(account.keyFingerprint()) + account.wallets.walletsList.append(wallet) return community - def membersFingerprints(self): ''' Listing members of a community diff --git a/src/cutecoin/models/person/__init__.py b/src/cutecoin/models/person/__init__.py index 410d81924917b1e8a081b051e9a1ce3d274ad86b..dc913e7ad62e1459aea8b4168dbd17295f92feeb 100644 --- a/src/cutecoin/models/person/__init__.py +++ b/src/cutecoin/models/person/__init__.py @@ -22,8 +22,9 @@ class Person(object): self.fingerprint = fingerprint self.email = email + @classmethod - def create(cls, pgpFingerprint, community): + def lookup(cls, pgpFingerprint, community): ''' Create a person from the pgpFingerprint found in a community ''' diff --git a/src/cutecoin/models/wallet/__init__.py b/src/cutecoin/models/wallet/__init__.py index 2d46c9f218f11cc4a349f9a4a14f8d84cdc5e0fd..65386c5187ba7f1d7c10850066017407f4fc71fa 100644 --- a/src/cutecoin/models/wallet/__init__.py +++ b/src/cutecoin/models/wallet/__init__.py @@ -47,12 +47,12 @@ class Wallet(object): return value def refreshCoins(self, pgpFingerprint): - dataList = self.community.ucoinRequest(lambda : ucoin.hdc.coins.List, ctor_args={'pgp_fingerprint':pgpFingerprint}) + dataList = self.community.ucoinRequest(ucoin.hdc.coins.List({'pgp_fingerprint':pgpFingerprint})) for issaunces in dataList['coins']: issuer = issaunces['issuer'] for coinsIds in issaunces['ids']: shortened_id = coinsIds - coin = Coin.fromId(pgpFingerprint, issuer+"-"+shortened_id) + coin = Coin.fromId(issuer+"-"+shortened_id) self.coins.append(coin) def getText(self):