summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/gui
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2016-05-18 12:13:52 -0400
committerKali Kaneko <kali@leap.se>2016-05-18 12:13:52 -0400
commit90aa7a275c41af130dcddaefd798ae35c505b6d5 (patch)
tree95441aa18d1022eea56d9348e0c32f392bb674ea /src/leap/bitmask/gui
parentaecb13feed8797acaa3f91be45a82a52b64d4723 (diff)
parentfacefed990195bd89bf1064e75b171edd084f632 (diff)
Merge tag '0.9.2'
Tag leap.bitmask version 0.9.2
Diffstat (limited to 'src/leap/bitmask/gui')
-rw-r--r--src/leap/bitmask/gui/account.py9
-rw-r--r--src/leap/bitmask/gui/advanced_key_management.py3
-rw-r--r--src/leap/bitmask/gui/app.py34
-rw-r--r--src/leap/bitmask/gui/eip_status.py2
-rw-r--r--src/leap/bitmask/gui/logwindow.py4
-rw-r--r--src/leap/bitmask/gui/mail_status.py65
-rw-r--r--src/leap/bitmask/gui/mainwindow.py72
-rw-r--r--src/leap/bitmask/gui/passwordwindow.py2
-rw-r--r--src/leap/bitmask/gui/preferences_account_page.py30
-rw-r--r--src/leap/bitmask/gui/preferences_email_page.py204
-rw-r--r--src/leap/bitmask/gui/preferences_page.py50
-rw-r--r--src/leap/bitmask/gui/preferences_vpn_page.py31
-rw-r--r--src/leap/bitmask/gui/preferenceswindow.py144
-rw-r--r--src/leap/bitmask/gui/qt_browser.py72
-rw-r--r--src/leap/bitmask/gui/statemachines.py5
-rw-r--r--src/leap/bitmask/gui/ui/mail_status.ui235
-rw-r--r--src/leap/bitmask/gui/ui/mainwindow.ui4
-rw-r--r--src/leap/bitmask/gui/ui/preferences.ui22
-rw-r--r--src/leap/bitmask/gui/ui/preferences_email_page.ui629
-rw-r--r--src/leap/bitmask/gui/ui/wizard.ui4
20 files changed, 1378 insertions, 243 deletions
diff --git a/src/leap/bitmask/gui/account.py b/src/leap/bitmask/gui/account.py
index 81f96389..b8b9509a 100644
--- a/src/leap/bitmask/gui/account.py
+++ b/src/leap/bitmask/gui/account.py
@@ -20,6 +20,7 @@ A frontend GUI object to hold the current username and domain.
from leap.bitmask.util import make_address
from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.services import EIP_SERVICE, MX_SERVICE
+from leap.bitmask._components import HAS_EIP, HAS_MAIL
class Account():
@@ -42,8 +43,8 @@ class Account():
"""
return self._settings.get_enabled_services(self.domain)
- def is_email_enabled(self):
- return MX_SERVICE in self.services()
+ def has_email(self):
+ return HAS_MAIL and MX_SERVICE in self.services()
- def is_eip_enabled(self):
- return EIP_SERVICE in self.services()
+ def has_eip(self):
+ return HAS_EIP and EIP_SERVICE in self.services()
diff --git a/src/leap/bitmask/gui/advanced_key_management.py b/src/leap/bitmask/gui/advanced_key_management.py
index 2e315d18..bc496a57 100644
--- a/src/leap/bitmask/gui/advanced_key_management.py
+++ b/src/leap/bitmask/gui/advanced_key_management.py
@@ -94,6 +94,7 @@ class AdvancedKeyManagement(QtGui.QDialog):
"""
Set the current user's key details into the gui.
"""
+ # XXX: We should avoid the key-id
self.ui.leKeyID.setText(details[0])
self.ui.leFingerprint.setText(details[1])
@@ -246,7 +247,7 @@ class AdvancedKeyManagement(QtGui.QDialog):
row = keys_table.rowCount()
keys_table.insertRow(row)
keys_table.setItem(row, 0, QtGui.QTableWidgetItem(key.address))
- keys_table.setItem(row, 1, QtGui.QTableWidgetItem(key.key_id))
+ keys_table.setItem(row, 1, QtGui.QTableWidgetItem(key.fingerprint))
def _backend_connect(self):
"""
diff --git a/src/leap/bitmask/gui/app.py b/src/leap/bitmask/gui/app.py
index 97fd0549..1011454e 100644
--- a/src/leap/bitmask/gui/app.py
+++ b/src/leap/bitmask/gui/app.py
@@ -20,6 +20,7 @@ and the signaler get signals from the backend.
"""
from PySide import QtCore, QtGui
+from leap.bitmask.gui.account import Account
from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.backend.backend_proxy import BackendProxy
from leap.bitmask.backend.leapsignaler import LeapSignaler
@@ -44,12 +45,37 @@ class App(QtGui.QWidget):
self.signaler.start()
self.soledad_started = False
+ self.service_tokens = {}
+ self.login_state = None
+ self.providers_widget = None
# periodically check if the backend is alive
self._backend_checker = QtCore.QTimer(self)
self._backend_checker.timeout.connect(self._check_backend_status)
self._backend_checker.start(2000)
+ # store the service tokens for later use, once they are known.
+ self.signaler.soledad_got_service_token.connect(
+ self._set_service_tokens)
+
+ def current_account(self):
+ """
+ Alas, the only definitive account information is buried in the memory
+ of QT widgets.
+
+ :returns: an object representing the current user account.
+ :rtype: Account
+ """
+ if self.login_state is None or self.providers_widget is None:
+ return None
+
+ if self.login_state.full_logged_username is not None:
+ username, domain = self.login_state.full_logged_username.split('@')
+ return Account(username, domain)
+ else:
+ domain = self.providers_widget.get_selected_provider()
+ return Account(None, domain)
+
def _check_backend_status(self):
"""
TRIGGERS:
@@ -64,3 +90,11 @@ class App(QtGui.QWidget):
self.tr("There is a problem contacting the backend, please "
"restart Bitmask."))
self._backend_checker.stop()
+
+ def _set_service_tokens(self, data):
+ """
+ Triggered by signal soledad_got_service_token.
+ Saves the service tokens.
+ """
+ service, token = data
+ self.service_tokens[service] = token
diff --git a/src/leap/bitmask/gui/eip_status.py b/src/leap/bitmask/gui/eip_status.py
index 64a408c4..470ef88a 100644
--- a/src/leap/bitmask/gui/eip_status.py
+++ b/src/leap/bitmask/gui/eip_status.py
@@ -733,7 +733,7 @@ class EIPStatusWidget(QtGui.QWidget):
self.set_eip_status(
# XXX this should change to polkit-kde where
# applicable.
- self.tr("We could not find any authentication agent in your "
+ self.tr("We could not find any authentication agent on your "
"system.<br/>Make sure you have "
"<b>polkit-gnome-authentication-agent-1</b> running and "
"try again."),
diff --git a/src/leap/bitmask/gui/logwindow.py b/src/leap/bitmask/gui/logwindow.py
index 718269c9..5d8c99fc 100644
--- a/src/leap/bitmask/gui/logwindow.py
+++ b/src/leap/bitmask/gui/logwindow.py
@@ -173,7 +173,7 @@ class LoggerWindow(QtGui.QDialog):
:type sending: bool
"""
if sending:
- self.ui.btnPastebin.setText(self.tr("Sending to pastebin..."))
+ self.ui.btnPastebin.setText(self.tr("Sending to Pastebin.com…"))
self.ui.btnPastebin.setEnabled(False)
else:
self.ui.btnPastebin.setText(self.tr("Send to Pastebin.com"))
@@ -193,7 +193,7 @@ class LoggerWindow(QtGui.QDialog):
# We save the dialog in an instance member to avoid dialog being
# deleted right after we exit this method
self._msgBox = msgBox = QtGui.QMessageBox(
- QtGui.QMessageBox.Information, self.tr("Pastebin OK"), msg)
+ QtGui.QMessageBox.Information, self.tr("Pastebin is OK"), msg)
msgBox.setWindowModality(QtCore.Qt.NonModal)
msgBox.show()
diff --git a/src/leap/bitmask/gui/mail_status.py b/src/leap/bitmask/gui/mail_status.py
index 8b4329d7..cb0314b5 100644
--- a/src/leap/bitmask/gui/mail_status.py
+++ b/src/leap/bitmask/gui/mail_status.py
@@ -26,7 +26,9 @@ from leap.common.check import leap_assert, leap_assert_type
from leap.common.events import register
from leap.common.events import catalog
+from leap.bitmask.gui.preferenceswindow import PreferencesWindow
from ui_mail_status import Ui_MailStatusWidget
+from .qt_browser import PixelatedWindow
logger = get_logger()
@@ -52,13 +54,21 @@ class MailStatusWidget(QtGui.QWidget):
self._systray = None
self._disabled = True
self._started = False
+ self._mainwindow = parent
self._unread_mails = 0
self.ui = Ui_MailStatusWidget()
self.ui.setupUi(self)
- self.ui.lblMailReadyHelp.setVisible(False)
+ self.ui.email_ready.setVisible(False)
+ self.ui.configure_button.clicked.connect(
+ self._show_configure)
+ self.ui.open_mail_button.clicked.connect(
+ self._show_pix_ua)
+ if not self._mainwindow._settings.get_pixelmail_enabled():
+ self.ui.open_mail_button.setVisible(False)
+ self.ui.or_label.setVisible(False)
# set systray tooltip status
self._mx_status = ""
@@ -144,7 +154,23 @@ class MailStatusWidget(QtGui.QWidget):
self.CONNECTED_ICON_TRAY = QtGui.QPixmap(EIP_ICONS_TRAY[1])
self.ERROR_ICON_TRAY = QtGui.QPixmap(EIP_ICONS_TRAY[2])
- # Systray and actions
+ #
+ # Button actions
+ #
+
+ def _show_configure(self):
+ pref_win = PreferencesWindow(self._mainwindow, self._mainwindow.app)
+ pref_win.set_page("email")
+ pref_win.show()
+
+ def _show_pix_ua(self):
+ win = PixelatedWindow(self._mainwindow)
+ win.show()
+ win.load_app()
+
+ #
+ # Systray
+ #
def set_systray(self, systray):
"""
@@ -166,6 +192,10 @@ class MailStatusWidget(QtGui.QWidget):
mx_status = u"{0}: {1}".format(self._service_name, self._mx_status)
self._systray.set_service_tooltip(MX_SERVICE, mx_status)
+ #
+ # Status
+ #
+
def set_action_mail_status(self, action_mail_status):
"""
Sets the action_mail_status to use.
@@ -186,7 +216,7 @@ class MailStatusWidget(QtGui.QWidget):
msg = self.tr("There was an unexpected problem with Soledad.")
self._set_mail_status(msg, ready=-1)
- def set_soledad_invalid_auth_token(self, event, content):
+ def set_soledad_invalid_auth_token(self, event, content=None):
"""
This method is called when the auth token is invalid
@@ -229,16 +259,22 @@ class MailStatusWidget(QtGui.QWidget):
elif ready < 0:
tray_status = self.tr("Mail is disabled")
+ if ready < 1:
+ self._hide_mail_ready()
+
self.ui.lblMailStatusIcon.setPixmap(icon)
self._action_mail_status.setText(tray_status)
self._update_systray_tooltip()
- def _mail_handle_soledad_events(self, event, content):
+ def _mail_handle_soledad_events(self, event, user_data, content=""):
"""
Callback for handling events that are emitted from Soledad
:param event: The event that triggered the callback.
:type event: str
+ :param user_id: The user_data of the soledad user. Ignored right now,
+ since we're only contemplating single-user in soledad.
+ :type user_id: dict
:param content: The content of the event.
:type content: dict
"""
@@ -346,7 +382,7 @@ class MailStatusWidget(QtGui.QWidget):
logger.warning("don't know to to handle %s" % (event,))
self._set_mail_status(ext_status, ready=1)
- def _mail_handle_smtp_events(self, event):
+ def _mail_handle_smtp_events(self, event, content=""):
"""
Callback for the SMTP events
@@ -380,12 +416,14 @@ class MailStatusWidget(QtGui.QWidget):
# ----- XXX deprecate (move to mail conductor)
- def _mail_handle_imap_events(self, event, content):
+ def _mail_handle_imap_events(self, event, uuid, content=""):
"""
Callback for the IMAP events
:param event: The event that triggered the callback.
:type event: str
+ :param uuid: The UUID for the user. Ignored right now.
+ :type uuid: str
:param content: The content of the event.
:type content: list
"""
@@ -419,9 +457,10 @@ class MailStatusWidget(QtGui.QWidget):
self._show_unread_mails()
elif event == catalog.IMAP_SERVICE_STARTED:
self._imap_started = True
- elif event == catalog.IMAP_CLIENT_LOGIN:
- # If a MUA has logged in then we don't need to show this.
- self._hide_mail_ready_help()
+ # this is disabled for now, because this event was being
+ # triggered at weird times.
+ # elif event == catalog.IMAP_CLIENT_LOGIN:
+ # self._hide_mail_ready()
if ext_status is not None:
self._set_mail_status(ext_status, ready=1)
@@ -490,15 +529,13 @@ class MailStatusWidget(QtGui.QWidget):
Display the correct UI for the connected state.
"""
self._set_mail_status(self.tr("ON"), 2)
+ self.ui.email_ready.setVisible(True)
- # this help message will hide when the MUA connects
- self.ui.lblMailReadyHelp.setVisible(True)
-
- def _hide_mail_ready_help(self):
+ def _hide_mail_ready(self):
"""
Hide the mail help message on the UI.
"""
- self.ui.lblMailReadyHelp.setVisible(False)
+ self.ui.email_ready.setVisible(False)
def mail_state_disabled(self):
"""
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py
index a8a4e41d..6637f170 100644
--- a/src/leap/bitmask/gui/mainwindow.py
+++ b/src/leap/bitmask/gui/mainwindow.py
@@ -46,7 +46,6 @@ from leap.bitmask.gui.signaltracker import SignalTracker
from leap.bitmask.gui.systray import SysTray
from leap.bitmask.gui.wizard import Wizard
from leap.bitmask.gui.providers import Providers
-from leap.bitmask.gui.account import Account
from leap.bitmask.gui.app import App
from leap.bitmask.platform_init import IS_WIN, IS_MAC, IS_LINUX
@@ -152,6 +151,14 @@ class MainWindow(QtGui.QMainWindow, SignalTracker):
# Provider List
self._providers = Providers(self.ui.cmbProviders)
+ ##
+ # tmphack: important state information about the application is stored
+ # in widgets. Rather than rewrite the UI, for now we simulate this
+ # info being stored in an application object:
+ ##
+ self.app.login_state = self._login_widget._state
+ self.app.providers_widget = self._providers
+
# Qt Signal Connections #####################################
# TODO separate logic from ui signals.
@@ -218,6 +225,7 @@ class MainWindow(QtGui.QMainWindow, SignalTracker):
self._backend_connect()
self.ui.action_preferences.triggered.connect(self._show_preferences)
+
self.ui.action_about_leap.triggered.connect(self._about)
self.ui.action_quit.triggered.connect(self.quit)
self.ui.action_wizard.triggered.connect(self._show_wizard)
@@ -294,6 +302,7 @@ class MainWindow(QtGui.QMainWindow, SignalTracker):
self._mail_conductor.connect_mail_signals(self._mail_status)
if not init_platform():
+ logger.critical('init_platform failed, quitting application.')
self.quit()
return
@@ -436,6 +445,9 @@ class MainWindow(QtGui.QMainWindow, SignalTracker):
# Refer to http://www.themacaque.com/?p=1067 for funny details.
self._wizard.show()
if IS_MAC:
+ # XXX hack. For some reason, there's a signal that doesn't arrive
+ # on time, so that the next button is disabled. See #8041
+ self._wizard.page(self._wizard.INTRO_PAGE).set_completed()
self._wizard.raise_()
self._settings.set_skip_first_run(True)
@@ -553,15 +565,7 @@ class MainWindow(QtGui.QMainWindow, SignalTracker):
Display the preferences window.
"""
- logged_user = self._login_widget.get_logged_user()
- if logged_user is not None:
- user, domain = logged_user.split('@')
- else:
- user = None
- domain = self._providers.get_selected_provider()
-
- account = Account(user, domain)
- pref_win = PreferencesWindow(self, account, self.app)
+ pref_win = PreferencesWindow(self, self.app)
pref_win.show()
def _update_eip_enabled_status(self, account=None, services=None):
@@ -1014,12 +1018,9 @@ class MainWindow(QtGui.QMainWindow, SignalTracker):
Display the About Bitmask dialog
"""
today = datetime.now().date()
- greet = ("Happy New 1984!... or not ;)<br><br>"
- if today.month == 1 and today.day < 15 else "")
title = self.tr("About Bitmask - %s") % (VERSION,)
msg = self.tr(
"Version: <b>{ver}</b> ({ver_hash})<br>"
- "<br>{greet}"
"Bitmask is the Desktop client application for the LEAP "
"platform, supporting Encrypted Internet Proxy "
"and <a href='https://bitmask.net/help/email'> "
@@ -1030,7 +1031,7 @@ class MainWindow(QtGui.QMainWindow, SignalTracker):
"available.<br>"
"<br>"
"<a href='https://leap.se'>More about LEAP</a>")
- msg = msg.format(ver=VERSION, ver_hash=VERSION_HASH[:10], greet=greet)
+ msg = msg.format(ver=VERSION, ver_hash=VERSION_HASH[:10])
QtGui.QMessageBox.about(self, title, msg)
def _help(self):
@@ -1038,46 +1039,9 @@ class MainWindow(QtGui.QMainWindow, SignalTracker):
TRIGGERS:
self.ui.action_help.triggered
- Display the Bitmask help dialog.
- """
- # TODO: don't hardcode!
- smtp_port = 2013
-
- help_url = "<p><a href='https://{0}'>{0}</a></p>".format(
- self.tr("bitmask.net/help"))
-
- lang = QtCore.QLocale.system().name().replace('_', '-')
- thunderbird_extension_url = \
- "https://addons.mozilla.org/{0}/" \
- "thunderbird/addon/bitmask/".format(lang)
-
- email_quick_reference = self.tr("Email quick reference")
- thunderbird_text = self.tr(
- "For Thunderbird, you can use the "
- "Bitmask extension. Search for \"Bitmask\" in the add-on "
- "manager or download it from <a href='{0}'>"
- "addons.mozilla.org</a>.".format(thunderbird_extension_url))
- manual_text = self.tr(
- "Alternatively, you can manually configure "
- "your mail client to use Bitmask Email with these options:")
- manual_imap = self.tr("IMAP: localhost, port {0}".format(IMAP_PORT))
- manual_smtp = self.tr("SMTP: localhost, port {0}".format(smtp_port))
- manual_username = self.tr("Username: your full email address")
- manual_password = self.tr("Password: any non-empty text")
-
- msg = help_url + self.tr(
- "<p><strong>{0}</strong></p>"
- "<p>{1}</p>"
- "<p>{2}"
- "<ul>"
- "<li>&nbsp;{3}</li>"
- "<li>&nbsp;{4}</li>"
- "<li>&nbsp;{5}</li>"
- "<li>&nbsp;{6}</li>"
- "</ul></p>").format(email_quick_reference, thunderbird_text,
- manual_text, manual_imap, manual_smtp,
- manual_username, manual_password)
- QtGui.QMessageBox.about(self, self.tr("Bitmask Help"), msg)
+ Open bitmask.net/help
+ """
+ QtGui.QDesktopServices.openUrl("https://bitmask.net/help")
def _needs_update(self):
"""
diff --git a/src/leap/bitmask/gui/passwordwindow.py b/src/leap/bitmask/gui/passwordwindow.py
index dedfcb10..fe70b250 100644
--- a/src/leap/bitmask/gui/passwordwindow.py
+++ b/src/leap/bitmask/gui/passwordwindow.py
@@ -83,7 +83,7 @@ class PasswordWindow(QtGui.QDialog, Flashable):
Returns true if the current account needs to change the soledad
password as well as the SRP password.
"""
- return self.account.is_email_enabled()
+ return self.account.has_email()
#
# MANAGE WIDGETS
diff --git a/src/leap/bitmask/gui/preferences_account_page.py b/src/leap/bitmask/gui/preferences_account_page.py
index da9da14d..141523c8 100644
--- a/src/leap/bitmask/gui/preferences_account_page.py
+++ b/src/leap/bitmask/gui/preferences_account_page.py
@@ -22,6 +22,7 @@ from PySide import QtCore, QtGui
from leap.bitmask.logs.utils import get_logger
from leap.bitmask.gui import ui_preferences_account_page as ui_pref
+from leap.bitmask.gui.preferences_page import PreferencesPage
from leap.bitmask.gui.passwordwindow import PasswordWindow
from leap.bitmask.services import get_service_display_name
from leap.bitmask._components import HAS_EIP
@@ -29,7 +30,7 @@ from leap.bitmask._components import HAS_EIP
logger = get_logger()
-class PreferencesAccountPage(QtGui.QWidget):
+class PreferencesAccountPage(PreferencesPage):
def __init__(self, parent, account, app):
"""
@@ -42,20 +43,15 @@ class PreferencesAccountPage(QtGui.QWidget):
:param app: the current App object
:type app: App
"""
- QtGui.QWidget.__init__(self, parent)
+ PreferencesPage.__init__(self, parent, account, app)
self.ui = ui_pref.Ui_PreferencesAccountPage()
self.ui.setupUi(self)
- self.account = account
- self.app = app
-
self._selected_services = set()
self.ui.change_password_label.setVisible(False)
self.ui.provider_services_label.setVisible(False)
- self.ui.change_password_button.clicked.connect(
- self._show_change_password)
- app.signaler.prov_get_supported_services.connect(self._load_services)
+ self.setup_connections()
app.backend.provider_get_supported_services(domain=account.domain)
if account.username is None:
@@ -64,6 +60,24 @@ class PreferencesAccountPage(QtGui.QWidget):
self.ui.change_password_label.setVisible(True)
self.ui.change_password_button.setEnabled(False)
+ def setup_connections(self):
+ """
+ connect signals
+ """
+ self.ui.change_password_button.clicked.connect(
+ self._show_change_password)
+ self.app.signaler.prov_get_supported_services.connect(
+ self._load_services)
+
+ def teardown_connections(self):
+ """
+ disconnect signals
+ """
+ self.ui.change_password_button.clicked.disconnect(
+ self._show_change_password)
+ self.app.signaler.prov_get_supported_services.disconnect(
+ self._load_services)
+
def _service_selection_changed(self, service, state):
"""
TRIGGERS:
diff --git a/src/leap/bitmask/gui/preferences_email_page.py b/src/leap/bitmask/gui/preferences_email_page.py
index 3087f343..93c77df1 100644
--- a/src/leap/bitmask/gui/preferences_email_page.py
+++ b/src/leap/bitmask/gui/preferences_email_page.py
@@ -16,20 +16,214 @@
"""
Widget for "email" preferences
"""
-from PySide import QtGui
+from PySide import QtCore, QtGui
+from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.logs.utils import get_logger
from leap.bitmask.gui.ui_preferences_email_page import Ui_PreferencesEmailPage
+from leap.bitmask.gui.preferences_page import PreferencesPage
+from leap.bitmask.pix import HAS_PIXELATED
+from leap.mail.imap.service.imap import IMAP_PORT
+
logger = get_logger()
-class PreferencesEmailPage(QtGui.QWidget):
+class PreferencesEmailPage(PreferencesPage):
def __init__(self, parent, account, app):
- QtGui.QWidget.__init__(self, parent)
+ """
+ :param parent: parent object of the PreferencesWindow.
+ :parent type: QWidget
+
+ :param account: user account (user + provider or just provider)
+ :type account: Account
+
+ :param app: the current App object
+ :type app: App
+ """
+ PreferencesPage.__init__(self, parent, account, app)
+ self.settings = LeapSettings()
self.ui = Ui_PreferencesEmailPage()
self.ui.setupUi(self)
- self.account = account
- self.app = app
+ # the only way to set the tab titles is to re-add them:
+ self.ui.email_tabs.addTab(self.ui.config_tab,
+ self.tr("Mail Client"))
+ self.ui.email_tabs.addTab(self.ui.my_key_tab,
+ self.tr("My Key"))
+ self.ui.email_tabs.addTab(self.ui.other_keys_tab,
+ self.tr("Other Keys"))
+
+ # set mail client configuration help text
+ lang = QtCore.QLocale.system().name().replace('_', '-')
+ thunderbird_extension_url = \
+ "https://addons.mozilla.org/{0}/" \
+ "thunderbird/addon/bitmask/".format(lang)
+ self.ui.thunderbird_label.setText(self.tr(
+ "For Thunderbird, you can use the Bitmask extension. "
+ "Search for \"Bitmask\" in the add-on manager or "
+ "download it from <a href='{0}'>addons.mozilla.org</a>.".format(
+ thunderbird_extension_url)))
+
+ self.ui.mail_client_label.setText(self.tr(
+ "Alternatively, you can manually configure your mail client to "
+ "use Bitmask with these options:"))
+
+ self.ui.webmail_label.setText(self.tr(
+ "Bitmask Mail is an integrated mail client based "
+ "on <a href='https://pixelated-project.org/'>Pixelated "
+ "User Agent</a>. If enabled, any user on your device "
+ "can read your mail by opening http://localhost:9090"))
+
+ self.ui.keys_table.horizontalHeader().setResizeMode(
+ 0, QtGui.QHeaderView.Stretch)
+
+ self.setup_connections()
+
+ def setup_connections(self):
+ """
+ connect signals
+ """
+ self.app.signaler.keymanager_key_details.connect(self._key_details)
+ self.app.signaler.keymanager_keys_list.connect(
+ self._keymanager_keys_list)
+ self.app.signaler.keymanager_export_ok.connect(
+ self._keymanager_export_ok)
+ self.app.signaler.keymanager_export_error.connect(
+ self._keymanager_export_error)
+ self.ui.import_button.clicked.connect(self._import_keys)
+ self.ui.export_button.clicked.connect(self._export_keys)
+ self.ui.webmail_checkbox.stateChanged.connect(self._toggle_webmail)
+
+ def teardown_connections(self):
+ """
+ disconnect signals
+ """
+ self.app.signaler.keymanager_key_details.disconnect(self._key_details)
+ self.app.signaler.keymanager_export_ok.disconnect(
+ self._keymanager_export_ok)
+ self.app.signaler.keymanager_export_error.disconnect(
+ self._keymanager_export_error)
+
+ def showEvent(self, event):
+ """
+ called whenever this widget is shown
+ """
+ self.ui.keys_table.clearContents()
+
+ if self.account.username is None:
+ self.ui.email_tabs.setVisible(False)
+ self.ui.message_label.setVisible(True)
+ self.ui.message_label.setText(
+ self.tr('You must be logged in to edit email settings.'))
+ else:
+ webmail_enabled = self.settings.get_pixelmail_enabled()
+ self.ui.webmail_checkbox.setChecked(webmail_enabled)
+ if not HAS_PIXELATED:
+ self.ui.webmail_box.setVisible(False)
+ self.ui.import_button.setVisible(False) # hide this until working
+ self.ui.message_label.setVisible(False)
+ self.ui.email_tabs.setVisible(True)
+ smtp_port = 2013
+ self.ui.imap_port_edit.setText(str(IMAP_PORT))
+ self.ui.imap_host_edit.setText("127.0.0.1")
+ self.ui.smtp_port_edit.setText(str(smtp_port))
+ self.ui.smtp_host_edit.setText("127.0.0.1")
+ self.ui.username_edit.setText(self.account.address)
+ self.ui.password_edit.setText(
+ self.app.service_tokens.get('mail_auth', ''))
+
+ self.app.backend.keymanager_list_keys()
+ self.app.backend.keymanager_get_key_details(
+ username=self.account.address)
+
+ def _key_details(self, details):
+ """
+ Trigger by signal: keymanager_key_details
+ Set the current user's key details into the gui.
+ """
+ self.ui.fingerprint_edit.setPlainText(
+ self._format_fingerprint(details["fingerprint"]))
+ self.ui.expiration_edit.setText(details["expiry_date"])
+ self.ui.uid_edit.setText(" ".join(details["uids"]))
+ self.ui.public_key_edit.setPlainText(details["key_data"])
+
+ def _format_fingerprint(self, fingerprint):
+ """
+ formats an openpgp fingerprint in a manner similar to what gpg
+ produces, wrapped to two lines.
+ """
+ fp = fingerprint.upper()
+ fp_list = [fp[i:i + 4] for i in range(0, len(fp), 4)]
+ fp_wrapped = " ".join(fp_list[0:5]) + "\n" + " ".join(fp_list[5:10])
+ return fp_wrapped
+
+ def _export_keys(self):
+ """
+ Exports the user's key pair.
+ """
+ file_name, filtr = QtGui.QFileDialog.getSaveFileName(
+ self, self.tr("Save private key file"),
+ filter="*.pem",
+ options=QtGui.QFileDialog.DontUseNativeDialog)
+
+ if file_name:
+ if not file_name.endswith('.pem'):
+ file_name += '.pem'
+ self.app.backend.keymanager_export_keys(
+ username=self.account.address,
+ filename=file_name)
+ else:
+ logger.debug('Export canceled by the user.')
+
+ def _keymanager_export_ok(self):
+ """
+ TRIGGERS:
+ Signaler.keymanager_export_ok
+
+ Notify the user that the key export went OK.
+ """
+ QtGui.QMessageBox.information(
+ self, self.tr("Export Successful"),
+ self.tr("The key pair was exported successfully.\n"
+ "Please, store your private key in a safe place."))
+
+ def _keymanager_export_error(self):
+ """
+ TRIGGERS:
+ Signaler.keymanager_export_error
+
+ Notify the user that the key export didn't go well.
+ """
+ QtGui.QMessageBox.critical(
+ self, self.tr("Input/Output error"),
+ self.tr("There was an error accessing the file.\n"
+ "Export canceled."))
+
+ def _import_keys(self):
+ """
+ not yet supported
+ """
+
+ def _keymanager_keys_list(self, keys):
+ """
+ TRIGGERS:
+ Signaler.keymanager_keys_list
+
+ Load the keys given as parameter in the table.
+
+ :param keys: the list of keys to load.
+ :type keys: list
+ """
+ for key in keys:
+ row = self.ui.keys_table.rowCount()
+ self.ui.keys_table.insertRow(row)
+ self.ui.keys_table.setItem(
+ row, 0, QtGui.QTableWidgetItem(" ".join(key["uids"])))
+ self.ui.keys_table.setItem(
+ row, 1, QtGui.QTableWidgetItem(key["fingerprint"]))
+
+ def _toggle_webmail(self, state):
+ value = True if state == QtCore.Qt.Checked else False
+ self.settings.set_pixelmail_enabled(value)
diff --git a/src/leap/bitmask/gui/preferences_page.py b/src/leap/bitmask/gui/preferences_page.py
new file mode 100644
index 00000000..a5d811f9
--- /dev/null
+++ b/src/leap/bitmask/gui/preferences_page.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2014 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/>.
+"""
+Base class for preference pages
+"""
+
+from PySide import QtGui
+
+
+class PreferencesPage(QtGui.QWidget):
+
+ def __init__(self, parent, account=None, app=None):
+ """
+ :param parent: parent object of the EIPPreferencesWindow.
+ :type parent: QWidget
+
+ :param account: the currently active account
+ :type account: Account
+
+ :param app: shared App instance
+ :type app: App
+ """
+ QtGui.QWidget.__init__(self, parent)
+ self.app = app
+ self.account = account
+
+ def setup_connections(self):
+ """
+ connect signals
+ must be overridden by subclass
+ """
+
+ def teardown_connections(self):
+ """
+ disconnect signals
+ must be overridden by subclass
+ """
diff --git a/src/leap/bitmask/gui/preferences_vpn_page.py b/src/leap/bitmask/gui/preferences_vpn_page.py
index 5b5c9604..87b86c4e 100644
--- a/src/leap/bitmask/gui/preferences_vpn_page.py
+++ b/src/leap/bitmask/gui/preferences_vpn_page.py
@@ -20,11 +20,11 @@ Widget for "vpn" preferences
from PySide import QtCore, QtGui
from leap.bitmask.gui.ui_preferences_vpn_page import Ui_PreferencesVpnPage
-from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.gui.flashable import Flashable
+from leap.bitmask.gui.preferences_page import PreferencesPage
-class PreferencesVpnPage(QtGui.QWidget, Flashable):
+class PreferencesVpnPage(PreferencesPage, Flashable):
"""
Page in the preferences window that shows VPN settings
@@ -41,19 +41,24 @@ class PreferencesVpnPage(QtGui.QWidget, Flashable):
:param app: shared App instance
:type app: App
"""
- QtGui.QWidget.__init__(self, parent)
+ PreferencesPage.__init__(self, parent, account, app)
self.AUTOMATIC_GATEWAY_LABEL = self.tr("Automatic")
- self.account = account
- self.app = app
-
# Load UI
self.ui = Ui_PreferencesVpnPage()
self.ui.setupUi(self)
self.ui.flash_label.setVisible(False)
self.hide_flash()
- # Connections
+ self.setup_connections()
+
+ # Trigger update
+ self.app.backend.eip_get_gateways_list(domain=self.account.domain)
+
+ def setup_connections(self):
+ """
+ connect signals
+ """
self.ui.gateways_list.clicked.connect(self._save_selected_gateway)
sig = self.app.signaler
sig.eip_get_gateways_list.connect(self._update_gateways_list)
@@ -61,8 +66,16 @@ class PreferencesVpnPage(QtGui.QWidget, Flashable):
sig.eip_uninitialized_provider.connect(
self._gateways_list_uninitialized)
- # Trigger update
- self.app.backend.eip_get_gateways_list(domain=self.account.domain)
+ def teardown_connections(self):
+ """
+ disconnect signals
+ """
+ self.ui.gateways_list.clicked.disconnect(self._save_selected_gateway)
+ sig = self.app.signaler
+ sig.eip_get_gateways_list.disconnect(self._update_gateways_list)
+ sig.eip_get_gateways_list_error.disconnect(self._gateways_list_error)
+ sig.eip_uninitialized_provider.disconnect(
+ self._gateways_list_uninitialized)
def _save_selected_gateway(self, index):
"""
diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py
index 44c4641c..50a972e1 100644
--- a/src/leap/bitmask/gui/preferenceswindow.py
+++ b/src/leap/bitmask/gui/preferenceswindow.py
@@ -20,11 +20,9 @@ Preferences window
"""
from PySide import QtCore, QtGui
-from leap.bitmask.services import EIP_SERVICE
-from leap.bitmask._components import HAS_EIP
-
from leap.bitmask.logs.utils import get_logger
from leap.bitmask.gui.ui_preferences import Ui_Preferences
+from leap.bitmask.gui.preferences_page import PreferencesPage
from leap.bitmask.gui.preferences_account_page import PreferencesAccountPage
from leap.bitmask.gui.preferences_vpn_page import PreferencesVpnPage
from leap.bitmask.gui.preferences_email_page import PreferencesEmailPage
@@ -40,39 +38,52 @@ class PreferencesWindow(QtGui.QDialog):
_current_window = None # currently visible preferences window
- def __init__(self, parent, account, app):
+ _panels = {
+ "account": 0,
+ "vpn": 1,
+ "email": 2
+ }
+
+ def __init__(self, parent, app):
"""
:param parent: parent object of the PreferencesWindow.
:parent type: QWidget
- :param account: the user or provider
- :type account: Account
-
:param app: the current App object
:type app: App
"""
QtGui.QDialog.__init__(self, parent)
- self.account = account
self.app = app
self.ui = Ui_Preferences()
self.ui.setupUi(self)
- self.ui.close_button.clicked.connect(self.close)
- self.ui.account_label.setText(account.address)
-
- self.app.service_selection_changed.connect(self._update_icons)
+ self._account_page = None
+ self._vpn_page = None
+ self._email_page = None
self._add_icons()
- self._add_pages()
- self._update_icons(self.account, self.account.services())
+ self._set_account(app.current_account())
+ self._setup_connections()
# only allow a single preferences window at a time.
if PreferencesWindow._current_window is not None:
PreferencesWindow._current_window.close()
PreferencesWindow._current_window = self
+ def _set_account(self, account):
+ """
+ Initially sets, or resets, the currently viewed account.
+ The account might not represent an authenticated user, but
+ just a domain.
+ """
+ self.ui.account_label.setText(account.address)
+ self._add_pages(account)
+ self._update_icons(account)
+ self.ui.pages_widget.setCurrentIndex(0)
+ self.ui.nav_widget.setCurrentRow(0)
+
def _add_icons(self):
"""
Adds all the icons for the different configuration categories.
@@ -114,22 +125,71 @@ class PreferencesWindow(QtGui.QDialog):
email_item.setSizeHint(QtCore.QSize(98, 56))
self._email_item = email_item
- self.ui.nav_widget.currentItemChanged.connect(self._change_page)
- self.ui.nav_widget.setCurrentRow(0)
-
- def _add_pages(self):
+ def _add_pages(self, account):
"""
Adds the pages for the different configuration categories.
"""
- self._account_page = PreferencesAccountPage(
- self, self.account, self.app)
- self._vpn_page = PreferencesVpnPage(self, self.account, self.app)
- self._email_page = PreferencesEmailPage(self, self.account, self.app)
-
+ self._remove_pages() # in case different account was loaded.
+
+ # load placeholder widgets if the page should not be loaded.
+ # the order of the pages is important, and must match the order
+ # of the nav_widget icons.
+ self._account_page = PreferencesAccountPage(self, account, self.app)
+ if account.has_eip():
+ self._vpn_page = PreferencesVpnPage(self, account, self.app)
+ else:
+ self._vpn_page = PreferencesPage(self)
+ if account.has_email():
+ self._email_page = PreferencesEmailPage(self, account, self.app)
+ else:
+ self._email_page = PreferencesPage(self)
self.ui.pages_widget.addWidget(self._account_page)
self.ui.pages_widget.addWidget(self._vpn_page)
self.ui.pages_widget.addWidget(self._email_page)
+ def _remove_pages(self):
+ # deleteLater does not seem to cascade to items in stackLayout
+ # (even with QtCore.Qt.WA_DeleteOnClose attribute).
+ # so, here we call deleteLater() explicitly.
+ if self._account_page is not None:
+ self.ui.pages_widget.removeWidget(self._account_page)
+ self._account_page.teardown_connections()
+ self._account_page.deleteLater()
+ if self._vpn_page is not None:
+ self.ui.pages_widget.removeWidget(self._vpn_page)
+ self._vpn_page.teardown_connections()
+ self._vpn_page.deleteLater()
+ if self._email_page is not None:
+ self.ui.pages_widget.removeWidget(self._email_page)
+ self._email_page.teardown_connections()
+ self._email_page.deleteLater()
+
+ def _setup_connections(self):
+ """
+ setup signal connections
+ """
+ self.ui.nav_widget.currentItemChanged.connect(self._change_page)
+ self.ui.close_button.clicked.connect(self.close)
+ self.app.service_selection_changed.connect(self._update_icons)
+ sig = self.app.signaler
+ sig.srp_auth_ok.connect(self._login_status_changed)
+ sig.srp_logout_ok.connect(self._login_status_changed)
+ sig.srp_status_logged_in.connect(self._update_account)
+ sig.srp_status_not_logged_in.connect(self._update_account)
+
+ def _teardown_connections(self):
+ """
+ clean up signal connections
+ """
+ self.ui.nav_widget.currentItemChanged.disconnect(self._change_page)
+ self.ui.close_button.clicked.disconnect(self.close)
+ self.app.service_selection_changed.disconnect(self._update_icons)
+ sig = self.app.signaler
+ sig.srp_auth_ok.disconnect(self._login_status_changed)
+ sig.srp_logout_ok.disconnect(self._login_status_changed)
+ sig.srp_status_logged_in.disconnect(self._update_account)
+ sig.srp_status_not_logged_in.disconnect(self._update_account)
+
#
# Slots
#
@@ -144,13 +204,8 @@ class PreferencesWindow(QtGui.QDialog):
Close this dialog and destroy it.
"""
PreferencesWindow._current_window = None
-
- # deleteLater does not seem to cascade to items in stackLayout
- # (even with QtCore.Qt.WA_DeleteOnClose attribute).
- # so, here we call deleteLater() explicitly:
- self._account_page.deleteLater()
- self._vpn_page.deleteLater()
- self._email_page.deleteLater()
+ self._teardown_connections()
+ self._remove_pages()
self.deleteLater()
def _change_page(self, current, previous):
@@ -170,17 +225,32 @@ class PreferencesWindow(QtGui.QDialog):
current = previous
self.ui.pages_widget.setCurrentIndex(self.ui.nav_widget.row(current))
- def _update_icons(self, account, services):
+ def _update_icons(self, account):
"""
TRIGGERS:
self.app.service_selection_changed
Change which icons are visible.
"""
- if account != self.account:
- return
+ self._vpn_item.setHidden(not account.has_eip())
+ self._email_item.setHidden(not account.has_email())
- if HAS_EIP:
- self._vpn_item.setHidden(EIP_SERVICE not in services)
- # self._email_item.setHidden(not MX_SERVICE in services)
- # ^^ disable email for now, there is nothing there yet.
+ def _login_status_changed(self):
+ """
+ Triggered by signal srp_auth_ok, srp_logout_ok
+ """
+ self.app.backend.user_get_logged_in_status()
+
+ def _update_account(self):
+ """
+ Triggered by get srp_status_logged_in, srp_status_not_logged_in
+ """
+ self._set_account(self.app.current_account())
+
+ def set_page(self, page):
+ """
+ Jump to a particular page
+ """
+ index = PreferencesWindow._panels[page]
+ self.ui.nav_widget.setCurrentRow(index)
+ self.ui.pages_widget.setCurrentIndex(index)
diff --git a/src/leap/bitmask/gui/qt_browser.py b/src/leap/bitmask/gui/qt_browser.py
new file mode 100644
index 00000000..2d9e20e6
--- /dev/null
+++ b/src/leap/bitmask/gui/qt_browser.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+# qt_browser.py
+# Copyright (C) 2016 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/>.
+"""
+QtWebKit-based browser to display Pixelated User Agent
+"""
+import os
+import urlparse
+
+from PySide import QtCore, QtWebKit, QtGui, QtNetwork
+
+PIXELATED_URI = 'http://localhost:9090'
+
+
+class PixelatedWindow(QtGui.QDialog):
+
+ def __init__(self, parent):
+ super(PixelatedWindow, self).__init__(parent)
+ self.view = QtWebKit.QWebView(self)
+
+ layout = QtGui.QGridLayout()
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.addWidget(self.view)
+ self.setLayout(layout)
+ self.setWindowTitle('Bitmask Mail')
+
+ # For the moment, we need to resize to a sensible default to avoid the
+ # "send" button to be out of view in the compose pane. This should be
+ # removed as soon as pixelated becomes size-responsive.
+ self.resize(800, 700)
+
+ def load_app(self):
+ self.view.load(QtCore.QUrl(PIXELATED_URI))
+ self.view.page().setForwardUnsupportedContent(True)
+ self.view.page().unsupportedContent.connect(self.download)
+
+ self.manager = QtNetwork.QNetworkAccessManager()
+ self.manager.finished.connect(self.finished)
+
+ def download(self, reply):
+ self.request = QtNetwork.QNetworkRequest(reply.url())
+ self.reply = self.manager.get(self.request)
+
+ def finished(self):
+ url = self.reply.url().toString()
+
+ filename = urlparse.parse_qs(url).get('filename', None)
+ if filename:
+ filename = filename[0]
+ name = filename or url
+
+ path = os.path.expanduser(os.path.join(
+ '~', unicode(name).split('/')[-1]))
+ destination = QtGui.QFileDialog.getSaveFileName(self, "Save", path)
+ if destination:
+ filename = destination[0]
+ with open(filename, 'wb') as f:
+ f.write(str(self.reply.readAll()))
+ f.close()
diff --git a/src/leap/bitmask/gui/statemachines.py b/src/leap/bitmask/gui/statemachines.py
index ab48b756..92c5431d 100644
--- a/src/leap/bitmask/gui/statemachines.py
+++ b/src/leap/bitmask/gui/statemachines.py
@@ -40,6 +40,7 @@ class SignallingState(QState):
"""
A state that emits a custom signal on entry.
"""
+
def __init__(self, signal, parent=None, name=None):
"""
Initializer.
@@ -134,6 +135,7 @@ class States(object):
class CompositeEvent(QtCore.QEvent):
+
def __init__(self):
super(CompositeEvent, self).__init__(
QtCore.QEvent.Type(self.ID))
@@ -174,6 +176,7 @@ class Events(QtCore.QObject):
A Wrapper object for containing the events that will be
posted to a composite state machine.
"""
+
def __init__(self, parent=None):
"""
Initializes the QObject with the given parent.
@@ -289,6 +292,7 @@ class ConnectionMachineBuilder(object):
"""
Builder class for state machines made from LEAPConnections.
"""
+
def __init__(self, connection):
"""
:param connection: an instance of a concrete LEAPConnection
@@ -352,7 +356,6 @@ class ConnectionMachineBuilder(object):
:rtype: QStateMachine
"""
# TODO split this method in smaller utility functions.
- parent = kwargs.get('parent', None)
# 1. create machine
machine = CompositeMachine()
diff --git a/src/leap/bitmask/gui/ui/mail_status.ui b/src/leap/bitmask/gui/ui/mail_status.ui
index 8e8f1848..f8ebb5a8 100644
--- a/src/leap/bitmask/gui/ui/mail_status.ui
+++ b/src/leap/bitmask/gui/ui/mail_status.ui
@@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
- <width>417</width>
- <height>185</height>
+ <width>427</width>
+ <height>157</height>
</rect>
</property>
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -20,26 +20,131 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <property name="topMargin">
- <number>0</number>
- </property>
+ <item row="1" column="1">
+ <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="3">
+ <widget class="QLabel" name="lblMailStatusIcon">
+ <property name="minimumSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../../../../../data/resources/icons.qrc">:/images/black/22/off.png</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QWidget" name="email_ready" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="configure_button">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Configure Client</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="or_label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>or</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="open_mail_button">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Open Bitmask Mail</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="email_ready_spacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>10</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
<item row="0" column="0">
- <layout class="QGridLayout" name="gridLayout_3">
- <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="1">
- <widget class="QLabel" name="label_4">
+ <widget class="QLabel" name="mail_icon">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../../../../../data/resources/icons.qrc">:/images/black/32/email.png</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="email_line">
+ <item>
+ <widget class="QLabel" name="email_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -51,85 +156,18 @@
</property>
</widget>
</item>
- <item row="0" column="4">
- <widget class="QLabel" name="lblMailStatusIcon">
- <property name="maximumSize">
+ <item>
+ <spacer name="horizontal1_spacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
<size>
- <width>24</width>
- <height>24</height>
+ <width>1</width>
+ <height>1</height>
</size>
</property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="../../../../../data/resources/icons.qrc">:/images/black/22/off.png</pixmap>
- </property>
- <property name="scaledContents">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="1" colspan="2">
- <widget class="QLabel" name="lblMailReadyHelp">
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="styleSheet">
- <string notr="true">background-color: #e0efd8;
-padding: 10px;</string>
- </property>
- <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="text">
- <string>Congratulations! You are ready to use Bitmask to encrypt your email. Go to &lt;a href=&quot;https://bitmask.net/en/help/email&quot;&gt;https://bitmask.net/en/help/email&lt;/a&gt; for instructions on how to set up your mail client.</string>
- </property>
- <property name="textFormat">
- <enum>Qt::AutoText</enum>
- </property>
- <property name="scaledContents">
- <bool>false</bool>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- <property name="margin">
- <number>0</number>
- </property>
- <property name="indent">
- <number>-1</number>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="../../../../../data/resources/icons.qrc">:/images/black/32/email.png</pixmap>
- </property>
- </widget>
- </item>
- <item row="2" column="1" colspan="2">
- <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>
+ </spacer>
</item>
</layout>
</item>
@@ -137,6 +175,7 @@ padding: 10px;</string>
</widget>
<resources>
<include location="../../../../../data/resources/icons.qrc"/>
+ <include location="dev/leap/client/bitmask_client/data/resources/icons.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/src/leap/bitmask/gui/ui/mainwindow.ui b/src/leap/bitmask/gui/ui/mainwindow.ui
index b1d68c4a..5d8e0f35 100644
--- a/src/leap/bitmask/gui/ui/mainwindow.ui
+++ b/src/leap/bitmask/gui/ui/mainwindow.ui
@@ -75,7 +75,7 @@
<x>0</x>
<y>0</y>
<width>524</width>
- <height>549</height>
+ <height>541</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -306,7 +306,7 @@
<x>0</x>
<y>0</y>
<width>524</width>
- <height>21</height>
+ <height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
diff --git a/src/leap/bitmask/gui/ui/preferences.ui b/src/leap/bitmask/gui/ui/preferences.ui
index 5e30ea57..8e884a63 100644
--- a/src/leap/bitmask/gui/ui/preferences.ui
+++ b/src/leap/bitmask/gui/ui/preferences.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>520</width>
- <height>439</height>
+ <width>630</width>
+ <height>560</height>
</rect>
</property>
<property name="windowTitle">
@@ -60,6 +60,24 @@
<height>16777215</height>
</size>
</property>
+ <property name="styleSheet">
+ <string notr="true">background: palette(base); border: 1px solid palette(dark); border-radius: 2px;</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="midLineWidth">
+ <number>0</number>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
<property name="iconSize">
<size>
<width>32</width>
diff --git a/src/leap/bitmask/gui/ui/preferences_email_page.ui b/src/leap/bitmask/gui/ui/preferences_email_page.ui
index 7cc5bb3c..610a43c7 100644
--- a/src/leap/bitmask/gui/ui/preferences_email_page.ui
+++ b/src/leap/bitmask/gui/ui/preferences_email_page.ui
@@ -6,13 +6,638 @@
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
- <height>300</height>
+ <width>526</width>
+ <height>605</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="email_tabs">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="config_tab">
+ <property name="accessibleName">
+ <string/>
+ </property>
+ <property name="accessibleDescription">
+ <string/>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background: palette(base);</string>
+ </property>
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</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>504</width>
+ <height>537</height>
+ </rect>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background: palette(base);</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_8">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="webmail_box">
+ <property name="title">
+ <string>Bitmask Mail</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QCheckBox" name="webmail_checkbox">
+ <property name="text">
+ <string>Enable Bitmask Mail (needs restart)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="webmail_label">
+ <property name="text">
+ <string>webmail info</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="thunderbird_box">
+ <property name="title">
+ <string>Thunderbird Configuration</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="thunderbird_label">
+ <property name="text">
+ <string>thunderbird information</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="imap_box">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Other Mail Clients Configuration</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QLabel" name="mail_client_label">
+ <property name="text">
+ <string>mail client information</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="1">
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Host</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_9">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="smtp_host_edit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QLabel" name="label_10">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>TLS: off</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLineEdit" name="smtp_port_edit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5">
+ <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>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>IMAP</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Username</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>SMTP</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Host</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="imap_host_edit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="label_6">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="6">
+ <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="1" column="5">
+ <widget class="QLabel" name="label_7">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>TLS: off</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLineEdit" name="imap_port_edit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="username_edit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="password_edit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </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>4</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="my_key_tab">
+ <attribute name="title">
+ <string>Tab 2</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QWidget" name="mykey_box" native="true">
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="4" column="0">
+ <widget class="QLabel" name="pub_label">
+ <property name="text">
+ <string>Public Key</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QPlainTextEdit" name="public_key_edit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <family>Courier</family>
+ </font>
+ </property>
+ <property name="lineWrapMode">
+ <enum>QPlainTextEdit::NoWrap</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QPlainTextEdit" name="fingerprint_edit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>42</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>48</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <family>Courier</family>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="lineWrapMode">
+ <enum>QPlainTextEdit::NoWrap</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="plainText">
+ <string notr="true"/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="expiration_label">
+ <property name="text">
+ <string>Expiration</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="fp_label">
+ <property name="text">
+ <string>Fingerprint</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="uid_edit">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="uid_label">
+ <property name="text">
+ <string>Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="expiration_edit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="1">
+ <widget class="QPushButton" name="export_button">
+ <property name="text">
+ <string>Export Private Key</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="import_button">
+ <property name="text">
+ <string>Import Private Key</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <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>
+ </layout>
+ </item>
+ </layout>
+ <zorder>uid_edit</zorder>
+ <zorder>fp_label</zorder>
+ <zorder>uid_label</zorder>
+ <zorder>expiration_edit</zorder>
+ <zorder>expiration_label</zorder>
+ <zorder>fingerprint_edit</zorder>
+ <zorder>public_key_edit</zorder>
+ <zorder>pub_label</zorder>
+ <zorder></zorder>
+ </widget>
+ </item>
+ <item>
+ <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>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="other_keys_tab">
+ <attribute name="title">
+ <string>Page</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <widget class="QTableWidget" name="keys_table">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="textElideMode">
+ <enum>Qt::ElideRight</enum>
+ </property>
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Email</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Fingerprint</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="message_label">
+ <property name="text">
+ <string>this message should be hidden</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
<resources/>
<connections/>
diff --git a/src/leap/bitmask/gui/ui/wizard.ui b/src/leap/bitmask/gui/ui/wizard.ui
index b125577e..37226d13 100644
--- a/src/leap/bitmask/gui/ui/wizard.ui
+++ b/src/leap/bitmask/gui/ui/wizard.ui
@@ -316,7 +316,7 @@
<item row="1" column="1">
<widget class="QLabel" name="label">
<property name="text">
- <string>https://</string>
+ <string notr="true">https://</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -339,7 +339,7 @@
<item row="0" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
- <string>https://</string>
+ <string notr="true">https://</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>