From 68b1be8ef443b088cf5c1f7f964e1bd7ad42408e Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 21 Jul 2014 17:03:47 -0300 Subject: Add heartbeat to check if backend is alive. Send a 'ping' request every 2 secs to ensure that the backend is running. Use polling instead of recv on the backend_proxy. This was already implemented for the signaler. --- src/leap/bitmask/gui/mainwindow.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 6959650b..a15c4dd8 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -125,6 +125,11 @@ class MainWindow(QtGui.QMainWindow): self._backend = BackendProxy() + # periodically check if the backend is alive + self._backend_checker = QtCore.QTimer(self) + self._backend_checker.timeout.connect(self._check_backend_status) + self._backend_checker.start(2000) + self._leap_signaler = LeapSignaler() self._leap_signaler.start() @@ -334,6 +339,23 @@ class MainWindow(QtGui.QMainWindow): logger.error("Bad call to the backend:") logger.error(data) + @QtCore.Slot() + def _check_backend_status(self): + """ + TRIGGERS: + self._backend_checker.timeout + + Check that the backend is running. Otherwise show an error to the user. + """ + online = self._backend.online + if not online: + logger.critical("Backend is not online.") + QtGui.QMessageBox.critical( + self, self.tr("Application error"), + self.tr("There is a problem contacting the backend, please " + "restart Bitmask.")) + self._backend_checker.stop() + def _backend_connect(self, only_tracked=False): """ Connect to backend signals. -- cgit v1.2.3 From aeacb80a34dc7b8996278e35e9cc888d93e2f853 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 22 Jul 2014 16:10:10 -0300 Subject: Kill backend on quit if it does not respond. --- src/leap/bitmask/gui/mainwindow.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index a15c4dd8..59a65b1e 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -22,6 +22,8 @@ import time from datetime import datetime +import psutil + from PySide import QtCore, QtGui from leap.bitmask import __version__ as VERSION @@ -97,7 +99,7 @@ class MainWindow(QtGui.QMainWindow): # We give the services some time to a halt before forcing quit. SERVICES_STOP_TIMEOUT = 20000 # in milliseconds - def __init__(self, start_hidden=False): + def __init__(self, start_hidden=False, backend_pid=None): """ Constructor for the client main window @@ -272,6 +274,7 @@ class MainWindow(QtGui.QMainWindow): self._logger_window = None self._start_hidden = start_hidden + self._backend_pid = backend_pid self._mail_conductor = mail_conductor.MailConductor(self._backend) self._mail_conductor.connect_mail_signals(self._mail_status) @@ -1819,6 +1822,15 @@ class MainWindow(QtGui.QMainWindow): # or if we reach the timeout QtDelayedCall(self.SERVICES_STOP_TIMEOUT, self.final_quit) + def _backend_kill(self): + """ + Send a kill signal to the backend process. + This is called if the backend does not respond to requests. + """ + if self._backend_pid is not None: + logger.debug("Killing backend") + psutil.Process(self._backend_pid).kill() + @QtCore.Slot() def _remove_service(self, service): """ @@ -1854,7 +1866,12 @@ class MainWindow(QtGui.QMainWindow): logger.debug('Final quit...') self._leap_signaler.stop() - self._backend.stop() + + if self._backend.online: + self._backend.stop() + else: + self._backend_kill() + time.sleep(0.05) # give the thread a little time to finish. # Remove lockfiles on a clean shutdown. -- cgit v1.2.3 From d97a9804c1a6fb06d7ce39066f92a0259a6ab8c3 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 24 Jul 2014 12:54:06 -0300 Subject: Don't call the backend if it's not online. --- src/leap/bitmask/gui/mainwindow.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 59a65b1e..ff19e17f 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -1813,10 +1813,14 @@ class MainWindow(QtGui.QMainWindow): # Set this in case that the app is hidden QtGui.QApplication.setQuitOnLastWindowClosed(True) - self._stop_services() - self._really_quit = True + if not self._backend.online: + self.final_quit() + return + + self._stop_services() + # call final quit when all the services are stopped self.all_services_stopped.connect(self.final_quit) # or if we reach the timeout @@ -1859,11 +1863,12 @@ class MainWindow(QtGui.QMainWindow): if self._finally_quitting: return + logger.debug('Final quit...') self._finally_quitting = True - logger.debug('Closing soledad...') - self._backend.soledad_close() - logger.debug('Final quit...') + if self._backend.online: + logger.debug('Closing soledad...') + self._backend.soledad_close() self._leap_signaler.stop() -- cgit v1.2.3 From beac7a8ce70acb17c320580538510761dff3ac93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 24 Jul 2014 16:33:25 -0300 Subject: Improve hide and show main window on Ubuntu --- src/leap/bitmask/gui/mainwindow.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index ff19e17f..383f97bb 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -999,6 +999,12 @@ class MainWindow(QtGui.QMainWindow): if not visible: QtGui.QApplication.setQuitOnLastWindowClosed(True) self.show() + if IS_LINUX: + # On ubuntu, activateWindow doesn't work reliably, so + # we do the following as a workaround. See + # https://bugreports.qt-project.org/browse/QTBUG-24932 + # for more details + QtGui.QX11Info.setAppUserTime(0) self.activateWindow() self.raise_() else: -- cgit v1.2.3 From 28553c41c3d879481923102a1b41ecd71641d0d8 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 25 Jul 2014 11:13:53 -0300 Subject: Add Linux autostart. Closes #4989. --- src/leap/bitmask/gui/mainwindow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 383f97bb..2f78fd14 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -58,7 +58,7 @@ from leap.bitmask.services.mail import conductor as mail_conductor from leap.bitmask.services import EIP_SERVICE, MX_SERVICE -from leap.bitmask.util import make_address +from leap.bitmask.util import autostart, make_address from leap.bitmask.util.keyring_helpers import has_keyring from leap.bitmask.logs.leap_log_handler import LeapLogHandler @@ -108,6 +108,7 @@ class MainWindow(QtGui.QMainWindow): :type start_hidden: bool """ QtGui.QMainWindow.__init__(self) + autostart.set_autostart(True) # register leap events ######################################## register(signal=proto.UPDATER_NEW_UPDATES, @@ -1797,6 +1798,8 @@ class MainWindow(QtGui.QMainWindow): if self._quitting: return + autostart.set_autostart(False) + self._quitting = True # first thing to do quitting, hide the mainwindow and show tooltip. -- cgit v1.2.3 From 72b6e999c883272cbe291ac610c528b5ae51077b Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 28 Jul 2014 16:49:44 -0300 Subject: Do `quit()` if the system requested the app to close. This fixes the issue where a system logout was blocked by bitmask since we were interpreting the closeEvent as if the user clicked on the 'X' button. Closes #5870. --- src/leap/bitmask/gui/mainwindow.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 2f78fd14..4f7f519c 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -1138,6 +1138,11 @@ class MainWindow(QtGui.QMainWindow): """ Reimplementation of closeEvent to close to tray """ + if not e.spontaneous(): + # if the system requested the `close` then we should quit. + self.quit() + return + if QtGui.QSystemTrayIcon.isSystemTrayAvailable() and \ not self._really_quit: self._toggle_visible() -- cgit v1.2.3 From 0f72cb6694ea8f6d17f731c469f976250eab61f8 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 30 Jul 2014 18:07:33 -0300 Subject: Reduce services stop timeout. --- src/leap/bitmask/gui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 4f7f519c..c08ef08d 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -97,7 +97,7 @@ class MainWindow(QtGui.QMainWindow): EIP_START_TIMEOUT = 60000 # in milliseconds # We give the services some time to a halt before forcing quit. - SERVICES_STOP_TIMEOUT = 20000 # in milliseconds + SERVICES_STOP_TIMEOUT = 3000 # in milliseconds def __init__(self, start_hidden=False, backend_pid=None): """ -- cgit v1.2.3 From 08d89399eb41261d796e8b35427354581c0c8f4a Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 30 Jul 2014 18:07:37 -0300 Subject: Handle the system's quit correctly. Use a simple sleep to wait until the services are stopped and then kill the backend, always in a fixed time in order to avoid blocks/hangs on the system session logout. Closes #5870. --- src/leap/bitmask/gui/mainwindow.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index c08ef08d..46f0928f 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -197,6 +197,7 @@ class MainWindow(QtGui.QMainWindow): # used to know if we are in the final steps of quitting self._quitting = False self._finally_quitting = False + self._system_quit = False self._backend_connected_signals = [] self._backend_connect() @@ -1140,6 +1141,7 @@ class MainWindow(QtGui.QMainWindow): """ if not e.spontaneous(): # if the system requested the `close` then we should quit. + self._system_quit = True self.quit() return @@ -1809,7 +1811,7 @@ class MainWindow(QtGui.QMainWindow): # first thing to do quitting, hide the mainwindow and show tooltip. self.hide() - if self._systray is not None: + if not self._system_quit and self._systray is not None: self._systray.showMessage( self.tr('Quitting...'), self.tr('Bitmask is quitting, please wait.')) @@ -1833,10 +1835,18 @@ class MainWindow(QtGui.QMainWindow): self.final_quit() return - self._stop_services() - # call final quit when all the services are stopped self.all_services_stopped.connect(self.final_quit) + + self._stop_services() + + # we wait and call manually since during the system's logout the + # backend process can be killed and we won't get a response. + # XXX: also, for some reason the services stop timeout does not work. + if self._system_quit: + time.sleep(0.5) + self.final_quit() + # or if we reach the timeout QtDelayedCall(self.SERVICES_STOP_TIMEOUT, self.final_quit) @@ -1859,6 +1869,7 @@ class MainWindow(QtGui.QMainWindow): :param service: the service that we want to remove :type service: str """ + logger.debug("Removing service: {0}".format(service)) self._services_being_stopped.discard(service) if not self._services_being_stopped: @@ -1886,13 +1897,13 @@ class MainWindow(QtGui.QMainWindow): self._leap_signaler.stop() - if self._backend.online: - self._backend.stop() - else: - self._backend_kill() - + self._backend.stop() time.sleep(0.05) # give the thread a little time to finish. + if self._system_quit or not self._backend.online: + logger.debug("Killing the backend") + self._backend_kill() + # Remove lockfiles on a clean shutdown. logger.debug('Cleaning pidfiles') if IS_WIN: -- cgit v1.2.3 From 3b469a2c006381ba9e56c1de92be4e87ad67e51b Mon Sep 17 00:00:00 2001 From: kali Date: Sun, 27 Jul 2014 19:00:37 -0500 Subject: Add cancel button for EIP connection. Closes: #4035 This falls in the "quick" workaround category. A proper state machine that extends the four basic connection states is hence needed. We have to accomodate design to have a connection-oriented state machine in the backend (I would favor a twisted protocol for this), and a more lightweight one that conducts the gui-level changes (ie, change the actions / buttons / labels accordingly). Since this "cancel" functionality has been long postponed, I chose to do one more ugly hack here, that is, show and hide dance with a button that just calls the bitmask-root to kill the vpn process. It should work well enough until we get to the reorganization needed for a clean process control for eip. --- src/leap/bitmask/gui/mainwindow.py | 64 +++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 25 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 46f0928f..25bda305 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -166,6 +166,9 @@ class MainWindow(QtGui.QMainWindow): self._disable_eip_missing_helpers) self.ui.eipLayout.addWidget(self._eip_status) + + # XXX we should get rid of the circular refs + # conductor <-> status, right now keeping state on the widget ifself. self._eip_conductor.add_eip_widget(self._eip_status) self._eip_conductor.connect_signals() @@ -180,6 +183,7 @@ class MainWindow(QtGui.QMainWindow): self.eip_needs_login.connect(self._eip_status.disable_eip_start) self.eip_needs_login.connect(self._disable_eip_start_action) + # XXX all this info about state should move to eip conductor too self._already_started_eip = False self._trying_to_start_eip = False @@ -561,7 +565,7 @@ class MainWindow(QtGui.QMainWindow): TRIGGERS: self.ui.action_show_logs.triggered - Displays the window with the history of messages logged until now + Display the window with the history of messages logged until now and displays the new ones on arrival. """ if self._logger_window is None: @@ -582,7 +586,7 @@ class MainWindow(QtGui.QMainWindow): TRIGGERS: self.ui.action_advanced_key_management.triggered - Displays the Advanced Key Management dialog. + Display the Advanced Key Management dialog. """ domain = self._login_widget.get_selected_provider() logged_user = "{0}@{1}".format(self._logged_user, domain) @@ -604,7 +608,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.btnPreferences.clicked (disabled for now) self.ui.action_preferences - Displays the preferences window. + Display the preferences window. """ user = self._logged_user domain = self._login_widget.get_selected_provider() @@ -722,7 +726,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.btnEIPPreferences.clicked self.ui.action_eip_preferences (disabled for now) - Displays the EIP preferences window. + Display the EIP preferences window. """ domain = self._login_widget.get_selected_provider() pref = EIPPreferencesWindow(self, domain, @@ -748,7 +752,7 @@ class MainWindow(QtGui.QMainWindow): TRIGGERS: self.new_updates - Displays the new updates label and sets the updates_content + Display the new updates label and sets the updates_content :param req: Request type :type req: leap.common.events.events_pb2.SignalRequest @@ -963,7 +967,7 @@ class MainWindow(QtGui.QMainWindow): :param reason: the reason why the tray got activated. :type reason: int - Displays the context menu from the tray icon + Display the context menu from the tray icon """ self._update_hideshow_menu() @@ -977,7 +981,7 @@ class MainWindow(QtGui.QMainWindow): def _update_hideshow_menu(self): """ - Updates the Hide/Show main window menu text based on the + Update the Hide/Show main window menu text based on the visibility of the window. """ get_action = lambda visible: ( @@ -994,7 +998,7 @@ class MainWindow(QtGui.QMainWindow): TRIGGERS: self._action_visible.triggered - Toggles the window visibility + Toggle the window visibility """ visible = self.isVisible() and self.isActiveWindow() @@ -1022,7 +1026,7 @@ class MainWindow(QtGui.QMainWindow): def _center_window(self): """ - Centers the mainwindow based on the desktop geometry + Center the main window based on the desktop geometry """ geometry = self._settings.get_geometry() state = self._settings.get_windowstate() @@ -1124,7 +1128,7 @@ class MainWindow(QtGui.QMainWindow): def changeEvent(self, e): """ - Reimplements the changeEvent method to minimize to tray + Reimplementation of changeEvent method to minimize to tray """ if not IS_MAC and \ QtGui.QSystemTrayIcon.isSystemTrayAvailable() and \ @@ -1158,7 +1162,7 @@ class MainWindow(QtGui.QMainWindow): def _first_run(self): """ - Returns True if there are no configured providers. False otherwise + Return True if there are no configured providers. False otherwise :rtype: bool """ @@ -1169,7 +1173,7 @@ class MainWindow(QtGui.QMainWindow): def _download_provider_config(self): """ - Starts the bootstrapping sequence. It will download the + Start the bootstrapping sequence. It will download the provider configuration if it's not present, otherwise will emit the corresponding signals inmediately """ @@ -1199,8 +1203,9 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _login_problem_provider(self): """ - Warns the user about a problem with the provider during login. + Warn the user about a problem with the provider during login. """ + # XXX triggers? self._login_widget.set_status( self.tr("Unable to login: Problem with provider")) self._login_widget.set_enabled(True) @@ -1211,7 +1216,7 @@ class MainWindow(QtGui.QMainWindow): TRIGGERS: self._login_widget.login - Starts the login sequence. Which involves bootstrapping the + Start the login sequence. Which involves bootstrapping the selected provider if the selection is valid (not empty), then start the SRP authentication, and as the last step bootstrapping the EIP service @@ -1256,7 +1261,7 @@ class MainWindow(QtGui.QMainWindow): TRIGGERS: self._login_widget.cancel_login - Stops the login sequence. + Stop the login sequence. """ logger.debug("Cancelling log in.") self._cancel_ongoing_defers() @@ -1280,7 +1285,7 @@ class MainWindow(QtGui.QMainWindow): Signaler.prov_cancelled_setup fired by self._backend.provider_cancel_setup() - This method re-enables the login widget and display a message for + Re-enable the login widget and display a message for the cancelled operation. """ self._login_widget.set_status(self.tr("Log in cancelled by the user.")) @@ -1340,7 +1345,7 @@ class MainWindow(QtGui.QMainWindow): def _start_eip_bootstrap(self): """ - Changes the stackedWidget index to the EIP status one and + Change the stackedWidget index to the EIP status one and triggers the eip bootstrapping. """ @@ -1384,7 +1389,7 @@ class MainWindow(QtGui.QMainWindow): def _provides_mx_and_enabled(self): """ - Defines if the current provider provides mx and if we have it enabled. + Define if the current provider provides mx and if we have it enabled. :returns: True if provides and is enabled, False otherwise :rtype: bool @@ -1401,7 +1406,7 @@ class MainWindow(QtGui.QMainWindow): def _provides_eip_and_enabled(self): """ - Defines if the current provider provides eip and if we have it enabled. + Define if the current provider provides eip and if we have it enabled. :returns: True if provides and is enabled, False otherwise :rtype: bool @@ -1503,14 +1508,14 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _disable_eip_start_action(self): """ - Disables the EIP start action in the systray menu. + Disable the EIP start action in the systray menu. """ self._action_eip_startstop.setEnabled(False) @QtCore.Slot() def _enable_eip_start_action(self): """ - Enables the EIP start action in the systray menu. + Enable the EIP start action in the systray menu. """ self._action_eip_startstop.setEnabled(True) self._eip_status.enable_eip_start() @@ -1567,7 +1572,7 @@ class MainWindow(QtGui.QMainWindow): def _try_autostart_eip(self): """ - Tries to autostart EIP + Try to autostart EIP. """ settings = self._settings default_provider = settings.get_defaultprovider() @@ -1587,6 +1592,8 @@ class MainWindow(QtGui.QMainWindow): :param autostart: we are autostarting EIP when this is True :type autostart: bool """ + # XXX should move to EIP conductor. + # during autostart we assume that the provider provides EIP if autostart: should_start = EIP_SERVICE in self._enabled_services @@ -1606,6 +1613,12 @@ class MainWindow(QtGui.QMainWindow): self._enable_eip_start_action() self._eip_status.set_eip_status( self.tr("Starting...")) + self._eip_status.show_eip_cancel_button() + + # We were disabling the button, but now that we have + # a cancel button we just hide it. It will be visible + # when the connection is completed successfully. + self._eip_status.eip_button.hide() self._eip_status.eip_button.setEnabled(False) domain = self._login_widget.get_selected_provider() @@ -1680,7 +1693,7 @@ class MainWindow(QtGui.QMainWindow): TRIGGERS: self._login_widget.logout - Starts the logout sequence + Start the logout sequence """ self._cancel_ongoing_defers() @@ -1708,7 +1721,7 @@ class MainWindow(QtGui.QMainWindow): TRIGGER: self._srp_auth.logout_ok - Switches the stackedWidget back to the login stage after + Switch the stackedWidget back to the login stage after logging out """ self._login_widget.done_logout() @@ -1729,7 +1742,7 @@ class MainWindow(QtGui.QMainWindow): self._backend.signaler.prov_https_connection self._backend.signaler.prov_download_ca_cert - If there was a problem, displays it, otherwise it does nothing. + If there was a problem, display it, otherwise it does nothing. This is used for intermediate bootstrapping stages, in case they fail. """ @@ -1783,6 +1796,7 @@ class MainWindow(QtGui.QMainWindow): imap_stopped = lambda: self._remove_service('imap') self._leap_signaler.imap_stopped.connect(imap_stopped) + # XXX change name, already used in conductor. eip_stopped = lambda: self._remove_service('eip') self._leap_signaler.eip_stopped.connect(eip_stopped) -- cgit v1.2.3 From f4e6d6a77b8b5498e9190c3d35841ef39222cfec Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 6 Aug 2014 14:46:37 -0300 Subject: Replace twisted thread with QThread. This fix the bug that prevents pastebin to work. Closes #5949. --- src/leap/bitmask/gui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 25bda305..1bc4c96f 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -1837,7 +1837,7 @@ class MainWindow(QtGui.QMainWindow): if self._wizard: self._wizard.close() - if self._logger_window: + if self._logger_window is not None: self._logger_window.close() # Set this in case that the app is hidden -- cgit v1.2.3 From e6a7feeb93a27ef36d15dddcb45c2cc4812a37b0 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 6 Aug 2014 16:03:49 -0300 Subject: Fix logger window blocking the bitmask quit(). - Set the logger window parent, - don't use an mainwindow instance variable to hold the window object. This fix have the side offect that prevent multiple log windows being created at the same time, but it does not causes any side effect or problem. --- src/leap/bitmask/gui/mainwindow.py | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 1bc4c96f..389ff172 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -277,8 +277,6 @@ class MainWindow(QtGui.QMainWindow): self._wizard = None self._wizard_firstrun = False - self._logger_window = None - self._start_hidden = start_hidden self._backend_pid = backend_pid @@ -568,17 +566,13 @@ class MainWindow(QtGui.QMainWindow): Display the window with the history of messages logged until now and displays the new ones on arrival. """ - if self._logger_window is None: - leap_log_handler = self._get_leap_logging_handler() - if leap_log_handler is None: - logger.error('Leap logger handler not found') - return - else: - self._logger_window = LoggerWindow(handler=leap_log_handler) - self._logger_window.setVisible( - not self._logger_window.isVisible()) + leap_log_handler = self._get_leap_logging_handler() + if leap_log_handler is None: + logger.error('Leap logger handler not found') + return else: - self._logger_window.setVisible(not self._logger_window.isVisible()) + lw = LoggerWindow(self, handler=leap_log_handler) + lw.show() @QtCore.Slot() def _show_AKM(self): @@ -1837,9 +1831,6 @@ class MainWindow(QtGui.QMainWindow): if self._wizard: self._wizard.close() - if self._logger_window is not None: - self._logger_window.close() - # Set this in case that the app is hidden QtGui.QApplication.setQuitOnLastWindowClosed(True) -- cgit v1.2.3 From db9e6c728118c93413d11262993548dbeb51e28b Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 8 Aug 2014 11:33:30 -0500 Subject: remove outdated comment eip machine was already moved into conductor --- src/leap/bitmask/gui/mainwindow.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 389ff172..02488af1 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -285,14 +285,8 @@ class MainWindow(QtGui.QMainWindow): self.logout.connect(self._mail_conductor.stop_mail_services) - # Eip machine is a public attribute where the state machine for - # the eip connection will be available to the different components. - # Remember that this will not live in the +1600LOC mainwindow for - # all the eternity, so at some point we will be moving this to - # the EIPConductor or some other clever component that we will - # instantiate from here. - - # start event machines + # start event machines from within the eip and mail conductors + # TODO should encapsulate all actions into one object self._eip_conductor.start_eip_machine( action=self._action_eip_startstop) -- cgit v1.2.3 From 8433b869c86fe6cc153ce410a1946d97d509b85f Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 10 Aug 2014 12:59:41 -0700 Subject: Clean up help dialog text. --- src/leap/bitmask/gui/mainwindow.py | 48 +++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 02488af1..3f74feb5 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -1073,22 +1073,38 @@ class MainWindow(QtGui.QMainWindow): # TODO: don't hardcode! smtp_port = 2013 - url = ("bitmask addon") - - msg = self.tr( - "Instructions to use mail:
" - "If you use Thunderbird you can use the Bitmask extension helper. " - "Search for 'Bitmask' in the add-on manager or download it " - "from: {0}.

