From dad87068b2556da9ab5a2054bf4bd2a4e106f28e Mon Sep 17 00:00:00 2001 From: Inso <insomniak.fr@gmail.com> Date: Mon, 9 Feb 2015 20:47:26 +0100 Subject: [PATCH] Added the ability to delete an account --- res/ui/account_cfg.ui | 47 ++++++++++++++++ src/cutecoin/core/app.py | 33 ++++++----- src/cutecoin/gui/currency_tab.py | 18 +++--- src/cutecoin/gui/mainwindow.py | 75 ++++++++++++------------- src/cutecoin/gui/process_cfg_account.py | 72 +++++++++++++----------- 5 files changed, 152 insertions(+), 93 deletions(-) diff --git a/res/ui/account_cfg.ui b/res/ui/account_cfg.ui index a3a56a7e..be6a8cd2 100644 --- a/res/ui/account_cfg.ui +++ b/res/ui/account_cfg.ui @@ -84,6 +84,36 @@ </item> </layout> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_8"> + <property name="topMargin"> + <number>6</number> + </property> + <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> + <item> + <widget class="QPushButton" name="button_delete"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> + </property> + <property name="text"> + <string>Delete account</string> + </property> + </widget> + </item> + </layout> + </item> <item> <spacer name="verticalSpacer_4"> <property name="orientation"> @@ -458,6 +488,22 @@ </hint> </hints> </connection> + <connection> + <sender>button_delete</sender> + <signal>clicked()</signal> + <receiver>AccountConfigurationDialog</receiver> + <slot>action_delete_account()</slot> + <hints> + <hint type="sourcelabel"> + <x>325</x> + <y>146</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>118</y> + </hint> + </hints> + </connection> </connections> <slots> <slot>open_process_add_community()</slot> @@ -471,5 +517,6 @@ <slot>action_edit_account_key()</slot> <slot>action_edit_account_parameters()</slot> <slot>action_show_pubkey()</slot> + <slot>action_delete_account()</slot> </slots> </ui> diff --git a/src/cutecoin/core/app.py b/src/cutecoin/core/app.py index 4c5cb018..8cc937be 100644 --- a/src/cutecoin/core/app.py +++ b/src/cutecoin/core/app.py @@ -8,9 +8,10 @@ import os import logging import json import tarfile +import shutil from . import config -from ..tools.exceptions import NameAlreadyExists, BadAccountFile +from ..tools.exceptions import NameAlreadyExists, BadAccountFile, KeyAlreadyUsed from .account import Account from .. import __version__ @@ -44,21 +45,20 @@ class Application(object): if a == name: raise NameAlreadyExists(a) - account_path = os.path.join(config.parameters['home'], name) - if not os.path.exists(account_path): - logging.info("Creating account directory") - os.makedirs(account_path) account = Account.create(name, [], [], config.parameters) - self.accounts[name] = account - self.current_account = account return account - def del_account(self, account): - self.accounts.remove(account) + def add_account(self, account): + self.accounts[account.name] = account + + def delete_account(self, account): + self.accounts.pop(account.name) + if self.current_account == account: + self.current_account = None def change_current_account(self, account): if self.current_account is not None: @@ -104,11 +104,18 @@ class Application(object): def save(self, account): with open(config.parameters['data'], 'w') as outfile: json.dump(self.jsonify(), outfile, indent=4, sort_keys=True) - account_path = os.path.join(config.parameters['home'], - account.name, 'properties') - with open(account_path, 'w') as outfile: - json.dump(account.jsonify(), outfile, indent=4, sort_keys=True) + account.name) + if account.name in self.accounts: + properties_path = os.path.join(account_path, 'properties') + if not os.path.exists(account_path): + logging.info("Creating account directory") + os.makedirs(account_path) + with open(properties_path, 'w') as outfile: + json.dump(account.jsonify(), outfile, indent=4, sort_keys=True) + else: + account_path = os.path.join(config.parameters['home'], account.name) + shutil.rmtree(account_path) def save_cache(self, account): if not os.path.exists(os.path.join(config.parameters['home'], diff --git a/src/cutecoin/gui/currency_tab.py b/src/cutecoin/gui/currency_tab.py index e8bd759e..36333482 100644 --- a/src/cutecoin/gui/currency_tab.py +++ b/src/cutecoin/gui/currency_tab.py @@ -174,16 +174,18 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): .format(block_number)) def refresh_wallets(self): - 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()) + if 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()) def refresh_wallet_content(self, index): - 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) + if self.app.current_account: + 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) diff --git a/src/cutecoin/gui/mainwindow.py b/src/cutecoin/gui/mainwindow.py index 7be28fe5..50339ba9 100644 --- a/src/cutecoin/gui/mainwindow.py +++ b/src/cutecoin/gui/mainwindow.py @@ -92,7 +92,6 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.loader.loaded.connect(self.loader_thread.quit) self.loader.connection_error.connect(self.display_error) self.loader_thread.started.connect(self.loader.load) - self.setWindowTitle("CuteCoin {0}".format(__version__)) self.refresh() def open_add_account_dialog(self): @@ -171,8 +170,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): def open_configure_account_dialog(self): dialog = ProcessConfigureAccount(self.app, self.app.current_account) - dialog.accepted.connect(self.refresh_wallets) - dialog.accepted.connect(self.refresh_communities) + dialog.accepted.connect(self.refresh) dialog.exec_() def open_about_popup(self): @@ -207,25 +205,37 @@ class MainWindow(QMainWindow, Ui_MainWindow): def refresh_communities(self): self.currencies_tabwidget.clear() - for community in self.app.current_account.communities: - tab_currency = CurrencyTabWidget(self.app, community, - self.password_asker, - self.status_label) - tab_currency.refresh() - self.currencies_tabwidget.addTab(tab_currency, - QIcon(":/icons/currency_icon"), - community.name()) + if self.app.current_account: + for community in self.app.current_account.communities: + try: + tab_currency = CurrencyTabWidget(self.app, community, + self.password_asker, + self.status_label) + tab_currency.refresh() + self.currencies_tabwidget.addTab(tab_currency, + QIcon(":/icons/currency_icon"), + community.name()) + except NoPeerAvailable as e: + QMessageBox.critical(self, "Could not join {0}".format(community.currency), + str(e), + QMessageBox.Ok) + continue + except requests.exceptions.RequestException as e: + QMessageBox.critical(self, ":(", + str(e), + QMessageBox.Ok) def refresh_contacts(self): self.menu_contacts_list.clear() - for contact in self.app.current_account.contacts: - contact_menu = self.menu_contacts_list.addMenu(contact.name) - edit_action = contact_menu.addAction("Edit") - edit_action.triggered.connect(self.edit_contact) - edit_action.setData(contact) - delete_action = contact_menu.addAction("Delete") - delete_action.setData(contact) - delete_action.triggered.connect(self.delete_contact) + if self.app.current_account: + for contact in self.app.current_account.contacts: + contact_menu = self.menu_contacts_list.addMenu(contact.name) + edit_action = contact_menu.addAction("Edit") + edit_action.triggered.connect(self.edit_contact) + edit_action.setData(contact) + delete_action = contact_menu.addAction("Delete") + delete_action.setData(contact) + delete_action.triggered.connect(self.delete_contact) def set_as_default_account(self): self.app.default_account = self.app.current_account.name @@ -250,12 +260,18 @@ class MainWindow(QMainWindow, Ui_MainWindow): action.triggered.connect(signal_mapper.map) signal_mapper.mapped[str].connect(self.action_change_account) + self.refresh_communities() + self.refresh_wallets() + self.refresh_contacts() + if self.app.current_account is None: + self.setWindowTitle("CuteCoin {0}".format(__version__)) self.menu_contacts.setEnabled(False) self.menu_actions.setEnabled(False) self.action_configure_parameters.setEnabled(False) self.action_set_as_default.setEnabled(False) self.combo_referential.setEnabled(False) + self.status_label.setText("") else: self.action_set_as_default.setEnabled(self.app.current_account.name != self.app.default_account) @@ -272,27 +288,6 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.setWindowTitle("CuteCoin {0} - Account : {1}".format(__version__, self.app.current_account.name)) - self.currencies_tabwidget.clear() - for community in self.app.current_account.communities: - try: - tab_currency = CurrencyTabWidget(self.app, community, - self.password_asker, - self.status_label) - tab_currency.refresh() - self.currencies_tabwidget.addTab(tab_currency, - QIcon(":/icons/currency_icon"), - community.name()) - except NoPeerAvailable as e: - QMessageBox.critical(self, "Could not join {0}".format(community.currency), - str(e), - QMessageBox.Ok) - continue - except requests.exceptions.RequestException as e: - QMessageBox.critical(self, ":(", - str(e), - QMessageBox.Ok) - self.refresh_contacts() - def import_account(self): dialog = ImportAccountDialog(self.app, self) dialog.accepted.connect(self.refresh) diff --git a/src/cutecoin/gui/process_cfg_account.py b/src/cutecoin/gui/process_cfg_account.py index 576147f7..af535556 100644 --- a/src/cutecoin/gui/process_cfg_account.py +++ b/src/cutecoin/gui/process_cfg_account.py @@ -107,7 +107,23 @@ class StepPageCommunities(Step): return True def process_next(self): - pass + password = self.config_dialog.password_asker.exec_() + if self.config_dialog.password_asker.result() == QDialog.Rejected: + return + + nb_wallets = self.config_dialog.spinbox_wallets.value() + self.config_dialog.account.set_walletpool_size(nb_wallets, password) + + if len(self.config_dialog.app.accounts) == 1: + self.config_dialog.app.default_account = self.config_dialog.account.name + + try: + self.config_dialog.app.add_account(self.config_dialog.account) + except KeyAlreadyUsed as e: + QMessageBox.critical(self, "Error", + str(e), QMessageBox.Ok) + return + self.config_dialog.app.save(self.config_dialog.account) def display_page(self): logging.debug("Communities DISPLAY") @@ -141,10 +157,12 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): self.step.display_page() if self.account is None: self.setWindowTitle("New account") + self.button_delete.hide() else: self.stacked_pages.removeWidget(self.stacked_pages.widget(1)) step_init.next_step = step_communities self.button_next.setEnabled(True) + self.stacked_pages.currentWidget() self.setWindowTitle("Configure " + self.account.name) def open_process_add_community(self): @@ -163,7 +181,6 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): def action_remove_community(self): for index in self.list_communities.selectedIndexes(): - community = self.account.communities[index.row()] self.account.communities.pop(index.row()) self.list_communities.setModel(CommunitiesListModel(self.account)) @@ -206,20 +223,32 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): dialog.accepted.connect(self.action_edit_community) dialog.exec_() + def action_delete_account(self): + reply = QMessageBox.question(self, "Warning", + """This action will delete your account locally. +Please note your key parameters (salt and password) if you wish to recover it later. +Your account won't be removed from the networks it joined. +Are you sure ?""") + if reply == QMessageBox.Yes: + account = self.app.current_account + self.app.delete_account(account) + self.app.save(account) + self.accept() + def next(self): - if self.step.next_step is not None: - if self.step.is_valid(): - try: - self.step.process_next() + if self.step.is_valid(): + try: + self.step.process_next() + if self.step.next_step is not None: self.step = self.step.next_step next_index = self.stacked_pages.currentIndex() + 1 self.stacked_pages.setCurrentIndex(next_index) self.step.display_page() - except Error as e: - QMessageBox.critical(self, "Error", - str(e), QMessageBox.Ok) - else: - self.accept() + else: + self.accept() + except Error as e: + QMessageBox.critical(self, "Error", + str(e), QMessageBox.Ok) def previous(self): if self.step.previous_step is not None: @@ -229,25 +258,4 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): self.step.display_page() def accept(self): - password = "" - if self.account.name not in self.app.accounts: - self.account.name = self.edit_account_name.text() - try: - self.app.add_account(self.account) - except KeyAlreadyUsed as e: - QMessageBox.critical(self, "Error", - str(e), QMessageBox.Ok) - password = self.edit_password.text() - else: - password = self.password_asker.exec_() - if self.password_asker.result() == QDialog.Rejected: - return - - nb_wallets = self.spinbox_wallets.value() - self.account.set_walletpool_size(nb_wallets, password) - - if len(self.app.accounts) == 1: - self.app.default_account = self.account.name - - self.app.save(self.account) super().accept() -- GitLab