Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions tagstudio/src/core/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import enum


class SettingItems(str, enum.Enum):
"""List of setting item names."""

START_LOAD_LAST = "start_load_last"
LAST_LIBRARY = "last_library"
LIBS_LIST = "libs_list"
WINDOW_SHOW_LIBS = "window_show_libs"


class Theme(str, enum.Enum):
COLOR_BG = "#65000000"
COLOR_HOVER = "#65AAAAAA"
COLOR_PRESSED = "#65EEEEEE"
133 changes: 101 additions & 32 deletions tagstudio/src/qt/ts_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import webbrowser
from datetime import datetime as dt
from pathlib import Path
from queue import Empty, Queue
from queue import Queue
from typing import Optional

from PIL import Image
Expand Down Expand Up @@ -46,6 +46,7 @@
)
from humanfriendly import format_timespan

from src.core.enums import SettingItems
from src.core.library import ItemType
from src.core.ts_core import (
PLAINTEXT_TYPES,
Expand Down Expand Up @@ -88,7 +89,9 @@
from src.qt.modals.fix_unlinked import FixUnlinkedEntriesModal
from src.qt.modals.fix_dupes import FixDupeFilesModal
from src.qt.modals.folders_to_tags import FoldersToTagsModal
import src.qt.resources_rc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this import is what causes in the splash screen to break, and is currently the pinpoint of a merge conflict

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah so it's not unused import, but it has side-effect of executing code. Not a good thing to do, but looks like there's no way around it. I'll add comment so it's obvious why is it here.


# this import has side-effect of import PySide resources
import src.qt.resources_rc # pylint: disable=unused-import

# SIGQUIT is not defined on Windows
if sys.platform == "win32":
Expand Down Expand Up @@ -282,6 +285,7 @@ def start(self):
edit_menu = QMenu("&Edit", menu_bar)
tools_menu = QMenu("&Tools", menu_bar)
macros_menu = QMenu("&Macros", menu_bar)
window_menu = QMenu("&Window", menu_bar)
help_menu = QMenu("&Help", menu_bar)

# File Menu ============================================================
Expand Down Expand Up @@ -376,6 +380,18 @@ def start(self):
tag_database_action.triggered.connect(lambda: self.show_tag_database())
edit_menu.addAction(tag_database_action)

check_action = QAction("Open library on start", self)
check_action.setCheckable(True)
check_action.setChecked(
self.settings.value(SettingItems.START_LOAD_LAST, True, type=bool)
)
check_action.triggered.connect(
lambda checked: self.settings.setValue(
SettingItems.START_LOAD_LAST, checked
)
)
window_menu.addAction(check_action)

# Tools Menu ===========================================================
fix_unlinked_entries_action = QAction("Fix &Unlinked Entries", menu_bar)
fue_modal = FixUnlinkedEntriesModal(self.lib, self)
Expand Down Expand Up @@ -423,6 +439,20 @@ def start(self):
macros_menu.addAction(self.sort_fields_action)

folders_to_tags_action = QAction("Create Tags From Folders", menu_bar)
show_libs_list_action = QAction("Show Recent Libraries", menu_bar)
show_libs_list_action.setCheckable(True)
show_libs_list_action.setChecked(
self.settings.value(SettingItems.WINDOW_SHOW_LIBS, True, type=bool)
)
show_libs_list_action.triggered.connect(
lambda checked: (
self.settings.setValue(SettingItems.WINDOW_SHOW_LIBS, checked),
self.toggle_libs_list(checked),
)
)
window_menu.addAction(show_libs_list_action)

folders_to_tags_action = QAction("Folders to Tags", menu_bar)
ftt_modal = FoldersToTagsModal(self.lib, self)
folders_to_tags_action.triggered.connect(lambda: ftt_modal.show())
macros_menu.addAction(folders_to_tags_action)
Expand All @@ -440,6 +470,7 @@ def start(self):
menu_bar.addMenu(edit_menu)
menu_bar.addMenu(tools_menu)
menu_bar.addMenu(macros_menu)
menu_bar.addMenu(window_menu)
menu_bar.addMenu(help_menu)

self.preview_panel = PreviewPanel(self.lib, self)
Expand All @@ -458,6 +489,31 @@ def start(self):
self.thumb_renderers: list[ThumbRenderer] = []
self.collation_thumb_size = math.ceil(self.thumb_size * 2)

self.init_library_window()

lib = None
if self.args.open:
lib = self.args.open
elif self.settings.value(SettingItems.START_LOAD_LAST, True, type=bool):
lib = self.settings.value(SettingItems.LAST_LIBRARY)

if lib:
self.splash.showMessage(
f'Opening Library "{lib}"...',
int(Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignHCenter),
QColor("#9782ff"),
)
self.open_library(lib)

if self.args.ci:
# gracefully terminate the app in CI environment
self.thumb_job_queue.put((self.SIGTERM.emit, []))

app.exec()

self.shutdown()

def init_library_window(self):
self._init_thumb_grid()

# TODO: Put this into its own method that copies the font file(s) into memory
Expand Down Expand Up @@ -510,31 +566,12 @@ def start(self):
self.splash.finish(self.main_window)
self.preview_panel.update_widgets()

# Check if a library should be opened on startup, args should override last_library
# TODO: check for behavior (open last, open default, start empty)
if (
self.args.open
or self.settings.contains("last_library")
and os.path.isdir(self.settings.value("last_library"))
):
if self.args.open:
lib = self.args.open
elif self.settings.value("last_library"):
lib = self.settings.value("last_library")
self.splash.showMessage(
f'Opening Library "{lib}"...',
int(Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignHCenter),
QColor("#9782ff"),
)
self.open_library(lib)

if self.args.ci:
# gracefully terminate the app in CI environment
self.thumb_job_queue.put((self.SIGTERM.emit, []))

app.exec()

self.shutdown()
def toggle_libs_list(self, value: bool):
if value:
self.preview_panel.libs_flow_container.show()
else:
self.preview_panel.libs_flow_container.hide()
self.preview_panel.update()

def callback_library_needed_check(self, func):
"""Check if loaded library has valid path before executing the button function"""
Expand All @@ -548,7 +585,7 @@ def shutdown(self):
"""Save Library on Application Exit"""
if self.lib.library_dir:
self.save_library()
self.settings.setValue("last_library", self.lib.library_dir)
self.settings.setValue(SettingItems.LAST_LIBRARY, self.lib.library_dir)
self.settings.sync()
logging.info("[SHUTDOWN] Ending Thumbnail Threads...")
for _ in self.thumb_threads:
Expand Down Expand Up @@ -597,7 +634,7 @@ def close_library(self):
self.main_window.statusbar.showMessage(f"Closing & Saving Library...")
start_time = time.time()
self.save_library(show_status=False)
self.settings.setValue("last_library", self.lib.library_dir)
self.settings.setValue(SettingItems.LAST_LIBRARY, self.lib.library_dir)
self.settings.sync()

self.lib.clear_internal_vars()
Expand Down Expand Up @@ -709,7 +746,7 @@ def add_new_files_callback(self):
iterator.value.connect(lambda x: pw.update_progress(x + 1))
iterator.value.connect(
lambda x: pw.update_label(
f'Scanning Directories for New Files...\n{x+1} File{"s" if x+1 != 1 else ""} Searched, {len(self.lib.files_not_in_library)} New Files Found'
f'Scanning Directories for New Files...\n{x + 1} File{"s" if x + 1 != 1 else ""} Searched, {len(self.lib.files_not_in_library)} New Files Found'
)
)
r = CustomRunnable(lambda: iterator.run())
Expand Down Expand Up @@ -760,7 +797,7 @@ def add_new_files_runnable(self):
iterator.value.connect(lambda x: pw.update_progress(x + 1))
iterator.value.connect(
lambda x: pw.update_label(
f"Running Configured Macros on {x+1}/{len(new_ids)} New Entries"
f"Running Configured Macros on {x + 1}/{len(new_ids)} New Entries"
)
)
r = CustomRunnable(lambda: iterator.run())
Expand Down Expand Up @@ -1297,6 +1334,38 @@ def filter_items(self, query=""):

# self.update_thumbs()

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: str | Path):
"""add library to list in SettingItems.LIBS_LIST"""
ITEMS_LIMIT = 5
path = Path(path)

self.settings.beginGroup(SettingItems.LIBS_LIST)

all_libs = {str(time.time()): str(path)}

for item_key in self.settings.allKeys():
item_path = self.settings.value(item_key)
if Path(item_path) != path:
all_libs[item_key] = item_path

# sort items, most recent first
all_libs = sorted(all_libs.items(), key=lambda item: item[0], reverse=True)

# remove previously saved items
self.settings.clear()

for item_key, item_value in all_libs[:ITEMS_LIMIT]:
self.settings.setValue(item_key, item_value)

self.settings.endGroup()
self.settings.sync()

def open_library(self, path):
"""Opens a TagStudio library."""
if self.lib.library_dir:
Expand All @@ -1314,7 +1383,7 @@ def open_library(self, path):
# self.lib.refresh_missing_files()
# title_text = f'{self.base_title} - Library \'{self.lib.library_dir}\''
# self.main_window.setWindowTitle(title_text)
pass
self.update_libs_list(path)

else:
logging.info(
Expand Down
Loading