Refactor SettingsDialog into SettingsTab

This commit is contained in:
Micah Lee 2021-10-20 18:56:37 -07:00
parent 7a45f801d9
commit 55d6ac4e3d
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
4 changed files with 115 additions and 121 deletions

View File

@ -24,8 +24,6 @@ from PySide2 import QtCore, QtWidgets, QtGui
from . import strings
from .tor_connection_dialog import TorConnectionDialog
from .tor_settings_dialog import TorSettingsDialog
from .settings_dialog import SettingsDialog
from .widgets import Alert
from .update_checker import UpdateThread
from .tab_widget import TabWidget
@ -245,21 +243,22 @@ class MainWindow(QtWidgets.QMainWindow):
def open_tor_settings(self):
"""
Open the TorSettingsDialog.
Open the TorSettingsTab
"""
self.common.log("MainWindow", "open_tor_settings")
d = TorSettingsDialog(self.common)
d.settings_saved.connect(self.settings_have_changed)
d.exec_()
# d = TorSettingsDialog(self.common)
# d.settings_saved.connect(self.settings_have_changed)
# d.exec_()
def open_settings(self):
"""
Open the SettingsDialog.
Open the SettingsTab
"""
self.common.log("MainWindow", "open_settings")
d = SettingsDialog(self.common)
d.settings_saved.connect(self.settings_have_changed)
d.exec_()
self.tabs.open_settings_tab()
# d = SettingsDialog(self.common)
# d.settings_saved.connect(self.settings_have_changed)
# d.exec_()
def settings_have_changed(self):
self.common.log("OnionShareGui", "settings_have_changed")

View File

