From 1632a00a9198b89faf45e4d32294855fdd8dd874 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 27 May 2020 12:56:33 +1000 Subject: [PATCH 1/4] #1116 Add a Clear All button in the File List area for share modes --- onionshare_gui/gui_common.py | 5 +++ .../tab/mode/share_mode/__init__.py | 20 +++++++++++ .../tab/mode/website_mode/__init__.py | 20 +++++++++++ share/locale/en.json | 3 +- tests/test_gui_share.py | 34 ++++++++++++++++--- 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/onionshare_gui/gui_common.py b/onionshare_gui/gui_common.py index 4381545e..91e05b68 100644 --- a/onionshare_gui/gui_common.py +++ b/onionshare_gui/gui_common.py @@ -208,6 +208,11 @@ class GuiCommon: color: #cc0000; }""", # Share mode and child widget styles + "share_clear_all_files_button": """ + QPushButton { + color: #3f7fcf; + } + """, "share_zip_progess_bar": """ QProgressBar { border: 1px solid #4e064f; diff --git a/onionshare_gui/tab/mode/share_mode/__init__.py b/onionshare_gui/tab/mode/share_mode/__init__.py index 1423d60a..4436ba25 100644 --- a/onionshare_gui/tab/mode/share_mode/__init__.py +++ b/onionshare_gui/tab/mode/share_mode/__init__.py @@ -111,6 +111,13 @@ class ShareMode(Mode): self.info_label = QtWidgets.QLabel() self.info_label.hide() + # Clear all files button + self.clear_all_button = QtWidgets.QPushButton(strings._("gui_file_selection_clear_all")) + self.clear_all_button.setFlat(True) + self.clear_all_button.setStyleSheet(self.common.gui.css["share_clear_all_files_button"]) + self.clear_all_button.clicked.connect(self.clear_all) + self.clear_all_button.hide() + # Toggle history self.toggle_history = ToggleHistory( self.common, @@ -126,6 +133,7 @@ class ShareMode(Mode): top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addWidget(self.info_label) top_bar_layout.addStretch() + top_bar_layout.addWidget(self.clear_all_button) top_bar_layout.addWidget(self.toggle_history) # Primary action layout @@ -343,6 +351,7 @@ class ShareMode(Mode): if self.server_status.file_selection.get_num_files() > 0: self.primary_action.show() self.info_label.show() + self.clear_all_button.show() def update_primary_action(self): self.common.log("ShareMode", "update_primary_action") @@ -352,6 +361,7 @@ class ShareMode(Mode): if file_count > 0: self.primary_action.show() self.info_label.show() + self.clear_all_button.show() # Update the file count in the info label total_size_bytes = 0 @@ -374,6 +384,7 @@ class ShareMode(Mode): else: self.primary_action.hide() self.info_label.hide() + self.clear_all_button.hide() def reset_info_counters(self): """ @@ -383,6 +394,15 @@ class ShareMode(Mode): self.toggle_history.indicator_count = 0 self.toggle_history.update_indicator() + def clear_all(self): + """ + Delete All button clicked + """ + self.file_selection.file_list.clear() + self.file_selection.file_list.files_updated.emit() + + self.file_selection.file_list.setCurrentItem(None) + @staticmethod def _compute_total_size(filenames): total_size = 0 diff --git a/onionshare_gui/tab/mode/website_mode/__init__.py b/onionshare_gui/tab/mode/website_mode/__init__.py index db8dbf09..11fba562 100644 --- a/onionshare_gui/tab/mode/website_mode/__init__.py +++ b/onionshare_gui/tab/mode/website_mode/__init__.py @@ -114,6 +114,13 @@ class WebsiteMode(Mode): self.info_label = QtWidgets.QLabel() self.info_label.hide() + # Clear all files button + self.clear_all_button = QtWidgets.QPushButton(strings._("gui_file_selection_clear_all")) + self.clear_all_button.setFlat(True) + self.clear_all_button.setStyleSheet(self.common.gui.css["share_clear_all_files_button"]) + self.clear_all_button.clicked.connect(self.clear_all) + self.clear_all_button.hide() + # Toggle history self.toggle_history = ToggleHistory( self.common, @@ -129,6 +136,7 @@ class WebsiteMode(Mode): top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addWidget(self.info_label) top_bar_layout.addStretch() + top_bar_layout.addWidget(self.clear_all_button) top_bar_layout.addWidget(self.toggle_history) # Primary action layout @@ -248,6 +256,7 @@ class WebsiteMode(Mode): if self.server_status.file_selection.get_num_files() > 0: self.primary_action.show() self.info_label.show() + self.clear_all_button.show() def update_primary_action(self): self.common.log("WebsiteMode", "update_primary_action") @@ -257,6 +266,7 @@ class WebsiteMode(Mode): if file_count > 0: self.primary_action.show() self.info_label.show() + self.clear_all_button.show() # Update the file count in the info label total_size_bytes = 0 @@ -279,6 +289,7 @@ class WebsiteMode(Mode): else: self.primary_action.hide() self.info_label.hide() + self.clear_all_button.hide() def reset_info_counters(self): """ @@ -288,6 +299,15 @@ class WebsiteMode(Mode): self.toggle_history.indicator_count = 0 self.toggle_history.update_indicator() + def clear_all(self): + """ + Delete All button clicked + """ + self.file_selection.file_list.clear() + self.file_selection.file_list.files_updated.emit() + + self.file_selection.file_list.setCurrentItem(None) + @staticmethod def _compute_total_size(filenames): total_size = 0 diff --git a/share/locale/en.json b/share/locale/en.json index cca7d92e..66c2d000 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -12,6 +12,7 @@ "gui_add_files": "Add Files", "gui_add_folder": "Add Folder", "gui_delete": "Delete", + "gui_file_selection_clear_all": "Clear All", "gui_choose_items": "Choose", "gui_share_start_server": "Start sharing", "gui_share_stop_server": "Stop sharing", @@ -205,4 +206,4 @@ "mode_settings_receive_data_dir_label": "Save files to", "mode_settings_receive_data_dir_browse_button": "Browse", "mode_settings_website_disable_csp_checkbox": "Disable Content Security Policy header (allows your website to use third-party resources)" -} \ No newline at end of file +} diff --git a/tests/test_gui_share.py b/tests/test_gui_share.py index c8b6292a..c3708c9d 100644 --- a/tests/test_gui_share.py +++ b/tests/test_gui_share.py @@ -55,6 +55,14 @@ class TestShare(GuiBaseTest): ).item_button.click() self.file_selection_widget_has_files(tab, num_files) + def add_a_file_and_delete_using_clear_all_widget(self, tab): + """Test that we can also delete all files by clicking on the Clear All widget""" + tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[0]) + tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[1]) + tab.get_mode().clear_all_button.click() + # Should be no files after clearing all + self.file_selection_widget_has_files(tab, 0) + def file_selection_widget_read_files(self, tab): """Re-add some files to the list so we can share""" num_files = tab.get_mode().server_status.file_selection.get_num_files() @@ -269,7 +277,7 @@ class TestShare(GuiBaseTest): self.run_all_share_mode_started_tests(tab) self.run_all_share_mode_download_tests(tab) - def run_all_clear_all_button_tests(self, tab): + def run_all_clear_all_history_button_tests(self, tab): """Test the Clear All history button""" self.run_all_share_mode_setup_tests(tab) self.run_all_share_mode_started_tests(tab) @@ -279,6 +287,11 @@ class TestShare(GuiBaseTest): self.individual_file_is_viewable_or_not(tab) self.clear_all_history_items(tab, 2) + def run_all_clear_all_file_selection_button_tests(self, tab): + """Test the Clear All File Selection button""" + self.run_all_share_mode_setup_tests(tab) + self.add_a_file_and_delete_using_clear_all_widget(tab) + def run_all_share_mode_individual_file_tests(self, tab): """Tests in share mode when viewing an individual file""" self.run_all_share_mode_setup_tests(tab) @@ -375,18 +388,31 @@ class TestShare(GuiBaseTest): self.close_all_tabs() @pytest.mark.gui - def test_clear_all_button(self): + def test_clear_all_history_button(self): """ - Test canceling a scheduled share + Test clearing all history items """ tab = self.new_share_tab() tab.get_mode().autostop_sharing_checkbox.click() self.run_all_common_setup_tests() - self.run_all_clear_all_button_tests(tab) + self.run_all_clear_all_history_button_tests(tab) self.close_all_tabs() + @pytest.mark.gui + def test_clear_all_file_selection_button(self): + """ + Test clearing all file items at once + """ + tab = self.new_share_tab() + + self.run_all_common_setup_tests() + self.run_all_clear_all_file_selection_button_tests(tab) + + self.close_all_tabs() + + @pytest.mark.gui def test_public_mode(self): """ From 327747fa3f6c376d25abb21dc0c6a329f5ef78d2 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 27 May 2020 12:59:13 +1000 Subject: [PATCH 2/4] Change code doc from 'Delete All' to 'Clear All' and remove whitespace in test --- onionshare_gui/tab/mode/share_mode/__init__.py | 2 +- onionshare_gui/tab/mode/website_mode/__init__.py | 2 +- tests/test_gui_share.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/onionshare_gui/tab/mode/share_mode/__init__.py b/onionshare_gui/tab/mode/share_mode/__init__.py index 4436ba25..c64fc78c 100644 --- a/onionshare_gui/tab/mode/share_mode/__init__.py +++ b/onionshare_gui/tab/mode/share_mode/__init__.py @@ -396,7 +396,7 @@ class ShareMode(Mode): def clear_all(self): """ - Delete All button clicked + Clear All button clicked """ self.file_selection.file_list.clear() self.file_selection.file_list.files_updated.emit() diff --git a/onionshare_gui/tab/mode/website_mode/__init__.py b/onionshare_gui/tab/mode/website_mode/__init__.py index 11fba562..1f7980ff 100644 --- a/onionshare_gui/tab/mode/website_mode/__init__.py +++ b/onionshare_gui/tab/mode/website_mode/__init__.py @@ -301,7 +301,7 @@ class WebsiteMode(Mode): def clear_all(self): """ - Delete All button clicked + Clear All button clicked """ self.file_selection.file_list.clear() self.file_selection.file_list.files_updated.emit() diff --git a/tests/test_gui_share.py b/tests/test_gui_share.py index c3708c9d..91d89d2c 100644 --- a/tests/test_gui_share.py +++ b/tests/test_gui_share.py @@ -412,7 +412,6 @@ class TestShare(GuiBaseTest): self.close_all_tabs() - @pytest.mark.gui def test_public_mode(self): """ From a22a559e989bd08f4b7928e2c511ebfdd4cdb3f8 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 28 May 2020 13:02:16 +1000 Subject: [PATCH 3/4] Hide the Clear All button on server start, show it again when stopped --- onionshare_gui/tab/mode/share_mode/__init__.py | 4 ++++ onionshare_gui/tab/mode/website_mode/__init__.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/onionshare_gui/tab/mode/share_mode/__init__.py b/onionshare_gui/tab/mode/share_mode/__init__.py index c64fc78c..942f856f 100644 --- a/onionshare_gui/tab/mode/share_mode/__init__.py +++ b/onionshare_gui/tab/mode/share_mode/__init__.py @@ -206,6 +206,8 @@ class ShareMode(Mode): # Hide and reset the downloads if we have previously shared self.reset_info_counters() + self.clear_all_button.hide() + def start_server_step2_custom(self): """ Step 2 in starting the server. Zipping up files. @@ -265,6 +267,8 @@ class ShareMode(Mode): self.history.update_in_progress() self.file_selection.file_list.adjustSize() + self.clear_all_button.show() + def cancel_server_custom(self): """ Stop the compression thread on cancel diff --git a/onionshare_gui/tab/mode/website_mode/__init__.py b/onionshare_gui/tab/mode/website_mode/__init__.py index 1f7980ff..e8c0a0ef 100644 --- a/onionshare_gui/tab/mode/website_mode/__init__.py +++ b/onionshare_gui/tab/mode/website_mode/__init__.py @@ -199,6 +199,8 @@ class WebsiteMode(Mode): # Hide and reset the downloads if we have previously shared self.reset_info_counters() + self.clear_all_button.hide() + def start_server_step2_custom(self): """ Step 2 in starting the server. Zipping up files. @@ -236,6 +238,8 @@ class WebsiteMode(Mode): self.history.completed_count = 0 self.file_selection.file_list.adjustSize() + self.clear_all_button.show() + def cancel_server_custom(self): """ Log that the server has been cancelled From 37cab504646174d5d7b78fc3203a4cdd6b53347d Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 8 Jun 2020 09:48:00 +1000 Subject: [PATCH 4/4] Use 'Delete' rather than 'Clear' when talking about removing file items from the FileList, since we have a Delete button for individual files --- onionshare_gui/gui_common.py | 2 +- .../tab/mode/share_mode/__init__.py | 28 +++++++++---------- .../tab/mode/website_mode/__init__.py | 28 +++++++++---------- share/locale/en.json | 2 +- tests/test_gui_share.py | 18 ++++++------ 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/onionshare_gui/gui_common.py b/onionshare_gui/gui_common.py index 91e05b68..40c912bb 100644 --- a/onionshare_gui/gui_common.py +++ b/onionshare_gui/gui_common.py @@ -208,7 +208,7 @@ class GuiCommon: color: #cc0000; }""", # Share mode and child widget styles - "share_clear_all_files_button": """ + "share_delete_all_files_button": """ QPushButton { color: #3f7fcf; } diff --git a/onionshare_gui/tab/mode/share_mode/__init__.py b/onionshare_gui/tab/mode/share_mode/__init__.py index 942f856f..3f595280 100644 --- a/onionshare_gui/tab/mode/share_mode/__init__.py +++ b/onionshare_gui/tab/mode/share_mode/__init__.py @@ -111,12 +111,12 @@ class ShareMode(Mode): self.info_label = QtWidgets.QLabel() self.info_label.hide() - # Clear all files button - self.clear_all_button = QtWidgets.QPushButton(strings._("gui_file_selection_clear_all")) - self.clear_all_button.setFlat(True) - self.clear_all_button.setStyleSheet(self.common.gui.css["share_clear_all_files_button"]) - self.clear_all_button.clicked.connect(self.clear_all) - self.clear_all_button.hide() + # Delete all files button + self.delete_all_button = QtWidgets.QPushButton(strings._("gui_file_selection_delete_all")) + self.delete_all_button.setFlat(True) + self.delete_all_button.setStyleSheet(self.common.gui.css["share_delete_all_files_button"]) + self.delete_all_button.clicked.connect(self.delete_all) + self.delete_all_button.hide() # Toggle history self.toggle_history = ToggleHistory( @@ -133,7 +133,7 @@ class ShareMode(Mode): top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addWidget(self.info_label) top_bar_layout.addStretch() - top_bar_layout.addWidget(self.clear_all_button) + top_bar_layout.addWidget(self.delete_all_button) top_bar_layout.addWidget(self.toggle_history) # Primary action layout @@ -206,7 +206,7 @@ class ShareMode(Mode): # Hide and reset the downloads if we have previously shared self.reset_info_counters() - self.clear_all_button.hide() + self.delete_all_button.hide() def start_server_step2_custom(self): """ @@ -267,7 +267,7 @@ class ShareMode(Mode): self.history.update_in_progress() self.file_selection.file_list.adjustSize() - self.clear_all_button.show() + self.delete_all_button.show() def cancel_server_custom(self): """ @@ -355,7 +355,7 @@ class ShareMode(Mode): if self.server_status.file_selection.get_num_files() > 0: self.primary_action.show() self.info_label.show() - self.clear_all_button.show() + self.delete_all_button.show() def update_primary_action(self): self.common.log("ShareMode", "update_primary_action") @@ -365,7 +365,7 @@ class ShareMode(Mode): if file_count > 0: self.primary_action.show() self.info_label.show() - self.clear_all_button.show() + self.delete_all_button.show() # Update the file count in the info label total_size_bytes = 0 @@ -388,7 +388,7 @@ class ShareMode(Mode): else: self.primary_action.hide() self.info_label.hide() - self.clear_all_button.hide() + self.delete_all_button.hide() def reset_info_counters(self): """ @@ -398,9 +398,9 @@ class ShareMode(Mode): self.toggle_history.indicator_count = 0 self.toggle_history.update_indicator() - def clear_all(self): + def delete_all(self): """ - Clear All button clicked + Delete All button clicked """ self.file_selection.file_list.clear() self.file_selection.file_list.files_updated.emit() diff --git a/onionshare_gui/tab/mode/website_mode/__init__.py b/onionshare_gui/tab/mode/website_mode/__init__.py index e8c0a0ef..badcd729 100644 --- a/onionshare_gui/tab/mode/website_mode/__init__.py +++ b/onionshare_gui/tab/mode/website_mode/__init__.py @@ -114,12 +114,12 @@ class WebsiteMode(Mode): self.info_label = QtWidgets.QLabel() self.info_label.hide() - # Clear all files button - self.clear_all_button = QtWidgets.QPushButton(strings._("gui_file_selection_clear_all")) - self.clear_all_button.setFlat(True) - self.clear_all_button.setStyleSheet(self.common.gui.css["share_clear_all_files_button"]) - self.clear_all_button.clicked.connect(self.clear_all) - self.clear_all_button.hide() + # Delete all files button + self.delete_all_button = QtWidgets.QPushButton(strings._("gui_file_selection_delete_all")) + self.delete_all_button.setFlat(True) + self.delete_all_button.setStyleSheet(self.common.gui.css["share_delete_all_files_button"]) + self.delete_all_button.clicked.connect(self.delete_all) + self.delete_all_button.hide() # Toggle history self.toggle_history = ToggleHistory( @@ -136,7 +136,7 @@ class WebsiteMode(Mode): top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addWidget(self.info_label) top_bar_layout.addStretch() - top_bar_layout.addWidget(self.clear_all_button) + top_bar_layout.addWidget(self.delete_all_button) top_bar_layout.addWidget(self.toggle_history) # Primary action layout @@ -199,7 +199,7 @@ class WebsiteMode(Mode): # Hide and reset the downloads if we have previously shared self.reset_info_counters() - self.clear_all_button.hide() + self.delete_all_button.hide() def start_server_step2_custom(self): """ @@ -238,7 +238,7 @@ class WebsiteMode(Mode): self.history.completed_count = 0 self.file_selection.file_list.adjustSize() - self.clear_all_button.show() + self.delete_all_button.show() def cancel_server_custom(self): """ @@ -260,7 +260,7 @@ class WebsiteMode(Mode): if self.server_status.file_selection.get_num_files() > 0: self.primary_action.show() self.info_label.show() - self.clear_all_button.show() + self.delete_all_button.show() def update_primary_action(self): self.common.log("WebsiteMode", "update_primary_action") @@ -270,7 +270,7 @@ class WebsiteMode(Mode): if file_count > 0: self.primary_action.show() self.info_label.show() - self.clear_all_button.show() + self.delete_all_button.show() # Update the file count in the info label total_size_bytes = 0 @@ -293,7 +293,7 @@ class WebsiteMode(Mode): else: self.primary_action.hide() self.info_label.hide() - self.clear_all_button.hide() + self.delete_all_button.hide() def reset_info_counters(self): """ @@ -303,9 +303,9 @@ class WebsiteMode(Mode): self.toggle_history.indicator_count = 0 self.toggle_history.update_indicator() - def clear_all(self): + def delete_all(self): """ - Clear All button clicked + Delete All button clicked """ self.file_selection.file_list.clear() self.file_selection.file_list.files_updated.emit() diff --git a/share/locale/en.json b/share/locale/en.json index 66c2d000..fbed6867 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -12,7 +12,7 @@ "gui_add_files": "Add Files", "gui_add_folder": "Add Folder", "gui_delete": "Delete", - "gui_file_selection_clear_all": "Clear All", + "gui_file_selection_delete_all": "Delete All", "gui_choose_items": "Choose", "gui_share_start_server": "Start sharing", "gui_share_stop_server": "Stop sharing", diff --git a/tests/test_gui_share.py b/tests/test_gui_share.py index 91d89d2c..9ee17ac5 100644 --- a/tests/test_gui_share.py +++ b/tests/test_gui_share.py @@ -55,11 +55,11 @@ class TestShare(GuiBaseTest): ).item_button.click() self.file_selection_widget_has_files(tab, num_files) - def add_a_file_and_delete_using_clear_all_widget(self, tab): - """Test that we can also delete all files by clicking on the Clear All widget""" + def add_a_file_and_delete_using_delete_all_widget(self, tab): + """Test that we can also delete all files by clicking on the Delete All widget""" tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[0]) tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[1]) - tab.get_mode().clear_all_button.click() + tab.get_mode().delete_all_button.click() # Should be no files after clearing all self.file_selection_widget_has_files(tab, 0) @@ -287,10 +287,10 @@ class TestShare(GuiBaseTest): self.individual_file_is_viewable_or_not(tab) self.clear_all_history_items(tab, 2) - def run_all_clear_all_file_selection_button_tests(self, tab): - """Test the Clear All File Selection button""" + def run_all_delete_all_file_selection_button_tests(self, tab): + """Test the Delete All File Selection button""" self.run_all_share_mode_setup_tests(tab) - self.add_a_file_and_delete_using_clear_all_widget(tab) + self.add_a_file_and_delete_using_delete_all_widget(tab) def run_all_share_mode_individual_file_tests(self, tab): """Tests in share mode when viewing an individual file""" @@ -401,14 +401,14 @@ class TestShare(GuiBaseTest): self.close_all_tabs() @pytest.mark.gui - def test_clear_all_file_selection_button(self): + def test_delete_all_file_selection_button(self): """ - Test clearing all file items at once + Test delete all file items at once """ tab = self.new_share_tab() self.run_all_common_setup_tests() - self.run_all_clear_all_file_selection_button_tests(tab) + self.run_all_delete_all_file_selection_button_tests(tab) self.close_all_tabs()