From a07dde45c5f0c189bece8ac32593d4034d3d24ad Mon Sep 17 00:00:00 2001 From: mashed5894 Date: Fri, 17 Jan 2025 21:43:46 +0200 Subject: [PATCH 1/3] moved menu_bar into dedicated class and fixed some function names --- tagstudio/src/qt/modals/drop_import.py | 2 +- tagstudio/src/qt/ts_qt.py | 360 ++----------------------- tagstudio/src/qt/widgets/landing.py | 2 +- tagstudio/src/qt/widgets/menu_bar.py | 347 ++++++++++++++++++++++++ 4 files changed, 376 insertions(+), 335 deletions(-) create mode 100644 tagstudio/src/qt/widgets/menu_bar.py diff --git a/tagstudio/src/qt/modals/drop_import.py b/tagstudio/src/qt/modals/drop_import.py index 9b13b3d11..56babeb9b 100644 --- a/tagstudio/src/qt/modals/drop_import.py +++ b/tagstudio/src/qt/modals/drop_import.py @@ -182,7 +182,7 @@ def displayed_text(x): pw.from_iterable_function( self.copy_files, displayed_text, - self.driver.add_new_files_callback, + self.driver.refresh_directories, self.deleteLater, ) diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index b6e36ae4a..e86e37ac9 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -14,7 +14,6 @@ import re import sys import time -import webbrowser from pathlib import Path from queue import Queue @@ -22,10 +21,8 @@ import src.qt.resources_rc # noqa: F401 import structlog from humanfriendly import format_timespan -from PySide6 import QtCore from PySide6.QtCore import QObject, QSettings, Qt, QThread, QThreadPool, QTimer, Signal from PySide6.QtGui import ( - QAction, QColor, QDragEnterEvent, QDragMoveEvent, @@ -42,8 +39,6 @@ QComboBox, QFileDialog, QLineEdit, - QMenu, - QMenuBar, QMessageBox, QPushButton, QScrollArea, @@ -75,16 +70,12 @@ from src.qt.helpers.custom_runnable import CustomRunnable from src.qt.helpers.function_iterator import FunctionIterator from src.qt.main_window import Ui_MainWindow -from src.qt.modals.build_tag import BuildTagPanel from src.qt.modals.drop_import import DropImportModal -from src.qt.modals.file_extension import FileExtensionModal -from src.qt.modals.fix_dupes import FixDupeFilesModal -from src.qt.modals.fix_unlinked import FixUnlinkedEntriesModal -from src.qt.modals.folders_to_tags import FoldersToTagsModal from src.qt.modals.tag_database import TagDatabasePanel from src.qt.resource_manager import ResourceManager from src.qt.translations import Translations from src.qt.widgets.item_thumb import BadgeType, ItemThumb +from src.qt.widgets.menu_bar import MenuBar from src.qt.widgets.migration_modal import JsonMigrationModal from src.qt.widgets.panel import PanelModal from src.qt.widgets.preview_panel import PreviewPanel @@ -188,7 +179,7 @@ def init_workers(self): self.thumb_threads.append(thread) thread.start() - def open_library_from_dialog(self): + def open_create_library_modal(self): dir = QFileDialog.getExistingDirectory( parent=None, caption=Translations["window.title.open_create_library"], @@ -267,228 +258,29 @@ def start(self) -> None: icon.addFile(str(icon_path)) app.setWindowIcon(icon) - menu_bar = QMenuBar(self.main_window) - self.main_window.setMenuBar(menu_bar) - menu_bar.setNativeMenuBar(True) - - file_menu = QMenu(menu_bar) - Translations.translate_qobject(file_menu, "menu.file") - edit_menu = QMenu(menu_bar) - Translations.translate_qobject(edit_menu, "generic.edit_alt") - view_menu = QMenu(menu_bar) - Translations.translate_qobject(view_menu, "menu.view") - tools_menu = QMenu(menu_bar) - Translations.translate_qobject(tools_menu, "menu.tools") - macros_menu = QMenu(menu_bar) - Translations.translate_qobject(macros_menu, "menu.macros") - help_menu = QMenu(menu_bar) - Translations.translate_qobject(help_menu, "menu.help") - - # File Menu ============================================================ - open_library_action = QAction(menu_bar) - Translations.translate_qobject(open_library_action, "menu.file.open_create_library") - open_library_action.triggered.connect(lambda: self.open_library_from_dialog()) - open_library_action.setShortcut( - QtCore.QKeyCombination( - QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), - QtCore.Qt.Key.Key_O, - ) - ) - open_library_action.setToolTip("Ctrl+O") - file_menu.addAction(open_library_action) - - self.open_recent_library_menu = QMenu(menu_bar) - Translations.translate_qobject( - self.open_recent_library_menu, "menu.file.open_recent_library" - ) - file_menu.addMenu(self.open_recent_library_menu) - self.update_recent_lib_menu() - - open_on_start_action = QAction(self) - Translations.translate_qobject(open_on_start_action, "settings.open_library_on_start") - open_on_start_action.setCheckable(True) - open_on_start_action.setChecked( - bool(self.settings.value(SettingItems.START_LOAD_LAST, defaultValue=True, type=bool)) - ) - open_on_start_action.triggered.connect( - lambda checked: self.settings.setValue(SettingItems.START_LOAD_LAST, checked) - ) - file_menu.addAction(open_on_start_action) - - file_menu.addSeparator() - - save_library_backup_action = QAction(menu_bar) - Translations.translate_qobject(save_library_backup_action, "menu.file.save_backup") - save_library_backup_action.triggered.connect( - lambda: self.callback_library_needed_check(self.backup_library) - ) - save_library_backup_action.setShortcut( - QtCore.QKeyCombination( - QtCore.Qt.KeyboardModifier( - QtCore.Qt.KeyboardModifier.ControlModifier - | QtCore.Qt.KeyboardModifier.ShiftModifier - ), - QtCore.Qt.Key.Key_S, - ) - ) - save_library_backup_action.setStatusTip("Ctrl+Shift+S") - file_menu.addAction(save_library_backup_action) - - file_menu.addSeparator() - - add_new_files_action = QAction(menu_bar) - Translations.translate_qobject(add_new_files_action, "menu.file.refresh_directories") - add_new_files_action.triggered.connect( - lambda: self.callback_library_needed_check(self.add_new_files_callback) - ) - add_new_files_action.setShortcut( - QtCore.QKeyCombination( - QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), - QtCore.Qt.Key.Key_R, - ) - ) - add_new_files_action.setStatusTip("Ctrl+R") - file_menu.addAction(add_new_files_action) - file_menu.addSeparator() - - close_library_action = QAction(menu_bar) - Translations.translate_qobject(close_library_action, "menu.file.close_library") - close_library_action.triggered.connect(self.close_library) - file_menu.addAction(close_library_action) - file_menu.addSeparator() - - # Edit Menu ============================================================ - new_tag_action = QAction(menu_bar) - Translations.translate_qobject(new_tag_action, "menu.edit.new_tag") - new_tag_action.triggered.connect(lambda: self.add_tag_action_callback()) - new_tag_action.setShortcut( - QtCore.QKeyCombination( - QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), - QtCore.Qt.Key.Key_T, - ) - ) - new_tag_action.setToolTip("Ctrl+T") - edit_menu.addAction(new_tag_action) - - edit_menu.addSeparator() - - select_all_action = QAction(menu_bar) - Translations.translate_qobject(select_all_action, "select.all") - select_all_action.triggered.connect(self.select_all_action_callback) - select_all_action.setShortcut( - QtCore.QKeyCombination( - QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), - QtCore.Qt.Key.Key_A, - ) - ) - select_all_action.setToolTip("Ctrl+A") - edit_menu.addAction(select_all_action) - - clear_select_action = QAction(menu_bar) - Translations.translate_qobject(clear_select_action, "select.clear") - clear_select_action.triggered.connect(self.clear_select_action_callback) - clear_select_action.setShortcut(QtCore.Qt.Key.Key_Escape) - clear_select_action.setToolTip("Esc") - edit_menu.addAction(clear_select_action) - - edit_menu.addSeparator() - - manage_file_extensions_action = QAction(menu_bar) - Translations.translate_qobject( - manage_file_extensions_action, "menu.edit.manage_file_extensions" - ) - manage_file_extensions_action.triggered.connect(self.show_file_extension_modal) - edit_menu.addAction(manage_file_extensions_action) - - tag_database_action = QAction(menu_bar) - Translations.translate_qobject(tag_database_action, "menu.edit.manage_tags") - tag_database_action.triggered.connect(lambda: self.show_tag_database()) - edit_menu.addAction(tag_database_action) - - # View Menu ============================================================ - show_libs_list_action = QAction(menu_bar) - Translations.translate_qobject(show_libs_list_action, "settings.show_recent_libraries") - show_libs_list_action.setCheckable(True) - show_libs_list_action.setChecked( - bool(self.settings.value(SettingItems.WINDOW_SHOW_LIBS, defaultValue=True, type=bool)) - ) - - show_filenames_action = QAction(menu_bar) - Translations.translate_qobject(show_filenames_action, "settings.show_filenames_in_grid") - show_filenames_action.setCheckable(True) - show_filenames_action.setChecked( - bool(self.settings.value(SettingItems.SHOW_FILENAMES, defaultValue=True, type=bool)) + self.menu_bar = MenuBar(self.main_window, self.settings, self.lib, self) + self.menu_bar.create_library_modal_signal.connect(self.open_create_library_modal) + self.menu_bar.open_library_signal.connect(self.open_library) + self.menu_bar.backup_library_signal.connect( + lambda: self.backup_library() if self.lib.library_dir else () ) - show_filenames_action.triggered.connect( - lambda checked: ( - self.settings.setValue(SettingItems.SHOW_FILENAMES, checked), - self.show_grid_filenames(checked), - ) - ) - view_menu.addAction(show_filenames_action) - - # Tools Menu =========================================================== - def create_fix_unlinked_entries_modal(): - if not hasattr(self, "unlinked_modal"): - self.unlinked_modal = FixUnlinkedEntriesModal(self.lib, self) - self.unlinked_modal.show() - - fix_unlinked_entries_action = QAction(menu_bar) - Translations.translate_qobject( - fix_unlinked_entries_action, "menu.tools.fix_unlinked_entries" + self.menu_bar.refresh_directories_signal.connect( + lambda: self.refresh_directories() if self.lib.library_dir else () ) - fix_unlinked_entries_action.triggered.connect(create_fix_unlinked_entries_modal) - tools_menu.addAction(fix_unlinked_entries_action) - - def create_dupe_files_modal(): - if not hasattr(self, "dupe_modal"): - self.dupe_modal = FixDupeFilesModal(self.lib, self) - self.dupe_modal.show() - - fix_dupe_files_action = QAction(menu_bar) - Translations.translate_qobject(fix_dupe_files_action, "menu.tools.fix_duplicate_files") - fix_dupe_files_action.triggered.connect(create_dupe_files_modal) - tools_menu.addAction(fix_dupe_files_action) - - # create_collage_action = QAction("Create Collage", menu_bar) - # create_collage_action.triggered.connect(lambda: self.create_collage()) - # tools_menu.addAction(create_collage_action) - - # Macros Menu ========================================================== - self.autofill_action = QAction("Autofill", menu_bar) - self.autofill_action.triggered.connect( + self.menu_bar.close_library_signal.connect(self.close_library) + self.menu_bar.select_all_items_signal.connect(self.select_all_items) + self.menu_bar.clear_selection_signal.connect(self.clear_selection) + self.menu_bar.filter_items_signal.connect(self.filter_items) + self.menu_bar.tag_database_modal_signal.connect(self.open_tag_database_modal) + self.menu_bar.show_grid_filenames_signal.connect(self.show_grid_filenames) + self.menu_bar.autofill_macro_signal.connect( lambda: ( self.run_macros(MacroID.AUTOFILL, self.selected), self.preview_panel.update_widgets(), ) ) - macros_menu.addAction(self.autofill_action) - - def create_folders_tags_modal(): - if not hasattr(self, "folders_modal"): - self.folders_modal = FoldersToTagsModal(self.lib, self) - self.folders_modal.show() - - folders_to_tags_action = QAction(menu_bar) - Translations.translate_qobject(folders_to_tags_action, "menu.macros.folders_to_tags") - folders_to_tags_action.triggered.connect(create_folders_tags_modal) - macros_menu.addAction(folders_to_tags_action) - - # Help Menu ============================================================ - self.repo_action = QAction(menu_bar) - Translations.translate_qobject(self.repo_action, "help.visit_github") - self.repo_action.triggered.connect( - lambda: webbrowser.open("https://github.com/TagStudioDev/TagStudio") - ) - help_menu.addAction(self.repo_action) - self.set_macro_menu_viability() - - menu_bar.addMenu(file_menu) - menu_bar.addMenu(edit_menu) - menu_bar.addMenu(view_menu) - menu_bar.addMenu(tools_menu) - menu_bar.addMenu(macros_menu) - menu_bar.addMenu(help_menu) + self.menu_bar.set_macro_menu_viability(not self.selected) + self.main_window.setMenuBar(self.menu_bar) self.main_window.searchField.textChanged.connect(self.update_completions_list) @@ -632,11 +424,6 @@ def show_grid_filenames(self, value: bool): for thumb in self.item_thumbs: thumb.set_filename_visibility(value) - def callback_library_needed_check(self, func): - """Check if loaded library has valid path before executing the button function.""" - if self.lib.library_dir: - func() - def handle_sigterm(self): self.shutdown() @@ -705,29 +492,7 @@ def backup_library(self): ) ) - def add_tag_action_callback(self): - panel = BuildTagPanel(self.lib) - self.modal = PanelModal( - panel, - has_save=True, - ) - Translations.translate_with_setter(self.modal.setTitle, "tag.new") - Translations.translate_with_setter(self.modal.setWindowTitle, "tag.add") - - self.modal.saved.connect( - lambda: ( - self.lib.add_tag( - panel.build_tag(), - set(panel.parent_ids), - set(panel.alias_names), - set(panel.alias_ids), - ), - self.modal.hide(), - ) - ) - self.modal.show() - - def select_all_action_callback(self): + def select_all_items(self): """Set the selection to all visible items.""" self.selected.clear() for item in self.item_thumbs: @@ -735,18 +500,18 @@ def select_all_action_callback(self): self.selected.append(item.item_id) item.thumb_button.set_selected(True) - self.set_macro_menu_viability() + self.menu_bar.set_macro_menu_viability(not self.selected) self.preview_panel.update_widgets() - def clear_select_action_callback(self): + def clear_selection(self): self.selected.clear() for item in self.item_thumbs: item.thumb_button.set_selected(False) - self.set_macro_menu_viability() + self.menu_bar.set_macro_menu_viability(not self.selected) self.preview_panel.update_widgets() - def show_tag_database(self): + def open_tag_database_modal(self): self.modal = PanelModal( widget=TagDatabasePanel(self.lib), done_callback=self.preview_panel.update_widgets, @@ -756,19 +521,7 @@ def show_tag_database(self): Translations.translate_with_setter(self.modal.setWindowTitle, "tag_manager.title") self.modal.show() - def show_file_extension_modal(self): - panel = FileExtensionModal(self.lib) - self.modal = PanelModal( - panel, - has_save=True, - ) - Translations.translate_with_setter(self.modal.setTitle, "ignore_list.title") - Translations.translate_with_setter(self.modal.setWindowTitle, "ignore_list.title") - - self.modal.saved.connect(lambda: (panel.save(), self.filter_items())) - self.modal.show() - - def add_new_files_callback(self): + def refresh_directories(self): """Run when user initiates adding new files to the Library.""" tracker = RefreshDirTracker(self.lib) @@ -1086,12 +839,9 @@ def toggle_item_selection(self, item_id: int, append: bool, bridge: bool): else: it.thumb_button.set_selected(False) - self.set_macro_menu_viability() + self.menu_bar.set_macro_menu_viability(not self.selected) self.preview_panel.update_widgets() - def set_macro_menu_viability(self): - self.autofill_action.setDisabled(not self.selected) - def update_completions_list(self, text: str) -> None: matches = re.search( r"((?:.* )?)(mediatype|filetype|path|tag|tag_id):(\"?[A-Za-z0-9\ \t]+\"?)?", text @@ -1340,63 +1090,7 @@ def update_libs_list(self, path: Path | str): self.settings.endGroup() self.settings.sync() - self.update_recent_lib_menu() - - def update_recent_lib_menu(self): - """Updates the recent library menu from the latest values from the settings file.""" - actions: list[QAction] = [] - lib_items: dict[str, tuple[str, str]] = {} - - settings = self.settings - settings.beginGroup(SettingItems.LIBS_LIST) - for item_tstamp in settings.allKeys(): - val = str(settings.value(item_tstamp, type=str)) - cut_val = val - if len(val) > 45: - cut_val = f"{val[0:10]} ... {val[-10:]}" - lib_items[item_tstamp] = (val, cut_val) - - # Sort lib_items by the key - libs_sorted = sorted(lib_items.items(), key=lambda item: item[0], reverse=True) - settings.endGroup() - - # Create actions for each library - for library_key in libs_sorted: - path = Path(library_key[1][0]) - action = QAction(self.open_recent_library_menu) - action.setText(str(path)) - action.triggered.connect(lambda checked=False, p=path: self.open_library(p)) - actions.append(action) - - clear_recent_action = QAction(self.open_recent_library_menu) - Translations.translate_qobject(clear_recent_action, "menu.file.clear_recent_libraries") - clear_recent_action.triggered.connect(self.clear_recent_libs) - actions.append(clear_recent_action) - - # Clear previous actions - for action in self.open_recent_library_menu.actions(): - self.open_recent_library_menu.removeAction(action) - - # Add new actions - for action in actions: - self.open_recent_library_menu.addAction(action) - - # Only enable add "clear recent" if there are still recent libraries. - if len(actions) > 1: - self.open_recent_library_menu.setDisabled(False) - self.open_recent_library_menu.addSeparator() - self.open_recent_library_menu.addAction(clear_recent_action) - else: - self.open_recent_library_menu.setDisabled(True) - - def clear_recent_libs(self): - """Clear the list of recent libraries from the settings file.""" - settings = self.settings - settings.beginGroup(SettingItems.LIBS_LIST) - self.settings.remove("") - self.settings.endGroup() - self.settings.sync() - self.update_recent_lib_menu() + self.menu_bar.update_recent_lib_menu() def open_library(self, path: Path) -> None: """Open a TagStudio library.""" @@ -1440,7 +1134,7 @@ def init_library(self, path: Path, open_status: LibraryStatus): # TODO - make this call optional if self.lib.entries_count < 10000: - self.add_new_files_callback() + self.refresh_directories() self.update_libs_list(path) Translations.translate_with_setter( diff --git a/tagstudio/src/qt/widgets/landing.py b/tagstudio/src/qt/widgets/landing.py index 3f6b15942..aa49107b1 100644 --- a/tagstudio/src/qt/widgets/landing.py +++ b/tagstudio/src/qt/widgets/landing.py @@ -66,7 +66,7 @@ def __init__(self, driver: "QtDriver", pixel_ratio: float): Translations.translate_qobject( self.open_button, "landing.open_create_library", shortcut=open_shortcut_text ) - self.open_button.clicked.connect(self.driver.open_library_from_dialog) + self.open_button.clicked.connect(self.driver.open_create_library_modal) # Create status label -------------------------------------------------- self.status_label = QLabel() diff --git a/tagstudio/src/qt/widgets/menu_bar.py b/tagstudio/src/qt/widgets/menu_bar.py new file mode 100644 index 000000000..03d458aa7 --- /dev/null +++ b/tagstudio/src/qt/widgets/menu_bar.py @@ -0,0 +1,347 @@ +import webbrowser +from pathlib import Path + +from PySide6 import QtCore +from PySide6.QtCore import Signal +from PySide6.QtGui import ( + QAction, +) +from PySide6.QtWidgets import ( + QMenu, + QMenuBar, +) +from src.core.enums import SettingItems +from src.qt.modals.build_tag import BuildTagPanel +from src.qt.modals.file_extension import FileExtensionModal +from src.qt.modals.fix_dupes import FixDupeFilesModal +from src.qt.modals.fix_unlinked import FixUnlinkedEntriesModal +from src.qt.modals.folders_to_tags import FoldersToTagsModal +from src.qt.translations import Translations +from src.qt.widgets.panel import PanelModal + + +class MenuBar(QMenuBar): + """Menubar for the main window.""" + + create_library_modal_signal = Signal() + open_library_signal = Signal(Path) + backup_library_signal = Signal() + refresh_directories_signal = Signal() + close_library_signal = Signal() + select_all_items_signal = Signal() + clear_selection_signal = Signal() + filter_items_signal = Signal() + tag_database_modal_signal = Signal() + show_grid_filenames_signal = Signal(bool) + autofill_macro_signal = Signal() + + def __init__(self, parent, settings, lib, driver): + super().__init__(parent) + self.settings = settings + self.lib = lib + self.driver = driver + + self.setNativeMenuBar(True) + + file_menu = QMenu(self) + Translations.translate_qobject(file_menu, "menu.file") + edit_menu = QMenu(self) + Translations.translate_qobject(edit_menu, "generic.edit_alt") + view_menu = QMenu(self) + Translations.translate_qobject(view_menu, "menu.view") + tools_menu = QMenu(self) + Translations.translate_qobject(tools_menu, "menu.tools") + macros_menu = QMenu(self) + Translations.translate_qobject(macros_menu, "menu.macros") + help_menu = QMenu(self) + Translations.translate_qobject(help_menu, "menu.help") + + # File Menu ============================================================ + open_library_action = QAction(self) + Translations.translate_qobject(open_library_action, "menu.file.open_create_library") + open_library_action.triggered.connect(lambda: self.create_library_modal_signal.emit()) + + open_library_action.setShortcut( + QtCore.QKeyCombination( + QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), + QtCore.Qt.Key.Key_O, + ) + ) + open_library_action.setToolTip("Ctrl+O") + file_menu.addAction(open_library_action) + + self.open_recent_library_menu = QMenu(self) + Translations.translate_qobject( + self.open_recent_library_menu, "menu.file.open_recent_library" + ) + file_menu.addMenu(self.open_recent_library_menu) + self.update_recent_lib_menu() + + open_on_start_action = QAction(self) + Translations.translate_qobject(open_on_start_action, "settings.open_library_on_start") + open_on_start_action.setCheckable(True) + open_on_start_action.setChecked( + bool(self.settings.value(SettingItems.START_LOAD_LAST, defaultValue=True, type=bool)) + ) + open_on_start_action.triggered.connect( + lambda checked: self.settings.setValue(SettingItems.START_LOAD_LAST, checked) + ) + file_menu.addAction(open_on_start_action) + + file_menu.addSeparator() + + save_library_backup_action = QAction(self) + Translations.translate_qobject(save_library_backup_action, "menu.file.save_backup") + save_library_backup_action.triggered.connect(lambda: self.backup_library_signal.emit()) + save_library_backup_action.setShortcut( + QtCore.QKeyCombination( + QtCore.Qt.KeyboardModifier( + QtCore.Qt.KeyboardModifier.ControlModifier + | QtCore.Qt.KeyboardModifier.ShiftModifier + ), + QtCore.Qt.Key.Key_S, + ) + ) + save_library_backup_action.setStatusTip("Ctrl+Shift+S") + file_menu.addAction(save_library_backup_action) + + file_menu.addSeparator() + + refresh_directories_action = QAction(self) + Translations.translate_qobject(refresh_directories_action, "menu.file.refresh_directories") + refresh_directories_action.triggered.connect(lambda: self.refresh_directories_signal.emit()) + refresh_directories_action.setShortcut( + QtCore.QKeyCombination( + QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), + QtCore.Qt.Key.Key_R, + ) + ) + refresh_directories_action.setStatusTip("Ctrl+R") + file_menu.addAction(refresh_directories_action) + file_menu.addSeparator() + + close_library_action = QAction(self) + Translations.translate_qobject(close_library_action, "menu.file.close_library") + close_library_action.triggered.connect(lambda: self.close_library_signal.emit()) + file_menu.addAction(close_library_action) + file_menu.addSeparator() + + # Edit Menu ============================================================ + new_tag_action = QAction(self) + Translations.translate_qobject(new_tag_action, "menu.edit.new_tag") + new_tag_action.triggered.connect(self._open_add_tag_modal) + new_tag_action.setShortcut( + QtCore.QKeyCombination( + QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), + QtCore.Qt.Key.Key_T, + ) + ) + new_tag_action.setToolTip("Ctrl+T") + edit_menu.addAction(new_tag_action) + + edit_menu.addSeparator() + + select_all_action = QAction(self) + Translations.translate_qobject(select_all_action, "select.all") + select_all_action.triggered.connect(lambda: self.select_all_items_signal.emit()) + select_all_action.setShortcut( + QtCore.QKeyCombination( + QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), + QtCore.Qt.Key.Key_A, + ) + ) + select_all_action.setToolTip("Ctrl+A") + edit_menu.addAction(select_all_action) + + clear_select_action = QAction(self) + Translations.translate_qobject(clear_select_action, "select.clear") + clear_select_action.triggered.connect(lambda: self.clear_selection_signal.emit()) + clear_select_action.setShortcut(QtCore.Qt.Key.Key_Escape) + clear_select_action.setToolTip("Esc") + edit_menu.addAction(clear_select_action) + + edit_menu.addSeparator() + + manage_file_extensions_action = QAction(self) + Translations.translate_qobject( + manage_file_extensions_action, "menu.edit.manage_file_extensions" + ) + manage_file_extensions_action.triggered.connect(self._open_file_extension_modal) + edit_menu.addAction(manage_file_extensions_action) + + tag_database_action = QAction(self) + Translations.translate_qobject(tag_database_action, "menu.edit.manage_tags") + tag_database_action.triggered.connect(lambda: self.tag_database_modal_signal.emit()) + edit_menu.addAction(tag_database_action) + + # View Menu ============================================================ + show_libs_list_action = QAction(self) + Translations.translate_qobject(show_libs_list_action, "settings.show_recent_libraries") + show_libs_list_action.setCheckable(True) + show_libs_list_action.setChecked( + bool(self.settings.value(SettingItems.WINDOW_SHOW_LIBS, defaultValue=True, type=bool)) + ) + + show_filenames_action = QAction(self) + Translations.translate_qobject(show_filenames_action, "settings.show_filenames_in_grid") + show_filenames_action.setCheckable(True) + show_filenames_action.setChecked( + bool(self.settings.value(SettingItems.SHOW_FILENAMES, defaultValue=True, type=bool)) + ) + show_filenames_action.triggered.connect( + lambda checked: ( + self.settings.setValue(SettingItems.SHOW_FILENAMES, checked), + self.show_grid_filenames_signal.emit(checked), + ) + ) + view_menu.addAction(show_filenames_action) + + # Tools Menu =========================================================== + fix_unlinked_entries_action = QAction(self) + Translations.translate_qobject( + fix_unlinked_entries_action, "menu.tools.fix_unlinked_entries" + ) + fix_unlinked_entries_action.triggered.connect(self._open_fix_unlinked_entries_modal) + tools_menu.addAction(fix_unlinked_entries_action) + + fix_dupe_files_action = QAction(self) + Translations.translate_qobject(fix_dupe_files_action, "menu.tools.fix_duplicate_files") + fix_dupe_files_action.triggered.connect(self._open_dupe_files_modal) + tools_menu.addAction(fix_dupe_files_action) + + # create_collage_action = QAction("Create Collage", self) + # create_collage_action.triggered.connect(lambda: self.create_collage()) + # tools_menu.addAction(create_collage_action) + + # Macros Menu ========================================================== + self.autofill_action = QAction("Autofill", self) + self.autofill_action.triggered.connect(lambda: self.autofill_macro_signal.emit()) + macros_menu.addAction(self.autofill_action) + + folders_to_tags_action = QAction(self) + Translations.translate_qobject(folders_to_tags_action, "menu.macros.folders_to_tags") + folders_to_tags_action.triggered.connect(self._open_folders_to_tags_modal) + macros_menu.addAction(folders_to_tags_action) + + # Help Menu ============================================================ + self.repo_action = QAction(self) + Translations.translate_qobject(self.repo_action, "help.visit_github") + self.repo_action.triggered.connect( + lambda: webbrowser.open("https://github.com/TagStudioDev/TagStudio") + ) + help_menu.addAction(self.repo_action) + + self.addMenu(file_menu) + self.addMenu(edit_menu) + self.addMenu(view_menu) + self.addMenu(tools_menu) + self.addMenu(macros_menu) + self.addMenu(help_menu) + + def _open_folders_to_tags_modal(self): + if not hasattr(self, "folders_modal"): + self.folders_modal = FoldersToTagsModal(self.lib, self.driver) + self.folders_modal.show() + + def _open_add_tag_modal(self): + panel = BuildTagPanel(self.lib) + self.modal = PanelModal( + panel, + has_save=True, + ) + Translations.translate_with_setter(self.modal.setTitle, "tag.new") + Translations.translate_with_setter(self.modal.setWindowTitle, "tag.add") + + self.modal.saved.connect( + lambda: ( + self.lib.add_tag( + panel.build_tag(), + set(panel.parent_ids), + set(panel.alias_names), + set(panel.alias_ids), + ), + self.modal.hide(), + ) + ) + self.modal.show() + + def _open_file_extension_modal(self): + panel = FileExtensionModal(self.lib) + self.modal = PanelModal( + panel, + has_save=True, + ) + Translations.translate_with_setter(self.modal.setTitle, "ignore_list.title") + Translations.translate_with_setter(self.modal.setWindowTitle, "ignore_list.title") + + self.modal.saved.connect(lambda: (panel.save(), self.filter_items_signal.emit())) + self.modal.show() + + def _open_fix_unlinked_entries_modal(self): + if not hasattr(self, "unlinked_modal"): + self.unlinked_modal = FixUnlinkedEntriesModal(self.lib, self.driver) + self.unlinked_modal.show() + + def _open_dupe_files_modal(self): + if not hasattr(self, "dupe_modal"): + self.dupe_modal = FixDupeFilesModal(self.lib, self.driver) + self.dupe_modal.show() + + def _clear_recent_libs(self): + """Clear the list of recent libraries from the settings file.""" + settings = self.settings + settings.beginGroup(SettingItems.LIBS_LIST) + self.settings.remove("") + self.settings.endGroup() + self.settings.sync() + self.update_recent_lib_menu() + + def set_macro_menu_viability(self, value: bool): + self.autofill_action.setDisabled(value) + + def update_recent_lib_menu(self): + """Updates the recent library menu from the latest values from the settings file.""" + actions: list[QAction] = [] + lib_items: dict[str, tuple[str, str]] = {} + + settings = self.settings + settings.beginGroup(SettingItems.LIBS_LIST) + for item_tstamp in settings.allKeys(): + val = str(settings.value(item_tstamp, type=str)) + cut_val = val + if len(val) > 45: + cut_val = f"{val[0:10]} ... {val[-10:]}" + lib_items[item_tstamp] = (val, cut_val) + + # Sort lib_items by the key + libs_sorted = sorted(lib_items.items(), key=lambda item: item[0], reverse=True) + settings.endGroup() + + # Create actions for each library + for library_key in libs_sorted: + path = Path(library_key[1][0]) + action = QAction(self.open_recent_library_menu) + action.setText(str(path)) + action.triggered.connect(lambda checked=False, p=path: self.open_library_signal.emit(p)) + actions.append(action) + + clear_recent_action = QAction(self.open_recent_library_menu) + Translations.translate_qobject(clear_recent_action, "menu.file.clear_recent_libraries") + clear_recent_action.triggered.connect(self._clear_recent_libs) + actions.append(clear_recent_action) + + # Clear previous actions + for action in self.open_recent_library_menu.actions(): + self.open_recent_library_menu.removeAction(action) + + # Add new actions + for action in actions: + self.open_recent_library_menu.addAction(action) + + # Only enable add "clear recent" if there are still recent libraries. + if len(actions) > 1: + self.open_recent_library_menu.setDisabled(False) + self.open_recent_library_menu.addSeparator() + self.open_recent_library_menu.addAction(clear_recent_action) + else: + self.open_recent_library_menu.setDisabled(True) From 5f3913f9c718c3094ed0867f4e340c4c37a9066c Mon Sep 17 00:00:00 2001 From: mashed5894 Date: Sun, 19 Jan 2025 08:23:40 +0200 Subject: [PATCH 2/3] renamed functions and added functions to disable actions --- tagstudio/src/qt/ts_qt.py | 11 +- tagstudio/src/qt/widgets/menu_bar.py | 256 +++++++++++++++------------ 2 files changed, 146 insertions(+), 121 deletions(-) diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index e86e37ac9..dc2157880 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -279,8 +279,9 @@ def start(self) -> None: self.preview_panel.update_widgets(), ) ) - self.menu_bar.set_macro_menu_viability(not self.selected) + self.menu_bar.set_macro_actions_disabled(not self.selected) self.main_window.setMenuBar(self.menu_bar) + self.menu_bar.set_library_actions_disabled(True) self.main_window.searchField.textChanged.connect(self.update_completions_list) @@ -454,6 +455,7 @@ def close_library(self, is_shutdown: bool = False): self.settings.sync() self.lib.close() + self.menu_bar.set_library_actions_disabled(True) self.thumb_job_queue.queue.clear() if is_shutdown: @@ -500,7 +502,7 @@ def select_all_items(self): self.selected.append(item.item_id) item.thumb_button.set_selected(True) - self.menu_bar.set_macro_menu_viability(not self.selected) + self.menu_bar.set_macro_actions_disabled(not self.selected) self.preview_panel.update_widgets() def clear_selection(self): @@ -508,7 +510,7 @@ def clear_selection(self): for item in self.item_thumbs: item.thumb_button.set_selected(False) - self.menu_bar.set_macro_menu_viability(not self.selected) + self.menu_bar.set_macro_actions_disabled(not self.selected) self.preview_panel.update_widgets() def open_tag_database_modal(self): @@ -839,7 +841,7 @@ def toggle_item_selection(self, item_id: int, append: bool, bridge: bool): else: it.thumb_button.set_selected(False) - self.menu_bar.set_macro_menu_viability(not self.selected) + self.menu_bar.set_macro_actions_disabled(not self.selected) self.preview_panel.update_widgets() def update_completions_list(self, text: str) -> None: @@ -1152,6 +1154,7 @@ def init_library(self, path: Path, open_status: LibraryStatus): self.filter_items() self.main_window.toggle_landing_page(enabled=False) + self.menu_bar.set_library_actions_disabled(False) return open_status def drop_event(self, event: QDropEvent): diff --git a/tagstudio/src/qt/widgets/menu_bar.py b/tagstudio/src/qt/widgets/menu_bar.py index 03d458aa7..5f7d3e9d8 100644 --- a/tagstudio/src/qt/widgets/menu_bar.py +++ b/tagstudio/src/qt/widgets/menu_bar.py @@ -43,57 +43,55 @@ def __init__(self, parent, settings, lib, driver): self.setNativeMenuBar(True) - file_menu = QMenu(self) - Translations.translate_qobject(file_menu, "menu.file") - edit_menu = QMenu(self) - Translations.translate_qobject(edit_menu, "generic.edit_alt") - view_menu = QMenu(self) - Translations.translate_qobject(view_menu, "menu.view") - tools_menu = QMenu(self) - Translations.translate_qobject(tools_menu, "menu.tools") - macros_menu = QMenu(self) - Translations.translate_qobject(macros_menu, "menu.macros") - help_menu = QMenu(self) - Translations.translate_qobject(help_menu, "menu.help") + self.file_menu = QMenu(self) + Translations.translate_qobject(self.file_menu, "menu.file") + self.edit_menu = QMenu(self) + Translations.translate_qobject(self.edit_menu, "generic.edit_alt") + self.view_menu = QMenu(self) + Translations.translate_qobject(self.view_menu, "menu.view") + self.tools_menu = QMenu(self) + Translations.translate_qobject(self.tools_menu, "menu.tools") + self.macros_menu = QMenu(self) + Translations.translate_qobject(self.macros_menu, "menu.macros") + self.help_menu = QMenu(self) + Translations.translate_qobject(self.help_menu, "menu.help") # File Menu ============================================================ - open_library_action = QAction(self) - Translations.translate_qobject(open_library_action, "menu.file.open_create_library") - open_library_action.triggered.connect(lambda: self.create_library_modal_signal.emit()) + self.open_library_action = QAction(self) + Translations.translate_qobject(self.open_library_action, "menu.file.open_create_library") + self.open_library_action.triggered.connect(lambda: self.create_library_modal_signal.emit()) - open_library_action.setShortcut( + self.open_library_action.setShortcut( QtCore.QKeyCombination( QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), QtCore.Qt.Key.Key_O, ) ) - open_library_action.setToolTip("Ctrl+O") - file_menu.addAction(open_library_action) + self.open_library_action.setToolTip("Ctrl+O") + self.file_menu.addAction(self.open_library_action) - self.open_recent_library_menu = QMenu(self) - Translations.translate_qobject( - self.open_recent_library_menu, "menu.file.open_recent_library" - ) - file_menu.addMenu(self.open_recent_library_menu) + self.open_recent_action = QMenu(self) + Translations.translate_qobject(self.open_recent_action, "menu.file.open_recent_library") + self.file_menu.addMenu(self.open_recent_action) self.update_recent_lib_menu() - open_on_start_action = QAction(self) - Translations.translate_qobject(open_on_start_action, "settings.open_library_on_start") - open_on_start_action.setCheckable(True) - open_on_start_action.setChecked( + self.open_on_start_action = QAction(self) + Translations.translate_qobject(self.open_on_start_action, "settings.open_library_on_start") + self.open_on_start_action.setCheckable(True) + self.open_on_start_action.setChecked( bool(self.settings.value(SettingItems.START_LOAD_LAST, defaultValue=True, type=bool)) ) - open_on_start_action.triggered.connect( + self.open_on_start_action.triggered.connect( lambda checked: self.settings.setValue(SettingItems.START_LOAD_LAST, checked) ) - file_menu.addAction(open_on_start_action) + self.file_menu.addAction(self.open_on_start_action) - file_menu.addSeparator() + self.file_menu.addSeparator() - save_library_backup_action = QAction(self) - Translations.translate_qobject(save_library_backup_action, "menu.file.save_backup") - save_library_backup_action.triggered.connect(lambda: self.backup_library_signal.emit()) - save_library_backup_action.setShortcut( + self.save_library_backup_action = QAction(self) + Translations.translate_qobject(self.save_library_backup_action, "menu.file.save_backup") + self.save_library_backup_action.triggered.connect(lambda: self.backup_library_signal.emit()) + self.save_library_backup_action.setShortcut( QtCore.QKeyCombination( QtCore.Qt.KeyboardModifier( QtCore.Qt.KeyboardModifier.ControlModifier @@ -102,112 +100,119 @@ def __init__(self, parent, settings, lib, driver): QtCore.Qt.Key.Key_S, ) ) - save_library_backup_action.setStatusTip("Ctrl+Shift+S") - file_menu.addAction(save_library_backup_action) + self.save_library_backup_action.setStatusTip("Ctrl+Shift+S") + self.file_menu.addAction(self.save_library_backup_action) - file_menu.addSeparator() + self.file_menu.addSeparator() - refresh_directories_action = QAction(self) - Translations.translate_qobject(refresh_directories_action, "menu.file.refresh_directories") - refresh_directories_action.triggered.connect(lambda: self.refresh_directories_signal.emit()) - refresh_directories_action.setShortcut( + self.refresh_directories_action = QAction(self) + Translations.translate_qobject( + self.refresh_directories_action, "menu.file.refresh_directories" + ) + self.refresh_directories_action.triggered.connect( + lambda: self.refresh_directories_signal.emit() + ) + self.refresh_directories_action.setShortcut( QtCore.QKeyCombination( QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), QtCore.Qt.Key.Key_R, ) ) - refresh_directories_action.setStatusTip("Ctrl+R") - file_menu.addAction(refresh_directories_action) - file_menu.addSeparator() + self.refresh_directories_action.setStatusTip("Ctrl+R") + self.file_menu.addAction(self.refresh_directories_action) + self.file_menu.addSeparator() - close_library_action = QAction(self) - Translations.translate_qobject(close_library_action, "menu.file.close_library") - close_library_action.triggered.connect(lambda: self.close_library_signal.emit()) - file_menu.addAction(close_library_action) - file_menu.addSeparator() + self.close_library_action = QAction(self) + Translations.translate_qobject(self.close_library_action, "menu.file.close_library") + self.close_library_action.triggered.connect(lambda: self.close_library_signal.emit()) + self.file_menu.addAction(self.close_library_action) + self.file_menu.addSeparator() # Edit Menu ============================================================ - new_tag_action = QAction(self) - Translations.translate_qobject(new_tag_action, "menu.edit.new_tag") - new_tag_action.triggered.connect(self._open_add_tag_modal) - new_tag_action.setShortcut( + self.new_tag_action = QAction(self) + Translations.translate_qobject(self.new_tag_action, "menu.edit.new_tag") + self.new_tag_action.triggered.connect(self._open_add_tag_modal) + self.new_tag_action.setShortcut( QtCore.QKeyCombination( QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), QtCore.Qt.Key.Key_T, ) ) - new_tag_action.setToolTip("Ctrl+T") - edit_menu.addAction(new_tag_action) + self.new_tag_action.setToolTip("Ctrl+T") + self.edit_menu.addAction(self.new_tag_action) - edit_menu.addSeparator() + self.edit_menu.addSeparator() - select_all_action = QAction(self) - Translations.translate_qobject(select_all_action, "select.all") - select_all_action.triggered.connect(lambda: self.select_all_items_signal.emit()) - select_all_action.setShortcut( + self.select_all_action = QAction(self) + Translations.translate_qobject(self.select_all_action, "select.all") + self.select_all_action.triggered.connect(lambda: self.select_all_items_signal.emit()) + self.select_all_action.setShortcut( QtCore.QKeyCombination( QtCore.Qt.KeyboardModifier(QtCore.Qt.KeyboardModifier.ControlModifier), QtCore.Qt.Key.Key_A, ) ) - select_all_action.setToolTip("Ctrl+A") - edit_menu.addAction(select_all_action) + self.select_all_action.setToolTip("Ctrl+A") + self.edit_menu.addAction(self.select_all_action) - clear_select_action = QAction(self) - Translations.translate_qobject(clear_select_action, "select.clear") - clear_select_action.triggered.connect(lambda: self.clear_selection_signal.emit()) - clear_select_action.setShortcut(QtCore.Qt.Key.Key_Escape) - clear_select_action.setToolTip("Esc") - edit_menu.addAction(clear_select_action) + self.clear_select_action = QAction(self) + Translations.translate_qobject(self.clear_select_action, "select.clear") + self.clear_select_action.triggered.connect(lambda: self.clear_selection_signal.emit()) + self.clear_select_action.setShortcut(QtCore.Qt.Key.Key_Escape) + self.clear_select_action.setToolTip("Esc") + self.edit_menu.addAction(self.clear_select_action) - edit_menu.addSeparator() + self.edit_menu.addSeparator() - manage_file_extensions_action = QAction(self) + self.manage_file_extensions_action = QAction(self) Translations.translate_qobject( - manage_file_extensions_action, "menu.edit.manage_file_extensions" + self.manage_file_extensions_action, "menu.edit.manage_file_extensions" ) - manage_file_extensions_action.triggered.connect(self._open_file_extension_modal) - edit_menu.addAction(manage_file_extensions_action) + self.manage_file_extensions_action.triggered.connect(self._open_file_extension_modal) + self.edit_menu.addAction(self.manage_file_extensions_action) - tag_database_action = QAction(self) - Translations.translate_qobject(tag_database_action, "menu.edit.manage_tags") - tag_database_action.triggered.connect(lambda: self.tag_database_modal_signal.emit()) - edit_menu.addAction(tag_database_action) + self.tag_database_action = QAction(self) + Translations.translate_qobject(self.tag_database_action, "menu.edit.manage_tags") + self.tag_database_action.triggered.connect(lambda: self.tag_database_modal_signal.emit()) + self.edit_menu.addAction(self.tag_database_action) # View Menu ============================================================ - show_libs_list_action = QAction(self) - Translations.translate_qobject(show_libs_list_action, "settings.show_recent_libraries") - show_libs_list_action.setCheckable(True) - show_libs_list_action.setChecked( + self.show_libs_list_action = QAction(self) + Translations.translate_qobject(self.show_libs_list_action, "settings.show_recent_libraries") + self.show_libs_list_action.setCheckable(True) + self.show_libs_list_action.setChecked( bool(self.settings.value(SettingItems.WINDOW_SHOW_LIBS, defaultValue=True, type=bool)) ) + self.view_menu.addAction(self.show_libs_list_action) - show_filenames_action = QAction(self) - Translations.translate_qobject(show_filenames_action, "settings.show_filenames_in_grid") - show_filenames_action.setCheckable(True) - show_filenames_action.setChecked( + self.show_filenames_action = QAction(self) + Translations.translate_qobject( + self.show_filenames_action, "settings.show_filenames_in_grid" + ) + self.show_filenames_action.setCheckable(True) + self.show_filenames_action.setChecked( bool(self.settings.value(SettingItems.SHOW_FILENAMES, defaultValue=True, type=bool)) ) - show_filenames_action.triggered.connect( + self.show_filenames_action.triggered.connect( lambda checked: ( self.settings.setValue(SettingItems.SHOW_FILENAMES, checked), self.show_grid_filenames_signal.emit(checked), ) ) - view_menu.addAction(show_filenames_action) + self.view_menu.addAction(self.show_filenames_action) # Tools Menu =========================================================== - fix_unlinked_entries_action = QAction(self) + self.fix_unlinked_entries_action = QAction(self) Translations.translate_qobject( - fix_unlinked_entries_action, "menu.tools.fix_unlinked_entries" + self.fix_unlinked_entries_action, "menu.tools.fix_unlinked_entries" ) - fix_unlinked_entries_action.triggered.connect(self._open_fix_unlinked_entries_modal) - tools_menu.addAction(fix_unlinked_entries_action) + self.fix_unlinked_entries_action.triggered.connect(self._open_fix_unlinked_entries_modal) + self.tools_menu.addAction(self.fix_unlinked_entries_action) - fix_dupe_files_action = QAction(self) - Translations.translate_qobject(fix_dupe_files_action, "menu.tools.fix_duplicate_files") - fix_dupe_files_action.triggered.connect(self._open_dupe_files_modal) - tools_menu.addAction(fix_dupe_files_action) + self.fix_dupe_files_action = QAction(self) + Translations.translate_qobject(self.fix_dupe_files_action, "menu.tools.fix_duplicate_files") + self.fix_dupe_files_action.triggered.connect(self._open_dupe_files_modal) + self.tools_menu.addAction(self.fix_dupe_files_action) # create_collage_action = QAction("Create Collage", self) # create_collage_action.triggered.connect(lambda: self.create_collage()) @@ -216,12 +221,12 @@ def __init__(self, parent, settings, lib, driver): # Macros Menu ========================================================== self.autofill_action = QAction("Autofill", self) self.autofill_action.triggered.connect(lambda: self.autofill_macro_signal.emit()) - macros_menu.addAction(self.autofill_action) + self.macros_menu.addAction(self.autofill_action) - folders_to_tags_action = QAction(self) - Translations.translate_qobject(folders_to_tags_action, "menu.macros.folders_to_tags") - folders_to_tags_action.triggered.connect(self._open_folders_to_tags_modal) - macros_menu.addAction(folders_to_tags_action) + self.folders_to_tags_action = QAction(self) + Translations.translate_qobject(self.folders_to_tags_action, "menu.macros.folders_to_tags") + self.folders_to_tags_action.triggered.connect(self._open_folders_to_tags_modal) + self.macros_menu.addAction(self.folders_to_tags_action) # Help Menu ============================================================ self.repo_action = QAction(self) @@ -229,14 +234,14 @@ def __init__(self, parent, settings, lib, driver): self.repo_action.triggered.connect( lambda: webbrowser.open("https://github.com/TagStudioDev/TagStudio") ) - help_menu.addAction(self.repo_action) + self.help_menu.addAction(self.repo_action) - self.addMenu(file_menu) - self.addMenu(edit_menu) - self.addMenu(view_menu) - self.addMenu(tools_menu) - self.addMenu(macros_menu) - self.addMenu(help_menu) + self.addMenu(self.file_menu) + self.addMenu(self.edit_menu) + self.addMenu(self.view_menu) + self.addMenu(self.tools_menu) + self.addMenu(self.macros_menu) + self.addMenu(self.help_menu) def _open_folders_to_tags_modal(self): if not hasattr(self, "folders_modal"): @@ -296,8 +301,25 @@ def _clear_recent_libs(self): self.settings.sync() self.update_recent_lib_menu() - def set_macro_menu_viability(self, value: bool): + def set_library_actions_disabled(self, value: bool): + actions: list[QAction] = [ + self.save_library_backup_action, + self.refresh_directories_action, + self.close_library_action, + self.new_tag_action, + self.select_all_action, + self.clear_select_action, + self.manage_file_extensions_action, + self.tag_database_action, + self.fix_unlinked_entries_action, + self.fix_dupe_files_action, + ] + for action in actions: + action.setDisabled(value) + + def set_macro_actions_disabled(self, value: bool): self.autofill_action.setDisabled(value) + self.folders_to_tags_action.setDisabled(value) def update_recent_lib_menu(self): """Updates the recent library menu from the latest values from the settings file.""" @@ -320,28 +342,28 @@ def update_recent_lib_menu(self): # Create actions for each library for library_key in libs_sorted: path = Path(library_key[1][0]) - action = QAction(self.open_recent_library_menu) + action = QAction(self.open_recent_action) action.setText(str(path)) action.triggered.connect(lambda checked=False, p=path: self.open_library_signal.emit(p)) actions.append(action) - clear_recent_action = QAction(self.open_recent_library_menu) + clear_recent_action = QAction(self.open_recent_action) Translations.translate_qobject(clear_recent_action, "menu.file.clear_recent_libraries") clear_recent_action.triggered.connect(self._clear_recent_libs) actions.append(clear_recent_action) # Clear previous actions - for action in self.open_recent_library_menu.actions(): - self.open_recent_library_menu.removeAction(action) + for action in self.open_recent_action.actions(): + self.open_recent_action.removeAction(action) # Add new actions for action in actions: - self.open_recent_library_menu.addAction(action) + self.open_recent_action.addAction(action) # Only enable add "clear recent" if there are still recent libraries. if len(actions) > 1: - self.open_recent_library_menu.setDisabled(False) - self.open_recent_library_menu.addSeparator() - self.open_recent_library_menu.addAction(clear_recent_action) + self.open_recent_action.setDisabled(False) + self.open_recent_action.addSeparator() + self.open_recent_action.addAction(clear_recent_action) else: - self.open_recent_library_menu.setDisabled(True) + self.open_recent_action.setDisabled(True) From e65744962090c23895d05c6db5c41079e2d2deaf Mon Sep 17 00:00:00 2001 From: mashed5894 Date: Sun, 19 Jan 2025 10:08:26 +0200 Subject: [PATCH 3/3] moved recent_library functions to menu_bar --- tagstudio/src/qt/ts_qt.py | 19 +++++++------------ tagstudio/src/qt/widgets/menu_bar.py | 6 ++++++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index dc2157880..77acbdbc3 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -261,12 +261,8 @@ def start(self) -> None: self.menu_bar = MenuBar(self.main_window, self.settings, self.lib, self) self.menu_bar.create_library_modal_signal.connect(self.open_create_library_modal) self.menu_bar.open_library_signal.connect(self.open_library) - self.menu_bar.backup_library_signal.connect( - lambda: self.backup_library() if self.lib.library_dir else () - ) - self.menu_bar.refresh_directories_signal.connect( - lambda: self.refresh_directories() if self.lib.library_dir else () - ) + self.menu_bar.backup_library_signal.connect(self.backup_library) + self.menu_bar.refresh_directories_signal.connect(self.refresh_directories) self.menu_bar.close_library_signal.connect(self.close_library) self.menu_bar.select_all_items_signal.connect(self.select_all_items) self.menu_bar.clear_selection_signal.connect(self.clear_selection) @@ -481,6 +477,8 @@ def close_library(self, is_shutdown: bool = False): ) def backup_library(self): + if not self.lib.library_dir: + return logger.info("Backing Up Library...") self.main_window.statusbar.showMessage(Translations["status.library_backup_in_progress"]) start_time = time.time() @@ -525,6 +523,9 @@ def open_tag_database_modal(self): def refresh_directories(self): """Run when user initiates adding new files to the Library.""" + if not self.lib.library_dir: + return + tracker = RefreshDirTracker(self.lib) pw = ProgressWidget( @@ -1061,12 +1062,6 @@ def filter_items(self, filter: FilterState | None = None) -> None: self.pages_count, self.filter.page_index, emit=False ) - def remove_recent_library(self, item_key: str): - self.settings.beginGroup(SettingItems.LIBS_LIST) - self.settings.remove(item_key) - self.settings.endGroup() - self.settings.sync() - def update_libs_list(self, path: Path | str): """Add library to list in SettingItems.LIBS_LIST.""" item_limit: int = 5 diff --git a/tagstudio/src/qt/widgets/menu_bar.py b/tagstudio/src/qt/widgets/menu_bar.py index 5f7d3e9d8..0c2ecc24b 100644 --- a/tagstudio/src/qt/widgets/menu_bar.py +++ b/tagstudio/src/qt/widgets/menu_bar.py @@ -301,6 +301,12 @@ def _clear_recent_libs(self): self.settings.sync() self.update_recent_lib_menu() + def _remove_recent_library(self, item_key: str): + self.settings.beginGroup(SettingItems.LIBS_LIST) + self.settings.remove(item_key) + self.settings.endGroup() + self.settings.sync() + def set_library_actions_disabled(self, value: bool): actions: list[QAction] = [ self.save_library_backup_action,