From e4f9f5f21226922e21a16f1ad1ae28ab3423aea4 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Fri, 1 Oct 2021 23:08:49 +0530 Subject: [PATCH 01/21] Initial structuring of the enable quickstart screen --- cli/onionshare_cli/settings.py | 1 + desktop/src/onionshare/auto_connect.py | 100 +++++++++++++++++++++++++ desktop/src/onionshare/main_window.py | 44 +++++++---- 3 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 desktop/src/onionshare/auto_connect.py diff --git a/cli/onionshare_cli/settings.py b/cli/onionshare_cli/settings.py index 29b59c80..d3bb74e2 100644 --- a/cli/onionshare_cli/settings.py +++ b/cli/onionshare_cli/settings.py @@ -103,6 +103,7 @@ class Settings(object): "socket_file_path": "/var/run/tor/control", "auth_type": "no_auth", "auth_password": "", + "auto_connect": False, "use_autoupdate": True, "autoupdate_timestamp": None, "no_bridges": True, diff --git a/desktop/src/onionshare/auto_connect.py b/desktop/src/onionshare/auto_connect.py new file mode 100644 index 00000000..f7e0c00a --- /dev/null +++ b/desktop/src/onionshare/auto_connect.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2021 Micah Lee, et al. + +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 PySide2 import QtCore, QtWidgets, QtGui + +from onionshare_cli.settings import Settings + +from .gui_common import GuiCommon + + +class AutoConnect(QtWidgets.QWidget): + """ + GUI window that appears in the very beginning to ask user if + should auto connect. + """ + def __init__(self, common, parent=None): + super(AutoConnect, self).__init__(parent) + common.log("AutoConnect", "__init__") + + # Was auto connected? + self.curr_settings = Settings(common) + self.curr_settings.load() + self.auto_connect_enabled = self.curr_settings.get("auto_connect") + + if self.auto_connect_enabled: + self.parent().start_onionshare() + else: + # Onionshare logo + self.image_label = QtWidgets.QLabel() + self.image_label.setPixmap( + QtGui.QPixmap.fromImage( + QtGui.QImage( + GuiCommon.get_resource_path( + "images/{}_logo_text.png".format(common.gui.color_mode) + ) + ) + ) + ) + self.image_label.setFixedSize(180, 40) + image_layout = QtWidgets.QVBoxLayout() + image_layout.addWidget(self.image_label) + self.image = QtWidgets.QWidget() + self.image.setLayout(image_layout) + + # Description and checkbox + description_label = QtWidgets.QLabel("Some description about OnionShare and explain autoconnect stuff") + self.enable_autoconnect_checkbox = QtWidgets.QCheckBox() + self.enable_autoconnect_checkbox.clicked.connect(self.toggle_auto_connect) + self.enable_autoconnect_checkbox.setText( + "Enable automatically connecting to OnionShare" + ) + + # CTA buttons + self.connect_button = QtWidgets.QPushButton("Start OnionShare") + self.connect_button.setStyleSheet( + common.gui.css["server_status_button_stopped"] + ) + self.configure_button = QtWidgets.QPushButton("Configure") + cta_layout = QtWidgets.QHBoxLayout() + cta_layout.addWidget(self.connect_button) + cta_layout.addWidget(self.configure_button) + cta_widget = QtWidgets.QWidget() + cta_widget.setLayout(cta_layout) + + + # Layout + self.layout = QtWidgets.QVBoxLayout() + self.layout.setContentsMargins(0, 0, 0, 0) + self.layout.addStretch() + self.layout.addWidget(self.image) + self.layout.addWidget(description_label) + self.layout.addWidget(self.enable_autoconnect_checkbox) + self.layout.addStretch() + self.layout.addWidget(cta_widget) + self.layout.addStretch() + self.layout.setAlignment(QtCore.Qt.AlignCenter) + self.setLayout(self.layout) + + def toggle_auto_connect(self): + self.curr_settings.set( + "auto_connect", self.enable_autoconnect_checkbox.isChecked() + ) + self.curr_settings.save() diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py index c125741c..22f813ad 100644 --- a/desktop/src/onionshare/main_window.py +++ b/desktop/src/onionshare/main_window.py @@ -23,6 +23,7 @@ import time from PySide2 import QtCore, QtWidgets, QtGui from . import strings +from .auto_connect import AutoConnect from .tor_connection_dialog import TorConnectionDialog from .tor_settings_dialog import TorSettingsDialog from .settings_dialog import SettingsDialog @@ -157,21 +158,17 @@ class MainWindow(QtWidgets.QMainWindow): layout = QtWidgets.QVBoxLayout() layout.addWidget(self.tabs) - central_widget = QtWidgets.QWidget() - central_widget.setLayout(layout) - self.setCentralWidget(central_widget) - self.show() + self.connected_central_widget = QtWidgets.QWidget() + self.connected_central_widget.setLayout(layout) + - # Start the "Connecting to Tor" dialog, which calls onion.connect() - tor_con = TorConnectionDialog(self.common) - tor_con.canceled.connect(self.tor_connection_canceled) - tor_con.open_tor_settings.connect(self.tor_connection_open_tor_settings) - if not self.common.gui.local_only: - tor_con.start() - self.settings_have_changed() - - # After connecting to Tor, check for updates - self.check_for_updates() + # Auto connect OnionShare? + auto_connect = AutoConnect(self.common, self) + if not auto_connect.auto_connect_enabled: + auto_connect.configure_button.clicked.connect(self.open_tor_settings) + auto_connect.connect_button.clicked.connect(self.start_onionshare) + self.setCentralWidget(auto_connect) + self.show() # Create the close warning dialog -- the dialog widget needs to be in the constructor # in order to test it @@ -187,6 +184,25 @@ class MainWindow(QtWidgets.QMainWindow): ) self.close_dialog.setDefaultButton(self.close_dialog.reject_button) + def start_onionshare(self): + """ + Once the user clicks on connect in the initial screen, start tor connection + and show new tab screen + """ + self.setCentralWidget(self.connected_central_widget) + self.show() + + # Start the "Connecting to Tor" dialog, which calls onion.connect() + tor_con = TorConnectionDialog(self.common) + tor_con.canceled.connect(self.tor_connection_canceled) + tor_con.open_tor_settings.connect(self.tor_connection_open_tor_settings) + if not self.common.gui.local_only: + tor_con.start() + self.settings_have_changed() + + # After connecting to Tor, check for updates + self.check_for_updates() + def tor_connection_canceled(self): """ If the user cancels before Tor finishes connecting, ask if they want to From 8e5da9558a997f79ed0e9d2845099b77ed91e14e Mon Sep 17 00:00:00 2001 From: Saptak S Date: Sat, 2 Oct 2021 02:18:25 +0530 Subject: [PATCH 02/21] Adds translatable strings for the different parts of the UI --- desktop/src/onionshare/resources/locale/en.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/desktop/src/onionshare/resources/locale/en.json b/desktop/src/onionshare/resources/locale/en.json index a9fb562a..84332c16 100644 --- a/desktop/src/onionshare/resources/locale/en.json +++ b/desktop/src/onionshare/resources/locale/en.json @@ -41,6 +41,10 @@ "gui_please_wait": "Starting… Click to cancel.", "zip_progress_bar_format": "Compressing: %p%", "gui_tor_settings_window_title": "Tor Settings", + "gui_autoconnect_description": "Some description about OnionShare and explain autoconnect stuff", + "gui_enable_autoconnect_checkbox": "Enable automatically connecting to OnionShare", + "gui_autoconnect_start": "Start OnionShare", + "gui_autoconnect_configure": "Configure", "gui_settings_window_title": "Settings", "gui_settings_autoupdate_label": "Check for new version", "gui_settings_autoupdate_option": "Notify me when a new version is available", From 6520d4ba2521bba432d2de48666c5e98cc9c2ff4 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Sat, 2 Oct 2021 02:19:01 +0530 Subject: [PATCH 03/21] Adjusts spacing and padding of different parts --- desktop/src/onionshare/auto_connect.py | 25 ++++++++++++++++++------- desktop/src/onionshare/gui_common.py | 16 ++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/desktop/src/onionshare/auto_connect.py b/desktop/src/onionshare/auto_connect.py index f7e0c00a..ff456aa4 100644 --- a/desktop/src/onionshare/auto_connect.py +++ b/desktop/src/onionshare/auto_connect.py @@ -22,6 +22,7 @@ from PySide2 import QtCore, QtWidgets, QtGui from onionshare_cli.settings import Settings +from . import strings from .gui_common import GuiCommon @@ -60,19 +61,30 @@ class AutoConnect(QtWidgets.QWidget): self.image.setLayout(image_layout) # Description and checkbox - description_label = QtWidgets.QLabel("Some description about OnionShare and explain autoconnect stuff") + description_label = QtWidgets.QLabel(strings._("gui_autoconnect_description")) self.enable_autoconnect_checkbox = QtWidgets.QCheckBox() self.enable_autoconnect_checkbox.clicked.connect(self.toggle_auto_connect) self.enable_autoconnect_checkbox.setText( - "Enable automatically connecting to OnionShare" + strings._("gui_enable_autoconnect_checkbox") ) + self.enable_autoconnect_checkbox.setStyleSheet( + common.gui.css["enable_autoconnect"] + ) + description_layout = QtWidgets.QVBoxLayout() + description_layout.addWidget(description_label) + description_layout.addWidget(self.enable_autoconnect_checkbox) + description_widget = QtWidgets.QWidget() + description_widget.setLayout(description_layout) # CTA buttons - self.connect_button = QtWidgets.QPushButton("Start OnionShare") + self.connect_button = QtWidgets.QPushButton(strings._("gui_autoconnect_start")) self.connect_button.setStyleSheet( - common.gui.css["server_status_button_stopped"] + common.gui.css["autoconnect_start_button"] + ) + self.configure_button = QtWidgets.QPushButton(strings._("gui_autoconnect_configure")) + self.configure_button.setStyleSheet( + common.gui.css["autoconnect_configure_button"] ) - self.configure_button = QtWidgets.QPushButton("Configure") cta_layout = QtWidgets.QHBoxLayout() cta_layout.addWidget(self.connect_button) cta_layout.addWidget(self.configure_button) @@ -85,8 +97,7 @@ class AutoConnect(QtWidgets.QWidget): self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addStretch() self.layout.addWidget(self.image) - self.layout.addWidget(description_label) - self.layout.addWidget(self.enable_autoconnect_checkbox) + self.layout.addWidget(description_widget) self.layout.addStretch() self.layout.addWidget(cta_widget) self.layout.addStretch() diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py index 019cf193..c092cddd 100644 --- a/desktop/src/onionshare/gui_common.py +++ b/desktop/src/onionshare/gui_common.py @@ -147,6 +147,22 @@ class GuiCommon: QStatusBar::item { border: 0px; }""", + "autoconnect_start_button": """ + QPushButton { + background-color: #5fa416; + color: #ffffff; + padding: 10px 30px; + border: 0; + border-radius: 5px; + }""", + "autoconnect_configure_button": """ + QPushButton { + padding: 9px 29px; + }""", + "enable_autoconnect": """ + QCheckBox { + margin-top: 30px; + }""", # Common styles between modes and their child widgets "mode_settings_toggle_advanced": """ QPushButton { From 8f4c804b48fb15735718bddf2a0d5825d95523ca Mon Sep 17 00:00:00 2001 From: Saptak S Date: Mon, 18 Oct 2021 14:45:36 +0530 Subject: [PATCH 04/21] Updates the strings and alignment of content --- desktop/src/onionshare/auto_connect.py | 22 ++++++++++++------- .../src/onionshare/resources/locale/en.json | 6 ++--- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/desktop/src/onionshare/auto_connect.py b/desktop/src/onionshare/auto_connect.py index ff456aa4..f4378372 100644 --- a/desktop/src/onionshare/auto_connect.py +++ b/desktop/src/onionshare/auto_connect.py @@ -93,15 +93,21 @@ class AutoConnect(QtWidgets.QWidget): # Layout - self.layout = QtWidgets.QVBoxLayout() - self.layout.setContentsMargins(0, 0, 0, 0) + content_layout = QtWidgets.QVBoxLayout() + content_layout.addStretch() + content_layout.addWidget(self.image) + content_layout.addWidget(description_widget) + content_layout.addStretch() + content_layout.addWidget(cta_widget) + content_layout.addStretch() + content_layout.setAlignment(QtCore.Qt.AlignCenter) + content_widget = QtWidgets.QWidgets() + content_widget.setLayout(content_layout) + + self.layout = QtWidgets.QHBoxLayout() + self.layout.addWidget(content_widget) self.layout.addStretch() - self.layout.addWidget(self.image) - self.layout.addWidget(description_widget) - self.layout.addStretch() - self.layout.addWidget(cta_widget) - self.layout.addStretch() - self.layout.setAlignment(QtCore.Qt.AlignCenter) + self.setLayout(self.layout) def toggle_auto_connect(self): diff --git a/desktop/src/onionshare/resources/locale/en.json b/desktop/src/onionshare/resources/locale/en.json index 84332c16..0d142017 100644 --- a/desktop/src/onionshare/resources/locale/en.json +++ b/desktop/src/onionshare/resources/locale/en.json @@ -41,9 +41,9 @@ "gui_please_wait": "Starting… Click to cancel.", "zip_progress_bar_format": "Compressing: %p%", "gui_tor_settings_window_title": "Tor Settings", - "gui_autoconnect_description": "Some description about OnionShare and explain autoconnect stuff", - "gui_enable_autoconnect_checkbox": "Enable automatically connecting to OnionShare", - "gui_autoconnect_start": "Start OnionShare", + "gui_autoconnect_description": "OnionShare relies on the Tor Network, run by thousands of volunteers around the world.", + "gui_enable_autoconnect_checkbox": "Enable automatically connecting to Tor", + "gui_autoconnect_start": "Connect to Tor", "gui_autoconnect_configure": "Configure", "gui_settings_window_title": "Settings", "gui_settings_autoupdate_label": "Check for new version", From 8505bdcca110bde83618c2091afd2223b26de2b8 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Mon, 18 Oct 2021 19:01:22 +0530 Subject: [PATCH 05/21] Cancel button shouldn't give warning message if opened from autoconnect window --- desktop/src/onionshare/auto_connect.py | 6 ++-- desktop/src/onionshare/main_window.py | 8 ++++-- .../resources/images/light_logo_text_bg.png | Bin 0 -> 15778 bytes desktop/src/onionshare/tor_settings_dialog.py | 27 ++++++++++-------- 4 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 desktop/src/onionshare/resources/images/light_logo_text_bg.png diff --git a/desktop/src/onionshare/auto_connect.py b/desktop/src/onionshare/auto_connect.py index f4378372..550a0611 100644 --- a/desktop/src/onionshare/auto_connect.py +++ b/desktop/src/onionshare/auto_connect.py @@ -49,12 +49,12 @@ class AutoConnect(QtWidgets.QWidget): QtGui.QPixmap.fromImage( QtGui.QImage( GuiCommon.get_resource_path( - "images/{}_logo_text.png".format(common.gui.color_mode) + "images/{}_logo_text_bg.png".format(common.gui.color_mode) ) ) ) ) - self.image_label.setFixedSize(180, 40) + self.image_label.setFixedSize(322, 65) image_layout = QtWidgets.QVBoxLayout() image_layout.addWidget(self.image_label) self.image = QtWidgets.QWidget() @@ -101,7 +101,7 @@ class AutoConnect(QtWidgets.QWidget): content_layout.addWidget(cta_widget) content_layout.addStretch() content_layout.setAlignment(QtCore.Qt.AlignCenter) - content_widget = QtWidgets.QWidgets() + content_widget = QtWidgets.QWidget() content_widget.setLayout(content_layout) self.layout = QtWidgets.QHBoxLayout() diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py index 22f813ad..ac100694 100644 --- a/desktop/src/onionshare/main_window.py +++ b/desktop/src/onionshare/main_window.py @@ -165,7 +165,9 @@ class MainWindow(QtWidgets.QMainWindow): # Auto connect OnionShare? auto_connect = AutoConnect(self.common, self) if not auto_connect.auto_connect_enabled: - auto_connect.configure_button.clicked.connect(self.open_tor_settings) + auto_connect.configure_button.clicked.connect( + lambda: self.open_tor_settings("autoconnect") + ) auto_connect.connect_button.clicked.connect(self.start_onionshare) self.setCentralWidget(auto_connect) self.show() @@ -259,12 +261,12 @@ class MainWindow(QtWidgets.QMainWindow): # Wait 1ms for the event loop to finish closing the TorConnectionDialog QtCore.QTimer.singleShot(1, self.open_tor_settings) - def open_tor_settings(self): + def open_tor_settings(self, openner=None): """ Open the TorSettingsDialog. """ self.common.log("MainWindow", "open_tor_settings") - d = TorSettingsDialog(self.common) + d = TorSettingsDialog(self.common, openner) d.settings_saved.connect(self.settings_have_changed) d.exec_() diff --git a/desktop/src/onionshare/resources/images/light_logo_text_bg.png b/desktop/src/onionshare/resources/images/light_logo_text_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..72156b50ce36dab8c61480974770eb465fa7bda1 GIT binary patch literal 15778 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 wNb^Apw!)o-LZ6|~rhul}&R_oxg8WlZ7D)s+ Date: Thu, 28 Oct 2021 14:10:22 +0530 Subject: [PATCH 06/21] Updates content layout --- desktop/src/onionshare/auto_connect.py | 2 +- desktop/src/onionshare/gui_common.py | 8 +++++++- desktop/src/onionshare/resources/locale/en.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/desktop/src/onionshare/auto_connect.py b/desktop/src/onionshare/auto_connect.py index 550a0611..399fef0f 100644 --- a/desktop/src/onionshare/auto_connect.py +++ b/desktop/src/onionshare/auto_connect.py @@ -82,6 +82,7 @@ class AutoConnect(QtWidgets.QWidget): common.gui.css["autoconnect_start_button"] ) self.configure_button = QtWidgets.QPushButton(strings._("gui_autoconnect_configure")) + self.configure_button.setFlat(True) self.configure_button.setStyleSheet( common.gui.css["autoconnect_configure_button"] ) @@ -97,7 +98,6 @@ class AutoConnect(QtWidgets.QWidget): content_layout.addStretch() content_layout.addWidget(self.image) content_layout.addWidget(description_widget) - content_layout.addStretch() content_layout.addWidget(cta_widget) content_layout.addStretch() content_layout.setAlignment(QtCore.Qt.AlignCenter) diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py index c092cddd..de69f360 100644 --- a/desktop/src/onionshare/gui_common.py +++ b/desktop/src/onionshare/gui_common.py @@ -151,17 +151,23 @@ class GuiCommon: QPushButton { background-color: #5fa416; color: #ffffff; - padding: 10px 30px; + padding: 10px; border: 0; border-radius: 5px; }""", "autoconnect_configure_button": """ QPushButton { padding: 9px 29px; + color: #3f7fcf; + text-align: left; }""", "enable_autoconnect": """ QCheckBox { margin-top: 30px; + background: #FCFCFC; + border: 1px solid #DDDBDA; + border-radius: 8px; + padding: 16px; }""", # Common styles between modes and their child widgets "mode_settings_toggle_advanced": """ diff --git a/desktop/src/onionshare/resources/locale/en.json b/desktop/src/onionshare/resources/locale/en.json index 0d142017..84312c8e 100644 --- a/desktop/src/onionshare/resources/locale/en.json +++ b/desktop/src/onionshare/resources/locale/en.json @@ -44,7 +44,7 @@ "gui_autoconnect_description": "OnionShare relies on the Tor Network, run by thousands of volunteers around the world.", "gui_enable_autoconnect_checkbox": "Enable automatically connecting to Tor", "gui_autoconnect_start": "Connect to Tor", - "gui_autoconnect_configure": "Configure", + "gui_autoconnect_configure": "Network Settings", "gui_settings_window_title": "Settings", "gui_settings_autoupdate_label": "Check for new version", "gui_settings_autoupdate_option": "Notify me when a new version is available", From 3283fb76077ca40601de4ad3d1532862f20b5108 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Tue, 30 Nov 2021 02:48:20 +0530 Subject: [PATCH 07/21] Updates autoconnect to use tab widget --- .../{auto_connect.py => connection_tab.py} | 77 +++++++++++++++++-- desktop/src/onionshare/main_window.py | 36 +-------- desktop/src/onionshare/tab_widget.py | 48 +++++++++++- 3 files changed, 120 insertions(+), 41 deletions(-) rename desktop/src/onionshare/{auto_connect.py => connection_tab.py} (64%) diff --git a/desktop/src/onionshare/auto_connect.py b/desktop/src/onionshare/connection_tab.py similarity index 64% rename from desktop/src/onionshare/auto_connect.py rename to desktop/src/onionshare/connection_tab.py index 399fef0f..eeb91d1e 100644 --- a/desktop/src/onionshare/auto_connect.py +++ b/desktop/src/onionshare/connection_tab.py @@ -24,16 +24,25 @@ from onionshare_cli.settings import Settings from . import strings from .gui_common import GuiCommon +from .tor_connection import TorConnectionWidget -class AutoConnect(QtWidgets.QWidget): +class AutoConnectTab(QtWidgets.QWidget): """ - GUI window that appears in the very beginning to ask user if + Initial Tab that appears in the very beginning to ask user if should auto connect. """ - def __init__(self, common, parent=None): - super(AutoConnect, self).__init__(parent) - common.log("AutoConnect", "__init__") + + close_this_tab = QtCore.Signal() + tor_is_connected = QtCore.Signal() + tor_is_disconnected = QtCore.Signal() + def __init__(self, common, tab_id, status_bar): + super(AutoConnectTab, self).__init__() + self.common = common + self.common.log("AutoConnectTab", "__init__") + + self.status_bar = status_bar + self.tab_id = tab_id # Was auto connected? self.curr_settings = Settings(common) @@ -76,8 +85,20 @@ class AutoConnect(QtWidgets.QWidget): description_widget = QtWidgets.QWidget() description_widget.setLayout(description_layout) + # Tor connection widget + self.tor_con = TorConnectionWidget(self.common, self.status_bar) + self.tor_con.success.connect(self.tor_con_success) + self.tor_con.fail.connect(self.tor_con_fail) + self.tor_con.hide() + + # Error label + self.error_label = QtWidgets.QLabel() + self.error_label.setStyleSheet(self.common.gui.css["tor_settings_error"]) + self.error_label.setWordWrap(True) + # CTA buttons self.connect_button = QtWidgets.QPushButton(strings._("gui_autoconnect_start")) + self.connect_button.clicked.connect(self.connect_clicked) self.connect_button.setStyleSheet( common.gui.css["autoconnect_start_button"] ) @@ -98,6 +119,7 @@ class AutoConnect(QtWidgets.QWidget): content_layout.addStretch() content_layout.addWidget(self.image) content_layout.addWidget(description_widget) + content_layout.addWidget(self.tor_con) content_layout.addWidget(cta_widget) content_layout.addStretch() content_layout.setAlignment(QtCore.Qt.AlignCenter) @@ -111,7 +133,52 @@ class AutoConnect(QtWidgets.QWidget): self.setLayout(self.layout) def toggle_auto_connect(self): + """ + Auto connect checkbox clicked + """ + self.common.log("AutoConnectTab", "autoconnect_checkbox_clicked") self.curr_settings.set( "auto_connect", self.enable_autoconnect_checkbox.isChecked() ) self.curr_settings.save() + + def connect_clicked(self): + """ + Connect button clicked. Try to connect to tor. + """ + self.common.log("AutoConnectTab", "connect_clicked") + + self.error_label.setText("") + self.connect_button.hide() + self.configure_button.hide() + + if not self.common.gui.local_only: + self.tor_con.show() + self.tor_con.start(self.curr_settings) + else: + self.close_this_tab.emit() + + def tor_con_success(self): + """ + Finished testing tor connection. + """ + self.tor_con.hide() + self.connect_button.show() + self.configure_button.show() + if ( + self.common.gui.onion.is_authenticated() + and not self.tor_con.wasCanceled() + ): + # Tell the tabs that Tor is connected + self.tor_is_connected.emit() + # Close the tab + self.close_this_tab.emit() + + def tor_con_fail(self, msg): + """ + Finished testing tor connection. + """ + self.tor_con.hide() + self.connect_button.show() + self.configure_button.show() + self.error_label.setText(msg) diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py index fd550970..8c38c38d 100644 --- a/desktop/src/onionshare/main_window.py +++ b/desktop/src/onionshare/main_window.py @@ -155,19 +155,10 @@ class MainWindow(QtWidgets.QMainWindow): layout = QtWidgets.QVBoxLayout() layout.addWidget(self.tabs) - self.connected_central_widget = QtWidgets.QWidget() - self.connected_central_widget.setLayout(layout) - - - # Auto connect OnionShare? - auto_connect = AutoConnect(self.common, self) - if not auto_connect.auto_connect_enabled: - auto_connect.configure_button.clicked.connect( - lambda: self.open_tor_settings("autoconnect") - ) - auto_connect.connect_button.clicked.connect(self.start_onionshare) - self.setCentralWidget(auto_connect) - self.show() + central_widget = QtWidgets.QWidget() + central_widget.setLayout(layout) + self.setCentralWidget(central_widget) + self.show() # Create the close warning dialog -- the dialog widget needs to be in the constructor # in order to test it @@ -183,25 +174,6 @@ class MainWindow(QtWidgets.QMainWindow): ) self.close_dialog.setDefaultButton(self.close_dialog.reject_button) - def start_onionshare(self): - """ - Once the user clicks on connect in the initial screen, start tor connection - and show new tab screen - """ - self.setCentralWidget(self.connected_central_widget) - self.show() - - # Start the "Connecting to Tor" dialog, which calls onion.connect() - tor_con = TorConnectionDialog(self.common) - tor_con.canceled.connect(self.tor_connection_canceled) - tor_con.open_tor_settings.connect(self.tor_connection_open_tor_settings) - if not self.common.gui.local_only: - tor_con.start() - self.settings_have_changed() - - # After connecting to Tor, check for updates - self.check_for_updates() - def tor_connection_canceled(self): """ If the user cancels before Tor finishes connecting, ask if they want to diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py index 7162fcc4..d26947e4 100644 --- a/desktop/src/onionshare/tab_widget.py +++ b/desktop/src/onionshare/tab_widget.py @@ -28,6 +28,7 @@ from .threads import EventHandlerThread from .gui_common import GuiCommon from .tor_settings_tab import TorSettingsTab from .settings_tab import SettingsTab +from .connection_tab import AutoConnectTab class TabWidget(QtWidgets.QTabWidget): @@ -98,6 +99,7 @@ class TabWidget(QtWidgets.QTabWidget): if not ( type(self.tabs[tab_id]) is SettingsTab or type(self.tabs[tab_id]) is TorSettingsTab + or type(self.tabs[tab_id]) is AutoConnectTab ): self.tabs[tab_id].cleanup() @@ -138,6 +140,7 @@ class TabWidget(QtWidgets.QTabWidget): if ( type(self.tabs[tab_id]) is SettingsTab or type(self.tabs[tab_id]) is TorSettingsTab + or type(self.tabs[tab_id]) is AutoConnectTab ): # Blank the server status indicator self.status_bar.server_status_image_label.clear() @@ -159,8 +162,12 @@ class TabWidget(QtWidgets.QTabWidget): pass def new_tab_clicked(self): - # Create a new tab - self.add_tab() + # if already connected to tor, create a new tab + # Else open the initial connection tab + if self.common.gui.onion.is_authenticated(): + self.add_tab() + else: + self.open_connection_tab() def load_tab(self, mode_settings_id): # Load the tab's mode settings @@ -198,6 +205,22 @@ 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_connection_tab(self): + self.common.log("TabWidget", "open_connection_tab") + + # See if a connection tab is already open, and if so switch to it + for tab_id in self.tabs: + if type(self.tabs[tab_id]) is AutoConnectTab: + self.setCurrentIndex(self.indexOf(self.tabs[tab_id])) + return + + connection_tab = AutoConnectTab(self.common, self.current_tab_id, self.status_bar) + connection_tab.close_this_tab.connect(self.close_connection_tab) + self.tabs[self.current_tab_id] = connection_tab + self.current_tab_id += 1 + index = self.addTab(connection_tab, strings._("gui_settings_window_title")) + self.setCurrentIndex(index) + def open_settings_tab(self): self.common.log("TabWidget", "open_settings_tab") @@ -281,6 +304,7 @@ class TabWidget(QtWidgets.QTabWidget): if not ( type(self.tabs[tab_id]) is SettingsTab or type(self.tabs[tab_id]) is TorSettingsTab + or type(self.tabs[tab_id]) is AutoConnectTab ): tab = self.widget(self.indexOf(self.tabs[tab_id])) if tab.settings.get("persistent", "enabled"): @@ -298,6 +322,7 @@ class TabWidget(QtWidgets.QTabWidget): if ( type(self.tabs[tab_id]) is SettingsTab or type(self.tabs[tab_id]) is TorSettingsTab + or type(self.tabs[tab_id]) is AutoConnectTab ): self.common.log("TabWidget", "closing a settings tab") @@ -333,6 +358,14 @@ class TabWidget(QtWidgets.QTabWidget): else: self.common.log("TabWidget", "user does not want to close the tab") + def close_connection_tab(self): + self.common.log("TabWidget", "close_connection_tab") + for tab_id in self.tabs: + if type(self.tabs[tab_id]) is AutoConnectTab: + index = self.indexOf(self.tabs[tab_id]) + self.close_tab(index) + return + def close_settings_tab(self): self.common.log("TabWidget", "close_settings_tab") for tab_id in self.tabs: @@ -357,6 +390,7 @@ class TabWidget(QtWidgets.QTabWidget): if not ( type(self.tabs[tab_id]) is SettingsTab or type(self.tabs[tab_id]) is TorSettingsTab + or type(self.tabs[tab_id]) is AutoConnectTab ): mode = self.tabs[tab_id].get_mode() if mode: @@ -381,7 +415,10 @@ class TabWidget(QtWidgets.QTabWidget): if type(self.tabs[tab_id]) is SettingsTab: self.tabs[tab_id].tor_is_connected() else: - if not type(self.tabs[tab_id]) is TorSettingsTab: + if not ( + type(self.tabs[tab_id]) is TorSettingsTab + or type(self.tabs[tab_id]) is AutoConnectTab + ): mode = self.tabs[tab_id].get_mode() if mode: mode.tor_connection_started() @@ -391,7 +428,10 @@ class TabWidget(QtWidgets.QTabWidget): if type(self.tabs[tab_id]) is SettingsTab: self.tabs[tab_id].tor_is_disconnected() else: - if not type(self.tabs[tab_id]) is TorSettingsTab: + if not ( + type(self.tabs[tab_id]) is TorSettingsTab + or type(self.tabs[tab_id]) is AutoConnectTab + ): mode = self.tabs[tab_id].get_mode() if mode: mode.tor_connection_stopped() From c8224a25460f6fa8c70698f8d3b98789998da2e1 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Tue, 30 Nov 2021 03:08:56 +0530 Subject: [PATCH 08/21] Resize components in the connection tab --- desktop/src/onionshare/connection_tab.py | 2 ++ desktop/src/onionshare/gui_common.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py index eeb91d1e..8d6aef29 100644 --- a/desktop/src/onionshare/connection_tab.py +++ b/desktop/src/onionshare/connection_tab.py @@ -76,6 +76,7 @@ class AutoConnectTab(QtWidgets.QWidget): self.enable_autoconnect_checkbox.setText( strings._("gui_enable_autoconnect_checkbox") ) + self.enable_autoconnect_checkbox.setFixedWidth(400) self.enable_autoconnect_checkbox.setStyleSheet( common.gui.css["enable_autoconnect"] ) @@ -99,6 +100,7 @@ class AutoConnectTab(QtWidgets.QWidget): # CTA buttons self.connect_button = QtWidgets.QPushButton(strings._("gui_autoconnect_start")) self.connect_button.clicked.connect(self.connect_clicked) + self.connect_button.setFixedWidth(150) self.connect_button.setStyleSheet( common.gui.css["autoconnect_start_button"] ) diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py index c9c0b349..5b0cb907 100644 --- a/desktop/src/onionshare/gui_common.py +++ b/desktop/src/onionshare/gui_common.py @@ -169,7 +169,7 @@ class GuiCommon: background: #FCFCFC; border: 1px solid #DDDBDA; border-radius: 8px; - padding: 16px; + padding: 24px 16px; }""", # Common styles between modes and their child widgets "mode_settings_toggle_advanced": """ From 1cde115f6ed17e71f0a03e81f5af826a86301500 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Tue, 30 Nov 2021 03:11:29 +0530 Subject: [PATCH 09/21] Corrects the auto connect with checkbox logic --- desktop/src/onionshare/connection_tab.py | 147 ++++++++++++----------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py index 8d6aef29..f066c6ed 100644 --- a/desktop/src/onionshare/connection_tab.py +++ b/desktop/src/onionshare/connection_tab.py @@ -49,90 +49,91 @@ class AutoConnectTab(QtWidgets.QWidget): self.curr_settings.load() self.auto_connect_enabled = self.curr_settings.get("auto_connect") - if self.auto_connect_enabled: - self.parent().start_onionshare() - else: - # Onionshare logo - self.image_label = QtWidgets.QLabel() - self.image_label.setPixmap( - QtGui.QPixmap.fromImage( - QtGui.QImage( - GuiCommon.get_resource_path( - "images/{}_logo_text_bg.png".format(common.gui.color_mode) - ) + # Onionshare logo + self.image_label = QtWidgets.QLabel() + self.image_label.setPixmap( + QtGui.QPixmap.fromImage( + QtGui.QImage( + GuiCommon.get_resource_path( + "images/{}_logo_text_bg.png".format(common.gui.color_mode) ) ) ) - self.image_label.setFixedSize(322, 65) - image_layout = QtWidgets.QVBoxLayout() - image_layout.addWidget(self.image_label) - self.image = QtWidgets.QWidget() - self.image.setLayout(image_layout) + ) + self.image_label.setFixedSize(322, 65) + image_layout = QtWidgets.QVBoxLayout() + image_layout.addWidget(self.image_label) + self.image = QtWidgets.QWidget() + self.image.setLayout(image_layout) - # Description and checkbox - description_label = QtWidgets.QLabel(strings._("gui_autoconnect_description")) - self.enable_autoconnect_checkbox = QtWidgets.QCheckBox() - self.enable_autoconnect_checkbox.clicked.connect(self.toggle_auto_connect) - self.enable_autoconnect_checkbox.setText( - strings._("gui_enable_autoconnect_checkbox") - ) - self.enable_autoconnect_checkbox.setFixedWidth(400) - self.enable_autoconnect_checkbox.setStyleSheet( - common.gui.css["enable_autoconnect"] - ) - description_layout = QtWidgets.QVBoxLayout() - description_layout.addWidget(description_label) - description_layout.addWidget(self.enable_autoconnect_checkbox) - description_widget = QtWidgets.QWidget() - description_widget.setLayout(description_layout) + # Description and checkbox + description_label = QtWidgets.QLabel(strings._("gui_autoconnect_description")) + self.enable_autoconnect_checkbox = QtWidgets.QCheckBox() + self.enable_autoconnect_checkbox.clicked.connect(self.toggle_auto_connect) + self.enable_autoconnect_checkbox.setText( + strings._("gui_enable_autoconnect_checkbox") + ) + self.enable_autoconnect_checkbox.setFixedWidth(400) + self.enable_autoconnect_checkbox.setStyleSheet( + common.gui.css["enable_autoconnect"] + ) + description_layout = QtWidgets.QVBoxLayout() + description_layout.addWidget(description_label) + description_layout.addWidget(self.enable_autoconnect_checkbox) + description_widget = QtWidgets.QWidget() + description_widget.setLayout(description_layout) - # Tor connection widget - self.tor_con = TorConnectionWidget(self.common, self.status_bar) - self.tor_con.success.connect(self.tor_con_success) - self.tor_con.fail.connect(self.tor_con_fail) - self.tor_con.hide() + # Tor connection widget + self.tor_con = TorConnectionWidget(self.common, self.status_bar) + self.tor_con.success.connect(self.tor_con_success) + self.tor_con.fail.connect(self.tor_con_fail) + self.tor_con.hide() - # Error label - self.error_label = QtWidgets.QLabel() - self.error_label.setStyleSheet(self.common.gui.css["tor_settings_error"]) - self.error_label.setWordWrap(True) + # Error label + self.error_label = QtWidgets.QLabel() + self.error_label.setStyleSheet(self.common.gui.css["tor_settings_error"]) + self.error_label.setWordWrap(True) - # CTA buttons - self.connect_button = QtWidgets.QPushButton(strings._("gui_autoconnect_start")) - self.connect_button.clicked.connect(self.connect_clicked) - self.connect_button.setFixedWidth(150) - self.connect_button.setStyleSheet( - common.gui.css["autoconnect_start_button"] - ) - self.configure_button = QtWidgets.QPushButton(strings._("gui_autoconnect_configure")) - self.configure_button.setFlat(True) - self.configure_button.setStyleSheet( - common.gui.css["autoconnect_configure_button"] - ) - cta_layout = QtWidgets.QHBoxLayout() - cta_layout.addWidget(self.connect_button) - cta_layout.addWidget(self.configure_button) - cta_widget = QtWidgets.QWidget() - cta_widget.setLayout(cta_layout) + # CTA buttons + self.connect_button = QtWidgets.QPushButton(strings._("gui_autoconnect_start")) + self.connect_button.clicked.connect(self.connect_clicked) + self.connect_button.setFixedWidth(150) + self.connect_button.setStyleSheet( + common.gui.css["autoconnect_start_button"] + ) + self.configure_button = QtWidgets.QPushButton(strings._("gui_autoconnect_configure")) + self.configure_button.clicked.connect(self.open_tor_settings) + self.configure_button.setFlat(True) + self.configure_button.setStyleSheet( + common.gui.css["autoconnect_configure_button"] + ) + cta_layout = QtWidgets.QHBoxLayout() + cta_layout.addWidget(self.connect_button) + cta_layout.addWidget(self.configure_button) + cta_widget = QtWidgets.QWidget() + cta_widget.setLayout(cta_layout) - # Layout - content_layout = QtWidgets.QVBoxLayout() - content_layout.addStretch() - content_layout.addWidget(self.image) - content_layout.addWidget(description_widget) - content_layout.addWidget(self.tor_con) - content_layout.addWidget(cta_widget) - content_layout.addStretch() - content_layout.setAlignment(QtCore.Qt.AlignCenter) - content_widget = QtWidgets.QWidget() - content_widget.setLayout(content_layout) + # Layout + content_layout = QtWidgets.QVBoxLayout() + content_layout.addStretch() + content_layout.addWidget(self.image) + content_layout.addWidget(description_widget) + content_layout.addWidget(self.tor_con) + content_layout.addWidget(cta_widget) + content_layout.addStretch() + content_layout.setAlignment(QtCore.Qt.AlignCenter) + content_widget = QtWidgets.QWidget() + content_widget.setLayout(content_layout) - self.layout = QtWidgets.QHBoxLayout() - self.layout.addWidget(content_widget) - self.layout.addStretch() + self.layout = QtWidgets.QHBoxLayout() + self.layout.addWidget(content_widget) + self.layout.addStretch() - self.setLayout(self.layout) + self.setLayout(self.layout) + + if self.auto_connect_enabled: + self.connect_clicked() def toggle_auto_connect(self): """ From e2dbe6089a3b640f7890e805c221de5cc51cf5b4 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Tue, 30 Nov 2021 03:23:16 +0530 Subject: [PATCH 10/21] Opens TorSettingsTab when clicked on network settings --- desktop/src/onionshare/connection_tab.py | 6 +++++- desktop/src/onionshare/tab_widget.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py index f066c6ed..4c06b713 100644 --- a/desktop/src/onionshare/connection_tab.py +++ b/desktop/src/onionshare/connection_tab.py @@ -36,13 +36,14 @@ class AutoConnectTab(QtWidgets.QWidget): close_this_tab = QtCore.Signal() tor_is_connected = QtCore.Signal() tor_is_disconnected = QtCore.Signal() - def __init__(self, common, tab_id, status_bar): + def __init__(self, common, tab_id, status_bar, parent=None): super(AutoConnectTab, self).__init__() self.common = common self.common.log("AutoConnectTab", "__init__") self.status_bar = status_bar self.tab_id = tab_id + self.parent = parent # Was auto connected? self.curr_settings = Settings(common) @@ -145,6 +146,9 @@ class AutoConnectTab(QtWidgets.QWidget): ) self.curr_settings.save() + def open_tor_settings(self): + self.parent.open_tor_settings_tab() + def connect_clicked(self): """ Connect button clicked. Try to connect to tor. diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py index d26947e4..b5c18023 100644 --- a/desktop/src/onionshare/tab_widget.py +++ b/desktop/src/onionshare/tab_widget.py @@ -214,7 +214,7 @@ class TabWidget(QtWidgets.QTabWidget): self.setCurrentIndex(self.indexOf(self.tabs[tab_id])) return - connection_tab = AutoConnectTab(self.common, self.current_tab_id, self.status_bar) + connection_tab = AutoConnectTab(self.common, self.current_tab_id, self.status_bar, parent=self) connection_tab.close_this_tab.connect(self.close_connection_tab) self.tabs[self.current_tab_id] = connection_tab self.current_tab_id += 1 From 4c3af76a5bf8513452e04d36f68653f660c1379f Mon Sep 17 00:00:00 2001 From: Saptak S Date: Fri, 3 Dec 2021 18:27:03 +0530 Subject: [PATCH 11/21] Creates a toggle checkbox --- desktop/src/onionshare/connection_tab.py | 12 +++--- desktop/src/onionshare/gui_common.py | 47 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py index 4c06b713..a0d7b78f 100644 --- a/desktop/src/onionshare/connection_tab.py +++ b/desktop/src/onionshare/connection_tab.py @@ -23,7 +23,7 @@ from PySide2 import QtCore, QtWidgets, QtGui from onionshare_cli.settings import Settings from . import strings -from .gui_common import GuiCommon +from .gui_common import GuiCommon, ToggleCheckbox from .tor_connection import TorConnectionWidget @@ -69,11 +69,13 @@ class AutoConnectTab(QtWidgets.QWidget): # Description and checkbox description_label = QtWidgets.QLabel(strings._("gui_autoconnect_description")) - self.enable_autoconnect_checkbox = QtWidgets.QCheckBox() - self.enable_autoconnect_checkbox.clicked.connect(self.toggle_auto_connect) - self.enable_autoconnect_checkbox.setText( + self.enable_autoconnect_checkbox = ToggleCheckbox( strings._("gui_enable_autoconnect_checkbox") - ) + ) + self.enable_autoconnect_checkbox.clicked.connect(self.toggle_auto_connect) + # self.enable_autoconnect_checkbox.setText( + # strings._("gui_enable_autoconnect_checkbox") + # ) self.enable_autoconnect_checkbox.setFixedWidth(400) self.enable_autoconnect_checkbox.setStyleSheet( common.gui.css["enable_autoconnect"] diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py index 5b0cb907..aa3a596e 100644 --- a/desktop/src/onionshare/gui_common.py +++ b/desktop/src/onionshare/gui_common.py @@ -21,6 +21,7 @@ along with this program. If not, see . import os import shutil from pkg_resources import resource_filename +from PySide2 import QtCore, QtWidgets, QtGui from . import strings from onionshare_cli.onion import ( @@ -170,6 +171,10 @@ class GuiCommon: border: 1px solid #DDDBDA; border-radius: 8px; padding: 24px 16px; + } + QCheckBox::indicator { + width: 0; + height: 0; }""", # Common styles between modes and their child widgets "mode_settings_toggle_advanced": """ @@ -531,3 +536,45 @@ class GuiCommon: return strings._("error_port_not_available") return None + + +class ToggleCheckbox(QtWidgets.QCheckBox): + def __init__(self, text): + super(ToggleCheckbox, self).__init__(text) + print(text) + # Set default parameters + self.setCursor(QtCore.Qt.PointingHandCursor) + self.w = 50 + self.h = 24 + self.bg_color = "#D4D4D4" + self.circle_color = "#BDBDBD" + self.active_color = "#4E0D4E" + self.inactive_color = "" + + def hitButton(self, pos): + return self.toggleRect.contains(pos) + + def paintEvent(self, e): + painter = QtGui.QPainter(self) + painter.setRenderHint(QtGui.QPainter.Antialiasing) + painter.setPen(QtCore.Qt.NoPen) + opt = QtWidgets.QStyleOptionButton() + opt.init(self) + self.initStyleOption(opt) + s = self.style() + s.drawControl(QtWidgets.QStyle.CE_CheckBox, opt, painter, self) + + rect = QtCore.QRect(s.subElementRect(QtWidgets.QStyle.SE_CheckBoxContents, opt, self)) + x = rect.width() - rect.x() - self.w + 20 # 20 is the padding between text and toggle + y = self.height() / 2 - self.h / 2 + self.y() / 2 + self.toggleRect = QtCore.QRect(x, y, self.w, self.h) + painter.setBrush(QtGui.QColor(self.bg_color)) + painter.drawRoundedRect(x, y, self.w, self.h, self.h / 2, self.h / 2) + if not self.isChecked(): + painter.setBrush(QtGui.QColor(self.circle_color)) + painter.drawEllipse(x, y - 3, self.h + 6, self.h + 6) + else: + painter.setBrush(QtGui.QColor(self.active_color)) + painter.drawEllipse(x + self.w - (self.h + 6), y - 3, self.h + 6, self.h + 6) + + painter.end() From bbdfea218efb083915e7f39e36b39291d0431f95 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Fri, 3 Dec 2021 18:34:53 +0530 Subject: [PATCH 12/21] Reflects the autoconnect status on toggle checkbox on opening --- desktop/src/onionshare/connection_tab.py | 4 +--- desktop/src/onionshare/gui_common.py | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py index a0d7b78f..6cdba20d 100644 --- a/desktop/src/onionshare/connection_tab.py +++ b/desktop/src/onionshare/connection_tab.py @@ -73,9 +73,6 @@ class AutoConnectTab(QtWidgets.QWidget): strings._("gui_enable_autoconnect_checkbox") ) self.enable_autoconnect_checkbox.clicked.connect(self.toggle_auto_connect) - # self.enable_autoconnect_checkbox.setText( - # strings._("gui_enable_autoconnect_checkbox") - # ) self.enable_autoconnect_checkbox.setFixedWidth(400) self.enable_autoconnect_checkbox.setStyleSheet( common.gui.css["enable_autoconnect"] @@ -136,6 +133,7 @@ class AutoConnectTab(QtWidgets.QWidget): self.setLayout(self.layout) if self.auto_connect_enabled: + self.enable_autoconnect_checkbox.setCheckState(QtCore.Qt.Checked) self.connect_clicked() def toggle_auto_connect(self): diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py index aa3a596e..dc9c74b6 100644 --- a/desktop/src/onionshare/gui_common.py +++ b/desktop/src/onionshare/gui_common.py @@ -541,7 +541,6 @@ class GuiCommon: class ToggleCheckbox(QtWidgets.QCheckBox): def __init__(self, text): super(ToggleCheckbox, self).__init__(text) - print(text) # Set default parameters self.setCursor(QtCore.Qt.PointingHandCursor) self.w = 50 From 51e49c01f1a32753efc3de74953ffcc0260d5b15 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Fri, 3 Dec 2021 19:02:41 +0530 Subject: [PATCH 13/21] Adds autoconnect settings in tor settings tab --- desktop/src/onionshare/tor_settings_tab.py | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/desktop/src/onionshare/tor_settings_tab.py b/desktop/src/onionshare/tor_settings_tab.py index e28e5260..76957a8e 100644 --- a/desktop/src/onionshare/tor_settings_tab.py +++ b/desktop/src/onionshare/tor_settings_tab.py @@ -303,6 +303,24 @@ class TorSettingsTab(QtWidgets.QWidget): ) connection_type_radio_group.setLayout(connection_type_radio_group_layout) + # Quickstart settings + self.autoconnect_checkbox = QtWidgets.QCheckBox( + strings._("gui_enable_autoconnect_checkbox") + ) + self.autoconnect_checkbox.toggled.connect( + self.autoconnect_toggled + ) + left_column_settings = QtWidgets.QVBoxLayout() + connection_type_radio_group.setFixedHeight(300) + left_column_settings.addWidget(connection_type_radio_group) + left_column_settings.addSpacing(20) + left_column_settings.addWidget(self.autoconnect_checkbox) + left_column_settings.addStretch() + left_column_settings.setContentsMargins(0, 0, 0, 0) + left_column_setting_widget = QtWidgets.QWidget() + left_column_setting_widget.setLayout(left_column_settings) + + # The Bridges options are not exclusive (enabling Bridges offers obfs4 or custom bridges) connection_type_bridges_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_bridges_radio_group_layout.addWidget(self.bridges) @@ -322,7 +340,7 @@ class TorSettingsTab(QtWidgets.QWidget): # Settings are in columns columns_layout = QtWidgets.QHBoxLayout() - columns_layout.addWidget(connection_type_radio_group) + columns_layout.addWidget(left_column_setting_widget) columns_layout.addSpacing(20) columns_layout.addLayout(connection_type_layout, stretch=1) columns_wrapper = QtWidgets.QWidget() @@ -477,6 +495,12 @@ class TorSettingsTab(QtWidgets.QWidget): self.bridge_use_checkbox.setCheckState(QtCore.Qt.Unchecked) self.bridge_settings.hide() + def autoconnect_toggled(self): + """ + Auto connect checkbox clicked + """ + self.common.log("TorSettingsTab", "autoconnect_checkbox_clicked") + def active_tabs_changed(self, are_tabs_active): if are_tabs_active: self.main_widget.hide() @@ -777,6 +801,9 @@ class TorSettingsTab(QtWidgets.QWidget): settings = Settings(self.common) settings.load() # To get the last update timestamp + # autoconnect + settings.set("auto_connect", self.autoconnect_checkbox.isChecked()) + # Tor connection if self.connection_type_bundled_radio.isChecked(): settings.set("connection_type", "bundled") From 97a604a4c86f795e29d6bcf6437c45de8ca105f3 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Fri, 3 Dec 2021 19:30:20 +0530 Subject: [PATCH 14/21] Shows the Main window before starting to connect to Tor on autoconnect enabled --- desktop/src/onionshare/connection_tab.py | 5 +++++ desktop/src/onionshare/main_window.py | 3 +++ desktop/src/onionshare/tab_widget.py | 4 ++++ desktop/src/onionshare/tor_settings_tab.py | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py index 6cdba20d..bb5f72a3 100644 --- a/desktop/src/onionshare/connection_tab.py +++ b/desktop/src/onionshare/connection_tab.py @@ -132,6 +132,11 @@ class AutoConnectTab(QtWidgets.QWidget): self.setLayout(self.layout) + def check_autoconnect(self): + """ + After rendering, check if autoconnect was clicked, then start connecting + """ + self.common.log("AutoConnectTab", "autoconnect_checking") if self.auto_connect_enabled: self.enable_autoconnect_checkbox.setCheckState(QtCore.Qt.Checked) self.connect_clicked() diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py index 8c38c38d..54fef40c 100644 --- a/desktop/src/onionshare/main_window.py +++ b/desktop/src/onionshare/main_window.py @@ -174,6 +174,9 @@ class MainWindow(QtWidgets.QMainWindow): ) self.close_dialog.setDefaultButton(self.close_dialog.reject_button) + # Check for autoconnect + self.tabs.check_autoconnect_tab() + def tor_connection_canceled(self): """ If the user cancels before Tor finishes connecting, ask if they want to diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py index b5c18023..901a2ce0 100644 --- a/desktop/src/onionshare/tab_widget.py +++ b/desktop/src/onionshare/tab_widget.py @@ -168,6 +168,10 @@ class TabWidget(QtWidgets.QTabWidget): self.add_tab() else: self.open_connection_tab() + + def check_autoconnect_tab(self): + if type(self.tabs[0]) is AutoConnectTab: + self.tabs[0].check_autoconnect() def load_tab(self, mode_settings_id): # Load the tab's mode settings diff --git a/desktop/src/onionshare/tor_settings_tab.py b/desktop/src/onionshare/tor_settings_tab.py index 76957a8e..28778365 100644 --- a/desktop/src/onionshare/tor_settings_tab.py +++ b/desktop/src/onionshare/tor_settings_tab.py @@ -409,6 +409,10 @@ class TorSettingsTab(QtWidgets.QWidget): self.old_settings = Settings(self.common) self.old_settings.load() + # Check if autoconnect was enabled + if self.old_settings.get("auto_connect"): + self.autoconnect_checkbox.setCheckState(QtCore.Qt.Checked) + connection_type = self.old_settings.get("connection_type") if connection_type == "bundled": if self.connection_type_bundled_radio.isEnabled(): From 3b16ca461b8ff0fca9e31d1a5b5248f32934d65f Mon Sep 17 00:00:00 2001 From: Saptak S Date: Fri, 3 Dec 2021 19:53:00 +0530 Subject: [PATCH 15/21] Fix window title in quickstart --- desktop/src/onionshare/tab_widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py index 901a2ce0..41833635 100644 --- a/desktop/src/onionshare/tab_widget.py +++ b/desktop/src/onionshare/tab_widget.py @@ -222,7 +222,7 @@ class TabWidget(QtWidgets.QTabWidget): connection_tab.close_this_tab.connect(self.close_connection_tab) self.tabs[self.current_tab_id] = connection_tab self.current_tab_id += 1 - index = self.addTab(connection_tab, strings._("gui_settings_window_title")) + index = self.addTab(connection_tab, strings._("gui_autoconnect_start")) self.setCurrentIndex(index) def open_settings_tab(self): From 5ca7236f0cdec55d7eb4a457affcb4dd78f84d84 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Fri, 3 Dec 2021 20:03:22 +0530 Subject: [PATCH 16/21] Fixes CLI tests --- cli/tests/test_cli_settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/tests/test_cli_settings.py b/cli/tests/test_cli_settings.py index 9513b013..f4222b81 100644 --- a/cli/tests/test_cli_settings.py +++ b/cli/tests/test_cli_settings.py @@ -36,6 +36,7 @@ class TestSettings: "bridges_custom": "", "persistent_tabs": [], "theme": 0, + "auto_connect": False, } for key in settings_obj._settings: # Skip locale, it will not always default to the same thing From 2ad9f8df589f33082fbda47ec49b312db4c93f3e Mon Sep 17 00:00:00 2001 From: Saptak S Date: Thu, 9 Dec 2021 03:15:21 +0530 Subject: [PATCH 17/21] Don't show autoconnect tab if local only --- desktop/src/onionshare/tab_widget.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py index 41833635..99770576 100644 --- a/desktop/src/onionshare/tab_widget.py +++ b/desktop/src/onionshare/tab_widget.py @@ -162,9 +162,9 @@ class TabWidget(QtWidgets.QTabWidget): pass def new_tab_clicked(self): - # if already connected to tor, create a new tab + # if already connected to tor or local only, create a new tab # Else open the initial connection tab - if self.common.gui.onion.is_authenticated(): + if self.common.gui.local_only or self.common.gui.onion.is_authenticated(): self.add_tab() else: self.open_connection_tab() From 8d1d395d1100f704d2e03cf57958a004f4dcf82b Mon Sep 17 00:00:00 2001 From: Saptak S Date: Thu, 9 Dec 2021 03:20:54 +0530 Subject: [PATCH 18/21] Dont start tor if torsettingstab opened from autoconnect --- desktop/src/onionshare/connection_tab.py | 9 +++------ desktop/src/onionshare/main_window.py | 5 +++-- desktop/src/onionshare/tab_widget.py | 4 ++-- desktop/src/onionshare/tor_settings_tab.py | 5 +++-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py index bb5f72a3..13a6b2ad 100644 --- a/desktop/src/onionshare/connection_tab.py +++ b/desktop/src/onionshare/connection_tab.py @@ -152,7 +152,7 @@ class AutoConnectTab(QtWidgets.QWidget): self.curr_settings.save() def open_tor_settings(self): - self.parent.open_tor_settings_tab() + self.parent.open_tor_settings_tab(from_autoconnect=True) def connect_clicked(self): """ @@ -164,11 +164,8 @@ class AutoConnectTab(QtWidgets.QWidget): self.connect_button.hide() self.configure_button.hide() - if not self.common.gui.local_only: - self.tor_con.show() - self.tor_con.start(self.curr_settings) - else: - self.close_this_tab.emit() + self.tor_con.show() + self.tor_con.start(self.curr_settings) def tor_con_success(self): """ diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py index 54fef40c..80d9b5c1 100644 --- a/desktop/src/onionshare/main_window.py +++ b/desktop/src/onionshare/main_window.py @@ -23,8 +23,8 @@ import time from PySide2 import QtCore, QtWidgets, QtGui from . import strings -from .tor_connection import TorConnectionDialog from .widgets import Alert +from .connection_tab import AutoConnectTab from .update_checker import UpdateThread from .tab_widget import TabWidget from .gui_common import GuiCommon @@ -238,7 +238,8 @@ class MainWindow(QtWidgets.QMainWindow): Open the TorSettingsTab """ self.common.log("MainWindow", "open_tor_settings") - self.tabs.open_tor_settings_tab() + from_autoconnect = type(self.tabs.tabs[0]) is AutoConnectTab + self.tabs.open_tor_settings_tab(from_autoconnect) def open_settings(self): """ diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py index 99770576..972792fd 100644 --- a/desktop/src/onionshare/tab_widget.py +++ b/desktop/src/onionshare/tab_widget.py @@ -241,7 +241,7 @@ class TabWidget(QtWidgets.QTabWidget): index = self.addTab(settings_tab, strings._("gui_settings_window_title")) self.setCurrentIndex(index) - def open_tor_settings_tab(self): + def open_tor_settings_tab(self, from_autoconnect=False): self.common.log("TabWidget", "open_tor_settings_tab") # See if a settings tab is already open, and if so switch to it @@ -251,7 +251,7 @@ class TabWidget(QtWidgets.QTabWidget): return self.tor_settings_tab = TorSettingsTab( - self.common, self.current_tab_id, self.are_tabs_active(), self.status_bar + self.common, self.current_tab_id, self.are_tabs_active(), self.status_bar, from_autoconnect ) self.tor_settings_tab.close_this_tab.connect(self.close_tor_settings_tab) self.tor_settings_tab.tor_is_connected.connect(self.tor_is_connected) diff --git a/desktop/src/onionshare/tor_settings_tab.py b/desktop/src/onionshare/tor_settings_tab.py index 28778365..1557a4d6 100644 --- a/desktop/src/onionshare/tor_settings_tab.py +++ b/desktop/src/onionshare/tor_settings_tab.py @@ -43,7 +43,7 @@ class TorSettingsTab(QtWidgets.QWidget): tor_is_connected = QtCore.Signal() tor_is_disconnected = QtCore.Signal() - def __init__(self, common, tab_id, are_tabs_active, status_bar): + def __init__(self, common, tab_id, are_tabs_active, status_bar, from_autoconnect=False): super(TorSettingsTab, self).__init__() self.common = common @@ -54,6 +54,7 @@ class TorSettingsTab(QtWidgets.QWidget): self.system = platform.system() self.tab_id = tab_id + self.from_autoconnect = from_autoconnect # Connection type: either automatic, control port, or socket file @@ -692,7 +693,7 @@ class TorSettingsTab(QtWidgets.QWidget): # If Tor isn't connected, or if Tor settings have changed, Reinitialize # the Onion object reboot_onion = False - if not self.common.gui.local_only: + if not self.common.gui.local_only and not self.from_autoconnect: if self.common.gui.onion.is_authenticated(): self.common.log( "TorSettingsTab", "save_clicked", "Connected to Tor" From 7e982f222364610165286a991451a23e93ea2695 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Thu, 9 Dec 2021 03:43:19 +0530 Subject: [PATCH 19/21] Opens connect tab if persistent tab is there --- desktop/src/onionshare/main_window.py | 3 +++ desktop/src/onionshare/tab_widget.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py index 80d9b5c1..4ad5c14c 100644 --- a/desktop/src/onionshare/main_window.py +++ b/desktop/src/onionshare/main_window.py @@ -147,6 +147,9 @@ class MainWindow(QtWidgets.QMainWindow): if len(self.common.settings.get("persistent_tabs")) > 0: for mode_settings_id in self.common.settings.get("persistent_tabs"): self.tabs.load_tab(mode_settings_id) + # If not connected to tor in beginning, show autoconnect tab + if not self.common.gui.onion.connected_to_tor: + self.tabs.new_tab_clicked() else: # Start with opening the first tab self.tabs.new_tab_clicked() diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py index 972792fd..b5df855e 100644 --- a/desktop/src/onionshare/tab_widget.py +++ b/desktop/src/onionshare/tab_widget.py @@ -220,6 +220,8 @@ class TabWidget(QtWidgets.QTabWidget): connection_tab = AutoConnectTab(self.common, self.current_tab_id, self.status_bar, parent=self) connection_tab.close_this_tab.connect(self.close_connection_tab) + connection_tab.tor_is_connected.connect(self.tor_is_connected) + connection_tab.tor_is_disconnected.connect(self.tor_is_disconnected) self.tabs[self.current_tab_id] = connection_tab self.current_tab_id += 1 index = self.addTab(connection_tab, strings._("gui_autoconnect_start")) From df85ea0f60f47c606ee59b8e96ebe94cf3b599aa Mon Sep 17 00:00:00 2001 From: Saptak S Date: Thu, 9 Dec 2021 14:07:25 +0530 Subject: [PATCH 20/21] Fixes from_autoconnect check from MainWindow --- desktop/src/onionshare/main_window.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py index 4ad5c14c..824aeb6c 100644 --- a/desktop/src/onionshare/main_window.py +++ b/desktop/src/onionshare/main_window.py @@ -241,7 +241,11 @@ class MainWindow(QtWidgets.QMainWindow): Open the TorSettingsTab """ self.common.log("MainWindow", "open_tor_settings") - from_autoconnect = type(self.tabs.tabs[0]) is AutoConnectTab + from_autoconnect = False + for tab_id in self.tabs.tabs: + if type(self.tabs.tabs[tab_id]) is AutoConnectTab: + from_autoconnect = True + break self.tabs.open_tor_settings_tab(from_autoconnect) def open_settings(self): From 24152e8b4d64082217e89a7b6a69b406c5435936 Mon Sep 17 00:00:00 2001 From: Saptak S Date: Thu, 9 Dec 2021 14:38:11 +0530 Subject: [PATCH 21/21] Reload settings in connection tab when tor settings tab closed --- desktop/src/onionshare/connection_tab.py | 7 ++++++- desktop/src/onionshare/tab_widget.py | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py index 13a6b2ad..bf9fbfea 100644 --- a/desktop/src/onionshare/connection_tab.py +++ b/desktop/src/onionshare/connection_tab.py @@ -138,7 +138,7 @@ class AutoConnectTab(QtWidgets.QWidget): """ self.common.log("AutoConnectTab", "autoconnect_checking") if self.auto_connect_enabled: - self.enable_autoconnect_checkbox.setCheckState(QtCore.Qt.Checked) + self.enable_autoconnect_checkbox.setChecked(True) self.connect_clicked() def toggle_auto_connect(self): @@ -191,3 +191,8 @@ class AutoConnectTab(QtWidgets.QWidget): self.connect_button.show() self.configure_button.show() self.error_label.setText(msg) + + def reload_settings(self): + self.curr_settings.load() + self.auto_connect_enabled = self.curr_settings.get("auto_connect") + self.enable_autoconnect_checkbox.setChecked(self.auto_connect_enabled) diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py index b5df855e..92032f85 100644 --- a/desktop/src/onionshare/tab_widget.py +++ b/desktop/src/onionshare/tab_widget.py @@ -382,6 +382,9 @@ class TabWidget(QtWidgets.QTabWidget): def close_tor_settings_tab(self): self.common.log("TabWidget", "close_tor_settings_tab") + for tab_id in self.tabs: + if type(self.tabs[tab_id]) is AutoConnectTab: + self.tabs[tab_id].reload_settings() for tab_id in self.tabs: if type(self.tabs[tab_id]) is TorSettingsTab: index = self.indexOf(self.tabs[tab_id])