diff --git a/desktop/onionshare/main_window.py b/desktop/onionshare/main_window.py index d6f0d914..dff18807 100644 --- a/desktop/onionshare/main_window.py +++ b/desktop/onionshare/main_window.py @@ -124,10 +124,10 @@ class MainWindow(QtWidgets.QMainWindow): self.settings_button.setAccessibleName(strings._("gui_settings_window_title")) self.settings_button.clicked.connect(self.open_settings) self.settings_button.setStyleSheet(self.common.gui.css["settings_button"]) - self.status_bar.addPermanentWidget(self.settings_button) + self.settings_button.setToolTip(strings._("gui_settings_window_title")) # Tabs - self.tabs = TabWidget(self.common, self.system_tray, self.status_bar, self) + self.tabs = TabWidget(self.common, self.system_tray, self.status_bar, self, self.settings_button) self.tabs.bring_to_front.connect(self.bring_to_front) # If we have saved persistent tabs, try opening those diff --git a/desktop/onionshare/tab/mode/chat_mode/__init__.py b/desktop/onionshare/tab/mode/chat_mode/__init__.py index cb4f6911..cd8e606b 100644 --- a/desktop/onionshare/tab/mode/chat_mode/__init__.py +++ b/desktop/onionshare/tab/mode/chat_mode/__init__.py @@ -23,6 +23,7 @@ from PySide6 import QtCore, QtWidgets, QtGui from onionshare_cli.web import Web from .. import Mode +from ..settings_button import SettingsButton from .... import strings from ....widgets import MinimumSizeWidget from ....gui_common import GuiCommon @@ -85,10 +86,14 @@ class ChatMode(Mode): chat_mode_explainer.setMinimumHeight(80) chat_mode_explainer.setWordWrap(True) + # Settings button + self.settings_button = SettingsButton(self.common, self.tab.tab_widget) + # Top bar top_bar_layout = QtWidgets.QHBoxLayout() # Add space at the top, same height as the toggle history bar in other modes top_bar_layout.addWidget(MinimumSizeWidget(0, 30)) + top_bar_layout.addWidget(self.settings_button) # Main layout self.main_layout = QtWidgets.QVBoxLayout() diff --git a/desktop/onionshare/tab/mode/receive_mode/__init__.py b/desktop/onionshare/tab/mode/receive_mode/__init__.py index 45b20c70..e59c6ffc 100644 --- a/desktop/onionshare/tab/mode/receive_mode/__init__.py +++ b/desktop/onionshare/tab/mode/receive_mode/__init__.py @@ -24,6 +24,7 @@ from PySide6 import QtCore, QtWidgets, QtGui from onionshare_cli.web import Web from ..history import History, ToggleHistory, ReceiveHistoryItem +from ..settings_button import SettingsButton from .. import Mode from .... import strings from ....widgets import MinimumSizeWidget, Alert @@ -175,10 +176,14 @@ class ReceiveMode(Mode): receive_warning.setMinimumHeight(80) receive_warning.setWordWrap(True) + # Settings button + self.settings_button = SettingsButton(self.common, self.tab.tab_widget) + # Top bar top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addStretch() top_bar_layout.addWidget(self.toggle_history) + top_bar_layout.addWidget(self.settings_button) # Main layout self.main_layout = QtWidgets.QVBoxLayout() diff --git a/desktop/onionshare/tab/mode/settings_button.py b/desktop/onionshare/tab/mode/settings_button.py new file mode 100644 index 00000000..8acf4478 --- /dev/null +++ b/desktop/onionshare/tab/mode/settings_button.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2022 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 PySide6 import QtWidgets, QtGui + +from ... import strings +from ...gui_common import GuiCommon + + +class SettingsButton(QtWidgets.QPushButton): + """ + Widget for toggling showing or hiding the history, as well as keeping track + of the indicator counter if it's hidden + """ + + def __init__(self, common, tab_widget): + super(SettingsButton, self).__init__() + self.common = common + self.tab_widget = tab_widget + + self.setDefault(False) + self.setFixedSize(40, 50) + self.setIcon( + QtGui.QIcon( + GuiCommon.get_resource_path( + "images/{}_settings.png".format(self.common.gui.color_mode) + ) + ) + ) + self.setAccessibleName(strings._("gui_settings_window_title")) + self.clicked.connect(self.open_settings) + self.setStyleSheet(self.common.gui.css["settings_button"]) + self.setToolTip(strings._("gui_settings_window_title")) + + def open_settings(self): + self.common.log("SettingsButton", "open settings") + self.tab_widget.open_settings_tab() diff --git a/desktop/onionshare/tab/mode/share_mode/__init__.py b/desktop/onionshare/tab/mode/share_mode/__init__.py index 0a532641..d95cf62b 100644 --- a/desktop/onionshare/tab/mode/share_mode/__init__.py +++ b/desktop/onionshare/tab/mode/share_mode/__init__.py @@ -28,6 +28,7 @@ from .threads import CompressThread from .. import Mode from ..file_selection import FileSelection from ..history import History, ToggleHistory, ShareHistoryItem +from ..settings_button import SettingsButton from .... import strings from ....widgets import MinimumSizeWidget from ....gui_common import GuiCommon @@ -141,12 +142,16 @@ class ShareMode(Mode): ), ) + # Settings button + self.settings_button = SettingsButton(self.common, self.tab.tab_widget) + # Top bar top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addWidget(self.info_label) top_bar_layout.addStretch() top_bar_layout.addWidget(self.remove_all_button) top_bar_layout.addWidget(self.toggle_history) + top_bar_layout.addWidget(self.settings_button) # Primary action layout self.primary_action_layout.addWidget(self.filesize_warning) diff --git a/desktop/onionshare/tab/mode/website_mode/__init__.py b/desktop/onionshare/tab/mode/website_mode/__init__.py index 3faab913..ee80e676 100644 --- a/desktop/onionshare/tab/mode/website_mode/__init__.py +++ b/desktop/onionshare/tab/mode/website_mode/__init__.py @@ -28,6 +28,7 @@ from onionshare_cli.web import Web from .. import Mode from ..file_selection import FileSelection from ..history import History, ToggleHistory +from ..settings_button import SettingsButton from .... import strings from ....widgets import MinimumSizeWidget from ....gui_common import GuiCommon @@ -163,12 +164,16 @@ class WebsiteMode(Mode): ), ) + # Settings button + self.settings_button = SettingsButton(self.common, self.tab.tab_widget) + # Top bar top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addWidget(self.info_label) top_bar_layout.addStretch() top_bar_layout.addWidget(self.remove_all_button) top_bar_layout.addWidget(self.toggle_history) + top_bar_layout.addWidget(self.settings_button) # Primary action layout self.primary_action_layout.addWidget(self.filesize_warning) diff --git a/desktop/onionshare/tab/tab.py b/desktop/onionshare/tab/tab.py index 9e5dda20..20cc6d35 100644 --- a/desktop/onionshare/tab/tab.py +++ b/desktop/onionshare/tab/tab.py @@ -102,6 +102,8 @@ class Tab(QtWidgets.QWidget): tab_id, system_tray, status_bar, + tab_widget, + settings_button, filenames=None, ): super(Tab, self).__init__() @@ -111,6 +113,8 @@ class Tab(QtWidgets.QWidget): self.tab_id = tab_id self.system_tray = system_tray self.status_bar = status_bar + self.tab_widget = tab_widget + self.settings_button = settings_button self.filenames = filenames self.mode = None @@ -190,7 +194,17 @@ class Tab(QtWidgets.QWidget): new_tab_bottom_layout.addStretch() new_tab_layout = QtWidgets.QVBoxLayout() - new_tab_layout.addStretch() + + # Add the settings button to a new top-right layout + top_settings_layout = QtWidgets.QHBoxLayout() + top_settings_layout.addStretch() # Move to the right + top_settings_layout.addWidget(self.settings_button) + # Ensure the settings button is always shown on the New Tab + # screen, including after all other tabs are closed. + self.new_tab_settings_button = self.settings_button + self.new_tab_settings_button.show() + + new_tab_layout.addLayout(top_settings_layout) new_tab_layout.addLayout(new_tab_top_layout) new_tab_layout.addLayout(new_tab_bottom_layout) new_tab_layout.addStretch() @@ -261,10 +275,12 @@ class Tab(QtWidgets.QWidget): self.common.log("Tab", "share_mode_clicked") self.mode = self.common.gui.MODE_SHARE self.new_tab.hide() + self.new_tab_settings_button.hide() self.share_mode = ShareMode(self) self.share_mode.change_persistent.connect(self.change_persistent) + # Attach the Settings icon to the top right of the mode self.layout.addWidget(self.share_mode) self.share_mode.show() @@ -296,6 +312,7 @@ class Tab(QtWidgets.QWidget): self.common.log("Tab", "receive_mode_clicked") self.mode = self.common.gui.MODE_RECEIVE self.new_tab.hide() + self.new_tab_settings_button.hide() self.receive_mode = ReceiveMode(self) self.receive_mode.change_persistent.connect(self.change_persistent) @@ -333,6 +350,7 @@ class Tab(QtWidgets.QWidget): self.common.log("Tab", "website_mode_clicked") self.mode = self.common.gui.MODE_WEBSITE self.new_tab.hide() + self.new_tab_settings_button.hide() self.website_mode = WebsiteMode(self) self.website_mode.change_persistent.connect(self.change_persistent) @@ -370,6 +388,7 @@ class Tab(QtWidgets.QWidget): self.common.log("Tab", "chat_mode_clicked") self.mode = self.common.gui.MODE_CHAT self.new_tab.hide() + self.new_tab_settings_button.hide() self.chat_mode = ChatMode(self) self.chat_mode.change_persistent.connect(self.change_persistent) diff --git a/desktop/onionshare/tab_widget.py b/desktop/onionshare/tab_widget.py index 2a867ba5..69cd2d5d 100644 --- a/desktop/onionshare/tab_widget.py +++ b/desktop/onionshare/tab_widget.py @@ -37,7 +37,7 @@ class TabWidget(QtWidgets.QTabWidget): bring_to_front = QtCore.Signal() - def __init__(self, common, system_tray, status_bar, window): + def __init__(self, common, system_tray, status_bar, window, settings_button): super(TabWidget, self).__init__() self.common = common self.common.log("TabWidget", "__init__") @@ -45,6 +45,7 @@ class TabWidget(QtWidgets.QTabWidget): self.system_tray = system_tray self.status_bar = status_bar self.window = window + self.settings_button = settings_button # Keep track of tabs in a dictionary that maps tab_id to tab. # Each tab has a unique, auto-incremented id (tab_id). This is different than the @@ -196,7 +197,7 @@ class TabWidget(QtWidgets.QTabWidget): def add_tab(self, mode_settings=None): self.common.log("TabWidget", "add_tab", f"mode_settings: {mode_settings}") - tab = Tab(self.common, self.current_tab_id, self.system_tray, self.status_bar) + tab = Tab(self.common, self.current_tab_id, self.system_tray, self.status_bar, self, self.settings_button) tab.change_title.connect(self.change_title) tab.change_icon.connect(self.change_icon) tab.change_persistent.connect(self.change_persistent)