From e9865f8561b3b506dddb723c780646e976636517 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Wed, 28 Dec 2016 18:44:41 -0800 Subject: [PATCH] Designed the GUI settings dialog, but none of it does anything yet --- onionshare_gui/menu.py | 3 +- onionshare_gui/settings_dialog.py | 227 ++++++++++++++++++++++++++++++ resources/locale/en.json | 18 ++- 3 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 onionshare_gui/settings_dialog.py diff --git a/onionshare_gui/menu.py b/onionshare_gui/menu.py index 59f63048..1027c786 100644 --- a/onionshare_gui/menu.py +++ b/onionshare_gui/menu.py @@ -20,6 +20,7 @@ along with this program. If not, see . from PyQt5 import QtCore, QtWidgets from onionshare import strings +from .settings_dialog import SettingsDialog class Menu(QtWidgets.QMenuBar): """ @@ -39,7 +40,7 @@ class Menu(QtWidgets.QMenuBar): """ Settings action triggered. """ - print("Settings clicked") + SettingsDialog() def quit(self): """ diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py new file mode 100644 index 00000000..93e94c1d --- /dev/null +++ b/onionshare_gui/settings_dialog.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2016 Micah Lee + +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 . +""" +from PyQt5 import QtCore, QtWidgets, QtGui + +from onionshare import strings + +class SettingsDialog(QtWidgets.QDialog): + """ + Settings dialog. + """ + def __init__(self, parent=None): + super(SettingsDialog, self).__init__(parent) + + self.setModal(True) + self.setWindowTitle(strings._('gui_settings_window_title', True)) + + # Connection type: either automatic, control port, or socket file + + # Automatic + self.connection_type_automatic_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_automatic_option', True)) + self.connection_type_automatic_radio.toggled.connect(self.connection_type_automatic_toggled) + + # Control port + self.connection_type_control_port_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_control_port_option', True)) + self.connection_type_control_port_radio.toggled.connect(self.connection_type_control_port_toggled) + + connection_type_control_port_extras_label = QtWidgets.QLabel(strings._('gui_settings_control_port_label', True)) + self.connection_type_control_port_extras_address = QtWidgets.QLineEdit('127.0.0.1') + self.connection_type_control_port_extras_port = QtWidgets.QLineEdit('9051') + connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout() + connection_type_control_port_extras_layout.addWidget(connection_type_control_port_extras_label) + connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_address) + connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_port) + + self.connection_type_control_port_extras = QtWidgets.QWidget() + self.connection_type_control_port_extras.setLayout(connection_type_control_port_extras_layout) + self.connection_type_control_port_extras.hide() + + # Socket file + self.connection_type_socket_file_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_socket_file_option', True)) + self.connection_type_socket_file_radio.toggled.connect(self.connection_type_socket_file_toggled) + + connection_type_socket_file_extras_label = QtWidgets.QLabel(strings._('gui_settings_socket_file_label', True)) + self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit('/var/run/tor/control') + connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout() + connection_type_socket_file_extras_layout.addWidget(connection_type_socket_file_extras_label) + connection_type_socket_file_extras_layout.addWidget(self.connection_type_socket_file_extras_path) + + self.connection_type_socket_file_extras = QtWidgets.QWidget() + self.connection_type_socket_file_extras.setLayout(connection_type_socket_file_extras_layout) + self.connection_type_socket_file_extras.hide() + + # Connection type layout + connection_type_group_layout = QtWidgets.QVBoxLayout() + connection_type_group_layout.addWidget(self.connection_type_automatic_radio) + connection_type_group_layout.addWidget(self.connection_type_control_port_radio) + connection_type_group_layout.addWidget(self.connection_type_socket_file_radio) + connection_type_group_layout.addWidget(self.connection_type_control_port_extras) + connection_type_group_layout.addWidget(self.connection_type_socket_file_extras) + connection_type_group = QtWidgets.QGroupBox(strings._("gui_settings_connection_type_label", True)) + connection_type_group.setLayout(connection_type_group_layout) + + + # Authentication options + + # No authentication + self.authenticate_no_auth_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_no_auth_option', True)) + self.authenticate_no_auth_radio.toggled.connect(self.authenticate_no_auth_toggled) + + # Password + self.authenticate_password_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_password_option', True)) + self.authenticate_password_radio.toggled.connect(self.authenticate_password_toggled) + + authenticate_password_extras_label = QtWidgets.QLabel(strings._('gui_settings_password_label', True)) + self.authenticate_password_extras_password = QtWidgets.QLineEdit('') + authenticate_password_extras_layout = QtWidgets.QHBoxLayout() + authenticate_password_extras_layout.addWidget(authenticate_password_extras_label) + authenticate_password_extras_layout.addWidget(self.authenticate_password_extras_password) + + self.authenticate_password_extras = QtWidgets.QWidget() + self.authenticate_password_extras.setLayout(authenticate_password_extras_layout) + self.authenticate_password_extras.hide() + + # Cookie + self.authenticate_cookie_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_cookie_option', True)) + self.authenticate_cookie_radio.toggled.connect(self.authenticate_cookie_toggled) + + authenticate_cookie_extras_label = QtWidgets.QLabel(strings._('gui_settings_cookie_label', True)) + self.authenticate_cookie_extras_cookie_path = QtWidgets.QLineEdit('/var/run/tor/control.authcookie') + authenticate_cookie_extras_layout = QtWidgets.QHBoxLayout() + authenticate_cookie_extras_layout.addWidget(authenticate_cookie_extras_label) + authenticate_cookie_extras_layout.addWidget(self.authenticate_cookie_extras_cookie_path) + + self.authenticate_cookie_extras = QtWidgets.QWidget() + self.authenticate_cookie_extras.setLayout(authenticate_cookie_extras_layout) + self.authenticate_cookie_extras.hide() + + # Authentication options layout + authenticate_group_layout = QtWidgets.QVBoxLayout() + authenticate_group_layout.addWidget(self.authenticate_no_auth_radio) + authenticate_group_layout.addWidget(self.authenticate_password_radio) + authenticate_group_layout.addWidget(self.authenticate_cookie_radio) + authenticate_group_layout.addWidget(self.authenticate_password_extras) + authenticate_group_layout.addWidget(self.authenticate_cookie_extras) + self.authenticate_group = QtWidgets.QGroupBox(strings._("gui_settings_authenticate_label", True)) + self.authenticate_group.setLayout(authenticate_group_layout) + + + # Buttons + test_button = QtWidgets.QPushButton(strings._('gui_settings_button_test', True)) + test_button.clicked.connect(self.test_clicked) + save_button = QtWidgets.QPushButton(strings._('gui_settings_button_save', True)) + save_button.clicked.connect(self.save_clicked) + cancel_button = QtWidgets.QPushButton(strings._('gui_settings_button_cancel', True)) + cancel_button.clicked.connect(self.cancel_clicked) + buttons_layout = QtWidgets.QHBoxLayout() + buttons_layout.addWidget(test_button) + buttons_layout.addWidget(save_button) + buttons_layout.addWidget(cancel_button) + + # Layout + layout = QtWidgets.QVBoxLayout() + layout.addWidget(connection_type_group) + layout.addWidget(self.authenticate_group) + layout.addStretch() + layout.addLayout(buttons_layout) + self.setLayout(layout) + + # Set default option + self.connection_type_automatic_radio.setChecked(True) + self.authenticate_no_auth_radio.setChecked(True) + + # Show the dialog + self.exec_() + + def connection_type_automatic_toggled(self, checked): + """ + Connection type automatic was toggled. If checked, disable all other + fields. If unchecked, enable all other fields. + """ + if checked: + self.authenticate_group.setEnabled(False) + else: + self.authenticate_group.setEnabled(True) + + def connection_type_control_port_toggled(self, checked): + """ + Connection type control port was toggled. If checked, show extra fields + for Tor control address and port. If unchecked, hide those extra fields. + """ + if checked: + self.connection_type_control_port_extras.show() + else: + self.connection_type_control_port_extras.hide() + + + def connection_type_socket_file_toggled(self, checked): + """ + Connection type socket file was toggled. If checked, show extra fields + for socket file. If unchecked, hide those extra fields. + """ + if checked: + self.connection_type_socket_file_extras.show() + else: + self.connection_type_socket_file_extras.hide() + + def authenticate_no_auth_toggled(self, checked): + """ + Authentication option no authentication was toggled. + """ + pass + + def authenticate_password_toggled(self, checked): + """ + Authentication option password was toggled. If checked, show extra fields + for password auth. If unchecked, hide those extra fields. + """ + if checked: + self.authenticate_password_extras.show() + else: + self.authenticate_password_extras.hide() + + def authenticate_cookie_toggled(self, checked): + """ + Authentication option cookie was toggled. If checked, show extra fields + for cookie auth. If unchecked, hide those extra fields. + """ + if checked: + self.authenticate_cookie_extras.show() + else: + self.authenticate_cookie_extras.hide() + + def test_clicked(self): + """ + Test Settings button clicked. With the given settings, see if we can + successfully connect and authenticate to Tor. + """ + pass + + def save_clicked(self): + """ + Save button clicked. Save current settings to disk. + """ + pass + + def cancel_clicked(self): + """ + Cancel button clicked. + """ + self.close() diff --git a/resources/locale/en.json b/resources/locale/en.json index f69e3133..66494a5f 100644 --- a/resources/locale/en.json +++ b/resources/locale/en.json @@ -61,5 +61,21 @@ "gui_create_stealth": "Create stealth onion service", "gui_menu_file_menu": "&File", "gui_menu_settings_action": "&Settings", - "gui_menu_quit_action": "&Quit" + "gui_menu_quit_action": "&Quit", + "gui_settings_window_title": "Settings", + "gui_settings_connection_type_label": "How should OnionShare connect to Tor?", + "gui_settings_connection_type_automatic_option": "Attempt automatic configuration with Tor Browser", + "gui_settings_connection_type_control_port_option": "Connect using control port", + "gui_settings_connection_type_socket_file_option": "Connect using socket file", + "gui_settings_control_port_label": "Control port", + "gui_settings_socket_file_label": "Socket file", + "gui_settings_authenticate_label": "Tor authentication options", + "gui_settings_authenticate_no_auth_option": "No authentication", + "gui_settings_authenticate_password_option": "Password", + "gui_settings_authenticate_cookie_option": "Cookie", + "gui_settings_password_label": "Password", + "gui_settings_cookie_label": "Cookie path", + "gui_settings_button_test": "Test Settings", + "gui_settings_button_save": "Save", + "gui_settings_button_cancel": "Cancel" }