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