diff --git a/src/cutecoin/core/app.py b/src/cutecoin/core/app.py index a061860aedbb20419cb9ee871c5d453cd2138402..13913356bced7b3a85a91ff4fc5056d0e84c8dc8 100644 --- a/src/cutecoin/core/app.py +++ b/src/cutecoin/core/app.py @@ -60,11 +60,25 @@ class Application(QObject): network_manager = QNetworkAccessManager() identities_registry = IdentitiesRegistry() app = cls(qapp, loop, network_manager, identities_registry) - app.load() app.switch_language() - return app + if app.preferences["account"] != "": + account = app.get_account(app.preferences["account"]) + app.change_current_account(account) + # no default account... + else: + # if at least one account exists, set it as default... + if len(app.accounts) > 0: + # capture names sorted alphabetically + names = list(app.accounts.keys()) + names.sort() + # set first name in list as default in preferences + app.preferences['account'] = names[0] + app.save_preferences(app.preferences) + # open it + logging.debug("No default account in preferences. Set %s as default account." % names[0]) + return app def switch_language(self): translator = QTranslator(self.qapp) diff --git a/src/cutecoin/gui/mainwindow.py b/src/cutecoin/gui/mainwindow.py index 56f45d804fb32272401c5e0134aa3ad9e0467cb4..5f21a3f641137393fa8b475cc2b85e0cf79c0a83 100644 --- a/src/cutecoin/gui/mainwindow.py +++ b/src/cutecoin/gui/mainwindow.py @@ -48,40 +48,41 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.status_label = QLabel("", self) self.label_time = QLabel("", self) self.import_dialog = None - self.export_dialog = None self.setupUi() def setupUi(self): super().setupUi(self) QApplication.setWindowIcon(QIcon(":/icons/cutecoin_logo")) - # self.busybar = QProgressBar(self.statusbar) - # self.busybar.setMinimum(0) - # self.busybar.setMaximum(0) - # self.busybar.setValue(-1) - # #self.statusbar.addWidget(self.busybar) - # self.busybar.hide() + self.busybar = QProgressBar(self.statusbar) + self.busybar.setMinimum(0) + self.busybar.setMaximum(0) + self.busybar.setValue(-1) + #self.statusbar.addWidget(self.busybar) + self.busybar.hide() self.app.version_requested.connect(self.latest_version_requested) self.combo_referential.setEnabled(False) self.combo_referential.currentIndexChanged.connect(self.referential_changed) self.status_label.setTextFormat(Qt.RichText) - # - # self.statusbar.addPermanentWidget(self.status_label, 1) - # self.statusbar.addPermanentWidget(self.label_time) - # self.statusbar.addPermanentWidget(self.combo_referential) - # - # self.homescreen = HomeScreenWidget(self.app) - # self.centralWidget().layout().addWidget(self.homescreen) - # self.homescreen.button_new.clicked.connect(self.open_add_account_dialog) - # self.homescreen.button_import.clicked.connect(self.import_account) - # self.open_ucoin_info = lambda: QDesktopServices.openUrl(QUrl("http://ucoin.io/theoretical/")) - # self.homescreen.button_info.clicked.connect(self.open_ucoin_info) + + + self.statusbar.addPermanentWidget(self.status_label, 1) + self.statusbar.addPermanentWidget(self.label_time) + self.statusbar.addPermanentWidget(self.combo_referential) + + self.homescreen = HomeScreenWidget(self.app) + self.centralWidget().layout().addWidget(self.homescreen) + self.homescreen.button_new.clicked.connect(self.open_add_account_dialog) + self.homescreen.button_import.clicked.connect(self.import_account) + self.open_ucoin_info = lambda: QDesktopServices.openUrl(QUrl("http://ucoin.io/theoretical/")) + self.homescreen.button_info.clicked.connect(self.open_ucoin_info) def startup(self): self.update_time() self.app.get_last_version() + self.refresh() def open_add_account_dialog(self): dialog = ProcessConfigureAccount(self.app, None) @@ -331,16 +332,17 @@ class MainWindow(QMainWindow, Ui_MainWindow): def export_account(self): # Testable way of using a QFileDialog - self.export_dialog = QFileDialog(self) - self.export_dialog.setObjectName('ExportFileDialog') - self.export_dialog.setWindowTitle(self.tr("Export an account")) - self.export_dialog.setNameFilter(self.tr("All account files (*.acc)")) - self.export_dialog.setLabelText(QFileDialog.Accept, self.tr('Export')) - self.export_dialog.accepted.connect(self.export_account_accepted) - self.export_dialog.show() + export_dialog = QFileDialog(self) + export_dialog.setObjectName('ExportFileDialog') + export_dialog.setWindowTitle(self.tr("Export an account")) + export_dialog.setNameFilter(self.tr("All account files (*.acc)")) + export_dialog.setLabelText(QFileDialog.Accept, self.tr('Export')) + export_dialog.accepted.connect(self.export_account_accepted) + export_dialog.show() def export_account_accepted(self): - selected_file = self.export_dialog.selectedFiles() + export_dialog = self.sender() + selected_file = export_dialog.selectedFiles() if selected_file: if selected_file[0][-4:] == ".acc": path = selected_file[0] diff --git a/src/cutecoin/main.py b/src/cutecoin/main.py index 5b31c2ba60079c35b38d46f64a79de805ec1dae9..2111a73acf7ed3be96781bc8158c6b88a820fe18 100755 --- a/src/cutecoin/main.py +++ b/src/cutecoin/main.py @@ -25,6 +25,7 @@ if __name__ == '__main__': with loop: app = Application.startup(sys.argv, cutecoin, loop) window = MainWindow(app) + window.startup() window.showMaximized() loop.run_forever() sys.exit() diff --git a/src/cutecoin/tests/__init__.py b/src/cutecoin/tests/__init__.py index 8b137891791fe96927ad78e64b0aad7bded08bdc..1d65e88026c473b057c001647a460228f8415d7c 100644 --- a/src/cutecoin/tests/__init__.py +++ b/src/cutecoin/tests/__init__.py @@ -1 +1 @@ - +from .qapp import get_application \ No newline at end of file diff --git a/src/cutecoin/tests/main_window/test_main_window_dialogs.py b/src/cutecoin/tests/main_window/test_main_window_dialogs.py index 2389f380f70e36334538cd59bd488f6b923fd45b..364cc9c771187e58702358a05d35050aed3e4ee7 100644 --- a/src/cutecoin/tests/main_window/test_main_window_dialogs.py +++ b/src/cutecoin/tests/main_window/test_main_window_dialogs.py @@ -1,15 +1,14 @@ import sys import unittest -import gc import os import asyncio import quamash -import PyQt5 -from PyQt5.QtWidgets import QMenu +from PyQt5.QtWidgets import QDialog, QFileDialog from PyQt5.QtCore import QLocale, QTimer from PyQt5.QtNetwork import QNetworkAccessManager from cutecoin.gui.mainwindow import MainWindow from cutecoin.core.app import Application +from cutecoin.tests import get_application from cutecoin.tests.stubs.core.registry import IdentitiesRegistry @@ -19,25 +18,9 @@ from cutecoin.tests.stubs.core.registry import IdentitiesRegistry class MainWindowDialogsTest(unittest.TestCase): def setUp(self): QLocale.setDefault(QLocale("en_GB")) - self.qapplication = quamash.QApplication([]) + self.qapplication = get_application() self.lp = quamash.QEventLoop(self.qapplication) asyncio.set_event_loop(self.lp) - - self.additional_exceptions = [] - - self.orig_excepthook = sys.excepthook - - def except_handler(loop, ctx): - self.additional_exceptions.append(ctx) - - def excepthook(type, *args): - self.lp.stop() - self.orig_excepthook(type, *args) - - sys.excepthook = excepthook - - self.lp.set_exception_handler(except_handler) - network_manager = QNetworkAccessManager() self.application = Application(self.qapplication, self.lp, network_manager, IdentitiesRegistry()) @@ -45,51 +28,38 @@ class MainWindowDialogsTest(unittest.TestCase): def tearDown(self): # delete all top widgets from main QApplication - sys.excepthook = self.orig_excepthook - self.qapplication.quit() - self.lp.stop() try: self.lp.close() finally: asyncio.set_event_loop(None) - self.qapplication.exit() - for exc in self.additional_exceptions: - if ( - os.name == 'nt' and - isinstance(exc['exception'], WindowsError) and - exc['exception'].winerror == 6 - ): - # ignore Invalid Handle Errors - continue - raise exc['exception'] - - # def test_action_about(self): - # #select menu - # self.main_window.actionAbout.trigger() - # widgets = self.qapplication.topLevelWidgets() - # for widget in widgets: - # if isinstance(widget, PyQt5.QtWidgets.QDialog): - # if widget.isVisible(): - # self.assertEqual('AboutPopup', widget.objectName()) - # widget.close() - # break - # - # def test_action_add_account(self): - # pass - # asynchronous test, cause dialog is waiting user response - #QTimer.singleShot(1, self._async_test_action_add_account) - # select menu - #self.main_window.action_add_account.trigger() - # - # def _async_test_action_add_account(self): - # widgets = self.qapplication.topLevelWidgets() - # for widget in widgets: - # if isinstance(widget, PyQt5.QtWidgets.QDialog): - # if widget.isVisible(): - # self.assertEqual('AccountConfigurationDialog', widget.objectName()) - # widget.close() - # break + def test_action_about(self): + #select menu + self.main_window.actionAbout.trigger() + widgets = self.qapplication.topLevelWidgets() + for widget in widgets: + if isinstance(widget, QDialog): + if widget.isVisible(): + self.assertEqual('AboutPopup', widget.objectName()) + widget.close() + break + + def test_action_add_account(self): + #asynchronous test, cause dialog is waiting user response + QTimer.singleShot(1, self._async_test_action_add_account) + #select menu + self.main_window.action_add_account.trigger() + + def _async_test_action_add_account(self): + widgets = self.qapplication.topLevelWidgets() + for widget in widgets: + if isinstance(widget, QDialog): + if widget.isVisible(): + try: + self.assertEqual('AccountConfigurationDialog', widget.objectName()) + break + finally: + widget.close() # fixme: require a app.current_account fixture # def test_action_configure_account(self): @@ -107,20 +77,19 @@ class MainWindowDialogsTest(unittest.TestCase): # widget.close() # break # - # def test_action_export_account(self): - # pass - # select menu - # self.main_window.action_export.trigger() - # - # widgets = self.qapplication.topLevelWidgets() - # for widget in widgets: - # if isinstance(widget, PyQt5.QtWidgets.QFileDialog): - # if widget.isVisible(): - # self.assertEqual('ExportFileDialog', widget.objectName()) - # widget.close() - # break - def test_empty(self): - self.assertEquals(1, 1) + def test_action_export_account(self): + #select menu + self.main_window.action_export.trigger() + + widgets = self.qapplication.topLevelWidgets() + for widget in widgets: + if isinstance(widget, QFileDialog): + if widget.isVisible(): + try: + self.assertEqual('ExportFileDialog', widget.objectName()) + break + finally: + widget.close() if __name__ == '__main__': unittest.main() diff --git a/src/cutecoin/tests/main_window/test_main_window_menus.py b/src/cutecoin/tests/main_window/test_main_window_menus.py index 87fd81b90cbb4f71e51d38ebc3b8cd9290dcc1b9..95c3e6e12607d05d2523681b8970342baaca1de9 100644 --- a/src/cutecoin/tests/main_window/test_main_window_menus.py +++ b/src/cutecoin/tests/main_window/test_main_window_menus.py @@ -1,70 +1,30 @@ -# -*- coding: utf-8 -*- - import sys import unittest -import gc import os import asyncio import quamash -from PyQt5.QtWidgets import QApplication, QMenu +from PyQt5.QtWidgets import QMenu from PyQt5.QtCore import QLocale from cutecoin.gui.mainwindow import MainWindow from cutecoin.core.app import Application - -# Qapplication cause a core dumped when re-run in setup -# set it as global var -qapplication = QApplication(sys.argv) - +from cutecoin.tests import get_application class MainWindowMenusTest(unittest.TestCase): def setUp(self): + self.qapplication = get_application() QLocale.setDefault(QLocale("en_GB")) - self.lp = quamash.QEventLoop(qapplication) + self.lp = quamash.QEventLoop(self.qapplication) asyncio.set_event_loop(self.lp) - self.additional_exceptions = [] - - self.orig_excepthook = sys.excepthook - - def except_handler(loop, ctx): - self.additional_exceptions.append(ctx) - - def excepthook(type, *args): - self.lp.stop() - self.orig_excepthook(type, *args) - - sys.excepthook = excepthook - - self.lp.set_exception_handler(except_handler) - - self.application = Application(qapplication, self.lp, None, None) + self.application = Application(self.qapplication, self.lp, None, None) self.main_window = MainWindow(self.application) def tearDown(self): - # delete all top widgets from main QApplication - - sys.excepthook = self.orig_excepthook - try: self.lp.close() finally: asyncio.set_event_loop(None) - for exc in self.additional_exceptions: - if ( - os.name == 'nt' and - isinstance(exc['exception'], WindowsError) and - exc['exception'].winerror == 6 - ): - # ignore Invalid Handle Errors - continue - raise exc['exception'] - - lw = qapplication.topLevelWidgets() - for w in lw: - del w - gc.collect() - def test_menubar(self): children = self.main_window.menubar.children() menus = [] @@ -93,9 +53,5 @@ class MainWindowMenusTest(unittest.TestCase): self.assertEqual(len(actions), 1) self.assertEqual(actions[0].objectName(), 'actionAbout') - def test_ignoreme(self): - return - if __name__ == '__main__': unittest.main() - qapplication.exit() diff --git a/src/cutecoin/tests/qapp.py b/src/cutecoin/tests/qapp.py new file mode 100644 index 0000000000000000000000000000000000000000..d3e1a8f657a8d8a72ca386ba3b2e8e7313d44fbb --- /dev/null +++ b/src/cutecoin/tests/qapp.py @@ -0,0 +1,14 @@ + +_application_ = [] + +def get_application(): + """Get the singleton QApplication""" + from PyQt5.QtWidgets import QApplication + if not len(_application_): + application = QApplication.instance() + if not application: + import sys + application = QApplication(sys.argv) + _application_.append( application ) + return _application_[0] + diff --git a/src/cutecoin/tests/stubs/core/net/network.py b/src/cutecoin/tests/stubs/core/net/network.py index d14181f48c365cd30dd653c75b3433218bc19557..3d2de537d84529bd64056c7d2b25094d8c08be87 100644 --- a/src/cutecoin/tests/stubs/core/net/network.py +++ b/src/cutecoin/tests/stubs/core/net/network.py @@ -28,7 +28,7 @@ class Network(QObject): self.network_manager = network_manager @classmethod - def create(cls, network_manager, node) + def create(cls, network_manager, node): nodes = [node] network = cls(network_manager, node.currency, nodes) return network