" - "You can configure Bitmask manually with these options:
" - "" - " Incoming -> IMAP, port: {1}
" - " Outgoing -> SMTP, port: {2}
" - " Username -> your bitmask username.
" - " Password -> does not matter, use any text. " - " Just don't leave it empty and don't use your account's password." - "
").format(url, IMAP_PORT, smtp_port) + help_url = "

{0}

".format( + self.tr("bitmask.net/help")) + + lang = QtCore.QLocale.system().name().replace('_','-') + thunderbird_extension_url = \ + "https://addons.mozilla.org/{0}/" \ + "thunderbird/addon/bitmask/".format(lang) + + email_quick_reference = self.tr("Email quick reference") + thunderbird_text = self.tr("For Thunderbird, you can use the " + "Bitmask extension. Search for \"Bitmask\" in the add-on " + "manager or download it from " + "addons.mozilla.org.".format(thunderbird_extension_url)) + manual_text = self.tr("Alternately, you can manually configure " + "your mail client to use Bitmask Email with these options:") + manual_imap = self.tr("IMAP: localhost, port {0}".format(IMAP_PORT)) + manual_smtp = self.tr("SMTP: localhost, port {0}".format(smtp_port)) + manual_username = self.tr("Username: your full email address") + manual_password = self.tr("Password: any non-empty text") + + msg = help_url + self.tr( + "

