summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Alejandro <ivanalejandro0@gmail.com>2013-10-01 12:36:28 -0300
committerIvan Alejandro <ivanalejandro0@gmail.com>2013-10-01 12:36:28 -0300
commit0fa4712d10936329aa5012b3173bdd0fc0362e9f (patch)
treeae8e41e17dcb31ea8162c733eb298e9d956314c3
parent95b69d0d2e9801e4db1fe3758b62ab9539ecf882 (diff)
parentfa3dcc727f3690439c57981ffa639453b395a618 (diff)
Merge remote-tracking branch 'chiiph/feature/new_ui' into develop
-rw-r--r--Makefile2
-rw-r--r--changes/feature_new_ui1
-rw-r--r--data/bitmask.pro10
-rw-r--r--data/images/black/32/arrow-down.pngbin0 -> 493 bytes
-rw-r--r--data/images/black/32/arrow-up.pngbin0 -> 468 bytes
-rw-r--r--data/images/black/32/cloud.pngbin0 -> 468 bytes
-rw-r--r--data/images/black/32/contract.pngbin0 -> 417 bytes
-rw-r--r--data/images/black/32/earth-square.pngbin0 -> 1068 bytes
-rw-r--r--data/images/black/32/earth.pngbin0 -> 1145 bytes
-rw-r--r--data/images/black/32/email-square.pngbin0 -> 787 bytes
-rw-r--r--data/images/black/32/email.pngbin0 -> 754 bytes
-rw-r--r--data/images/black/32/expand.pngbin0 -> 451 bytes
-rw-r--r--data/images/black/32/gear.pngbin0 -> 644 bytes
-rw-r--r--data/images/black/32/off.pngbin0 -> 695 bytes
-rw-r--r--data/images/black/32/on.pngbin0 -> 667 bytes
-rw-r--r--data/images/black/32/refresh.pngbin0 -> 624 bytes
-rw-r--r--data/images/black/32/user.pngbin0 -> 534 bytes
-rw-r--r--data/images/black/32/wait.pngbin0 -> 836 bytes
-rw-r--r--data/images/white/32/arrow-down.pngbin0 -> 486 bytes
-rw-r--r--data/images/white/32/arrow-up.pngbin0 -> 463 bytes
-rw-r--r--data/images/white/32/cloud.pngbin0 -> 504 bytes
-rw-r--r--data/images/white/32/contract.pngbin0 -> 417 bytes
-rw-r--r--data/images/white/32/earth-square.pngbin0 -> 1068 bytes
-rw-r--r--data/images/white/32/earth.pngbin0 -> 896 bytes
-rw-r--r--data/images/white/32/email-square.pngbin0 -> 787 bytes
-rw-r--r--data/images/white/32/email.pngbin0 -> 622 bytes
-rw-r--r--data/images/white/32/expand.pngbin0 -> 451 bytes
-rw-r--r--data/images/white/32/gear.pngbin0 -> 656 bytes
-rw-r--r--data/images/white/32/off.pngbin0 -> 703 bytes
-rw-r--r--data/images/white/32/on.pngbin0 -> 677 bytes
-rw-r--r--data/images/white/32/refresh.pngbin0 -> 654 bytes
-rw-r--r--data/images/white/32/user.pngbin0 -> 556 bytes
-rw-r--r--data/images/white/32/wait.pngbin0 -> 855 bytes
-rw-r--r--data/resources/mainwindow.qrc18
-rw-r--r--src/leap/bitmask/config/providerconfig.py19
-rw-r--r--src/leap/bitmask/gui/clickablelabel.py28
-rw-r--r--src/leap/bitmask/gui/eip_preferenceswindow.py177
-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.py126
-rw-r--r--src/leap/bitmask/gui/mail_status.py399
-rw-r--r--src/leap/bitmask/gui/mainwindow.py208
-rw-r--r--src/leap/bitmask/gui/preferenceswindow.py117
-rw-r--r--src/leap/bitmask/gui/ui/eip_status.ui287
-rw-r--r--src/leap/bitmask/gui/ui/eippreferences.ui94
-rw-r--r--src/leap/bitmask/gui/ui/login.ui302
-rw-r--r--src/leap/bitmask/gui/ui/mail_status.ui98
-rw-r--r--src/leap/bitmask/gui/ui/mainwindow.ui437
-rw-r--r--src/leap/bitmask/gui/ui/preferences.ui175
-rw-r--r--src/leap/bitmask/gui/ui/statuspanel.ui393
49 files changed, 1905 insertions, 1347 deletions
diff --git a/Makefile b/Makefile
index 4f4d77c4..766544f4 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ TRANSLAT_DIR = data/translations
PROJFILE = data/bitmask.pro
#UI files to compile
-UI_FILES = loggerwindow.ui mainwindow.ui wizard.ui login.ui statuspanel.ui preferences.ui
+UI_FILES = loggerwindow.ui mainwindow.ui wizard.ui login.ui preferences.ui eip_status.ui mail_status.ui eippreferences.ui
#Qt resource files to compile
RESOURCES = locale.qrc loggerwindow.qrc mainwindow.qrc icons.qrc
diff --git a/changes/feature_new_ui b/changes/feature_new_ui
new file mode 100644
index 00000000..b84fd39e
--- /dev/null
+++ b/changes/feature_new_ui
@@ -0,0 +1 @@
+ o Implement new UI design. Closes #3973. \ No newline at end of file
diff --git a/data/bitmask.pro b/data/bitmask.pro
index e117668b..0f9aaf90 100644
--- a/data/bitmask.pro
+++ b/data/bitmask.pro
@@ -14,10 +14,13 @@ SOURCES += ../src/leap/bitmask/app.py \
../src/leap/bitmask/gui/loggerwindow.py \
../src/leap/bitmask/gui/login.py \
../src/leap/bitmask/gui/mainwindow.py \
- ../src/leap/bitmask/gui/statuspanel.py \
../src/leap/bitmask/gui/twisted_main.py \
../src/leap/bitmask/gui/wizardpage.py \
../src/leap/bitmask/gui/wizard.py \
+ ../src/leap/bitmask/gui/eip_status.py \
+ ../src/leap/bitmask/gui/mail_status.py \
+ ../src/leap/bitmask/gui/eippreferences.py \
+ ../src/leap/bitmask/gui/preferences.py \
../src/leap/bitmask/platform_init/initializers.py \
../src/leap/bitmask/platform_init/locks.py \
../src/leap/bitmask/provider/supportedapis.py \
@@ -45,8 +48,11 @@ SOURCES += ../src/leap/bitmask/app.py \
FORMS += ../src/leap/bitmask/gui/ui/loggerwindow.ui \
../src/leap/bitmask/gui/ui/login.ui \
../src/leap/bitmask/gui/ui/mainwindow.ui \
- ../src/leap/bitmask/gui/ui/statuspanel.ui \
../src/leap/bitmask/gui/ui/wizard.ui \
+ ../src/leap/bitmask/gui/ui/eip_status.ui \
+ ../src/leap/bitmask/gui/ui/mail_status.ui \
+ ../src/leap/bitmask/gui/ui/eippreferences.ui \
+ ../src/leap/bitmask/gui/ui/preferences.ui \
# where to generate ts files -- tx will pick from here
diff --git a/data/images/black/32/arrow-down.png b/data/images/black/32/arrow-down.png
new file mode 100644
index 00000000..328eb08d
--- /dev/null
+++ b/data/images/black/32/arrow-down.png
Binary files differ
diff --git a/data/images/black/32/arrow-up.png b/data/images/black/32/arrow-up.png
new file mode 100644
index 00000000..5eea5108
--- /dev/null
+++ b/data/images/black/32/arrow-up.png
Binary files differ
diff --git a/data/images/black/32/cloud.png b/data/images/black/32/cloud.png
new file mode 100644
index 00000000..10cbd62d
--- /dev/null
+++ b/data/images/black/32/cloud.png
Binary files differ
diff --git a/data/images/black/32/contract.png b/data/images/black/32/contract.png
new file mode 100644
index 00000000..9f0ee605
--- /dev/null
+++ b/data/images/black/32/contract.png
Binary files differ
diff --git a/data/images/black/32/earth-square.png b/data/images/black/32/earth-square.png
new file mode 100644
index 00000000..da7bf2cf
--- /dev/null
+++ b/data/images/black/32/earth-square.png
Binary files differ
diff --git a/data/images/black/32/earth.png b/data/images/black/32/earth.png
new file mode 100644
index 00000000..64919edc
--- /dev/null
+++ b/data/images/black/32/earth.png
Binary files differ
diff --git a/data/images/black/32/email-square.png b/data/images/black/32/email-square.png
new file mode 100644
index 00000000..499d7a8f
--- /dev/null
+++ b/data/images/black/32/email-square.png
Binary files differ
diff --git a/data/images/black/32/email.png b/data/images/black/32/email.png
new file mode 100644
index 00000000..a6f40297
--- /dev/null
+++ b/data/images/black/32/email.png
Binary files differ
diff --git a/data/images/black/32/expand.png b/data/images/black/32/expand.png
new file mode 100644
index 00000000..c581503d
--- /dev/null
+++ b/data/images/black/32/expand.png
Binary files differ
diff --git a/data/images/black/32/gear.png b/data/images/black/32/gear.png
new file mode 100644
index 00000000..93c8742d
--- /dev/null
+++ b/data/images/black/32/gear.png
Binary files differ
diff --git a/data/images/black/32/off.png b/data/images/black/32/off.png
new file mode 100644
index 00000000..6ddde746
--- /dev/null
+++ b/data/images/black/32/off.png
Binary files differ
diff --git a/data/images/black/32/on.png b/data/images/black/32/on.png
new file mode 100644
index 00000000..bbd28bad
--- /dev/null
+++ b/data/images/black/32/on.png
Binary files differ
diff --git a/data/images/black/32/refresh.png b/data/images/black/32/refresh.png
new file mode 100644
index 00000000..ad67f563
--- /dev/null
+++ b/data/images/black/32/refresh.png
Binary files differ
diff --git a/data/images/black/32/user.png b/data/images/black/32/user.png
new file mode 100644
index 00000000..7ea0f43a
--- /dev/null
+++ b/data/images/black/32/user.png
Binary files differ
diff --git a/data/images/black/32/wait.png b/data/images/black/32/wait.png
new file mode 100644
index 00000000..a01ce923
--- /dev/null
+++ b/data/images/black/32/wait.png
Binary files differ
diff --git a/data/images/white/32/arrow-down.png b/data/images/white/32/arrow-down.png
new file mode 100644
index 00000000..02ccc540
--- /dev/null
+++ b/data/images/white/32/arrow-down.png
Binary files differ
diff --git a/data/images/white/32/arrow-up.png b/data/images/white/32/arrow-up.png
new file mode 100644
index 00000000..fbe1f816
--- /dev/null
+++ b/data/images/white/32/arrow-up.png
Binary files differ
diff --git a/data/images/white/32/cloud.png b/data/images/white/32/cloud.png
new file mode 100644
index 00000000..39d589ef
--- /dev/null
+++ b/data/images/white/32/cloud.png
Binary files differ
diff --git a/data/images/white/32/contract.png b/data/images/white/32/contract.png
new file mode 100644
index 00000000..262ff3c0
--- /dev/null
+++ b/data/images/white/32/contract.png
Binary files differ
diff --git a/data/images/white/32/earth-square.png b/data/images/white/32/earth-square.png
new file mode 100644
index 00000000..da7bf2cf
--- /dev/null
+++ b/data/images/white/32/earth-square.png
Binary files differ
diff --git a/data/images/white/32/earth.png b/data/images/white/32/earth.png
new file mode 100644
index 00000000..efca7ccb
--- /dev/null
+++ b/data/images/white/32/earth.png
Binary files differ
diff --git a/data/images/white/32/email-square.png b/data/images/white/32/email-square.png
new file mode 100644
index 00000000..499d7a8f
--- /dev/null
+++ b/data/images/white/32/email-square.png
Binary files differ
diff --git a/data/images/white/32/email.png b/data/images/white/32/email.png
new file mode 100644
index 00000000..abb36035
--- /dev/null
+++ b/data/images/white/32/email.png
Binary files differ
diff --git a/data/images/white/32/expand.png b/data/images/white/32/expand.png
new file mode 100644
index 00000000..0ec28dcc
--- /dev/null
+++ b/data/images/white/32/expand.png
Binary files differ
diff --git a/data/images/white/32/gear.png b/data/images/white/32/gear.png
new file mode 100644
index 00000000..83f8d5ff
--- /dev/null
+++ b/data/images/white/32/gear.png
Binary files differ
diff --git a/data/images/white/32/off.png b/data/images/white/32/off.png
new file mode 100644
index 00000000..22621594
--- /dev/null
+++ b/data/images/white/32/off.png
Binary files differ
diff --git a/data/images/white/32/on.png b/data/images/white/32/on.png
new file mode 100644
index 00000000..8946f763
--- /dev/null
+++ b/data/images/white/32/on.png
Binary files differ
diff --git a/data/images/white/32/refresh.png b/data/images/white/32/refresh.png
new file mode 100644
index 00000000..36a89da9
--- /dev/null
+++ b/data/images/white/32/refresh.png
Binary files differ
diff --git a/data/images/white/32/user.png b/data/images/white/32/user.png
new file mode 100644
index 00000000..ff8edd00
--- /dev/null
+++ b/data/images/white/32/user.png
Binary files differ
diff --git a/data/images/white/32/wait.png b/data/images/white/32/wait.png
new file mode 100644
index 00000000..8562d636
--- /dev/null
+++ b/data/images/white/32/wait.png
Binary files differ
diff --git a/data/resources/mainwindow.qrc b/data/resources/mainwindow.qrc
index 1e4159b8..0a917d5a 100644
--- a/data/resources/mainwindow.qrc
+++ b/data/resources/mainwindow.qrc
@@ -1,5 +1,23 @@
<RCC>
<qresource prefix="/">
+ <file>../images/white/32/off.png</file>
+ <file>../images/white/32/on.png</file>
+ <file>../images/white/32/wait.png</file>
+ <file>../images/black/32/arrow-down.png</file>
+ <file>../images/black/32/arrow-up.png</file>
+ <file>../images/black/32/cloud.png</file>
+ <file>../images/black/32/contract.png</file>
+ <file>../images/black/32/earth-square.png</file>
+ <file>../images/black/32/earth.png</file>
+ <file>../images/black/32/email-square.png</file>
+ <file>../images/black/32/email.png</file>
+ <file>../images/black/32/expand.png</file>
+ <file>../images/black/32/gear.png</file>
+ <file>../images/black/32/off.png</file>
+ <file>../images/black/32/on.png</file>
+ <file>../images/black/32/refresh.png</file>
+ <file>../images/black/32/user.png</file>
+ <file>../images/black/32/wait.png</file>
<file>../images/mask-launcher.png</file>
<file>../images/mask-icon.png</file>
<file>../images/leap-gray-big.png</file>
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>&lt;Select provider&gt;</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="lblSelectProvider">
+ <property name="text">
+ <string>&amp;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>&lt; Providers Gateway Status &gt;</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 &quot;Lucida Grande&quot;;</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>&lt;b&gt;Provider:&lt;/b&gt;</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>&lt;b&gt;Username:&lt;/b&gt;</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>&lt;b&gt;Provider:&lt;/b&gt;</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>&lt;b&gt;Username:&lt;/b&gt;</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>&lt;b&gt;Password:&lt;/b&gt;</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>&lt;b&gt;Password:&lt;/b&gt;</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>&amp;Session</string>
+ <string>&amp;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 &amp;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 &amp;logs</string>
+ <string>Show &amp;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>&lt;Select provider&gt;</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>&amp;Select provider:</string>
+ <string>&amp;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>&amp;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>&amp;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>&lt; Providers Gateway Status &gt;</string>
+ <string>Change</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QLabel" name="lblPasswordChangeStatus">
+ <property name="text">
+ <string>&lt;Password change status&gt;</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>&amp;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>&amp;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>&amp;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>&lt;Password change status&gt;</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>