@ -19,57 +19,34 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from PySide2 import QtCore, QtWidgets, QtGui
from PySide2.QtCore import Slot, Qt
from PySide2.QtGui import QPalette, QColor
import sys
import platform
import datetime
import re
import os
from onionshare_cli.settings import Settings
from onionshare_cli.onion import (
Onion,
TorErrorInvalidSetting,
TorErrorAutomatic,
TorErrorSocketPort,
TorErrorSocketFile,
TorErrorMissingPassword,
TorErrorUnreadableCookieFile,
TorErrorAuthError,
TorErrorProtocolError,
BundledTorTimeout,
BundledTorBroken,
TorTooOldEphemeral,
TorTooOldStealth,
PortNotAvailable,
)
from . import strings
from .widgets import Alert
from .update_checker import UpdateThread
from .tor_connection_dialog import TorConnectionDialog
from .gui_common import GuiCommon
class SettingsDialog(QtWidgets.QDialog):
class SettingsTab(QtWidgets.QWidget):
"""
Settings dialog.
"""
settings_saved = QtCore.Signal()
def __init__(self, common):
super(SettingsDialog, self).__init__()
def __init__(self, common, tab_id):
super(SettingsTab, self).__init__()
self.common = common
self.common.log("SettingsDialog", "__init__")
self.setModal(True)
self.setWindowTitle(strings._("gui_settings_window_title"))
self.setWindowIcon(QtGui.QIcon(GuiCommon.get_resource_path("images/logo.png")))
self.common.log("SettingsTab", "__init__")
self.system = platform.system()
self.tab_id = tab_id
# Automatic updates options
@ -146,31 +123,26 @@ class SettingsDialog(QtWidgets.QDialog):
# Buttons
self.save_button = QtWidgets.QPushButton(strings._("gui_settings_button_save"))
self.save_button.clicked.connect(self.save_clicked)
self.cancel_button = QtWidgets.QPushButton(
strings._("gui_settings_button_cancel")
)
self.cancel_button.clicked.connect(self.cancel_clicked)
buttons_layout = QtWidgets.QHBoxLayout()
buttons_layout.addStretch()
buttons_layout.addWidget(self.save_button)
buttons_layout.addWidget(self.cancel_button)
# Layout
layout = QtWidgets.QVBoxLayout()
layout.addStretch()
layout.addWidget(autoupdate_group)
if autoupdate_group.isVisible():
layout.addSpacing(20)
layout.addLayout(language_layout)
layout.addLayout(theme_layout)
layout.addSpacing(20)
layout.addStretch()
layout.addWidget(version_label)
layout.addWidget(help_label)
layout.addSpacing(20)
layout.addLayout(buttons_layout)
layout.addStretch()
self.setLayout(layout)
self.cancel_button.setFocus()
self.reload_settings()
@ -199,7 +171,7 @@ class SettingsDialog(QtWidgets.QDialog):
"""
Check for Updates button clicked. Manually force an update check.
"""
self.common.log("SettingsDialog", "check_for_updates")
self.common.log("SettingsTab", "check_for_updates")
# Disable buttons
self._disable_buttons()
self.common.gui.qtapp.processEvents()
@ -261,7 +233,7 @@ class SettingsDialog(QtWidgets.QDialog):
"""
Save button clicked. Save current settings to disk.
"""
self.common.log("SettingsDialog", "save_clicked")
self.common.log("SettingsTab", "save_clicked")
def changed(s1, s2, keys):
"""
@ -301,30 +273,12 @@ class SettingsDialog(QtWidgets.QDialog):
self.settings_saved.emit()
self.close()
def cancel_clicked(self):
"""
Cancel button clicked.
"""
self.common.log("SettingsDialog", "cancel_clicked")
if (
not self.common.gui.local_only
and not self.common.gui.onion.is_authenticated()
):
Alert(
self.common,
strings._("gui_tor_connection_canceled"),
QtWidgets.QMessageBox.Warning,
)
sys.exit()
else:
self.close()
def help_clicked(self):
"""
Help button clicked.
"""
self.common.log("SettingsDialog", "help_clicked")
SettingsDialog.open_help()
self.common.log("SettingsTab", "help_clicked")
SettingsTab.open_help()
@staticmethod
def open_help():
@ -335,7 +289,7 @@ class SettingsDialog(QtWidgets.QDialog):
"""
Return a Settings object that's full of values from the settings dialog.
"""
self.common.log("SettingsDialog", "settings_from_fields")
self.common.log("SettingsTab", "settings_from_fields")
settings = Settings(self.common)
settings.load() # To get the last update timestamp
@ -351,7 +305,7 @@ class SettingsDialog(QtWidgets.QDialog):
return settings
def _update_autoupdate_timestamp(self, autoupdate_timestamp):
self.common.log("SettingsDialog", "_update_autoupdate_timestamp")
self.common.log("SettingsTab", "_update_autoupdate_timestamp")
if autoupdate_timestamp:
dt = datetime.datetime.fromtimestamp(autoupdate_timestamp)
@ -363,18 +317,16 @@ class SettingsDialog(QtWidgets.QDialog):
)
def _disable_buttons(self):
self.common.log("SettingsDialog", "_disable_buttons")
self.common.log("SettingsTab", "_disable_buttons")
self.check_for_updates_button.setEnabled(False)
self.save_button.setEnabled(False)
self.cancel_button.setEnabled(False)
def _enable_buttons(self):
self.common.log("SettingsDialog", "_enable_buttons")
self.common.log("SettingsTab", "_enable_buttons")
# We can't check for updates if we're still not connected to Tor
if not self.common.gui.onion.connected_to_tor:
self.check_for_updates_button.setEnabled(False)
else:
self.check_for_updates_button.setEnabled(True)
self.save_button.setEnabled(True)
self.cancel_button.setEnabled(True)

View File

@ -26,6 +26,8 @@ from . import strings
from .tab import Tab
from .threads import EventHandlerThread
from .gui_common import GuiCommon
from .tor_settings_tab import TorSettingsTab
from .settings_tab import SettingsTab
class TabWidget(QtWidgets.QTabWidget):
@ -116,6 +118,11 @@ class TabWidget(QtWidgets.QTabWidget):
# Active tab was changed
tab_id = self.currentIndex()
self.common.log("TabWidget", "tab_changed", f"Tab was changed to {tab_id}")
# If it's Settings or Tor Settings, ignore
if self.is_settings_tab(tab_id):
return
try:
mode = self.tabs[tab_id].get_mode()
if mode:
@ -160,20 +167,7 @@ class TabWidget(QtWidgets.QTabWidget):
# In macOS, manually create a close button because tabs don't seem to have them otherwise
if self.common.platform == "Darwin":
def close_tab():
self.tabBar().tabCloseRequested.emit(self.indexOf(tab))
tab.close_button = QtWidgets.QPushButton()
tab.close_button.setFlat(True)
tab.close_button.setFixedWidth(40)
tab.close_button.setIcon(
QtGui.QIcon(GuiCommon.get_resource_path("images/close_tab.png"))
)
tab.close_button.clicked.connect(close_tab)
self.tabBar().setTabButton(
index, QtWidgets.QTabBar.RightSide, tab.close_button
)
self.macos_create_close_button(tab, index)
tab.init(mode_settings)
@ -187,6 +181,25 @@ class TabWidget(QtWidgets.QTabWidget):
# Bring the window to front, in case this is being added by an event
self.bring_to_front.emit()
def open_settings_tab(self):
self.common.log("TabWidget", "open_settings_tab")
# See if a settings tab is already open, and if so switch to it
for index in range(self.count()):
if self.is_settings_tab(index):
self.setCurrentIndex(index)
return
settings_tab = SettingsTab(self.common, self.current_tab_id)
self.tabs[self.current_tab_id] = settings_tab
self.current_tab_id += 1
index = self.addTab(settings_tab, strings._("gui_settings_window_title"))
self.setCurrentIndex(index)
# In macOS, manually create a close button because tabs don't seem to have them otherwise
if self.common.platform == "Darwin":
self.macos_create_close_button(settings_tab, index)
def change_title(self, tab_id, title):
shortened_title = title
if len(shortened_title) > 11:
@ -224,9 +237,10 @@ class TabWidget(QtWidgets.QTabWidget):
# Figure out the order of persistent tabs to save in settings
persistent_tabs = []
for index in range(self.count()):
tab = self.widget(index)
if tab.settings.get("persistent", "enabled"):
persistent_tabs.append(tab.settings.id)
if not self.is_settings_tab(index):
tab = self.widget(index)
if tab.settings.get("persistent", "enabled"):
persistent_tabs.append(tab.settings.id)
# Only save if tabs have actually moved
if persistent_tabs != self.common.settings.get("persistent_tabs"):
self.common.settings.set("persistent_tabs", persistent_tabs)
@ -235,11 +249,8 @@ class TabWidget(QtWidgets.QTabWidget):
def close_tab(self, index):
self.common.log("TabWidget", "close_tab", f"{index}")
tab = self.widget(index)
if tab.close_tab():
# If the tab is persistent, delete the settings file from disk
if tab.settings.get("persistent", "enabled"):
tab.settings.delete()
if self.is_settings_tab(index):
# Remove the tab
self.removeTab(index)
del self.tabs[tab.tab_id]
@ -248,7 +259,21 @@ class TabWidget(QtWidgets.QTabWidget):
if self.count() == 0:
self.new_tab_clicked()
self.save_persistent_tabs()
else:
if tab.close_tab():
# If the tab is persistent, delete the settings file from disk
if tab.settings.get("persistent", "enabled"):
tab.settings.delete()
self.save_persistent_tabs()
# Remove the tab
self.removeTab(index)
del self.tabs[tab.tab_id]
# If the last tab is closed, open a new one
if self.count() == 0:
self.new_tab_clicked()
def are_tabs_active(self):
"""
@ -273,6 +298,28 @@ class TabWidget(QtWidgets.QTabWidget):
super(TabWidget, self).resizeEvent(event)
self.move_new_tab_button()
def macos_create_close_button(self, tab, index):
def close_tab():
self.tabBar().tabCloseRequested.emit(self.indexOf(tab))
close_button = QtWidgets.QPushButton()
close_button.setFlat(True)
close_button.setFixedWidth(40)
close_button.setIcon(
QtGui.QIcon(GuiCommon.get_resource_path("images/close_tab.png"))
)
close_button.clicked.connect(close_tab)
self.tabBar().setTabButton(index, QtWidgets.QTabBar.RightSide, tab.close_button)
def is_settings_tab(self, tab_id):
if tab_id not in self.tabs:
return True
return (
type(self.tabs[tab_id]) is SettingsTab
or type(self.tabs[tab_id]) is TorSettingsTab
)
class TabBar(QtWidgets.QTabBar):
"""

View File

@ -34,25 +34,21 @@ from .moat_dialog import MoatDialog
from .gui_common import GuiCommon
class TorSettingsDialog(QtWidgets.QDialog):
class TorSettingsTab(QtWidgets.QWidget):
"""
Settings dialog.
"""
settings_saved = QtCore.Signal()
def __init__(self, common):
super(TorSettingsDialog, self).__init__()
def __init__(self, common, tab_id):
super(TorSettingsTab, self).__init__()
self.common = common
self.common.log("TorSettingsDialog", "__init__")
self.setModal(True)
self.setWindowTitle(strings._("gui_tor_settings_window_title"))
self.setWindowIcon(QtGui.QIcon(GuiCommon.get_resource_path("images/logo.png")))
self.common.log("TorSettingsTab", "__init__")
self.system = platform.system()
self.tab_id = tab_id
# Connection type: either automatic, control port, or socket file
@ -443,7 +439,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
"""
Connection type bundled was toggled
"""
self.common.log("TorSettingsDialog", "connection_type_bundled_toggled")
self.common.log("TorSettingsTab", "connection_type_bundled_toggled")
if checked:
self.tor_settings_group.hide()
self.connection_type_socks.hide()
@ -495,7 +491,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
"""
Request new bridge button clicked
"""
self.common.log("TorSettingsDialog", "bridge_moat_button_clicked")
self.common.log("TorSettingsTab", "bridge_moat_button_clicked")
moat_dialog = MoatDialog(self.common)
moat_dialog.got_bridges.connect(self.bridge_moat_got_bridges)
@ -505,7 +501,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
"""
Got new bridges from moat
"""
self.common.log("TorSettingsDialog", "bridge_moat_got_bridges")
self.common.log("TorSettingsTab", "bridge_moat_got_bridges")
self.bridge_moat_textbox.document().setPlainText(bridges)
self.bridge_moat_textbox.show()
@ -522,7 +518,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
"""
Connection type automatic was toggled. If checked, hide authentication fields.
"""
self.common.log("TorSettingsDialog", "connection_type_automatic_toggled")
self.common.log("TorSettingsTab", "connection_type_automatic_toggled")
if checked:
self.tor_settings_group.hide()
self.connection_type_socks.hide()
@ -533,7 +529,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
Connection type control port was toggled. If checked, show extra fields
for Tor control address and port. If unchecked, hide those extra fields.
"""
self.common.log("TorSettingsDialog", "connection_type_control_port_toggled")
self.common.log("TorSettingsTab", "connection_type_control_port_toggled")
if checked:
self.tor_settings_group.show()
self.connection_type_control_port_extras.show()
@ -547,7 +543,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
Connection type socket file was toggled. If checked, show extra fields
for socket file. If unchecked, hide those extra fields.
"""
self.common.log("TorSettingsDialog", "connection_type_socket_file_toggled")
self.common.log("TorSettingsTab", "connection_type_socket_file_toggled")
if checked:
self.tor_settings_group.show()
self.connection_type_socket_file_extras.show()
@ -560,7 +556,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
"""
Authentication option no authentication was toggled.
"""
self.common.log("TorSettingsDialog", "authenticate_no_auth_toggled")
self.common.log("TorSettingsTab", "authenticate_no_auth_toggled")
if checked:
self.authenticate_password_extras.hide()
else:
@ -571,7 +567,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
Test Tor Settings button clicked. With the given settings, see if we can
successfully connect and authenticate to Tor.
"""
self.common.log("TorSettingsDialog", "test_tor_clicked")
self.common.log("TorSettingsTab", "test_tor_clicked")
settings = self.settings_from_fields()
if not settings:
return
@ -605,7 +601,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
"""
Save button clicked. Save current settings to disk.
"""
self.common.log("TorSettingsDialog", "save_clicked")
self.common.log("TorSettingsTab", "save_clicked")
def changed(s1, s2, keys):
"""
@ -628,7 +624,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
if not self.common.gui.local_only:
if self.common.gui.onion.is_authenticated():
self.common.log(
"TorSettingsDialog", "save_clicked", "Connected to Tor"
"TorSettingsTab", "save_clicked", "Connected to Tor"
)
if changed(
@ -654,7 +650,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
else:
self.common.log(
"TorSettingsDialog", "save_clicked", "Not connected to Tor"
"TorSettingsTab", "save_clicked", "Not connected to Tor"
)
# Tor isn't connected, so try connecting
reboot_onion = True
@ -663,7 +659,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
if reboot_onion:
# Reinitialize the Onion object
self.common.log(
"TorSettingsDialog", "save_clicked", "rebooting the Onion"
"TorSettingsTab", "save_clicked", "rebooting the Onion"
)
self.common.gui.onion.cleanup()
@ -671,7 +667,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
tor_con.start()
self.common.log(
"TorSettingsDialog",
"TorSettingsTab",
"save_clicked",
f"Onion done rebooting, connected to Tor: {self.common.gui.onion.connected_to_tor}",
)
@ -694,7 +690,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
"""
Cancel button clicked.
"""
self.common.log("TorSettingsDialog", "cancel_clicked")
self.common.log("TorSettingsTab", "cancel_clicked")
if (
not self.common.gui.local_only
and not self.common.gui.onion.is_authenticated()
@ -712,7 +708,7 @@ class TorSettingsDialog(QtWidgets.QDialog):
"""
Return a Settings object that's full of values from the settings dialog.
"""
self.common.log("TorSettingsDialog", "settings_from_fields")
self.common.log("TorSettingsTab", "settings_from_fields")
settings = Settings(self.common)
settings.load() # To get the last update timestamp
@ -833,13 +829,13 @@ class TorSettingsDialog(QtWidgets.QDialog):
return settings
def closeEvent(self, e):
self.common.log("TorSettingsDialog", "closeEvent")
self.common.log("TorSettingsTab", "closeEvent")
# On close, if Tor isn't connected, then quit OnionShare altogether
if not self.common.gui.local_only:
if not self.common.gui.onion.is_authenticated():
self.common.log(
"TorSettingsDialog",
"TorSettingsTab",
"closeEvent",
"Closing while not connected to Tor",
)