Show settings at the top of each mode, both mode-specific settings and setting that exist for all mode types

This commit is contained in:
Micah Lee 2019-10-27 18:16:48 -07:00
parent f4e3f92c7b
commit 784d6e8144
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
9 changed files with 243 additions and 59 deletions

View File

@ -91,6 +91,12 @@ class GuiCommon:
border: 0px;
}""",
# Common styles between modes and their child widgets
"mode_settings_toggle_advanced": """
QPushButton {
color: #3f7fcf;
text-align: left;
}
""",
"mode_info_label": """
QLabel {
font-size: 12px;

View File

@ -42,7 +42,7 @@ class MainWindow(QtWidgets.QMainWindow):
# Initialize the window
self.setMinimumWidth(820)
self.setMinimumHeight(660)
self.setMinimumHeight(700)
self.setWindowTitle("OnionShare")
self.setWindowIcon(
QtGui.QIcon(self.common.get_resource_path("images/logo.png"))

View File

@ -23,6 +23,7 @@ from onionshare import strings
from onionshare.common import AutoStopTimer
from .history import IndividualFileHistoryItem
from .mode_settings import ModeSettings
from ..server_status import ServerStatus
from ...threads import OnionThread, AutoStartTimer
@ -42,34 +43,23 @@ class Mode(QtWidgets.QWidget):
starting_server_early = QtCore.pyqtSignal()
set_server_active = QtCore.pyqtSignal(bool)
def __init__(
self,
common,
qtapp,
app,
status_bar,
server_status_label,
system_tray,
filenames=None,
local_only=False,
):
def __init__(self, tab):
super(Mode, self).__init__()
self.common = common
self.qtapp = qtapp
self.app = app
self.tab = tab
self.status_bar = status_bar
self.server_status_label = server_status_label
self.system_tray = system_tray
self.common = tab.common
self.qtapp = self.common.gui.qtapp
self.app = tab.app
self.filenames = filenames
self.status_bar = tab.status_bar
self.server_status_label = tab.status_bar.server_status_label
self.system_tray = tab.system_tray
self.filenames = tab.filenames
# The web object gets created in init()
self.web = None
# Local mode is passed from OnionShareGui
self.local_only = local_only
# Threads start out as None
self.onion_thread = None
self.web_thread = None
@ -81,16 +71,19 @@ class Mode(QtWidgets.QWidget):
self.header_label.setStyleSheet(self.common.gui.css["mode_header_label"])
self.header_label.setAlignment(QtCore.Qt.AlignHCenter)
self.mode_settings = ModeSettings(self.common)
header_layout = QtWidgets.QVBoxLayout()
header_layout.setContentsMargins(0, 0, 0, 0)
header_layout.addWidget(self.header_label)
header_layout.addWidget(self.mode_settings)
self.header = QtWidgets.QWidget()
self.header.setLayout(header_layout)
# Server status
self.server_status = ServerStatus(
self.common, self.qtapp, self.app, None, self.local_only
self.common, self.qtapp, self.app, None, self.common.gui.local_only
)
self.server_status.server_started.connect(self.start_server)
self.server_status.server_stopped.connect(self.stop_server)

View File

@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
"""
OnionShare | https://onionshare.org/
Copyright (C) 2014-2018 Micah Lee <micah@micahflee.com>
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/>.
"""
from PyQt5 import QtCore, QtWidgets, QtGui
from onionshare import strings
class ModeSettings(QtWidgets.QWidget):
"""
A settings widget
"""
def __init__(self, common):
super(ModeSettings, self).__init__()
self.common = common
# Downstream Mode need to fill in this layout with its settings
self.mode_specific_layout = QtWidgets.QVBoxLayout()
# Persistent
self.persistent_checkbox = QtWidgets.QCheckBox()
self.persistent_checkbox.setCheckState(QtCore.Qt.Unchecked)
self.persistent_checkbox.setText(strings._("mode_settings_persistent_checkbox"))
# Public
self.public_checkbox = QtWidgets.QCheckBox()
self.public_checkbox.setCheckState(QtCore.Qt.Unchecked)
self.public_checkbox.setText(strings._("mode_settings_public_checkbox"))
# Whether or not to use an auto-start timer
self.autostart_timer_checkbox = QtWidgets.QCheckBox()
self.autostart_timer_checkbox.setCheckState(QtCore.Qt.Unchecked)
self.autostart_timer_checkbox.setText(
strings._("mode_settings_autostart_timer_checkbox")
)
# Whether or not to use an auto-stop timer
self.autostop_timer_checkbox = QtWidgets.QCheckBox()
self.autostop_timer_checkbox.setCheckState(QtCore.Qt.Unchecked)
self.autostop_timer_checkbox.setText(
strings._("mode_settings_autostop_timer_checkbox")
)
# Legacy address
self.legacy_checkbox = QtWidgets.QCheckBox()
self.legacy_checkbox.clicked.connect(self.update_ui)
self.legacy_checkbox.setCheckState(QtCore.Qt.Unchecked)
self.legacy_checkbox.setText(strings._("mode_settings_legacy_checkbox"))
# Client auth
self.client_auth_checkbox = QtWidgets.QCheckBox()
self.client_auth_checkbox.clicked.connect(self.update_ui)
self.client_auth_checkbox.setCheckState(QtCore.Qt.Unchecked)
self.client_auth_checkbox.setText(
strings._("mode_settings_client_auth_checkbox")
)
# Toggle advanced settings
self.toggle_advanced_button = QtWidgets.QPushButton()
self.toggle_advanced_button.clicked.connect(self.toggle_advanced_clicked)
self.toggle_advanced_button.setFlat(True)
self.toggle_advanced_button.setStyleSheet(
self.common.gui.css["mode_settings_toggle_advanced"]
)
# Advanced group itself
advanced_layout = QtWidgets.QVBoxLayout()
advanced_layout.setContentsMargins(0, 0, 0, 0)
advanced_layout.addWidget(self.public_checkbox)
advanced_layout.addWidget(self.autostart_timer_checkbox)
advanced_layout.addWidget(self.autostop_timer_checkbox)
advanced_layout.addWidget(self.legacy_checkbox)
advanced_layout.addWidget(self.client_auth_checkbox)
self.advanced_widget = QtWidgets.QWidget()
self.advanced_widget.setLayout(advanced_layout)
self.advanced_widget.hide()
layout = QtWidgets.QVBoxLayout()
layout.addLayout(self.mode_specific_layout)
layout.addWidget(self.persistent_checkbox)
layout.addWidget(self.advanced_widget)
layout.addWidget(self.toggle_advanced_button)
self.setLayout(layout)
self.update_ui()
def update_ui(self):
# Update text on advanced group toggle button
if self.advanced_widget.isVisible():
self.toggle_advanced_button.setText(
strings._("mode_settings_advanced_toggle_hide")
)
else:
self.toggle_advanced_button.setText(
strings._("mode_settings_advanced_toggle_show")
)
# Client auth is only a legacy option
if self.client_auth_checkbox.isChecked():
self.legacy_checkbox.setChecked(True)
self.legacy_checkbox.setEnabled(False)
else:
self.legacy_checkbox.setEnabled(True)
if self.legacy_checkbox.isChecked():
self.client_auth_checkbox.show()
else:
self.client_auth_checkbox.hide()
def toggle_advanced_clicked(self):
if self.advanced_widget.isVisible():
self.advanced_widget.hide()
else:
self.advanced_widget.show()
self.update_ui()

View File

@ -41,6 +41,23 @@ class ReceiveMode(Mode):
# Header
self.header_label.setText(strings._("gui_new_tab_receive_button"))
data_dir_label = QtWidgets.QLabel(
strings._("mode_settings_receive_data_dir_label")
)
self.data_dir_lineedit = QtWidgets.QLineEdit()
self.data_dir_lineedit.setReadOnly(True)
self.data_dir_lineedit.setText(self.tab.tab_settings["receive"]["data_dir"])
data_dir_button = QtWidgets.QPushButton(
strings._("mode_settings_receive_data_dir_browse_button")
)
data_dir_button.clicked.connect(self.data_dir_button_clicked)
data_dir_layout = QtWidgets.QHBoxLayout()
data_dir_layout.addWidget(data_dir_label)
data_dir_layout.addWidget(self.data_dir_lineedit)
data_dir_layout.addWidget(data_dir_button)
self.mode_settings.mode_specific_layout.addLayout(data_dir_layout)
# Server status
self.server_status.set_mode("receive")
self.server_status.server_started_finished.connect(self.update_primary_action)
@ -102,6 +119,23 @@ class ReceiveMode(Mode):
self.wrapper_layout.addWidget(self.history, stretch=1)
self.setLayout(self.wrapper_layout)
def data_dir_button_clicked(self):
"""
Browse for a new OnionShare data directory
"""
data_dir = self.data_dir_lineedit.text()
selected_dir = QtWidgets.QFileDialog.getExistingDirectory(
self, strings._("mode_settings_receive_data_dir_label"), data_dir
)
if selected_dir:
self.common.log(
"ReceiveMode",
"data_dir_button_clicked",
f"selected dir: {selected_dir}",
)
self.data_dir_lineedit.setText(selected_dir)
def get_stop_server_autostop_timer_text(self):
"""
Return the string to put on the stop server button, if there's an auto-stop timer

View File

@ -50,6 +50,15 @@ class ShareMode(Mode):
# Header
self.header_label.setText(strings._("gui_new_tab_share_button"))
self.autostop_sharing_checkbox = QtWidgets.QCheckBox()
self.autostop_sharing_checkbox.setCheckState(QtCore.Qt.Checked)
self.autostop_sharing_checkbox.setText(
strings._("mode_settings_share_autostop_sharing_checkbox")
)
self.mode_settings.mode_specific_layout.addWidget(
self.autostop_sharing_checkbox
)
# File selection
self.file_selection = FileSelection(self.common, self)
if self.filenames:

View File

@ -52,6 +52,13 @@ class WebsiteMode(Mode):
# Header
self.header_label.setText(strings._("gui_new_tab_website_button"))
self.disable_csp_checkbox = QtWidgets.QCheckBox()
self.disable_csp_checkbox.setCheckState(QtCore.Qt.Unchecked)
self.disable_csp_checkbox.setText(
strings._("mode_settings_website_disable_csp_checkbox")
)
self.mode_settings.mode_specific_layout.addWidget(self.disable_csp_checkbox)
# File selection
self.file_selection = FileSelection(self.common, self)
if self.filenames:

View File

@ -118,7 +118,24 @@ class Tab(QtWidgets.QWidget):
self.timer.timeout.connect(self.timer_callback)
# Settings for this tab
self.tab_settings = {"persistent": False}
self.tab_settings = {
"persistent": {
"enabled": False,
"private_key": None,
"hidservauth": None,
"password": None,
},
"general": {
"public": False,
"autostart_timer": False,
"autostop_timer": False,
"legacy_addresses": False,
"client_auth": False,
},
"share": {"autostop_sharing": True},
"receive": {"data_dir": self.common.settings.build_default_data_dir()},
"website": {"disable_csp": False},
}
# Persistence button
self.persistence_button = QtWidgets.QPushButton()
@ -133,16 +150,7 @@ class Tab(QtWidgets.QWidget):
self.mode = self.common.gui.MODE_SHARE
self.new_tab.hide()
self.share_mode = ShareMode(
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.status_bar.server_status_label,
self.system_tray,
self.filenames,
self.common.gui.local_only,
)
self.share_mode = ShareMode(self)
self.layout.addWidget(self.share_mode)
self.share_mode.show()
@ -176,16 +184,7 @@ class Tab(QtWidgets.QWidget):
self.mode = self.common.gui.MODE_RECEIVE
self.new_tab.hide()
self.receive_mode = ReceiveMode(
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.status_bar.server_status_label,
self.system_tray,
None,
self.common.gui.local_only,
)
self.receive_mode = ReceiveMode(self)
self.layout.addWidget(self.receive_mode)
self.receive_mode.show()
@ -221,15 +220,7 @@ class Tab(QtWidgets.QWidget):
self.mode = self.common.gui.MODE_WEBSITE
self.new_tab.hide()
self.website_mode = WebsiteMode(
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.status_bar.server_status_label,
self.system_tray,
self.filenames,
)
self.website_mode = WebsiteMode(self)
self.layout.addWidget(self.website_mode)
self.website_mode.show()
@ -508,15 +499,15 @@ class Tab(QtWidgets.QWidget):
def persistence_button_clicked(self):
self.common.log("Tab", "persistence_button_clicked")
if self.tab_settings["persistent"]:
self.tab_settings["persistent"] = False
if self.tab_settings["persistent"]["enabled"]:
self.tab_settings["persistent"]["enabled"] = False
else:
self.tab_settings["persistent"] = True
self.tab_settings["persistent"]["enabled"] = True
self.update_persistence_button()
def update_persistence_button(self):
self.common.log("Tab", "update_persistence_button")
if self.tab_settings["persistent"]:
if self.tab_settings["persistent"]["enabled"]:
self.persistence_button.setIcon(
QtGui.QIcon(
self.common.get_resource_path("images/persistent_enabled.png")
@ -534,7 +525,7 @@ class Tab(QtWidgets.QWidget):
if self.mode is None:
return True
if self.tab_settings["persistent"]:
if self.tab_settings["persistent"]["enabled"]:
dialog_text = strings._("gui_close_tab_warning_persistent_description")
else:
server_status = self.get_mode().server_status

View File

@ -193,5 +193,17 @@
"gui_quit_warning_title": "Are you sure?",
"gui_quit_warning_description": "Sharing is active in some of your tabs. If you quit, all of your tabs will close. Are you sure you want to quit?",
"gui_quit_warning_quit": "Quit",
"gui_quit_warning_cancel": "Cancel"
"gui_quit_warning_cancel": "Cancel",
"mode_settings_advanced_toggle_show": "Show advanced settings",
"mode_settings_advanced_toggle_hide": "Hide advanced settings",
"mode_settings_persistent_checkbox": "Save this tab, and automatically open it when I open OnionShare",
"mode_settings_public_checkbox": "Don't use a password",
"mode_settings_autostart_timer_checkbox": "Start onion service at scheduled time",
"mode_settings_autostop_timer_checkbox": "Stop onion service at scheduled time",
"mode_settings_legacy_checkbox": "Use a legacy address (v2 onion service, not recommended)",
"mode_settings_client_auth_checkbox": "Use client authorization",
"mode_settings_share_autostop_sharing_checkbox": "Stop sharing after files have been sent (uncheck to allow downloading individual files)",
"mode_settings_receive_data_dir_label": "Save files to",
"mode_settings_receive_data_dir_browse_button": "Browse",
"mode_settings_website_disable_csp_checkbox": "Disable Content Security Policy header (allows your website to use third-party resources)"
}