diff --git a/onionshare_gui/gui_common.py b/onionshare_gui/gui_common.py index 9241dbf6..9ab16470 100644 --- a/onionshare_gui/gui_common.py +++ b/onionshare_gui/gui_common.py @@ -50,13 +50,8 @@ class GuiCommon: self.css = { # OnionShareGui styles - "tab_bar_new_tab": """ - QTabBar::tab:last { - border: 0; - margin: 3px; - }""", "tab_bar_new_tab_button": """ - QToolButton { + QPushButton { font-weight: bold; font-size: 20px; }""", diff --git a/onionshare_gui/main_window.py b/onionshare_gui/main_window.py index dfd6c10c..497fde62 100644 --- a/onionshare_gui/main_window.py +++ b/onionshare_gui/main_window.py @@ -26,7 +26,7 @@ from .tor_connection_dialog import TorConnectionDialog from .settings_dialog import SettingsDialog from .widgets import Alert from .update_checker import UpdateThread -from .tab import Tab +from .tab_widget import TabWidget class MainWindow(QtWidgets.QMainWindow): @@ -96,25 +96,12 @@ class MainWindow(QtWidgets.QMainWindow): self.status_bar.addPermanentWidget(self.status_bar.server_status_indicator) # Tabs - self.tabs = QtWidgets.QTabWidget() - self.tabs.setStyleSheet(self.common.gui.css["tab_bar_new_tab"]) - self.tabs.setMovable(True) - self.tabs.setTabsClosable(True) - self.tabs.setUsesScrollButtons(True) - - # New tab button - new_tab_button = QtWidgets.QToolButton() - new_tab_button.setStyleSheet(self.common.gui.css["tab_bar_new_tab_button"]) - new_tab_button.setText("+") - new_tab_button.setAutoRaise(True) - self.tabs.insertTab(0, QtWidgets.QWidget(), "") - self.tabs.tabBar().setTabButton(0, QtWidgets.QTabBar.RightSide, new_tab_button) - self.tabs.tabBar().setTabToolTip(0, strings._("gui_new_tab_tooltip")) + self.tabs = TabWidget(self.common, self.system_tray, self.status_bar) # Start with a tab - new_tab = Tab(self.common, self.system_tray, self.status_bar, filenames) - self.tabs.insertTab(0, new_tab, strings._("gui_new_tab")) - self.tabs.setCurrentIndex(0) + # new_tab = Tab(self.common, self.system_tray, self.status_bar, filenames) + # self.tabs.insertTab(0, new_tab, strings._("gui_new_tab")) + # self.tabs.setCurrentIndex(0) # Layout layout = QtWidgets.QVBoxLayout() diff --git a/onionshare_gui/tab/tab.py b/onionshare_gui/tab/tab.py index 141122ac..6a76583f 100644 --- a/onionshare_gui/tab/tab.py +++ b/onionshare_gui/tab/tab.py @@ -38,7 +38,7 @@ class Tab(QtWidgets.QWidget): A GUI tab, you know, sort of like in a web browser """ - def __init__(self, common, system_tray, status_bar, filenames): + def __init__(self, common, system_tray, status_bar, filenames=None): super(Tab, self).__init__() self.common = common self.common.log("Tab", "__init__") diff --git a/onionshare_gui/tab_widget.py b/onionshare_gui/tab_widget.py new file mode 100644 index 00000000..48388144 --- /dev/null +++ b/onionshare_gui/tab_widget.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2018 Micah Lee + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +from PyQt5 import QtCore, QtWidgets, QtGui + +from onionshare import strings + +from .tab import Tab + + +class TabWidget(QtWidgets.QTabWidget): + """ + A custom tab widget, that has a "+" button for adding new tabs + """ + + def __init__(self, common, system_tray, status_bar): + super(TabWidget, self).__init__() + self.common = common + self.common.log("TabWidget", "__init__") + + self.system_tray = system_tray + self.status_bar = status_bar + + # Definte the new tab button + self.new_tab_button = QtWidgets.QPushButton("+", parent=self) + self.new_tab_button.setFlat(True) + self.new_tab_button.setAutoFillBackground(True) + self.new_tab_button.setFixedSize(30, 30) + self.new_tab_button.clicked.connect(self.new_tab_clicked) + self.new_tab_button.setStyleSheet(self.common.gui.css["tab_bar_new_tab_button"]) + self.new_tab_button.setToolTip(strings._("gui_new_tab_tooltip")) + + # Use a custom tab bar + tab_bar = TabBar() + tab_bar.move_new_tab_button.connect(self.move_new_tab_button) + self.setTabBar(tab_bar) + + # Set up the tab widget + self.setMovable(True) + self.setTabsClosable(True) + self.setUsesScrollButtons(True) + + self.move_new_tab_button() + + def move_new_tab_button(self): + # Find the width of all tabs + tabs_width = sum( + [self.tabBar().tabRect(i).width() for i in range(self.count())] + ) + + # The current positoin of the new tab button + pos = self.new_tab_button.pos() + + # If there are so many tabs it scrolls, move the button to the left of the scroll buttons + if tabs_width > self.width(): + pos.setX(self.width() - 61) + else: + # Otherwise move the button to the right of the tabs + pos.setX(self.tabBar().sizeHint().width()) + + self.new_tab_button.move(pos) + self.new_tab_button.raise_() + + def resizeEvent(self, event): + # Make sure to move new tab button on each resize + super(TabWidget, self).resizeEvent(event) + self.move_new_tab_button() + + def new_tab_clicked(self): + # Add a new tab + tab = Tab(self.common, self.system_tray, self.status_bar) + self.addTab(tab, "New Tab") + + +class TabBar(QtWidgets.QTabBar): + """ + A custom tab bar + """ + + move_new_tab_button = QtCore.pyqtSignal() + + def __init__(self): + super(TabBar, self).__init__() + + def tabLayoutChange(self): + self.move_new_tab_button.emit()