{0}

" + "

{1}

" + "

{2}" + "

    " + "
  •  {3}
  • " + "
  •  {4}
  • " + "
  •  {5}
  • " + "
  •  {6}
  • " + "

").format(email_quick_reference, thunderbird_text, + manual_text, manual_imap, manual_smtp, + manual_username, manual_password) QtGui.QMessageBox.about(self, self.tr("Bitmask Help"), msg) def _needs_update(self): -- cgit v1.2.3 From a54a4bcd1aac5d42953f5f7f152080a391cbf643 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 10 Aug 2014 13:06:37 -0700 Subject: remove "Hide Main Window" -- much better UX, less buggy, and makes it possible raise window when it is obscured. To hide, just close window. --- src/leap/bitmask/gui/mainwindow.py | 79 +++++++++++++------------------------- 1 file changed, 26 insertions(+), 53 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 3f74feb5..c11cff9f 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -237,8 +237,8 @@ class MainWindow(QtGui.QMainWindow): self._action_eip_startstop = QtGui.QAction("", self) self._eip_status.set_action_eip_startstop(self._action_eip_startstop) - self._action_visible = QtGui.QAction(self.tr("Hide Main Window"), self) - self._action_visible.triggered.connect(self._toggle_visible) + self._action_visible = QtGui.QAction(self.tr("Show Main Window"), self) + self._action_visible.triggered.connect(self._ensure_visible) # disable buttons for now, may come back later. # self.ui.btnPreferences.clicked.connect(self._show_preferences) @@ -957,8 +957,6 @@ class MainWindow(QtGui.QMainWindow): Display the context menu from the tray icon """ - self._update_hideshow_menu() - context_menu = self._systray.contextMenu() if not IS_MAC: # for some reason, context_menu.show() @@ -967,50 +965,38 @@ class MainWindow(QtGui.QMainWindow): # this works however. context_menu.exec_(self._systray.geometry().center()) - def _update_hideshow_menu(self): - """ - Update the Hide/Show main window menu text based on the - visibility of the window. + @QtCore.Slot() + def _ensure_visible(self): """ - get_action = lambda visible: ( - self.tr("Show Main Window"), - self.tr("Hide Main Window"))[int(visible)] + TRIGGERS: + self._action_visible.triggered - # set labels - visible = self.isVisible() and self.isActiveWindow() - self._action_visible.setText(get_action(visible)) + Ensure that the window is visible and raised. + """ + QtGui.QApplication.setQuitOnLastWindowClosed(True) + self.show() + if IS_LINUX: + # On ubuntu, activateWindow doesn't work reliably, so + # we do the following as a workaround. See + # https://bugreports.qt-project.org/browse/QTBUG-24932 + # for more details + QtGui.QX11Info.setAppUserTime(0) + self.activateWindow() + self.raise_() @QtCore.Slot() - def _toggle_visible(self): + def _ensure_invisible(self): """ TRIGGERS: self._action_visible.triggered - Toggle the window visibility + Ensure that the window is hidden. """ - visible = self.isVisible() and self.isActiveWindow() - - if not visible: - QtGui.QApplication.setQuitOnLastWindowClosed(True) - self.show() - if IS_LINUX: - # On ubuntu, activateWindow doesn't work reliably, so - # we do the following as a workaround. See - # https://bugreports.qt-project.org/browse/QTBUG-24932 - # for more details - QtGui.QX11Info.setAppUserTime(0) - self.activateWindow() - self.raise_() - else: - # We set this in order to avoid dialogs shutting down the - # app on close, as they will be the only visible window. - # e.g.: PreferencesWindow, LoggerWindow - QtGui.QApplication.setQuitOnLastWindowClosed(False) - self.hide() - - # Wait a bit until the window visibility has changed so - # the menu is set with the correct value. - QtDelayedCall(500, self._update_hideshow_menu) + # We set this in order to avoid dialogs shutting down the + # app on close, as they will be the only visible window. + # e.g.: PreferencesWindow, LoggerWindow + QtGui.QApplication.setQuitOnLastWindowClosed(False) + self.hide() def _center_window(self): """ @@ -1130,19 +1116,6 @@ class MainWindow(QtGui.QMainWindow): "Error: API version incompatible.") QtGui.QMessageBox.warning(self, self.tr("Incompatible Provider"), msg) - def changeEvent(self, e): - """ - Reimplementation of changeEvent method to minimize to tray - """ - if not IS_MAC and \ - QtGui.QSystemTrayIcon.isSystemTrayAvailable() and \ - e.type() == QtCore.QEvent.WindowStateChange and \ - self.isMinimized(): - self._toggle_visible() - e.accept() - return - QtGui.QMainWindow.changeEvent(self, e) - def closeEvent(self, e): """ Reimplementation of closeEvent to close to tray @@ -1155,7 +1128,7 @@ class MainWindow(QtGui.QMainWindow): if QtGui.QSystemTrayIcon.isSystemTrayAvailable() and \ not self._really_quit: - self._toggle_visible() + self._ensure_invisible() e.ignore() return -- cgit v1.2.3 From ff4f8e1b1b0cbe48e8d94fed5128acc60be9bf1a Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Sat, 9 Aug 2014 15:39:37 -0500 Subject: Wait until EIP is up to autologin. Closes #5939. --- src/leap/bitmask/gui/mainwindow.py | 51 +++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 389ff172..990ea643 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -1165,12 +1165,14 @@ class MainWindow(QtGui.QMainWindow): skip_first_run = self._settings.get_skip_first_run() return not (has_provider_on_disk and skip_first_run) + @QtCore.Slot() def _download_provider_config(self): """ Start the bootstrapping sequence. It will download the provider configuration if it's not present, otherwise will emit the corresponding signals inmediately """ + self._disconnect_scheduled_login() domain = self._login_widget.get_selected_provider() self._backend.provider_setup(provider=domain) @@ -1204,6 +1206,40 @@ class MainWindow(QtGui.QMainWindow): self.tr("Unable to login: Problem with provider")) self._login_widget.set_enabled(True) + def _schedule_login(self): + """ + Schedule the login sequence to go after the EIP started. + + The login sequence is connected to all finishing status of EIP + (connected, disconnected, aborted or died) to continue with the login + after EIP. + """ + logger.debug('Login scheduled when eip_connected is triggered') + eip_sigs = self._eip_conductor.qtsigs + eip_sigs.connected_signal.connect(self._download_provider_config) + eip_sigs.disconnected_signal.connect(self._download_provider_config) + eip_sigs.connection_aborted_signal.connect(self._download_provider_config) + eip_sigs.connection_died_signal.connect(self._download_provider_config) + + def _disconnect_scheduled_login(self): + """ + Disconnect scheduled login signals if exists + """ + try: + eip_sigs = self._eip_conductor.qtsigs + eip_sigs.connected_signal.disconnect( + self._download_provider_config) + eip_sigs.disconnected_signal.disconnect( + self._download_provider_config) + eip_sigs.connection_aborted_signal.disconnect( + self._download_provider_config) + eip_sigs.connection_died_signal.disconnect( + self._download_provider_config) + except Exception: + # signal not connected + pass + + @QtCore.Slot() def _login(self): """ @@ -1229,7 +1265,10 @@ class MainWindow(QtGui.QMainWindow): else: self.ui.action_create_new_account.setEnabled(False) if self._login_widget.start_login(): - self._download_provider_config() + if self._trying_to_start_eip: + self._schedule_login() + else: + self._download_provider_config() @QtCore.Slot(unicode) def _authentication_error(self, msg): @@ -1258,8 +1297,13 @@ class MainWindow(QtGui.QMainWindow): Stop the login sequence. """ logger.debug("Cancelling log in.") + self._disconnect_scheduled_login() + self._cancel_ongoing_defers() + # Needed in case of EIP starting and login deferer never set + self._set_login_cancelled() + def _cancel_ongoing_defers(self): """ Cancel the running defers to avoid app blocking. @@ -1673,8 +1717,9 @@ class MainWindow(QtGui.QMainWindow): """ passed = data[PASSED_KEY] if not passed: - self._login_widget.set_status( - self.tr("Unable to connect: Problem with provider")) + self._eip_status.set_eip_status( + self.tr("Unable to connect: Problem with provider"), + error=True) logger.error(data[ERROR_KEY]) self._already_started_eip = False self._eip_status.aborted() -- cgit v1.2.3 From 769f334a3a424612b454061f4dc3937e3e46071f Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 11 Aug 2014 17:35:36 -0300 Subject: Do some pep8 fixes. --- src/leap/bitmask/gui/mainwindow.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 0518350e..c6fd12e1 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -1062,17 +1062,19 @@ class MainWindow(QtGui.QMainWindow): help_url = "

{0}

".format( self.tr("bitmask.net/help")) - lang = QtCore.QLocale.system().name().replace('_','-') + lang = QtCore.QLocale.system().name().replace('_', '-') thunderbird_extension_url = \ "https://addons.mozilla.org/{0}/" \ "thunderbird/addon/bitmask/".format(lang) email_quick_reference = self.tr("Email quick reference") - thunderbird_text = self.tr("For Thunderbird, you can use the " + thunderbird_text = self.tr( + "For Thunderbird, you can use the " "Bitmask extension. Search for \"Bitmask\" in the add-on " "manager or download it from " "addons.mozilla.org.".format(thunderbird_extension_url)) - manual_text = self.tr("Alternately, you can manually configure " + manual_text = self.tr( + "Alternately, you can manually configure " "your mail client to use Bitmask Email with these options:") manual_imap = self.tr("IMAP: localhost, port {0}".format(IMAP_PORT)) manual_smtp = self.tr("SMTP: localhost, port {0}".format(smtp_port)) @@ -1089,8 +1091,8 @@ class MainWindow(QtGui.QMainWindow): "
  •  {5}
  • " "
  •  {6}
  • " "

    ").format(email_quick_reference, thunderbird_text, - manual_text, manual_imap, manual_smtp, - manual_username, manual_password) + manual_text, manual_imap, manual_smtp, + manual_username, manual_password) QtGui.QMessageBox.about(self, self.tr("Bitmask Help"), msg) def _needs_update(self): @@ -1201,7 +1203,8 @@ class MainWindow(QtGui.QMainWindow): eip_sigs = self._eip_conductor.qtsigs eip_sigs.connected_signal.connect(self._download_provider_config) eip_sigs.disconnected_signal.connect(self._download_provider_config) - eip_sigs.connection_aborted_signal.connect(self._download_provider_config) + eip_sigs.connection_aborted_signal.connect( + self._download_provider_config) eip_sigs.connection_died_signal.connect(self._download_provider_config) def _disconnect_scheduled_login(self): @@ -1211,18 +1214,17 @@ class MainWindow(QtGui.QMainWindow): try: eip_sigs = self._eip_conductor.qtsigs eip_sigs.connected_signal.disconnect( - self._download_provider_config) + self._download_provider_config) eip_sigs.disconnected_signal.disconnect( - self._download_provider_config) + self._download_provider_config) eip_sigs.connection_aborted_signal.disconnect( - self._download_provider_config) + self._download_provider_config) eip_sigs.connection_died_signal.disconnect( - self._download_provider_config) + self._download_provider_config) except Exception: # signal not connected pass - @QtCore.Slot() def _login(self): """ -- cgit v1.2.3 From 1d8fd48517a44f81d816eba2488e23fe3080f83b Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 11 Aug 2014 15:48:54 -0300 Subject: Stop the services if the selected provider is changed. Store the last 2 indexes on a deque and improve the 'select previous provider' action. --- src/leap/bitmask/gui/mainwindow.py | 62 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index c6fd12e1..a85cb657 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -153,8 +153,8 @@ class MainWindow(QtGui.QMainWindow): self._login_widget.login.connect(self._login) self._login_widget.cancel_login.connect(self._cancel_login) - self._login_widget.show_wizard.connect(self._launch_wizard) self._login_widget.logout.connect(self._logout) + self._login_widget.provider_changed.connect(self._on_provider_changed) # EIP Control redux ######################################### self._eip_conductor = eip_conductor.EIPConductor( @@ -174,6 +174,8 @@ class MainWindow(QtGui.QMainWindow): self._eip_conductor.connect_signals() self._eip_conductor.qtsigs.connected_signal.connect( self._on_eip_connection_connected) + self._eip_conductor.qtsigs.disconnected_signal.connect( + self._on_eip_connection_disconnected) self._eip_conductor.qtsigs.connected_signal.connect( self._maybe_run_soledad_setup_checks) @@ -187,7 +189,6 @@ class MainWindow(QtGui.QMainWindow): self._already_started_eip = False self._trying_to_start_eip = False - self._already_started_eip = False self._soledad_started = False # This is created once we have a valid provider config @@ -502,7 +503,6 @@ class MainWindow(QtGui.QMainWindow): def _launch_wizard(self): """ TRIGGERS: - self._login_widget.show_wizard self.ui.action_wizard.triggered Also called in first run. @@ -1225,6 +1225,52 @@ class MainWindow(QtGui.QMainWindow): # signal not connected pass + @QtCore.Slot(object) + def _on_provider_changed(self, wizard): + """ + TRIGGERS: + self._login.provider_changed + + Ask the user if really wants to change provider since a services stop + is required for that action. + + :param wizard: whether the 'other...' option was picked or not. + :type wizard: bool + """ + # TODO: we should handle the case that EIP is autostarting since we + # won't get a warning until EIP has fully started. + # TODO: we need to add a check for the mail status (smtp/imap/soledad) + something_runing = (self._logged_user is not None or + self._already_started_eip) + if not something_runing: + if wizard: + self._launch_wizard() + return + + title = self.tr("Stop services") + text = self.tr("Do you want to stop all services?") + informative_text = self.tr("In order to change the provider, the " + "running services needs to be stopped.") + + msg = QtGui.QMessageBox(self) + msg.setWindowTitle(title) + msg.setText(text) + msg.setInformativeText(informative_text) + msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) + msg.setDefaultButton(QtGui.QMessageBox.No) + msg.setIcon(QtGui.QMessageBox.Warning) + res = msg.exec_() + + if res == QtGui.QMessageBox.Yes: + self._stop_services() + self._eip_conductor.qtsigs.do_disconnect_signal.emit() + if wizard: + self._launch_wizard() + else: + if not wizard: + # if wizard, the widget restores itself + self._login_widget.restore_previous_provider() + @QtCore.Slot() def _login(self): """ @@ -1563,6 +1609,16 @@ class MainWindow(QtGui.QMainWindow): # check for connectivity self._backend.eip_check_dns(domain=domain) + @QtCore.Slot() + def _on_eip_connection_disconnected(self): + """ + TRIGGERS: + self._eip_conductor.qtsigs.disconnected_signal + + Set the eip status to not started. + """ + self._already_started_eip = False + @QtCore.Slot() def _set_eip_provider(self, country_code=None): """ -- cgit v1.2.3 From dd2097d27efc32820a25faff9236d091372f7930 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 12 Aug 2014 17:12:11 -0300 Subject: Ask for services stop when the wizard is needed. --- src/leap/bitmask/gui/mainwindow.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index a85cb657..03f91996 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -215,8 +215,9 @@ class MainWindow(QtGui.QMainWindow): self.ui.action_wizard.triggered.connect(self._launch_wizard) self.ui.action_show_logs.triggered.connect(self._show_logger_window) self.ui.action_help.triggered.connect(self._help) + self.ui.action_create_new_account.triggered.connect( - self._launch_wizard) + self._on_provider_changed) self.ui.action_advanced_key_management.triggered.connect( self._show_AKM) @@ -1226,10 +1227,11 @@ class MainWindow(QtGui.QMainWindow): pass @QtCore.Slot(object) - def _on_provider_changed(self, wizard): + def _on_provider_changed(self, wizard=True): """ TRIGGERS: self._login.provider_changed + self.ui.action_create_new_account.triggered Ask the user if really wants to change provider since a services stop is required for that action. @@ -1251,6 +1253,9 @@ class MainWindow(QtGui.QMainWindow): text = self.tr("Do you want to stop all services?") informative_text = self.tr("In order to change the provider, the " "running services needs to be stopped.") + if wizard: + informative_text = self.tr("In order to start the wizard, the " + "running services needs to be stopped.") msg = QtGui.QMessageBox(self) msg.setWindowTitle(title) -- cgit v1.2.3 From 9a7df988191e2cdeb2e01fb30da55a0c5f4651f9 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 13 Aug 2014 16:20:49 -0700 Subject: moved provider selection popup menu to be at the top of the main window --- src/leap/bitmask/gui/mainwindow.py | 76 ++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 41 deletions(-) (limited to 'src/leap/bitmask/gui/mainwindow.py') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 03f91996..8ce7f2fc 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -45,6 +45,7 @@ from leap.bitmask.gui.mail_status import MailStatusWidget from leap.bitmask.gui.preferenceswindow import PreferencesWindow from leap.bitmask.gui.systray import SysTray from leap.bitmask.gui.wizard import Wizard +from leap.bitmask.gui.providers import Providers from leap.bitmask.platform_init import IS_WIN, IS_MAC, IS_LINUX from leap.bitmask.platform_init.initializers import init_platform @@ -148,13 +149,17 @@ class MainWindow(QtGui.QMainWindow): self._mail_status = MailStatusWidget(self) self.ui.mailLayout.addWidget(self._mail_status) + # Provider List + self._providers = Providers(self.ui.cmbProviders) + # Qt Signal Connections ##################################### # TODO separate logic from ui signals. self._login_widget.login.connect(self._login) self._login_widget.cancel_login.connect(self._cancel_login) self._login_widget.logout.connect(self._logout) - self._login_widget.provider_changed.connect(self._on_provider_changed) + + self._providers.connect_provider_changed(self._on_provider_changed) # EIP Control redux ######################################### self._eip_conductor = eip_conductor.EIPConductor( @@ -577,7 +582,7 @@ class MainWindow(QtGui.QMainWindow): Display the Advanced Key Management dialog. """ - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() logged_user = "{0}@{1}".format(self._logged_user, domain) details = self._provider_details @@ -600,7 +605,7 @@ class MainWindow(QtGui.QMainWindow): Display the preferences window. """ user = self._logged_user - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() mx_provided = False if self._provider_details is not None: mx_provided = MX_SERVICE in self._provider_details['services'] @@ -717,7 +722,7 @@ class MainWindow(QtGui.QMainWindow): Display the EIP preferences window. """ - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() pref = EIPPreferencesWindow(self, domain, self._backend, self._leap_signaler) pref.show() @@ -794,7 +799,7 @@ class MainWindow(QtGui.QMainWindow): # XXX: May be this can be divided into two methods? providers = self._settings.get_configured_providers() - self._login_widget.set_providers(providers) + self._providers.set_providers(providers) self._show_systray() if not self._start_hidden: @@ -810,12 +815,12 @@ class MainWindow(QtGui.QMainWindow): # select the configured provider in the combo box domain = self._wizard.get_domain() - self._login_widget.select_provider_by_name(domain) + self._providers.select_provider_by_name(domain) self._login_widget.set_remember(self._wizard.get_remember()) self._enabled_services = list(self._wizard.get_services()) self._settings.set_enabled_services( - self._login_widget.get_selected_provider(), + self._providers.get_selected_provider(), self._enabled_services) if possible_username is not None: self._login_widget.set_user(possible_username) @@ -832,7 +837,7 @@ class MainWindow(QtGui.QMainWindow): domain = self._settings.get_provider() if domain is not None: - self._login_widget.select_provider_by_name(domain) + self._providers.select_provider_by_name(domain) if not self._settings.get_remember(): # nothing to do here @@ -895,11 +900,7 @@ class MainWindow(QtGui.QMainWindow): """ Set the login label to reflect offline status. """ - provider = "" - if not self._logged_in_offline: - provider = self.ui.lblLoginProvider.text() - - self.ui.lblLoginProvider.setText(provider + self.tr(" (offline mode)")) + # TODO: figure out what widget to use for this. Maybe the window title? # # systray @@ -1159,7 +1160,7 @@ class MainWindow(QtGui.QMainWindow): emit the corresponding signals inmediately """ self._disconnect_scheduled_login() - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() self._backend.provider_setup(provider=domain) @QtCore.Slot(dict) @@ -1176,7 +1177,7 @@ class MainWindow(QtGui.QMainWindow): :type data: dict """ if data[PASSED_KEY]: - selected_provider = self._login_widget.get_selected_provider() + selected_provider = self._providers.get_selected_provider() self._backend.provider_bootstrap(provider=selected_provider) else: logger.error(data[ERROR_KEY]) @@ -1230,7 +1231,7 @@ class MainWindow(QtGui.QMainWindow): def _on_provider_changed(self, wizard=True): """ TRIGGERS: - self._login.provider_changed + self._providers._provider_changed self.ui.action_create_new_account.triggered Ask the user if really wants to change provider since a services stop @@ -1250,12 +1251,9 @@ class MainWindow(QtGui.QMainWindow): return title = self.tr("Stop services") - text = self.tr("Do you want to stop all services?") + text = "" + self.tr("Do you want to stop all services?") + "" informative_text = self.tr("In order to change the provider, the " "running services needs to be stopped.") - if wizard: - informative_text = self.tr("In order to start the wizard, the " - "running services needs to be stopped.") msg = QtGui.QMessageBox(self) msg.setWindowTitle(title) @@ -1274,7 +1272,7 @@ class MainWindow(QtGui.QMainWindow): else: if not wizard: # if wizard, the widget restores itself - self._login_widget.restore_previous_provider() + self._providers.restore_previous_provider() @QtCore.Slot() def _login(self): @@ -1288,19 +1286,18 @@ class MainWindow(QtGui.QMainWindow): bootstrapping the EIP service """ # TODO most of this could ve handled by the login widget, - # but we'd have to move lblLoginProvider into the widget itself, - # instead of having it as a top-level attribute. + provider = self._providers.get_selected_provider() if flags.OFFLINE is True: logger.debug("OFFLINE mode! bypassing remote login") # TODO reminder, we're not handling logout for offline # mode. - self._login_widget.logged_in() + self._login_widget.logged_in(provider) self._logged_in_offline = True self._set_label_offline() self.offline_mode_bypass_login.emit() else: self.ui.action_create_new_account.setEnabled(False) - if self._login_widget.start_login(): + if self._login_widget.start_login(provider): if self._trying_to_start_eip: self._schedule_login() else: @@ -1380,7 +1377,7 @@ class MainWindow(QtGui.QMainWindow): self._show_hide_unsupported_services() - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() self._backend.user_login(provider=domain, username=username, password=password) else: @@ -1400,7 +1397,7 @@ class MainWindow(QtGui.QMainWindow): self._logged_user = self._login_widget.get_user() user = self._logged_user - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() full_user_id = make_address(user, domain) self._mail_conductor.userid = full_user_id self._start_eip_bootstrap() @@ -1423,9 +1420,8 @@ class MainWindow(QtGui.QMainWindow): triggers the eip bootstrapping. """ - self._login_widget.logged_in() - domain = self._login_widget.get_selected_provider() - self.ui.lblLoginProvider.setText(domain) + domain = self._providers.get_selected_provider() + self._login_widget.logged_in(domain) self._enabled_services = self._settings.get_enabled_services(domain) @@ -1447,7 +1443,7 @@ class MainWindow(QtGui.QMainWindow): and enabled. This is triggered right after the provider has been set up. """ - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() lang = QtCore.QLocale.system().name() self._backend.provider_get_details(domain=domain, lang=lang) @@ -1468,7 +1464,7 @@ class MainWindow(QtGui.QMainWindow): :returns: True if provides and is enabled, False otherwise :rtype: bool """ - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() enabled_services = self._settings.get_enabled_services(domain) mx_enabled = MX_SERVICE in enabled_services @@ -1485,7 +1481,7 @@ class MainWindow(QtGui.QMainWindow): :returns: True if provides and is enabled, False otherwise :rtype: bool """ - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() enabled_services = self._settings.get_enabled_services(domain) eip_enabled = EIP_SERVICE in enabled_services @@ -1506,7 +1502,7 @@ class MainWindow(QtGui.QMainWindow): username = self._login_widget.get_user() password = unicode(self._login_widget.get_password()) - provider_domain = self._login_widget.get_selected_provider() + provider_domain = self._providers.get_selected_provider() if flags.OFFLINE: full_user_id = make_address(username, provider_domain) @@ -1522,7 +1518,7 @@ class MainWindow(QtGui.QMainWindow): password=password, uuid=uuid) else: if self._logged_user is not None: - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() self._backend.soledad_bootstrap(username=username, domain=domain, password=password) @@ -1606,7 +1602,7 @@ class MainWindow(QtGui.QMainWindow): """ self._already_started_eip = True - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() self._settings.set_defaultprovider(domain) self._backend.eip_get_gateway_country_code(domain=domain) @@ -1633,7 +1629,7 @@ class MainWindow(QtGui.QMainWindow): Set the current provider and country code in the eip status widget. """ - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() self._eip_status.set_provider(domain, country_code) @QtCore.Slot() @@ -1641,7 +1637,7 @@ class MainWindow(QtGui.QMainWindow): """ Trigger this if we don't have a working DNS resolver. """ - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() msg = self.tr( "The server at {0} can't be found, because the DNS lookup " "failed. DNS is the network service that translates a " @@ -1705,7 +1701,7 @@ class MainWindow(QtGui.QMainWindow): self._eip_status.eip_button.hide() self._eip_status.eip_button.setEnabled(False) - domain = self._login_widget.get_selected_provider() + domain = self._providers.get_selected_provider() self._backend.eip_setup(provider=domain) self._already_started_eip = True @@ -1796,7 +1792,6 @@ class MainWindow(QtGui.QMainWindow): Inform the user about a logout error. """ self._login_widget.done_logout() - self.ui.lblLoginProvider.setText(self.tr("Login")) self._login_widget.set_status( self.tr("Something went wrong with the logout.")) @@ -1810,7 +1805,6 @@ class MainWindow(QtGui.QMainWindow): logging out """ self._login_widget.done_logout() - self.ui.lblLoginProvider.setText(self.tr("Login")) self._logged_user = None self._login_widget.logged_out() -- cgit v1.2.3