diff options
author | Ivan Alejandro <ivanalejandro0@gmail.com> | 2013-10-01 12:36:28 -0300 |
---|---|---|
committer | Ivan Alejandro <ivanalejandro0@gmail.com> | 2013-10-01 12:36:28 -0300 |
commit | 0fa4712d10936329aa5012b3173bdd0fc0362e9f (patch) | |
tree | ae8e41e17dcb31ea8162c733eb298e9d956314c3 /src | |
parent | 95b69d0d2e9801e4db1fe3758b62ab9539ecf882 (diff) | |
parent | fa3dcc727f3690439c57981ffa639453b395a618 (diff) |
Merge remote-tracking branch 'chiiph/feature/new_ui' into develop
Diffstat (limited to 'src')
-rw-r--r-- | src/leap/bitmask/config/providerconfig.py | 19 | ||||
-rw-r--r-- | src/leap/bitmask/gui/clickablelabel.py | 28 | ||||
-rw-r--r-- | src/leap/bitmask/gui/eip_preferenceswindow.py | 177 | ||||
-rw-r--r-- | src/leap/bitmask/gui/eip_status.py (renamed from src/leap/bitmask/gui/statuspanel.py) | 361 | ||||
-rw-r--r-- | src/leap/bitmask/gui/login.py | 126 | ||||
-rw-r--r-- | src/leap/bitmask/gui/mail_status.py | 399 | ||||
-rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 208 | ||||
-rw-r--r-- | src/leap/bitmask/gui/preferenceswindow.py | 117 | ||||
-rw-r--r-- | src/leap/bitmask/gui/ui/eip_status.ui | 287 | ||||
-rw-r--r-- | src/leap/bitmask/gui/ui/eippreferences.ui | 94 | ||||
-rw-r--r-- | src/leap/bitmask/gui/ui/login.ui | 302 | ||||
-rw-r--r-- | src/leap/bitmask/gui/ui/mail_status.ui | 98 | ||||
-rw-r--r-- | src/leap/bitmask/gui/ui/mainwindow.ui | 437 | ||||
-rw-r--r-- | src/leap/bitmask/gui/ui/preferences.ui | 175 | ||||
-rw-r--r-- | src/leap/bitmask/gui/ui/statuspanel.ui | 393 |
15 files changed, 1877 insertions, 1344 deletions
diff --git a/src/leap/bitmask/config/providerconfig.py b/src/leap/bitmask/config/providerconfig.py index c8c8a59e..44698d83 100644 --- a/src/leap/bitmask/config/providerconfig.py +++ b/src/leap/bitmask/config/providerconfig.py @@ -44,6 +44,25 @@ class ProviderConfig(BaseConfig): def __init__(self): BaseConfig.__init__(self) + @classmethod + def get_provider_config(self, domain): + """ + Helper to return a valid Provider Config from the domain name. + + :param domain: the domain name of the provider. + :type domain: str + + :rtype: ProviderConfig or None if there is a problem loading the config + """ + provider_config = ProviderConfig() + provider_config_path = os.path.join( + "leap", "providers", domain, "provider.json") + + if not provider_config.load(provider_config_path): + provider_config = None + + return provider_config + def _get_schema(self): """ Returns the schema corresponding to the version given. diff --git a/src/leap/bitmask/gui/clickablelabel.py b/src/leap/bitmask/gui/clickablelabel.py new file mode 100644 index 00000000..2808a601 --- /dev/null +++ b/src/leap/bitmask/gui/clickablelabel.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# clickablelabel.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +""" +Clickable label +""" +from PySide import QtCore, QtGui + + +class ClickableLabel(QtGui.QLabel): + clicked = QtCore.Signal() + + def mousePressEvent(self, event): + self.clicked.emit() diff --git a/src/leap/bitmask/gui/eip_preferenceswindow.py b/src/leap/bitmask/gui/eip_preferenceswindow.py new file mode 100644 index 00000000..0e6e8dda --- /dev/null +++ b/src/leap/bitmask/gui/eip_preferenceswindow.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# eip_preferenceswindow.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +""" +EIP Preferences window +""" +import os +import logging + +from functools import partial +from PySide import QtGui + +from leap.bitmask.config.leapsettings import LeapSettings +from leap.bitmask.config.providerconfig import ProviderConfig +from leap.bitmask.gui.ui_eippreferences import Ui_EIPPreferences +from leap.bitmask.services.eip.eipconfig import EIPConfig, VPNGatewaySelector + +logger = logging.getLogger(__name__) + + +class EIPPreferencesWindow(QtGui.QDialog): + """ + Window that displays the EIP preferences. + """ + def __init__(self, parent): + """ + :param parent: parent object of the EIPPreferencesWindow. + :parent type: QWidget + """ + QtGui.QDialog.__init__(self, parent) + self.AUTOMATIC_GATEWAY_LABEL = self.tr("Automatic") + + self._settings = LeapSettings() + + # Load UI + self.ui = Ui_EIPPreferences() + self.ui.setupUi(self) + self.ui.lblProvidersGatewayStatus.setVisible(False) + + # Connections + self.ui.cbProvidersGateway.currentIndexChanged[unicode].connect( + self._populate_gateways) + + self.ui.cbGateways.currentIndexChanged[unicode].connect( + lambda x: self.ui.lblProvidersGatewayStatus.setVisible(False)) + + self._add_configured_providers() + + def _set_providers_gateway_status(self, status, success=False, + error=False): + """ + Sets the status label for the gateway change. + + :param status: status message to display, can be HTML + :type status: str + :param success: is set to True if we should display the + message as green + :type success: bool + :param error: is set to True if we should display the + message as red + :type error: bool + """ + if success: + status = "<font color='green'><b>%s</b></font>" % (status,) + elif error: + status = "<font color='red'><b>%s</b></font>" % (status,) + + self.ui.lblProvidersGatewayStatus.setVisible(True) + self.ui.lblProvidersGatewayStatus.setText(status) + + def _add_configured_providers(self): + """ + Add the client's configured providers to the providers combo boxes. + """ + self.ui.cbProvidersGateway.clear() + for provider in self._settings.get_configured_providers(): + self.ui.cbProvidersGateway.addItem(provider) + + def _save_selected_gateway(self, provider): + """ + SLOT + TRIGGERS: + self.ui.pbSaveGateway.clicked + + Saves the new gateway setting to the configuration file. + + :param provider: the provider config that we need to save. + :type provider: str + """ + gateway = self.ui.cbGateways.currentText() + + if gateway == self.AUTOMATIC_GATEWAY_LABEL: + gateway = self._settings.GATEWAY_AUTOMATIC + else: + idx = self.ui.cbGateways.currentIndex() + gateway = self.ui.cbGateways.itemData(idx) + + self._settings.set_selected_gateway(provider, gateway) + + msg = self.tr( + "Gateway settings for provider '{0}' saved.").format(provider) + self._set_providers_gateway_status(msg, success=True) + + def _populate_gateways(self, domain): + """ + SLOT + TRIGGERS: + self.ui.cbProvidersGateway.currentIndexChanged[unicode] + + Loads the gateways that the provider provides into the UI for + the user to select. + + :param domain: the domain of the provider to load gateways from. + :type domain: str + """ + # We hide the maybe-visible status label after a change + self.ui.lblProvidersGatewayStatus.setVisible(False) + + if not domain: + return + + try: + # disconnect previously connected save method + self.ui.pbSaveGateway.clicked.disconnect() + except RuntimeError: + pass # Signal was not connected + + # set the proper connection for the 'save' button + save_gateway = partial(self._save_selected_gateway, domain) + self.ui.pbSaveGateway.clicked.connect(save_gateway) + + eip_config = EIPConfig() + provider_config = ProviderConfig.get_provider_config(domain) + + eip_config_path = os.path.join("leap", "providers", + domain, "eip-service.json") + api_version = provider_config.get_api_version() + eip_config.set_api_version(api_version) + eip_loaded = eip_config.load(eip_config_path) + + if not eip_loaded or provider_config is None: + self._set_providers_gateway_status( + self.tr("There was a problem with configuration files."), + error=True) + return + + gateways = VPNGatewaySelector(eip_config).get_gateways_list() + logger.debug(gateways) + + self.ui.cbGateways.clear() + self.ui.cbGateways.addItem(self.AUTOMATIC_GATEWAY_LABEL) + + # Add the available gateways and + # select the one stored in configuration file. + selected_gateway = self._settings.get_selected_gateway(domain) + index = 0 + for idx, (gw_name, gw_ip) in enumerate(gateways): + gateway = "{0} ({1})".format(gw_name, gw_ip) + self.ui.cbGateways.addItem(gateway, gw_ip) + if gw_ip == selected_gateway: + index = idx + 1 + + self.ui.cbGateways.setCurrentIndex(index) diff --git a/src/leap/bitmask/gui/statuspanel.py b/src/leap/bitmask/gui/eip_status.py index 679f00b1..f7408b13 100644 --- a/src/leap/bitmask/gui/statuspanel.py +++ b/src/leap/bitmask/gui/eip_status.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# statuspanel.py +# eip_status.py # Copyright (C) 2013 LEAP # # This program is free software: you can redistribute it and/or modify @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ -Status Panel widget implementation +EIP Status Panel widget implementation """ import logging @@ -26,33 +26,24 @@ from PySide import QtCore, QtGui from leap.bitmask.services.eip.connection import EIPConnection from leap.bitmask.services.eip.vpnprocess import VPNManager -from leap.bitmask.platform_init import IS_WIN, IS_LINUX +from leap.bitmask.platform_init import IS_LINUX from leap.bitmask.util.averages import RateMovingAverage -from leap.common.check import leap_assert, leap_assert_type -from leap.common.events import register -from leap.common.events import events_pb2 as proto +from leap.common.check import leap_assert_type -from ui_statuspanel import Ui_StatusPanel +from ui_eip_status import Ui_EIPStatus logger = logging.getLogger(__name__) -class StatusPanelWidget(QtGui.QWidget): +class EIPStatusWidget(QtGui.QWidget): """ - Status widget that displays the current state of the LEAP services + EIP Status widget that displays the current state of the EIP service """ DISPLAY_TRAFFIC_RATES = True RATE_STR = "%14.2f KB/s" TOTAL_STR = "%14.2f Kb" - MAIL_OFF_ICON = ":/images/mail-unlocked.png" - MAIL_ON_ICON = ":/images/mail-locked.png" - eip_connection_connected = QtCore.Signal() - _soledad_event = QtCore.Signal(object) - _smtp_event = QtCore.Signal(object) - _imap_event = QtCore.Signal(object) - _keymanager_event = QtCore.Signal(object) def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) @@ -60,15 +51,15 @@ class StatusPanelWidget(QtGui.QWidget): self._systray = None self._eip_status_menu = None - self.ui = Ui_StatusPanel() + self.ui = Ui_EIPStatus() self.ui.setupUi(self) self.eipconnection = EIPConnection() - self.hide_status_box() + # set systray tooltip status + self._eip_status = "" - # set systray tooltip statuses - self._eip_status = self._mx_status = "" + self.ui.eip_bandwidth.hide() # Set the EIP status icons self.CONNECTING_ICON = None @@ -82,72 +73,7 @@ class StatusPanelWidget(QtGui.QWidget): self._set_traffic_rates() self._make_status_clickable() - register(signal=proto.KEYMANAGER_LOOKING_FOR_KEY, - callback=self._mail_handle_keymanager_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.KEYMANAGER_KEY_FOUND, - callback=self._mail_handle_keymanager_events, - reqcbk=lambda req, resp: None) - - # register(signal=proto.KEYMANAGER_KEY_NOT_FOUND, - # callback=self._mail_handle_keymanager_events, - # reqcbk=lambda req, resp: None) - - register(signal=proto.KEYMANAGER_STARTED_KEY_GENERATION, - callback=self._mail_handle_keymanager_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.KEYMANAGER_FINISHED_KEY_GENERATION, - callback=self._mail_handle_keymanager_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.KEYMANAGER_DONE_UPLOADING_KEYS, - callback=self._mail_handle_keymanager_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.SOLEDAD_DONE_DOWNLOADING_KEYS, - callback=self._mail_handle_soledad_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.SOLEDAD_DONE_UPLOADING_KEYS, - callback=self._mail_handle_soledad_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.SMTP_SERVICE_STARTED, - callback=self._mail_handle_smtp_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.SMTP_SERVICE_FAILED_TO_START, - callback=self._mail_handle_smtp_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.IMAP_SERVICE_STARTED, - callback=self._mail_handle_imap_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.IMAP_SERVICE_FAILED_TO_START, - callback=self._mail_handle_imap_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.IMAP_UNREAD_MAIL, - callback=self._mail_handle_imap_events, - reqcbk=lambda req, resp: None) - - self._set_long_mail_status("") - self.ui.lblUnread.setVisible(False) - - self._smtp_started = False - self._imap_started = False - - self._soledad_event.connect( - self._mail_handle_soledad_events_slot) - self._imap_event.connect( - self._mail_handle_imap_events_slot) - self._smtp_event.connect( - self._mail_handle_smtp_events_slot) - self._keymanager_event.connect( - self._mail_handle_keymanager_events_slot) + self._provider = "" def _make_status_clickable(self): """ @@ -233,20 +159,15 @@ class StatusPanelWidget(QtGui.QWidget): WIN : light icons """ EIP_ICONS = EIP_ICONS_TRAY = ( - ":/images/conn_connecting-light.png", - ":/images/conn_connected-light.png", - ":/images/conn_error-light.png") + ":/images/black/32/wait.png", + ":/images/black/32/on.png", + ":/images/black/32/off.png") if IS_LINUX: EIP_ICONS_TRAY = ( - ":/images/conn_connecting.png", - ":/images/conn_connected.png", - ":/images/conn_error.png") - elif IS_WIN: - EIP_ICONS = EIP_ICONS_TRAY = ( - ":/images/conn_connecting.png", - ":/images/conn_connected.png", - ":/images/conn_error.png") + ":/images/white/32/wait.png", + ":/images/white/32/on.png", + ":/images/white/32/off.png") self.CONNECTING_ICON = QtGui.QPixmap(EIP_ICONS[0]) self.CONNECTED_ICON = QtGui.QPixmap(EIP_ICONS[1]) @@ -271,11 +192,9 @@ class StatusPanelWidget(QtGui.QWidget): def _update_systray_tooltip(self): """ - Updates the system tray icon tooltip using the eip and mx statuses. + Updates the system tray icon tooltip using the eip and mx status. """ - status = self.tr("Encrypted Internet is {0}").format(self._eip_status) - status += '\n' - status += self.tr("Mail is {0}").format(self._mx_status) + status = self.tr("Encrypted Internet: {0}").format(self._eip_status) self._systray.setToolTip(status) def set_action_eip_startstop(self, action_eip_startstop): @@ -297,17 +216,7 @@ class StatusPanelWidget(QtGui.QWidget): leap_assert_type(eip_status_menu, QtGui.QMenu) self._eip_status_menu = eip_status_menu - def set_action_mail_status(self, action_mail_status): - """ - Sets the action_mail_status to use. - - :param action_mail_status: action_mail_status to be used - :type action_mail_status: QtGui.QAction - """ - leap_assert_type(action_mail_status, QtGui.QAction) - self._action_mail_status = action_mail_status - - def set_global_status(self, status, error=False): + def set_eip_status(self, status, error=False): """ Sets the global status label. @@ -320,14 +229,8 @@ class StatusPanelWidget(QtGui.QWidget): leap_assert_type(error, bool) if error: status = "<font color='red'><b>%s</b></font>" % (status,) - self.ui.lblGlobalStatus.setText(status) - self.ui.globalStatusBox.show() - - def hide_status_box(self): - """ - Hide global status box. - """ - self.ui.globalStatusBox.hide() + self.ui.lblEIPStatus.setText(status) + self.ui.lblEIPStatus.show() # EIP status --- @@ -344,7 +247,6 @@ class StatusPanelWidget(QtGui.QWidget): Triggered when the app activates eip. Hides the status box and disables the start/stop button. """ - self.hide_status_box() self.set_startstop_enabled(False) # XXX disable (later) -------------------------- @@ -365,6 +267,7 @@ class StatusPanelWidget(QtGui.QWidget): if error: status = "<font color='red'>%s</font>" % (status,) self.ui.lblEIPStatus.setText(status) + self.ui.lblEIPStatus.show() self._update_systray_tooltip() # XXX disable --------------------------------- @@ -405,6 +308,11 @@ class StatusPanelWidget(QtGui.QWidget): self.ui.btnEipStartStop.clicked.connect( self.eipconnection.qtsigs.do_disconnect_signal) + self.ui.eip_bandwidth.hide() + self.ui.lblEIPMessage.setText( + self.tr("Traffic is being routed in the clear")) + self.ui.lblEIPStatus.show() + def update_vpn_status(self, data): """ SLOT @@ -451,9 +359,10 @@ class StatusPanelWidget(QtGui.QWidget): status = data[VPNManager.STATUS_STEP_KEY] self.set_eip_status_icon(status) if status == "CONNECTED": + self.ui.eip_bandwidth.show() + self.ui.lblEIPStatus.hide() + # XXX should be handled by the state machine too. - self.set_eip_status(self.tr("ON")) - logger.debug("STATUS IS CONNECTED --- emitting signal") self.eip_connection_connected.emit() # XXX should lookup status map in EIPConnection @@ -472,7 +381,7 @@ class StatusPanelWidget(QtGui.QWidget): # the UI won't update properly QtCore.QTimer.singleShot( 0, self.eipconnection.qtsigs.do_disconnect_signal) - QtCore.QTimer.singleShot(0, partial(self.set_global_status, + QtCore.QTimer.singleShot(0, partial(self.set_eip_status, self.tr("Unable to start VPN, " "it's already " "running."))) @@ -497,14 +406,14 @@ class StatusPanelWidget(QtGui.QWidget): """ selected_pixmap = self.ERROR_ICON selected_pixmap_tray = self.ERROR_ICON_TRAY - tray_message = self.tr("Encrypted Internet is OFF") + tray_message = self.tr("Encrypted Internet: OFF") if status in ("WAIT", "AUTH", "GET_CONFIG", "RECONNECTING", "ASSIGN_IP"): selected_pixmap = self.CONNECTING_ICON selected_pixmap_tray = self.CONNECTING_ICON_TRAY - tray_message = self.tr("Encrypted Internet is STARTING") + tray_message = self.tr("Encrypted Internet: Starting...") elif status in ("CONNECTED"): - tray_message = self.tr("Encrypted Internet is ON") + tray_message = self.tr("Encrypted Internet: ON") selected_pixmap = self.CONNECTED_ICON selected_pixmap_tray = self.CONNECTED_ICON_TRAY @@ -513,198 +422,6 @@ class StatusPanelWidget(QtGui.QWidget): self._eip_status_menu.setTitle(tray_message) def set_provider(self, provider): - self.ui.lblProvider.setText(provider) - - # - # mail methods - # - - def _set_mail_status(self, status, ready=False): - """ - Sets the Mail status in the label and in the tray icon. - - :param status: the status text to display - :type status: unicode - :param ready: if mx is ready or not. - :type ready: bool - """ - self.ui.lblMailStatus.setText(status) - - self._mx_status = self.tr('OFF') - tray_status = self.tr('Mail is OFF') - - icon = QtGui.QPixmap(self.MAIL_OFF_ICON) - if ready: - icon = QtGui.QPixmap(self.MAIL_ON_ICON) - self._mx_status = self.tr('ON') - tray_status = self.tr('Mail is ON') - - self.ui.lblMailIcon.setPixmap(icon) - self._action_mail_status.setText(tray_status) - self._update_systray_tooltip() - - def _mail_handle_soledad_events(self, req): - """ - Callback for ... - - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest - """ - self._soledad_event.emit(req) - - def _mail_handle_soledad_events_slot(self, req): - """ - SLOT - TRIGGER: _mail_handle_soledad_events - - Reacts to an Soledad event - - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest - """ - self._set_mail_status(self.tr("Starting...")) - - ext_status = "" - - if req.event == proto.SOLEDAD_DONE_UPLOADING_KEYS: - ext_status = self.tr("Soledad has started...") - elif req.event == proto.SOLEDAD_DONE_DOWNLOADING_KEYS: - ext_status = self.tr("Soledad is starting, please wait...") - else: - leap_assert(False, - "Don't know how to handle this state: %s" - % (req.event)) - - self._set_long_mail_status(ext_status) - - def _mail_handle_keymanager_events(self, req): - """ - Callback for the KeyManager events - - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest - """ - self._keymanager_event.emit(req) - - def _mail_handle_keymanager_events_slot(self, req): - """ - SLOT - TRIGGER: _mail_handle_keymanager_events - - Reacts to an KeyManager event - - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest - """ - # We want to ignore this kind of events once everything has - # started - if self._smtp_started and self._imap_started: - return - - self._set_mail_status(self.tr("Starting...")) - - ext_status = "" - - if req.event == proto.KEYMANAGER_LOOKING_FOR_KEY: - ext_status = self.tr("Looking for key for this user") - elif req.event == proto.KEYMANAGER_KEY_FOUND: - ext_status = self.tr("Found key! Starting mail...") - # elif req.event == proto.KEYMANAGER_KEY_NOT_FOUND: - # ext_status = self.tr("Key not found!") - elif req.event == proto.KEYMANAGER_STARTED_KEY_GENERATION: - ext_status = self.tr("Generating new key, please wait...") - elif req.event == proto.KEYMANAGER_FINISHED_KEY_GENERATION: - ext_status = self.tr("Finished generating key!") - elif req.event == proto.KEYMANAGER_DONE_UPLOADING_KEYS: - ext_status = self.tr("Starting mail...") - else: - leap_assert(False, - "Don't know how to handle this state: %s" - % (req.event)) - - self._set_long_mail_status(ext_status) - - def _mail_handle_smtp_events(self, req): - """ - Callback for the SMTP events - - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest - """ - self._smtp_event.emit(req) - - def _mail_handle_smtp_events_slot(self, req): - """ - SLOT - TRIGGER: _mail_handle_smtp_events - - Reacts to an SMTP event - - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest - """ - ext_status = "" - - if req.event == proto.SMTP_SERVICE_STARTED: - ext_status = self.tr("SMTP has started...") - self._smtp_started = True - if self._smtp_started and self._imap_started: - self._set_mail_status(self.tr("ON"), ready=True) - ext_status = "" - elif req.event == proto.SMTP_SERVICE_FAILED_TO_START: - ext_status = self.tr("SMTP failed to start, check the logs.") - self._set_mail_status(self.tr("Failed")) - else: - leap_assert(False, - "Don't know how to handle this state: %s" - % (req.event)) - - self._set_long_mail_status(ext_status) - - def _mail_handle_imap_events(self, req): - """ - Callback for the IMAP events - - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest - """ - self._imap_event.emit(req) - - def _mail_handle_imap_events_slot(self, req): - """ - SLOT - TRIGGER: _mail_handle_imap_events - - Reacts to an IMAP event - - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest - """ - ext_status = None - - if req.event == proto.IMAP_SERVICE_STARTED: - ext_status = self.tr("IMAP has started...") - self._imap_started = True - if self._smtp_started and self._imap_started: - self._set_mail_status(self.tr("ON"), ready=True) - ext_status = "" - elif req.event == proto.IMAP_SERVICE_FAILED_TO_START: - ext_status = self.tr("IMAP failed to start, check the logs.") - self._set_mail_status(self.tr("Failed")) - elif req.event == proto.IMAP_UNREAD_MAIL: - if self._smtp_started and self._imap_started: - self.ui.lblUnread.setText( - self.tr("%s Unread Emails") % (req.content)) - self.ui.lblUnread.setVisible(req.content != "0") - self._set_mail_status(self.tr("ON"), ready=True) - else: - leap_assert(False, # XXX ??? - "Don't know how to handle this state: %s" - % (req.event)) - - if ext_status is not None: - self._set_long_mail_status(ext_status) - - def _set_long_mail_status(self, ext_status): - self.ui.lblLongMailStatus.setText(ext_status) - self.ui.grpMailStatus.setVisible(len(ext_status) > 0) + self._provider = provider + self.ui.lblEIPMessage.setText( + self.tr("Route traffic through: {0}").format(self._provider)) diff --git a/src/leap/bitmask/gui/login.py b/src/leap/bitmask/gui/login.py index db7b8e2a..9a369f6d 100644 --- a/src/leap/bitmask/gui/login.py +++ b/src/leap/bitmask/gui/login.py @@ -20,10 +20,13 @@ Login widget implementation """ import logging +import keyring + from PySide import QtCore, QtGui from ui_login import Ui_LoginWidget from leap.bitmask.util.keyring_helpers import has_keyring +from leap.common.check import leap_assert_type logger = logging.getLogger(__name__) @@ -37,6 +40,7 @@ class LoginWidget(QtGui.QWidget): # Emitted when the login button is clicked login = QtCore.Signal() cancel_login = QtCore.Signal() + logout = QtCore.Signal() # Emitted when the user selects "Other..." in the provider # combobox or click "Create Account" @@ -76,13 +80,21 @@ class LoginWidget(QtGui.QWidget): self.ui.cmbProviders.currentIndexChanged.connect( self._current_provider_changed) - self.ui.btnCreateAccount.clicked.connect( - self.show_wizard) + + self.ui.btnLogout.clicked.connect( + self.logout) username_re = QtCore.QRegExp(self.BARE_USERNAME_REGEX) self.ui.lnUser.setValidator( QtGui.QRegExpValidator(username_re, self)) + self.logged_out() + + self.ui.btnLogout.clicked.connect(self.start_logout) + + self.ui.clblErrorMsg.hide() + self.ui.clblErrorMsg.clicked.connect(self.ui.clblErrorMsg.hide) + def _remember_state_changed(self, state): """ Saves the remember state in the LeapSettings @@ -185,8 +197,10 @@ class LoginWidget(QtGui.QWidget): if len(status) > self.MAX_STATUS_WIDTH: status = status[:self.MAX_STATUS_WIDTH] + "..." if error: - status = "<font color='red'><b>%s</b></font>" % (status,) - self.ui.lblStatus.setText(status) + self.ui.clblErrorMsg.show() + self.ui.clblErrorMsg.setText(status) + else: + self.ui.lblStatus.setText(status) def set_enabled(self, enabled=False): """ @@ -211,6 +225,7 @@ class LoginWidget(QtGui.QWidget): """ text = self.tr("Cancel") login_or_cancel = self.cancel_login + hide_remember = enabled if not enabled: text = self.tr("Log In") @@ -220,6 +235,8 @@ class LoginWidget(QtGui.QWidget): self.ui.btnLogin.clicked.disconnect() self.ui.btnLogin.clicked.connect(login_or_cancel) + self.ui.chkRemember.setVisible(not hide_remember) + self.ui.lblStatus.setVisible(hide_remember) def _focus_password(self): """ @@ -243,3 +260,104 @@ class LoginWidget(QtGui.QWidget): self.ui.cmbProviders.blockSignals(False) else: self._selected_provider_index = param + + def start_login(self): + """ + Setups the login widgets for actually performing the login and + performs some basic checks. + + :returns: True if everything's good to go, False otherwise + :rtype: bool + """ + username = self.get_user() + password = self.get_password() + provider = self.get_selected_provider() + + self._enabled_services = self._settings.get_enabled_services( + self.get_selected_provider()) + + if len(provider) == 0: + self.set_status( + self.tr("Please select a valid provider")) + return False + + if len(username) == 0: + self.set_status( + self.tr("Please provide a valid username")) + return False + + if len(password) == 0: + self.set_status( + self.tr("Please provide a valid password")) + return False + + self.set_status(self.tr("Logging in..."), error=False) + self.set_enabled(False) + + if self.get_remember() and has_keyring(): + # in the keyring and in the settings + # we store the value 'usename@provider' + username_domain = (username + '@' + provider).encode("utf8") + try: + keyring.set_password(self.KEYRING_KEY, + username_domain, + password.encode("utf8")) + # Only save the username if it was saved correctly in + # the keyring + self._settings.set_user(username_domain) + except Exception as e: + logger.exception("Problem saving data to keyring. %r" + % (e,)) + return True + + def logged_in(self): + """ + Sets the widgets to the logged in state + """ + self.ui.login_widget.hide() + self.ui.logged_widget.show() + self.ui.lblUser.setText("%s@%s" % (self.get_user(), + self.get_selected_provider())) + self.set_login_status("") + + def logged_out(self): + """ + Sets the widgets to the logged out state + """ + self.ui.login_widget.show() + self.ui.logged_widget.hide() + + self.set_password("") + self.set_enabled(True) + self.set_status("") + + def set_login_status(self, msg, error=False): + """ + Sets the status label for the logged in state. + + :param msg: status message + :type msg: str or unicode + :param error: if the status is an erroneous one, then set this + to True + :type error: bool + """ + leap_assert_type(error, bool) + if error: + msg = "<font color='red'><b>%s</b></font>" % (msg,) + self.ui.lblLoginStatus.setText(msg) + self.ui.lblLoginStatus.show() + + def start_logout(self): + """ + Sets the widgets to the logging out state + """ + self.ui.btnLogout.setText(self.tr("Loggin out...")) + self.ui.btnLogout.setEnabled(False) + + def done_logout(self): + """ + Sets the widgets to the logged out state + """ + self.ui.btnLogout.setText(self.tr("Logout")) + self.ui.btnLogout.setEnabled(True) + self.ui.clblErrorMsg.hide() diff --git a/src/leap/bitmask/gui/mail_status.py b/src/leap/bitmask/gui/mail_status.py new file mode 100644 index 00000000..770d991f --- /dev/null +++ b/src/leap/bitmask/gui/mail_status.py @@ -0,0 +1,399 @@ +# -*- coding: utf-8 -*- +# mail_status.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +""" +Mail Status Panel widget implementation +""" +import logging + +from PySide import QtCore, QtGui + +from leap.bitmask.platform_init import IS_LINUX +from leap.common.check import leap_assert, leap_assert_type +from leap.common.events import register +from leap.common.events import events_pb2 as proto + +from ui_mail_status import Ui_MailStatusWidget + +logger = logging.getLogger(__name__) + + +class MailStatusWidget(QtGui.QWidget): + """ + Status widget that displays the state of the LEAP Mail service + """ + eip_connection_connected = QtCore.Signal() + _soledad_event = QtCore.Signal(object) + _smtp_event = QtCore.Signal(object) + _imap_event = QtCore.Signal(object) + _keymanager_event = QtCore.Signal(object) + + def __init__(self, parent=None): + """ + Constructor for MailStatusWidget + + :param parent: parent widget for this one. + :type parent: QtGui.QWidget + """ + QtGui.QWidget.__init__(self, parent) + + self._systray = None + + self.ui = Ui_MailStatusWidget() + self.ui.setupUi(self) + + # set systray tooltip status + self._mx_status = "" + + # Set the Mail status icons + self.CONNECTING_ICON = None + self.CONNECTED_ICON = None + self.ERROR_ICON = None + self.CONNECTING_ICON_TRAY = None + self.CONNECTED_ICON_TRAY = None + self.ERROR_ICON_TRAY = None + self._set_mail_icons() + + register(signal=proto.KEYMANAGER_LOOKING_FOR_KEY, + callback=self._mail_handle_keymanager_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.KEYMANAGER_KEY_FOUND, + callback=self._mail_handle_keymanager_events, + reqcbk=lambda req, resp: None) + + # register(signal=proto.KEYMANAGER_KEY_NOT_FOUND, + # callback=self._mail_handle_keymanager_events, + # reqcbk=lambda req, resp: None) + + register(signal=proto.KEYMANAGER_STARTED_KEY_GENERATION, + callback=self._mail_handle_keymanager_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.KEYMANAGER_FINISHED_KEY_GENERATION, + callback=self._mail_handle_keymanager_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.KEYMANAGER_DONE_UPLOADING_KEYS, + callback=self._mail_handle_keymanager_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.SOLEDAD_DONE_DOWNLOADING_KEYS, + callback=self._mail_handle_soledad_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.SOLEDAD_DONE_UPLOADING_KEYS, + callback=self._mail_handle_soledad_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.SMTP_SERVICE_STARTED, + callback=self._mail_handle_smtp_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.SMTP_SERVICE_FAILED_TO_START, + callback=self._mail_handle_smtp_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.IMAP_SERVICE_STARTED, + callback=self._mail_handle_imap_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.IMAP_SERVICE_FAILED_TO_START, + callback=self._mail_handle_imap_events, + reqcbk=lambda req, resp: None) + + register(signal=proto.IMAP_UNREAD_MAIL, + callback=self._mail_handle_imap_events, + reqcbk=lambda req, resp: None) + + self._smtp_started = False + self._imap_started = False + + self._soledad_event.connect( + self._mail_handle_soledad_events_slot) + self._imap_event.connect( + self._mail_handle_imap_events_slot) + self._smtp_event.connect( + self._mail_handle_smtp_events_slot) + self._keymanager_event.connect( + self._mail_handle_keymanager_events_slot) + + def _set_mail_icons(self): + """ + Sets the Mail status icons for the main window and for the tray + + MAC : dark icons + LINUX : dark icons in window, light icons in tray + WIN : light icons + """ + EIP_ICONS = EIP_ICONS_TRAY = ( + ":/images/black/32/wait.png", + ":/images/black/32/on.png", + ":/images/black/32/off.png") + + if IS_LINUX: + EIP_ICONS_TRAY = ( + ":/images/white/32/wait.png", + ":/images/white/32/on.png", + ":/images/white/32/off.png") + + self.CONNECTING_ICON = QtGui.QPixmap(EIP_ICONS[0]) + self.CONNECTED_ICON = QtGui.QPixmap(EIP_ICONS[1]) + self.ERROR_ICON = QtGui.QPixmap(EIP_ICONS[2]) + + self.CONNECTING_ICON_TRAY = QtGui.QPixmap(EIP_ICONS_TRAY[0]) + self.CONNECTED_ICON_TRAY = QtGui.QPixmap(EIP_ICONS_TRAY[1]) + self.ERROR_ICON_TRAY = QtGui.QPixmap(EIP_ICONS_TRAY[2]) + + # Systray and actions + + def set_systray(self, systray): + """ + Sets the systray object to use. + + :param systray: Systray object + :type systray: QtGui.QSystemTrayIcon + """ + leap_assert_type(systray, QtGui.QSystemTrayIcon) + self._systray = systray + self._systray.setToolTip(self.tr("All services are OFF")) + + def _update_systray_tooltip(self): + """ + Updates the system tray icon tooltip using the eip and mx status. + """ + # TODO: Figure out how to handle this with the two status in different + # classes + # status = self.tr("Encrypted Internet: {0}").format(self._eip_status) + # status += '\n' + # status += self.tr("Mail is {0}").format(self._mx_status) + # self._systray.setToolTip(status) + pass + + def set_action_mail_status(self, action_mail_status): + """ + Sets the action_mail_status to use. + + :param action_mail_status: action_mail_status to be used + :type action_mail_status: QtGui.QAction + """ + leap_assert_type(action_mail_status, QtGui.QAction) + self._action_mail_status = action_mail_status + + def _set_mail_status(self, status, ready=0): + """ + Sets the Mail status in the label and in the tray icon. + + :param status: the status text to display + :type status: unicode + :param ready: 2 or >2 if mx is ready, 0 if stopped, 1 if it's starting. + :type ready: int + """ + self.ui.lblMailStatus.setText(status) + + self._mx_status = self.tr('OFF') + tray_status = self.tr('Mail is OFF') + + icon = self.ERROR_ICON + if ready == 0: + self.ui.lblMailStatus.setText( + self.tr("You must be logged in to use encrypted email.")) + elif ready == 1: + icon = self.CONNECTING_ICON + self._mx_status = self.tr('Starting..') + tray_status = self.tr('Mail is starting') + elif ready >= 2: + icon = self.CONNECTED_ICON + self._mx_status = self.tr('ON') + tray_status = self.tr('Mail is ON') + + self.ui.lblMailStatusIcon.setPixmap(icon) + self._action_mail_status.setText(tray_status) + self._update_systray_tooltip() + + def _mail_handle_soledad_events(self, req): + """ + Callback for handling events that are emitted from Soledad + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + self._soledad_event.emit(req) + + def _mail_handle_soledad_events_slot(self, req): + """ + SLOT + TRIGGER: _mail_handle_soledad_events + + Reacts to an Soledad event + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + self._set_mail_status(self.tr("Starting..."), ready=1) + + ext_status = "" + + if req.event == proto.SOLEDAD_DONE_UPLOADING_KEYS: + ext_status = self.tr("Soledad has started...") + elif req.event == proto.SOLEDAD_DONE_DOWNLOADING_KEYS: + ext_status = self.tr("Soledad is starting, please wait...") + else: + leap_assert(False, + "Don't know how to handle this state: %s" + % (req.event)) + + self._set_mail_status(ext_status, ready=1) + + def _mail_handle_keymanager_events(self, req): + """ + Callback for the KeyManager events + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + self._keymanager_event.emit(req) + + def _mail_handle_keymanager_events_slot(self, req): + """ + SLOT + TRIGGER: _mail_handle_keymanager_events + + Reacts to an KeyManager event + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + # We want to ignore this kind of events once everything has + # started + if self._smtp_started and self._imap_started: + return + + self._set_mail_status(self.tr("Starting..."), ready=1) + + ext_status = "" + + if req.event == proto.KEYMANAGER_LOOKING_FOR_KEY: + ext_status = self.tr("Looking for key for this user") + elif req.event == proto.KEYMANAGER_KEY_FOUND: + ext_status = self.tr("Found key! Starting mail...") + # elif req.event == proto.KEYMANAGER_KEY_NOT_FOUND: + # ext_status = self.tr("Key not found!") + elif req.event == proto.KEYMANAGER_STARTED_KEY_GENERATION: + ext_status = self.tr("Generating new key, please wait...") + elif req.event == proto.KEYMANAGER_FINISHED_KEY_GENERATION: + ext_status = self.tr("Finished generating key!") + elif req.event == proto.KEYMANAGER_DONE_UPLOADING_KEYS: + ext_status = self.tr("Starting mail...") + else: + leap_assert(False, + "Don't know how to handle this state: %s" + % (req.event)) + + self._set_mail_status(ext_status, ready=1) + + def _mail_handle_smtp_events(self, req): + """ + Callback for the SMTP events + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + self._smtp_event.emit(req) + + def _mail_handle_smtp_events_slot(self, req): + """ + SLOT + TRIGGER: _mail_handle_smtp_events + + Reacts to an SMTP event + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + ext_status = "" + + if req.event == proto.SMTP_SERVICE_STARTED: + ext_status = self.tr("SMTP has started...") + self._smtp_started = True + if self._smtp_started and self._imap_started: + self._set_mail_status(self.tr("ON"), ready=2) + ext_status = "" + elif req.event == proto.SMTP_SERVICE_FAILED_TO_START: + ext_status = self.tr("SMTP failed to start, check the logs.") + self._set_mail_status(self.tr("Failed")) + else: + leap_assert(False, + "Don't know how to handle this state: %s" + % (req.event)) + + self._set_mail_status(ext_status, ready=2) + + def _mail_handle_imap_events(self, req): + """ + Callback for the IMAP events + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + self._imap_event.emit(req) + + def _mail_handle_imap_events_slot(self, req): + """ + SLOT + TRIGGER: _mail_handle_imap_events + + Reacts to an IMAP event + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + ext_status = None + + if req.event == proto.IMAP_SERVICE_STARTED: + ext_status = self.tr("IMAP has started...") + self._imap_started = True + if self._smtp_started and self._imap_started: + self._set_mail_status(self.tr("ON"), ready=2) + ext_status = "" + elif req.event == proto.IMAP_SERVICE_FAILED_TO_START: + ext_status = self.tr("IMAP failed to start, check the logs.") + self._set_mail_status(self.tr("Failed")) + elif req.event == proto.IMAP_UNREAD_MAIL: + if self._smtp_started and self._imap_started: + self._set_mail_status(self.tr("%s Unread Emails") % + (req.content), ready=2) + else: + leap_assert(False, # XXX ??? + "Don't know how to handle this state: %s" + % (req.event)) + + if ext_status is not None: + self._set_mail_status(ext_status, ready=1) + + def about_to_start(self): + """ + Displays the correct UI for the point where mail components + haven't really started, but they are about to in a second. + """ + self._set_mail_status(self.tr("About to start, please wait..."), + ready=1) + + def stopped_mail(self): + """ + Displayes the correct UI for the stopped state. + """ + self._set_mail_status(self.tr("OFF")) diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 92d6906e..58ed3eb3 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -32,8 +32,10 @@ from leap.bitmask.crypto.srpauth import SRPAuth from leap.bitmask.gui.loggerwindow import LoggerWindow from leap.bitmask.gui.login import LoginWidget from leap.bitmask.gui.preferenceswindow import PreferencesWindow +from leap.bitmask.gui.eip_preferenceswindow import EIPPreferencesWindow from leap.bitmask.gui import statemachines -from leap.bitmask.gui.statuspanel import StatusPanelWidget +from leap.bitmask.gui.eip_status import EIPStatusWidget +from leap.bitmask.gui.mail_status import MailStatusWidget from leap.bitmask.gui.wizard import Wizard from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper @@ -147,7 +149,7 @@ class MainWindow(QtGui.QMainWindow): self._login_widget = LoginWidget( self._settings, - self.ui.stackedWidget.widget(self.LOGIN_INDEX)) + self) self.ui.loginLayout.addWidget(self._login_widget) # Qt Signal Connections ##################################### @@ -155,17 +157,14 @@ 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.ui.btnShowLog.clicked.connect(self._show_logger_window) - self.ui.btnPreferences.clicked.connect(self._show_preferences) + self._login_widget.show_wizard.connect(self._launch_wizard) + self._login_widget.logout.connect(self._logout) - self._status_panel = StatusPanelWidget( - self.ui.stackedWidget.widget(self.EIP_STATUS_INDEX)) - self.ui.statusLayout.addWidget(self._status_panel) + self._eip_status = EIPStatusWidget(self) + self.ui.eipLayout.addWidget(self._eip_status) - self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) + self._mail_status = MailStatusWidget(self) + self.ui.mailLayout.addWidget(self._mail_status) self._eip_connection = EIPConnection() @@ -173,7 +172,7 @@ class MainWindow(QtGui.QMainWindow): self._start_eip) self._eip_connection.qtsigs.disconnecting_signal.connect( self._stop_eip) - self._status_panel.eip_connection_connected.connect( + self._eip_status.eip_connection_connected.connect( self._on_eip_connected) # This is loaded only once, there's a bug when doing that more @@ -221,9 +220,9 @@ class MainWindow(QtGui.QMainWindow): self._finish_eip_bootstrap) self._vpn = VPN(openvpn_verb=openvpn_verb) self._vpn.qtsigs.state_changed.connect( - self._status_panel.update_vpn_state) + self._eip_status.update_vpn_state) self._vpn.qtsigs.status_changed.connect( - self._status_panel.update_vpn_status) + self._eip_status.update_vpn_status) self._vpn.qtsigs.process_finished.connect( self._eip_finished) @@ -241,12 +240,16 @@ class MainWindow(QtGui.QMainWindow): self._smtp_bootstrapper.download_config.connect( self._smtp_bootstrapped_stage) - self.ui.action_log_out.setEnabled(False) - self.ui.action_log_out.triggered.connect(self._logout) self.ui.action_about_leap.triggered.connect(self._about) self.ui.action_quit.triggered.connect(self.quit) self.ui.action_wizard.triggered.connect(self._launch_wizard) self.ui.action_show_logs.triggered.connect(self._show_logger_window) + self.ui.action_create_new_account.triggered.connect( + self._launch_wizard) + + if IS_MAC: + self.ui.menuFile.menuAction().setText(self.tr("Util")) + self.raise_window.connect(self._do_raise_mainwindow) # Used to differentiate between real quits and close to tray @@ -256,17 +259,17 @@ class MainWindow(QtGui.QMainWindow): self._action_mail_status = QtGui.QAction(self.tr("Mail is OFF"), self) self._action_mail_status.setEnabled(False) - self._status_panel.set_action_mail_status(self._action_mail_status) + self._mail_status.set_action_mail_status(self._action_mail_status) self._action_eip_startstop = QtGui.QAction("", self) - self._status_panel.set_action_eip_startstop(self._action_eip_startstop) - - self._action_preferences = QtGui.QAction(self.tr("Preferences"), self) - self._action_preferences.triggered.connect(self._show_preferences) + 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.ui.btnPreferences.clicked.connect(self._show_preferences) + self.ui.btnEIPPreferences.clicked.connect(self._show_eip_preferences) + self._enabled_services = [] self._center_window() @@ -282,6 +285,7 @@ class MainWindow(QtGui.QMainWindow): self.mail_client_logged_in.connect(self._fetch_incoming_mail) self.logout.connect(self._stop_imap_service) self.logout.connect(self._stop_smtp_service) + self.logout.connect(self._mail_status.stopped_mail) ################################# end Qt Signals connection ######## @@ -393,7 +397,6 @@ class MainWindow(QtGui.QMainWindow): SLOT TRIGGERS: self.ui.action_show_logs.triggered - self.ui.btnShowLog.clicked Displays the window with the history of messages logged until now and displays the new ones on arrival. @@ -407,18 +410,13 @@ class MainWindow(QtGui.QMainWindow): self._logger_window = LoggerWindow(handler=leap_log_handler) self._logger_window.setVisible( not self._logger_window.isVisible()) - self.ui.btnShowLog.setChecked(self._logger_window.isVisible()) else: self._logger_window.setVisible(not self._logger_window.isVisible()) - self.ui.btnShowLog.setChecked(self._logger_window.isVisible()) - - self._logger_window.finished.connect(self._uncheck_logger_button) def _show_preferences(self): """ SLOT TRIGGERS: - self.ui.action_show_preferences.triggered self.ui.btnPreferences.clicked Displays the preferences window. @@ -433,22 +431,25 @@ class MainWindow(QtGui.QMainWindow): preferences_window.show() - def _set_soledad_ready(self): + def _show_eip_preferences(self): """ SLOT TRIGGERS: - self.soledad_ready + self.ui.btnEIPPreferences.clicked - It sets the soledad object as ready to use. + Displays the EIP preferences window. """ - self._soledad_ready = True + EIPPreferencesWindow(self).show() - def _uncheck_logger_button(self): + def _set_soledad_ready(self): """ SLOT - Sets the checked state of the loggerwindow button to false. + TRIGGERS: + self.soledad_ready + + It sets the soledad object as ready to use. """ - self.ui.btnShowLog.setChecked(False) + self._soledad_ready = True def _new_updates_available(self, req): """ @@ -623,24 +624,20 @@ class MainWindow(QtGui.QMainWindow): systrayMenu.addAction(self._action_visible) systrayMenu.addSeparator() - eip_menu = systrayMenu.addMenu(self.tr("Encrypted Internet is OFF")) + eip_menu = systrayMenu.addMenu(self.tr("Encrypted Internet: OFF")) eip_menu.addAction(self._action_eip_startstop) - self._status_panel.set_eip_status_menu(eip_menu) + self._eip_status.set_eip_status_menu(eip_menu) systrayMenu.addAction(self._action_mail_status) systrayMenu.addSeparator() - systrayMenu.addAction(self._action_preferences) - systrayMenu.addAction(help_action) - systrayMenu.addSeparator() - systrayMenu.addAction(self.ui.action_log_out) systrayMenu.addAction(self.ui.action_quit) self._systray = QtGui.QSystemTrayIcon(self) self._systray.setContextMenu(systrayMenu) - self._systray.setIcon(self._status_panel.ERROR_ICON_TRAY) + self._systray.setIcon(self._eip_status.ERROR_ICON_TRAY) self._systray.setVisible(True) self._systray.activated.connect(self._tray_activated) - self._status_panel.set_systray(self._systray) + self._eip_status.set_systray(self._systray) def _tray_activated(self, reason=None): """ @@ -846,47 +843,8 @@ class MainWindow(QtGui.QMainWindow): """ leap_assert(self._provider_config, "We need a provider config") - username = self._login_widget.get_user() - password = self._login_widget.get_password() - provider = self._login_widget.get_selected_provider() - - self._enabled_services = self._settings.get_enabled_services( - self._login_widget.get_selected_provider()) - - if len(provider) == 0: - self._login_widget.set_status( - self.tr("Please select a valid provider")) - return - - if len(username) == 0: - self._login_widget.set_status( - self.tr("Please provide a valid username")) - return - - if len(password) == 0: - self._login_widget.set_status( - self.tr("Please provide a valid Password")) - return - - self._login_widget.set_status(self.tr("Logging in..."), error=False) - self._login_widget.set_enabled(False) - - if self._login_widget.get_remember() and has_keyring(): - # in the keyring and in the settings - # we store the value 'usename@provider' - username_domain = (username + '@' + provider).encode("utf8") - try: - keyring.set_password(self.KEYRING_KEY, - username_domain, - password.encode("utf8")) - # Only save the username if it was saved correctly in - # the keyring - self._settings.set_user(username_domain) - except Exception as e: - logger.error("Problem saving data to keyring. %r" - % (e,)) - - self._download_provider_config() + if self._login_widget.start_login(): + self._download_provider_config() def _cancel_login(self): """ @@ -954,7 +912,6 @@ class MainWindow(QtGui.QMainWindow): if ok: self._logged_user = self._login_widget.get_user() - self.ui.action_log_out.setEnabled(True) # We leave a bit of room for the user to see the # "Succeeded" message and then we switch to the EIP status # panel @@ -969,15 +926,15 @@ class MainWindow(QtGui.QMainWindow): Changes the stackedWidget index to the EIP status one and triggers the eip bootstrapping """ - if not self._already_started_eip: - self._status_panel.set_provider( - "%s@%s" % (self._login_widget.get_user(), - self._get_best_provider_config().get_domain())) - self.ui.stackedWidget.setCurrentIndex(self.EIP_STATUS_INDEX) + self._login_widget.logged_in() # TODO separate UI from logic. # TODO soledad should check if we want to run only over EIP. + if self._provider_config.provides_mx() and \ + self._enabled_services.count(self.MX_SERVICE) > 0: + self._mail_status.about_to_start() + self._soledad_bootstrapper.run_soledad_setup_checks( self._provider_config, self._login_widget.get_user(), @@ -1199,9 +1156,9 @@ class MainWindow(QtGui.QMainWindow): """ Initializes and starts the EIP state machine """ - button = self._status_panel.eip_button + button = self._eip_status.eip_button action = self._action_eip_startstop - label = self._status_panel.eip_label + label = self._eip_status.eip_label builder = statemachines.ConnectionMachineBuilder(self._eip_connection) eip_machine = builder.make_machine(button=button, action=action, @@ -1214,7 +1171,7 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - self._status_panel.eip_connection_connected + self._eip_status.eip_connection_connected Emits the EIPConnection.qtsigs.connected_signal This is a little workaround for connecting the vpn-connected @@ -1229,7 +1186,7 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - self._status_panel.start_eip + self._eip_status.start_eip self._action_eip_startstop.triggered or called from _finish_eip_bootstrap @@ -1237,7 +1194,7 @@ class MainWindow(QtGui.QMainWindow): """ provider_config = self._get_best_provider_config() provider = provider_config.get_domain() - self._status_panel.eip_pre_up() + self._eip_status.eip_pre_up() self.user_stopped_eip = False try: @@ -1248,16 +1205,14 @@ class MainWindow(QtGui.QMainWindow): socket_host=host, socket_port=port) self._settings.set_defaultprovider(provider) - if self._logged_user is not None: - provider = "%s@%s" % (self._logged_user, provider) # XXX move to the state machine too - self._status_panel.set_provider(provider) + self._eip_status.set_provider(provider) # TODO refactor exceptions so they provide translatable # usef-facing messages. except EIPNoPolkitAuthAgentAvailable: - self._status_panel.set_global_status( + self._eip_status.set_eip_status( # XXX this should change to polkit-kde where # applicable. self.tr("We could not find any " @@ -1270,30 +1225,30 @@ class MainWindow(QtGui.QMainWindow): error=True) self._set_eipstatus_off() except EIPNoTunKextLoaded: - self._status_panel.set_global_status( + self._eip_status.set_eip_status( self.tr("Encrypted Internet cannot be started because " "the tuntap extension is not installed properly " "in your system.")) self._set_eipstatus_off() except EIPNoPkexecAvailable: - self._status_panel.set_global_status( + self._eip_status.set_eip_status( self.tr("We could not find <b>pkexec</b> " "in your system."), error=True) self._set_eipstatus_off() except OpenVPNNotFoundException: - self._status_panel.set_global_status( + self._eip_status.set_eip_status( self.tr("We could not find openvpn binary."), error=True) self._set_eipstatus_off() except OpenVPNAlreadyRunning as e: - self._status_panel.set_global_status( + self._eip_status.set_eip_status( self.tr("Another openvpn instance is already running, and " "could not be stopped."), error=True) self._set_eipstatus_off() except AlienOpenVPNAlreadyRunning as e: - self._status_panel.set_global_status( + self._eip_status.set_eip_status( self.tr("Another openvpn instance is already running, and " "could not be stopped because it was not launched by " "Bitmask. Please stop it and try again."), @@ -1302,7 +1257,7 @@ class MainWindow(QtGui.QMainWindow): except VPNLauncherException as e: # XXX We should implement again translatable exceptions so # we can pass a translatable string to the panel (usermessage attr) - self._status_panel.set_global_status("%s" % (e,), error=True) + self._eip_status.set_eip_status("%s" % (e,), error=True) self._set_eipstatus_off() else: self._already_started_eip = True @@ -1312,7 +1267,7 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - self._status_panel.stop_eip + self._eip_status.stop_eip self._action_eip_startstop.triggered or called from _eip_finished @@ -1328,23 +1283,25 @@ class MainWindow(QtGui.QMainWindow): self.user_stopped_eip = True self._vpn.terminate() - self._set_eipstatus_off() + self._set_eipstatus_off(False) self._already_started_eip = False # XXX do via signal self._settings.set_defaultprovider(None) if self._logged_user: - self._status_panel.set_provider( + self._eip_status.set_provider( "%s@%s" % (self._logged_user, self._get_best_provider_config().get_domain())) + self._eip_status.eip_stopped() - def _set_eipstatus_off(self): + def _set_eipstatus_off(self, error=True): """ Sets eip status to off """ - self._status_panel.set_eip_status(self.tr("OFF"), error=True) - self._status_panel.set_eip_status_icon("error") + self._eip_status.set_eip_status(self.tr("EIP has stopped"), + error=error) + self._eip_status.set_eip_status_icon("error") def _download_eip_config(self): """ @@ -1359,7 +1316,7 @@ class MainWindow(QtGui.QMainWindow): not self._already_started_eip: # XXX this should be handled by the state machine. - self._status_panel.set_eip_status( + self._eip_status.set_eip_status( self.tr("Starting...")) self._eip_bootstrapper.run_eip_setup_checks( provider_config, @@ -1367,11 +1324,11 @@ class MainWindow(QtGui.QMainWindow): self._already_started_eip = True elif not self._already_started_eip: if self._enabled_services.count(self.OPENVPN_SERVICE) > 0: - self._status_panel.set_eip_status( + self._eip_status.set_eip_status( self.tr("Not supported"), error=True) else: - self._status_panel.set_eip_status(self.tr("Disabled")) + self._eip_status.set_eip_status(self.tr("Disabled")) def _finish_eip_bootstrap(self, data): """ @@ -1386,7 +1343,7 @@ class MainWindow(QtGui.QMainWindow): if not passed: error_msg = self.tr("There was a problem with the provider") - self._status_panel.set_eip_status(error_msg, error=True) + self._eip_status.set_eip_status(error_msg, error=True) logger.error(data[self._eip_bootstrapper.ERROR_KEY]) self._already_started_eip = False return @@ -1406,7 +1363,7 @@ class MainWindow(QtGui.QMainWindow): # DO START EIP Connection! self._eip_connection.qtsigs.do_connect_signal.emit() else: - self._status_panel.set_eip_status( + self._eip_status.set_eip_status( self.tr("Could not load Encrypted Internet " "Configuration."), error=True) @@ -1441,7 +1398,7 @@ class MainWindow(QtGui.QMainWindow): def _logout(self): """ SLOT - TRIGGER: self.ui.action_log_out.triggered + TRIGGER: self._login_widget.logout Starts the logout sequence """ @@ -1461,16 +1418,17 @@ class MainWindow(QtGui.QMainWindow): Switches the stackedWidget back to the login stage after logging out """ + self._login_widget.done_logout() + if ok: self._logged_user = None - self.ui.action_log_out.setEnabled(False) - self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) - self._login_widget.set_password("") - self._login_widget.set_enabled(True) - self._login_widget.set_status("") + + self._login_widget.logged_out() + else: - status_text = self.tr("Something went wrong with the logout.") - self._status_panel.set_global_status(status_text, error=True) + self._login_widget.set_login_status( + self.tr("Something went wrong with the logout."), + error=True) def _intermediate_stage(self, data): """ @@ -1541,7 +1499,7 @@ class MainWindow(QtGui.QMainWindow): # XXX check if these exitCodes are pkexec/cocoasudo specific if exitCode in (126, 127): - self._status_panel.set_global_status( + self._eip_status.set_eip_status( self.tr("Encrypted Internet could not be launched " "because you did not authenticate properly."), error=True) @@ -1549,7 +1507,7 @@ class MainWindow(QtGui.QMainWindow): signal = qtsigs.connection_aborted_signal elif exitCode != 0 or not self.user_stopped_eip: - self._status_panel.set_global_status( + self._eip_status.set_eip_status( self.tr("Encrypted Internet finished in an " "unexpected manner!"), error=True) signal = qtsigs.connection_died_signal diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index 2d17f6c2..7e281b44 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -60,7 +60,6 @@ class PreferencesWindow(QtGui.QDialog): self.ui.setupUi(self) self.ui.lblPasswordChangeStatus.setVisible(False) self.ui.lblProvidersServicesStatus.setVisible(False) - self.ui.lblProvidersGatewayStatus.setVisible(False) self._selected_services = set() @@ -68,11 +67,6 @@ class PreferencesWindow(QtGui.QDialog): self.ui.pbChangePassword.clicked.connect(self._change_password) self.ui.cbProvidersServices.currentIndexChanged[unicode].connect( self._populate_services) - self.ui.cbProvidersGateway.currentIndexChanged[unicode].connect( - self._populate_gateways) - - self.ui.cbGateways.currentIndexChanged[unicode].connect( - lambda x: self.ui.lblProvidersGatewayStatus.setVisible(False)) if not self._settings.get_configured_providers(): self.ui.gbEnabledServices.setEnabled(False) @@ -217,37 +211,13 @@ class PreferencesWindow(QtGui.QDialog): self.ui.lblProvidersServicesStatus.setVisible(True) self.ui.lblProvidersServicesStatus.setText(status) - def _set_providers_gateway_status(self, status, success=False, - error=False): - """ - Sets the status label for the gateway change. - - :param status: status message to display, can be HTML - :type status: str - :param success: is set to True if we should display the - message as green - :type success: bool - :param error: is set to True if we should display the - message as red - :type error: bool - """ - if success: - status = "<font color='green'><b>%s</b></font>" % (status,) - elif error: - status = "<font color='red'><b>%s</b></font>" % (status,) - - self.ui.lblProvidersGatewayStatus.setVisible(True) - self.ui.lblProvidersGatewayStatus.setText(status) - def _add_configured_providers(self): """ Add the client's configured providers to the providers combo boxes. """ self.ui.cbProvidersServices.clear() - self.ui.cbProvidersGateway.clear() for provider in self._settings.get_configured_providers(): self.ui.cbProvidersServices.addItem(provider) - self.ui.cbProvidersGateway.addItem(provider) def _service_selection_changed(self, service, state): """ @@ -366,90 +336,3 @@ class PreferencesWindow(QtGui.QDialog): provider_config = None return provider_config - - def _save_selected_gateway(self, provider): - """ - SLOT - TRIGGERS: - self.ui.pbSaveGateway.clicked - - Saves the new gateway setting to the configuration file. - - :param provider: the provider config that we need to save. - :type provider: str - """ - gateway = self.ui.cbGateways.currentText() - - if gateway == self.AUTOMATIC_GATEWAY_LABEL: - gateway = self._settings.GATEWAY_AUTOMATIC - else: - idx = self.ui.cbGateways.currentIndex() - gateway = self.ui.cbGateways.itemData(idx) - - self._settings.set_selected_gateway(provider, gateway) - - msg = self.tr( - "Gateway settings for provider '{0}' saved.".format(provider)) - logger.debug(msg) - self._set_providers_gateway_status(msg, success=True) - - def _populate_gateways(self, domain): - """ - SLOT - TRIGGERS: - self.ui.cbProvidersGateway.currentIndexChanged[unicode] - - Loads the gateways that the provider provides into the UI for - the user to select. - - :param domain: the domain of the provider to load gateways from. - :type domain: str - """ - # We hide the maybe-visible status label after a change - self.ui.lblProvidersGatewayStatus.setVisible(False) - - if not domain: - return - - try: - # disconnect prevoiusly connected save method - self.ui.pbSaveGateway.clicked.disconnect() - except RuntimeError: - pass # Signal was not connected - - # set the proper connection for the 'save' button - save_gateway = partial(self._save_selected_gateway, domain) - self.ui.pbSaveGateway.clicked.connect(save_gateway) - - eip_config = EIPConfig() - provider_config = self._get_provider_config(domain) - - eip_config_path = os.path.join("leap", "providers", - domain, "eip-service.json") - api_version = provider_config.get_api_version() - eip_config.set_api_version(api_version) - eip_loaded = eip_config.load(eip_config_path) - - if not eip_loaded or provider_config is None: - self._set_providers_gateway_status( - self.tr("There was a problem with configuration files."), - error=True) - return - - gateways = VPNGatewaySelector(eip_config).get_gateways_list() - logger.debug(gateways) - - self.ui.cbGateways.clear() - self.ui.cbGateways.addItem(self.AUTOMATIC_GATEWAY_LABEL) - - # Add the available gateways and - # select the one stored in configuration file. - selected_gateway = self._settings.get_selected_gateway(domain) - index = 0 - for idx, (gw_name, gw_ip) in enumerate(gateways): - gateway = "{0} ({1})".format(gw_name, gw_ip) - self.ui.cbGateways.addItem(gateway, gw_ip) - if gw_ip == selected_gateway: - index = idx + 1 - - self.ui.cbGateways.setCurrentIndex(index) diff --git a/src/leap/bitmask/gui/ui/eip_status.ui b/src/leap/bitmask/gui/ui/eip_status.ui new file mode 100644 index 00000000..27df3f31 --- /dev/null +++ b/src/leap/bitmask/gui/ui/eip_status.ui @@ -0,0 +1,287 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>EIPStatus</class> + <widget class="QWidget" name="EIPStatus"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>470</width> + <height>157</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="bottomMargin"> + <number>24</number> + </property> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="2"> + <widget class="QPushButton" name="btnEipStartStop"> + <property name="text"> + <string>Turn On</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../../../data/resources/mainwindow.qrc">:/images/black/32/earth.png</pixmap> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="lblEIPStatus"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>32</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">color: rgb(80, 80, 80);</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="lblEIPMessage"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <pointsize>14</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Traffic is being routed in the clear</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="lblVPNStatusIcon"> + <property name="maximumSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../../../data/resources/mainwindow.qrc">:/images/black/32/off.png</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="1"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1" colspan="3"> + <widget class="QWidget" name="eip_bandwidth" native="true"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>32</height> + </size> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="eip_bandwidth_layout"> + <property name="spacing"> + <number>4</number> + </property> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../../../data/resources/icons.qrc">:/images/light/16/down-arrow.png</pixmap> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnDownload"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + <property name="font"> + <font> + <pointsize>11</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>PointingHandCursor</cursorShape> + </property> + <property name="text"> + <string>0.0 KB/s</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../../../data/resources/icons.qrc">:/images/light/16/up-arrow.png</pixmap> + </property> + </widget> + </item> + <item alignment="Qt::AlignLeft"> + <widget class="QPushButton" name="btnUpload"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + <property name="font"> + <font> + <pointsize>11</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>PointingHandCursor</cursorShape> + </property> + <property name="text"> + <string>0.0 KB/s</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../../../../../data/resources/mainwindow.qrc"/> + <include location="../../../../../data/resources/icons.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/leap/bitmask/gui/ui/eippreferences.ui b/src/leap/bitmask/gui/ui/eippreferences.ui new file mode 100644 index 00000000..e9bc203d --- /dev/null +++ b/src/leap/bitmask/gui/ui/eippreferences.ui @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>EIPPreferences</class> + <widget class="QDialog" name="EIPPreferences"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>170</height> + </rect> + </property> + <property name="windowTitle"> + <string>EIP Preferences</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../../../data/resources/mainwindow.qrc"> + <normaloff>:/images/mask-icon.png</normaloff>:/images/mask-icon.png</iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="gbGatewaySelector"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Select gateway for provider</string> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1" colspan="2"> + <widget class="QComboBox" name="cbProvidersGateway"> + <item> + <property name="text"> + <string><Select provider></string> + </property> + </item> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="lblSelectProvider"> + <property name="text"> + <string>&Select provider:</string> + </property> + <property name="buddy"> + <cstring>cbProvidersGateway</cstring> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Select gateway:</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QComboBox" name="cbGateways"> + <item> + <property name="text"> + <string>Automatic</string> + </property> + </item> + </widget> + </item> + <item row="5" column="2"> + <widget class="QPushButton" name="pbSaveGateway"> + <property name="text"> + <string>Save this provider settings</string> + </property> + </widget> + </item> + <item row="2" column="0" colspan="3"> + <widget class="QLabel" name="lblProvidersGatewayStatus"> + <property name="text"> + <string>< Providers Gateway Status ></string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../../../../data/resources/mainwindow.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/leap/bitmask/gui/ui/login.ui b/src/leap/bitmask/gui/ui/login.ui index 42a6897a..a1842608 100644 --- a/src/leap/bitmask/gui/ui/login.ui +++ b/src/leap/bitmask/gui/ui/login.ui @@ -6,127 +6,273 @@ <rect> <x>0</x> <y>0</y> - <width>356</width> - <height>223</height> + <width>468</width> + <height>350</height> </rect> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> <property name="windowTitle"> <string>Form</string> </property> + <property name="styleSheet"> + <string notr="true"/> + </property> <layout class="QGridLayout" name="gridLayout"> - <item row="5" column="2"> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> + <property name="margin"> + <number>0</number> + </property> + <item row="2" column="2" colspan="2"> + <widget class="QWidget" name="logged_widget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - <property name="sizeHint" stdset="0"> + <property name="minimumSize"> <size> - <width>40</width> - <height>20</height> + <width>0</width> + <height>0</height> </size> </property> - </spacer> - </item> - <item row="1" column="1" colspan="2"> - <widget class="QComboBox" name="cmbProviders"/> + <layout class="QGridLayout" name="gridLayout_5"> + <property name="bottomMargin"> + <number>24</number> + </property> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="lblUser"> + <property name="font"> + <font> + <pointsize>15</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QPushButton" name="btnLogout"> + <property name="text"> + <string>Logout</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <spacer name="horizontalSpacer"> + <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 row="2" column="0" colspan="2"> + <widget class="QLabel" name="lblLoginStatus"> + <property name="styleSheet"> + <string notr="true">color: rgb(132, 132, 132); +font: 75 12pt "Lucida Grande";</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> </item> - <item row="5" column="0"> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> + <item row="1" column="1" rowspan="2"> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - <property name="sizeHint" stdset="0"> + <property name="maximumSize"> <size> - <width>40</width> - <height>20</height> + <width>16777215</width> + <height>800</height> </size> </property> - </spacer> - </item> - <item row="6" column="1"> - <widget class="QPushButton" name="btnCreateAccount"> <property name="text"> - <string>Create a new account</string> + <string/> </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string><b>Provider:</b></string> + <property name="pixmap"> + <pixmap resource="../../../../../data/resources/mainwindow.qrc">:/images/black/32/user.png</pixmap> </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <property name="scaledContents"> + <bool>false</bool> </property> - </widget> - </item> - <item row="3" column="1" colspan="2"> - <widget class="QLineEdit" name="lnPassword"> - <property name="inputMask"> - <string/> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> - </widget> - </item> - <item row="2" column="1" colspan="2"> - <widget class="QLineEdit" name="lnUser"/> - </item> - <item row="4" column="1" colspan="2"> - <widget class="QCheckBox" name="chkRemember"> - <property name="text"> - <string>Remember username and password</string> + <property name="margin"> + <number>0</number> </property> </widget> </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string><b>Username:</b></string> + <item row="1" column="2" colspan="2"> + <widget class="QWidget" name="login_widget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> </property> + <layout class="QGridLayout" name="gridLayout_4"> + <property name="rightMargin"> + <number>24</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string><b>Provider:</b></string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QPushButton" name="btnLogin"> + <property name="text"> + <string>Log In</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QCheckBox" name="chkRemember"> + <property name="text"> + <string>Remember username and password</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lblStatus"> + <property name="text"> + <string/> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="cmbProviders"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string><b>Username:</b></string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="lnUser"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string><b>Password:</b></string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="lnPassword"> + <property name="inputMask"> + <string/> + </property> + </widget> + </item> + </layout> </widget> </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string><b>Password:</b></string> + <item row="1" column="0"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QPushButton" name="btnLogin"> - <property name="text"> - <string>Log In</string> + <property name="sizeHint" stdset="0"> + <size> + <width>12</width> + <height>0</height> + </size> </property> - </widget> + </spacer> </item> - <item row="0" column="0" colspan="3"> - <widget class="QLabel" name="lblStatus"> + <item row="0" column="0" colspan="4"> + <widget class="ClickableLabel" name="clblErrorMsg"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>50</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">background-color: rgb(255, 127, 114);</string> + </property> <property name="text"> <string/> </property> <property name="alignment"> <set>Qt::AlignCenter</set> </property> - <property name="wordWrap"> - <bool>true</bool> - </property> </widget> </item> </layout> </widget> + <customwidgets> + <customwidget> + <class>ClickableLabel</class> + <extends>QLabel</extends> + <header>clickablelabel.h</header> + </customwidget> + </customwidgets> <tabstops> - <tabstop>cmbProviders</tabstop> - <tabstop>lnUser</tabstop> - <tabstop>lnPassword</tabstop> <tabstop>chkRemember</tabstop> - <tabstop>btnLogin</tabstop> - <tabstop>btnCreateAccount</tabstop> </tabstops> - <resources/> + <resources> + <include location="../../../../../data/resources/mainwindow.qrc"/> + </resources> <connections/> </ui> diff --git a/src/leap/bitmask/gui/ui/mail_status.ui b/src/leap/bitmask/gui/ui/mail_status.ui new file mode 100644 index 00000000..1327f9e7 --- /dev/null +++ b/src/leap/bitmask/gui/ui/mail_status.ui @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MailStatusWidget</class> + <widget class="QWidget" name="MailStatusWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>72</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1" rowspan="2"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="1" column="0" colspan="3"> + <widget class="QLabel" name="lblMailStatus"> + <property name="styleSheet"> + <string notr="true">color: rgb(80, 80, 80);</string> + </property> + <property name="text"> + <string>You must login to use encrypted email.</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Email</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <spacer name="horizontalSpacer_4"> + <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 row="0" column="3"> + <widget class="QLabel" name="lblMailStatusIcon"> + <property name="maximumSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../../../data/resources/mainwindow.qrc">:/images/black/32/off.png</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../../../data/resources/mainwindow.qrc">:/images/black/32/email.png</pixmap> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../../../../data/resources/mainwindow.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/leap/bitmask/gui/ui/mainwindow.ui b/src/leap/bitmask/gui/ui/mainwindow.ui index 17837642..920160b8 100644 --- a/src/leap/bitmask/gui/ui/mainwindow.ui +++ b/src/leap/bitmask/gui/ui/mainwindow.ui @@ -6,10 +6,28 @@ <rect> <x>0</x> <y>0</y> - <width>429</width> - <height>579</height> + <width>524</width> + <height>722</height> </rect> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>524</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>524</width> + <height>16777215</height> + </size> + </property> <property name="windowTitle"> <string>Bitmask</string> </property> @@ -28,9 +46,222 @@ </property> <widget class="QWidget" name="centralwidget"> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0" colspan="5"> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="1" column="0" colspan="2"> + <widget class="QScrollArea" name="scrollArea"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>524</width> + <height>635</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QWidget" name="widget_2" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <property name="leftMargin"> + <number>24</number> + </property> + <property name="rightMargin"> + <number>24</number> + </property> + <item> + <widget class="QLabel" name="label_2"> + <property name="font"> + <font> + <pointsize>16</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Encrypted Internet</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnEIPPreferences"> + <property name="maximumSize"> + <size> + <width>48</width> + <height>20</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../../../../../data/resources/mainwindow.qrc"> + <normaloff>:/images/black/32/gear.png</normaloff>:/images/black/32/gear.png</iconset> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="eipLayout"> + <property name="leftMargin"> + <number>12</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>12</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + </layout> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QWidget" name="widget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="leftMargin"> + <number>24</number> + </property> + <property name="rightMargin"> + <number>24</number> + </property> + <item> + <widget class="QLabel" name="lblLoginProvider"> + <property name="font"> + <font> + <pointsize>16</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Login</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnPreferences"> + <property name="maximumSize"> + <size> + <width>48</width> + <height>20</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../../../../../data/resources/mainwindow.qrc"> + <normaloff>:/images/black/32/gear.png</normaloff>:/images/black/32/gear.png</iconset> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="loginLayout"/> + </item> + <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="mailLayout"> + <property name="margin"> + <number>12</number> + </property> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item row="0" column="0" colspan="2"> <layout class="QGridLayout" name="gridLayout_4"> - <item row="2" column="0"> + <item row="1" column="1"> + <widget class="QLabel" name="lblNewUpdates"> + <property name="text"> + <string>There are new updates available, please restart.</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="0"> <spacer name="horizontalSpacer_8"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -43,7 +274,7 @@ </property> </spacer> </item> - <item row="1" column="1"> + <item row="0" column="1"> <spacer name="horizontalSpacer_7"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -56,17 +287,7 @@ </property> </spacer> </item> - <item row="2" column="1"> - <widget class="QLabel" name="lblNewUpdates"> - <property name="text"> - <string>There are new updates available, please restart.</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="2" column="2"> + <item row="1" column="2"> <widget class="QPushButton" name="btnMore"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> @@ -82,7 +303,7 @@ </property> </widget> </item> - <item row="2" column="3"> + <item row="1" column="3"> <spacer name="horizontalSpacer_9"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -97,164 +318,6 @@ </item> </layout> </item> - <item row="6" column="2"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="10" column="0" colspan="5"> - <widget class="QStackedWidget" name="stackedWidget"> - <property name="currentIndex"> - <number>1</number> - </property> - <widget class="QWidget" name="loginPage"> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="1"> - <layout class="QHBoxLayout" name="loginLayout"/> - </item> - <item row="0" column="2"> - <spacer name="horizontalSpacer_4"> - <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 row="0" column="0"> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <widget class="QWidget" name="page_2"> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="statusLayout"/> - </item> - </layout> - </widget> - </widget> - </item> - <item row="7" column="2"> - <widget class="QLabel" name="label"> - <property name="autoFillBackground"> - <bool>false</bool> - </property> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../../../data/resources/mainwindow.qrc">:/images/mask-launcher.png</pixmap> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="7" column="3" colspan="2"> - <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 row="17" column="2"> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="7" column="0" colspan="2"> - <spacer name="horizontalSpacer"> - <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 row="18" column="2"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="btnPreferences"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Preferences</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_10"> - <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="btnShowLog"> - <property name="text"> - <string>Show Log</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> </layout> </widget> <widget class="QMenuBar" name="menubar"> @@ -262,15 +325,15 @@ <rect> <x>0</x> <y>0</y> - <width>429</width> - <height>21</height> + <width>524</width> + <height>22</height> </rect> </property> - <widget class="QMenu" name="menuSession"> + <widget class="QMenu" name="menuFile"> <property name="title"> - <string>&Session</string> + <string>&Bitmask</string> </property> - <addaction name="action_log_out"/> + <addaction name="action_create_new_account"/> <addaction name="separator"/> <addaction name="action_quit"/> </widget> @@ -279,16 +342,17 @@ <string>Help</string> </property> <addaction name="action_help"/> + <addaction name="action_show_logs"/> <addaction name="separator"/> <addaction name="action_about_leap"/> </widget> - <addaction name="menuSession"/> + <addaction name="menuFile"/> <addaction name="menuHelp"/> </widget> <widget class="QStatusBar" name="statusbar"/> - <action name="action_log_out"> + <action name="action_preferences"> <property name="text"> - <string>Log &out</string> + <string>Preferences...</string> </property> </action> <action name="action_quit"> @@ -313,7 +377,12 @@ </action> <action name="action_show_logs"> <property name="text"> - <string>Show &logs</string> + <string>Show &Log</string> + </property> + </action> + <action name="action_create_new_account"> + <property name="text"> + <string>Create a new account...</string> </property> </action> </widget> diff --git a/src/leap/bitmask/gui/ui/preferences.ui b/src/leap/bitmask/gui/ui/preferences.ui index e66a2d68..e187c016 100644 --- a/src/leap/bitmask/gui/ui/preferences.ui +++ b/src/leap/bitmask/gui/ui/preferences.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>503</width> - <height>529</height> + <height>401</height> </rect> </property> <property name="windowTitle"> @@ -18,7 +18,7 @@ <normaloff>:/images/mask-icon.png</normaloff>:/images/mask-icon.png</iconset> </property> <layout class="QGridLayout" name="gridLayout_3"> - <item row="5" column="0"> + <item row="4" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -31,64 +31,80 @@ </property> </spacer> </item> - <item row="1" column="0"> - <widget class="QGroupBox" name="gbGatewaySelector"> + <item row="0" column="0"> + <widget class="QGroupBox" name="gbPasswordChange"> <property name="enabled"> - <bool>true</bool> + <bool>false</bool> </property> <property name="title"> - <string>Select gateway for provider</string> - </property> - <property name="checkable"> - <bool>false</bool> + <string>Password Change</string> </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="1" colspan="2"> - <widget class="QComboBox" name="cbProvidersGateway"> - <item> - <property name="text"> - <string><Select provider></string> - </property> - </item> - </widget> - </item> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> <item row="0" column="0"> - <widget class="QLabel" name="lblSelectProvider"> + <widget class="QLabel" name="lblCurrentPassword"> <property name="text"> - <string>&Select provider:</string> + <string>&Current password:</string> </property> <property name="buddy"> - <cstring>cbProvidersGateway</cstring> + <cstring>leCurrentPassword</cstring> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="leCurrentPassword"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> </property> </widget> </item> <item row="1" column="0"> - <widget class="QLabel" name="label"> + <widget class="QLabel" name="lblNewPassword"> <property name="text"> - <string>Select gateway:</string> + <string>&New password:</string> + </property> + <property name="buddy"> + <cstring>leNewPassword</cstring> </property> </widget> </item> - <item row="1" column="1" colspan="2"> - <widget class="QComboBox" name="cbGateways"> - <item> - <property name="text"> - <string>Automatic</string> - </property> - </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="leNewPassword"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> </widget> </item> - <item row="5" column="2"> - <widget class="QPushButton" name="pbSaveGateway"> + <item row="2" column="0"> + <widget class="QLabel" name="lblNewPassword2"> <property name="text"> - <string>Save this provider settings</string> + <string>&Re-enter new password:</string> + </property> + <property name="buddy"> + <cstring>leNewPassword2</cstring> </property> </widget> </item> - <item row="2" column="0" colspan="3"> - <widget class="QLabel" name="lblProvidersGatewayStatus"> + <item row="2" column="1"> + <widget class="QLineEdit" name="leNewPassword2"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QPushButton" name="pbChangePassword"> <property name="text"> - <string>< Providers Gateway Status ></string> + <string>Change</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QLabel" name="lblPasswordChangeStatus"> + <property name="text"> + <string><Password change status></string> </property> <property name="alignment"> <set>Qt::AlignCenter</set> @@ -98,7 +114,7 @@ </layout> </widget> </item> - <item row="4" column="0"> + <item row="3" column="0"> <widget class="QGroupBox" name="gbEnabledServices"> <property name="title"> <string>Enabled services</string> @@ -155,89 +171,6 @@ </layout> </widget> </item> - <item row="0" column="0"> - <widget class="QGroupBox" name="gbPasswordChange"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="title"> - <string>Password Change</string> - </property> - <layout class="QFormLayout" name="formLayout"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="lblCurrentPassword"> - <property name="text"> - <string>&Current password:</string> - </property> - <property name="buddy"> - <cstring>leCurrentPassword</cstring> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="leCurrentPassword"> - <property name="echoMode"> - <enum>QLineEdit::Password</enum> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="lblNewPassword"> - <property name="text"> - <string>&New password:</string> - </property> - <property name="buddy"> - <cstring>leNewPassword</cstring> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="leNewPassword"> - <property name="echoMode"> - <enum>QLineEdit::Password</enum> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="lblNewPassword2"> - <property name="text"> - <string>&Re-enter new password:</string> - </property> - <property name="buddy"> - <cstring>leNewPassword2</cstring> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="leNewPassword2"> - <property name="echoMode"> - <enum>QLineEdit::Password</enum> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QPushButton" name="pbChangePassword"> - <property name="text"> - <string>Change</string> - </property> - </widget> - </item> - <item row="3" column="0" colspan="2"> - <widget class="QLabel" name="lblPasswordChangeStatus"> - <property name="text"> - <string><Password change status></string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - </layout> - </widget> - </item> </layout> </widget> <resources> diff --git a/src/leap/bitmask/gui/ui/statuspanel.ui b/src/leap/bitmask/gui/ui/statuspanel.ui deleted file mode 100644 index d77af1da..00000000 --- a/src/leap/bitmask/gui/ui/statuspanel.ui +++ /dev/null @@ -1,393 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>StatusPanel</class> - <widget class="QWidget" name="StatusPanel"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>470</width> - <height>477</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="lblProvider"> - <property name="styleSheet"> - <string notr="true">font: bold;</string> - </property> - <property name="text"> - <string>user@domain.org</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QWidget" name="status_rows" native="true"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="styleSheet"> - <string notr="true"/> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="5" column="1"> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="1" column="0" colspan="3"> - <widget class="QLabel" name="lblUnread"> - <property name="text"> - <string>0 Unread Emails</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="lblMailStatus"> - <property name="styleSheet"> - <string notr="true">font: bold;</string> - </property> - <property name="text"> - <string>Disabled</string> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="label_4"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Encrypted Mail:</string> - </property> - </widget> - </item> - <item row="0" column="2"> - <spacer name="horizontalSpacer_4"> - <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 row="2" column="0" colspan="3"> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>1</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="1" column="1"> - <layout class="QHBoxLayout" name="eip_bandwidth"> - <property name="spacing"> - <number>4</number> - </property> - <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> - </property> - <item> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../../../data/resources/icons.qrc">:/images/light/16/down-arrow.png</pixmap> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="btnDownload"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>120</width> - <height>16777215</height> - </size> - </property> - <property name="cursor"> - <cursorShape>PointingHandCursor</cursorShape> - </property> - <property name="text"> - <string>0.0 KB/s</string> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../../../data/resources/icons.qrc">:/images/light/16/up-arrow.png</pixmap> - </property> - </widget> - </item> - <item alignment="Qt::AlignLeft"> - <widget class="QPushButton" name="btnUpload"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>120</width> - <height>16777215</height> - </size> - </property> - <property name="cursor"> - <cursorShape>PointingHandCursor</cursorShape> - </property> - <property name="text"> - <string>0.0 KB/s</string> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - <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> - </layout> - </item> - <item row="2" column="0"> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>0</width> - <height>11</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="0" rowspan="2"> - <widget class="QLabel" name="lblVPNStatusIcon"> - <property name="maximumSize"> - <size> - <width>64</width> - <height>64</height> - </size> - </property> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../../../data/resources/icons.qrc">:/images/light/64/network-eip-down.png</pixmap> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="4" column="0" rowspan="2"> - <widget class="QLabel" name="lblMailIcon"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>64</width> - <height>64</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>64</width> - <height>999</height> - </size> - </property> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../../../data/resources/icons.qrc">:/images/mail-unlocked.png</pixmap> - </property> - </widget> - </item> - <item row="7" column="0" colspan="2"> - <widget class="QGroupBox" name="grpMailStatus"> - <property name="title"> - <string/> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QLabel" name="lblLongMailStatus"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="3" column="0" colspan="2"> - <widget class="QGroupBox" name="globalStatusBox"> - <property name="enabled"> - <bool>false</bool> - </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0"> - <widget class="QLabel" name="lblGlobalStatus"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="0" column="1"> - <layout class="QHBoxLayout" name="eip_controls"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Encrypted Internet: </string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="lblEIPStatus"> - <property name="styleSheet"> - <string notr="true">font: bold;</string> - </property> - <property name="text"> - <string>Off</string> - </property> - <property name="textFormat"> - <enum>Qt::AutoText</enum> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <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="btnEipStartStop"> - <property name="text"> - <string>Turn On</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <resources> - <include location="../../../../../data/resources/icons.qrc"/> - </resources> - <connections/> -</ui> |