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

Multiwallet feature is live !

parent 371d183d
No related branches found
No related tags found
No related merge requests found
......@@ -57,6 +57,33 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="topMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Wallets</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinbox_wallets">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
......@@ -387,7 +414,7 @@
<sender>edit_account_name</sender>
<signal>textChanged(QString)</signal>
<receiver>AccountConfigurationDialog</receiver>
<slot>action_edit_account_name()</slot>
<slot>action_edit_account_parameters()</slot>
<hints>
<hint type="sourcelabel">
<x>240</x>
......@@ -415,6 +442,22 @@
</hint>
</hints>
</connection>
<connection>
<sender>spinbox_wallets</sender>
<signal>valueChanged(int)</signal>
<receiver>AccountConfigurationDialog</receiver>
<slot>action_edit_account_parameters()</slot>
<hints>
<hint type="sourcelabel">
<x>285</x>
<y>127</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>118</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>open_process_add_community()</slot>
......@@ -426,7 +469,7 @@
<slot>open_import_key()</slot>
<slot>open_generate_account_key()</slot>
<slot>action_edit_account_key()</slot>
<slot>action_edit_account_name()</slot>
<slot>action_edit_account_parameters()</slot>
<slot>action_show_pubkey()</slot>
</slots>
</ui>
......@@ -37,7 +37,11 @@
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="list_wallets"/>
<widget class="QListView" name="list_wallets">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="list_wallet_content"/>
......@@ -87,5 +91,42 @@
</layout>
</widget>
<resources/>
<connections/>
<connections>
<connection>
<sender>list_wallets</sender>
<signal>clicked(QModelIndex)</signal>
<receiver>CurrencyTabWidget</receiver>
<slot>refresh_wallet_content(QModelIndex)</slot>
<hints>
<hint type="sourcelabel">
<x>113</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
<connection>
<sender>list_wallets</sender>
<signal>customContextMenuRequested(QPoint)</signal>
<receiver>CurrencyTabWidget</receiver>
<slot>wallet_context_menu(QPoint)</slot>
<hints>
<hint type="sourcelabel">
<x>113</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>refresh_wallet_content(QModelIndex)</slot>
<slot>wallet_context_menu(QPoint)</slot>
</slots>
</ui>
......@@ -98,19 +98,16 @@ class Account(object):
community = Community.create(currency, peer)
self.communities.append(community)
wallet = Wallet.create(self.next_walletid(), self.pubkey,
currency, "Default wallet")
self.wallets.append(wallet)
return community
def next_walletid(self):
wid = 0
for w in self.wallets:
if w.walletid > wid:
wid = w.walletid + 1
return wid
def set_walletpool_size(self, size, password):
logging.debug("Defining wallet pool size")
if len(self.wallets) < size:
for i in range(len(self.wallets), size):
wallet = Wallet.create(i, self.salt, password, "Wallet {0}".format(i))
self.wallets.append(wallet)
else:
self.wallets = self.wallets[:size]
def certify(self, password, community, pubkey):
certified = Person.lookup(pubkey, community)
......
......@@ -97,7 +97,6 @@ class Community(object):
return members
def request(self, request, req_args={}, get_args={}):
logging.debug("Peers : {0}".format(self.peers))
for peer in self.peers:
e = next(e for e in peer.endpoints if type(e) is BMAEndpoint)
# We request the current block every five minutes
......@@ -125,8 +124,8 @@ class Community(object):
self.requests_cache = {cache_key: data}
else:
if cache_key in self.requests_cache.keys():
logging.debug("Cache : {0} : {1}".format(cache_key,
self.requests_cache[cache_key]))
#logging.debug("Cache : {0} : {1}".format(cache_key,
# self.requests_cache[cache_key]))
return self.requests_cache[cache_key]
# If we cant find it, we request for it
else:
......
......@@ -17,28 +17,30 @@ class Wallet(object):
A wallet is used to manage money with a unique key.
'''
def __init__(self, walletid, pubkey, currency, name):
def __init__(self, walletid, pubkey, name):
'''
Constructor
'''
self.coins = []
self.walletid = walletid
self.pubkey = pubkey
self.currency = currency
self.name = name
self.inputs_cache = None
@classmethod
def create(cls, walletid, pubkey, currency, name):
return cls(walletid, pubkey, currency, name)
def create(cls, walletid, salt, password, name):
if walletid == 0:
key = SigningKey(salt, password)
else:
key = SigningKey("{0}{1}".format(salt, walletid), password)
return cls(walletid, key.pubkey, name)
@classmethod
def load(cls, json_data):
walletid = json_data['walletid']
pubkey = json_data['pubkey']
name = json_data['name']
currency = json_data['currency']
return cls(walletid, pubkey, currency, name)
return cls(walletid, pubkey, name)
def __eq__(self, other):
return (self.keyid == other.keyid)
......@@ -138,11 +140,10 @@ class Wallet(object):
def get_text(self, community):
return "%s : \n \
%d %s \n \
%.2f UD" % (self.name, self.value(community), self.currency,
%.2f UD" % (self.name, self.value(community), community.currency,
self.relative_value(community))
def jsonify(self):
return {'walletid': self.walletid,
'pubkey': self.pubkey,
'name': self.name,
'currency': self.currency}
'name': self.name}
......@@ -5,8 +5,8 @@ Created on 2 févr. 2014
'''
import logging
from PyQt5.QtWidgets import QWidget, QErrorMessage
from PyQt5.QtCore import QModelIndex
from PyQt5.QtWidgets import QWidget, QMenu, QAction, QApplication
from PyQt5.QtCore import QModelIndex, Qt
from cutecoin.gen_resources.currency_tab_uic import Ui_CurrencyTabWidget
from cutecoin.gui.community_tab import CommunityTabWidget
from cutecoin.models.sent import SentListModel
......@@ -46,7 +46,9 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
self.tabs_account.addTab(tab_community, "Community")
def refresh_wallets(self):
wallets_list_model = WalletsListModel(self.app.current_account)
wallets_list_model = WalletsListModel(self.app.current_account,
self.community)
wallets_list_model.dataChanged.connect(self.wallet_changed)
self.list_wallets.setModel(wallets_list_model)
self.refresh_wallet_content(QModelIndex())
......@@ -54,3 +56,36 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
current_wallet = self.app.current_account.wallets[index.row()]
wallet_list_model = WalletListModel(current_wallet, self.community)
self.list_wallet_content.setModel(wallet_list_model)
def wallet_context_menu(self, point):
index = self.list_wallets.indexAt(point)
model = self.list_wallets.model()
if index.row() < model.rowCount(None):
wallet = model.wallets[index.row()]
logging.debug(wallet)
menu = QMenu(model.data(index, Qt.DisplayRole), self)
rename = QAction("Rename", self)
rename.triggered.connect(self.rename_wallet)
rename.setData(index)
copy_pubkey = QAction("Copy pubkey to clipboard", self)
copy_pubkey.triggered.connect(self.copy_pubkey_to_clipboard)
copy_pubkey.setData(wallet)
menu.addAction(rename)
menu.addAction(copy_pubkey)
# Show the context menu.
menu.exec_(self.list_wallets.mapToGlobal(point))
def rename_wallet(self):
index = self.sender().data()
self.list_wallets.edit(index)
def copy_pubkey_to_clipboard(self):
wallet = self.sender().data()
clipboard = QApplication.clipboard()
clipboard.setText(wallet.pubkey)
def wallet_changed(self):
self.app.save(self.app.current_account)
......@@ -11,7 +11,7 @@ from cutecoin.gui.process_cfg_community import ProcessConfigureCommunity
from cutecoin.models.communities import CommunitiesListModel
from cutecoin.tools.exceptions import KeyAlreadyUsed, Error
from PyQt5.QtWidgets import QDialog, QErrorMessage, QFileDialog, QMessageBox
from PyQt5.QtWidgets import QDialog, QErrorMessage, QInputDialog, QMessageBox, QLineEdit
class Step():
......@@ -47,6 +47,8 @@ class StepPageInit(Step):
self.config_dialog.edit_account_name.setText(self.config_dialog.account.name)
model = CommunitiesListModel(self.config_dialog.account)
self.config_dialog.list_communities.setModel(model)
nb_wallets = len(self.config_dialog.account.wallets)
self.config_dialog.spinbox_wallets.setValue(nb_wallets)
self.config_dialog.button_previous.setEnabled(False)
self.config_dialog.button_next.setEnabled(False)
......@@ -109,8 +111,7 @@ class StepPageCommunities(Step):
port = self.config_dialog.spinbox_port.value()
account = self.config_dialog.account
self.config_dialog.community = account.add_community(server, port)
account.wallets.add_wallet(0,
self.config_dialog.community)
self.config_dialog.refresh()
def display_page(self):
......@@ -147,6 +148,7 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog):
else:
self.stacked_pages.removeWidget(self.stacked_pages.widget(1))
step_init.next_step = step_communities
self.button_next.setEnabled(True)
self.setWindowTitle("Configure " + self.account.name)
def open_process_add_community(self):
......@@ -181,9 +183,10 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog):
salt = self.edit_email.text()
password = self.edit_password.text()
pubkey = SigningKey(salt, password).pubkey
QMessageBox.information(self, "Public key", "These parameters pubkeys are : {0}".format(pubkey))
QMessageBox.information(self, "Public key",
"These parameters pubkeys are : {0}".format(pubkey))
def action_edit_account_name(self):
def action_edit_account_parameters(self):
if self.step.is_valid():
self.button_next.setEnabled(True)
else:
......@@ -217,12 +220,28 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog):
self.step.display_page()
def accept(self):
password = ""
if self.account not in self.app.accounts:
self.account.name = self.edit_account_name.text()
try:
self.app.add_account(self.account)
except KeyAlreadyUsed as e:
QErrorMessage(self).showMessage(e.message)
password = self.edit_password.text()
else:
message = "Please enter your password"
while not self.account.check_password(password):
password = QInputDialog.getText(self, "Account password",
message,
QLineEdit.Password)
message = "Error, wrong password. Please enter your password"
if password[1] is True:
password = password[0]
else:
return
nb_wallets = self.spinbox_wallets.value()
self.account.set_walletpool_size(nb_wallets, password)
self.app.save(self.account)
self.accepted.emit()
self.close()
......@@ -98,10 +98,6 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog):
self.account = account
self.step = None
self.peers = []
self.wallet_edit = {}
for w in self.account.wallets:
self.wallet_edit[w.name] = False
step_init = StepPageInit(self)
step_add_peers = StepPageAddpeers(self)
......
......@@ -40,7 +40,7 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
self.combo_contact.addItem(contact.name)
def accept(self):
message = self.edit_message.text()
comment = self.edit_message.text()
if self.radio_contact.isChecked():
index = self.combo_contact.currentIndex()
......@@ -48,18 +48,15 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
else:
recipient = self.edit_pubkey.text()
amount = self.spinbox_amount.value()
password = QInputDialog.getText(self, "Wallet password",
"Please enter your password",
QLineEdit.Password)
if password[1] is True:
password = password[0]
else:
return
while not self.wallet.check_password(self.sender.salt, password):
password = QInputDialog.getText(self, "Wallet password",
"Wrong password.\nPlease enter your password",
QLineEdit.Password)
password = ""
message = "Please enter your password"
while not self.sender.check_password(password):
password = QInputDialog.getText(self, "Account password",
message,
QLineEdit.Password)
message = "Error, wrong password. Please enter your password"
if password[1] is True:
password = password[0]
else:
......@@ -67,7 +64,7 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
try:
self.wallet.send_money(self.sender.salt, password, self.community,
recipient, amount, message)
recipient, amount, comment)
QMessageBox.information(self, "Money transfer",
"Success transfering {0} {1} to {2}".format(amount,
self.community.currency,
......
......@@ -5,32 +5,41 @@ Created on 8 févr. 2014
'''
from PyQt5.QtCore import QAbstractListModel, Qt
import logging
class WalletsListModel(QAbstractListModel):
'''
A Qt abstract item model to display communities in a tree
A Qt list model to display wallets and edit their names
'''
def __init__(self, account, parent=None):
def __init__(self, account, community, parent=None):
'''
Constructor
'''
super(WalletsListModel, self).__init__(parent)
self.wallets = account.wallets
self.communities = account.communities
self.community = community
def rowCount(self, parent):
return len(self.wallets) * len(self.communities)
return len(self.wallets)
def data(self, index, role):
row = index.row()
if role == Qt.DisplayRole:
row = index.row()
index_community = row % len(self.communities)
index_wallet = int(row / len(self.communities))
value = self.wallets[index_wallet].get_text(self.communities[index_community])
value = self.wallets[row].get_text(self.community)
return value
elif role == Qt.EditRole:
return self.wallets[row].name
def setData(self, index, value, role):
if role == Qt.EditRole:
row = index.row()
self.wallets[row].name = value
self.dataChanged.emit(index, index)
return True
return False
def flags(self, index):
return Qt.ItemIsSelectable | Qt.ItemIsEnabled
return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment