v0.9.13
This commit is contained in:
110
bagheeraview.py
110
bagheeraview.py
@@ -14,7 +14,7 @@ Classes:
|
||||
MainWindow: The main application window containing the thumbnail grid and docks.
|
||||
"""
|
||||
__appname__ = "BagheeraView"
|
||||
__version__ = "0.9.12"
|
||||
__version__ = "0.9.13"
|
||||
__author__ = "Ignacio Serantes"
|
||||
__email__ = "kde@aynoa.net"
|
||||
__license__ = "LGPL"
|
||||
@@ -55,7 +55,7 @@ from pathlib import Path
|
||||
from constants import (
|
||||
APP_CONFIG, CONFIG_PATH, CURRENT_LANGUAGE, DEFAULT_GLOBAL_SHORTCUTS,
|
||||
DEFAULT_VIEWER_SHORTCUTS, GLOBAL_ACTIONS, HISTORY_PATH, ICON_THEME,
|
||||
ICON_THEME_FALLBACK, IMAGE_MIME_TYPES, LAYOUTS_DIR, PROG_AUTHOR,
|
||||
ICON_THEME_FALLBACK, IMAGE_MIME_TYPES, LAYOUTS_DIR, FAVORITES_PATH, PROG_AUTHOR,
|
||||
PROG_NAME, PROG_VERSION, RATING_XATTR_NAME, SCANNER_GENERATE_SIZES,
|
||||
SCANNER_SETTINGS_DEFAULTS, SUPPORTED_LANGUAGES, TAGS_MENU_MAX_ITEMS_DEFAULT,
|
||||
THUMBNAILS_BG_COLOR_DEFAULT, THUMBNAILS_DEFAULT_SIZE, VIEWER_ACTIONS,
|
||||
@@ -74,7 +74,8 @@ from imageviewer import ImageViewer
|
||||
from propertiesdialog import PropertiesDialog
|
||||
from widgets import (
|
||||
CircularProgressBar,
|
||||
TagEditWidget, LayoutsWidget, HistoryWidget, RatingWidget, CommentWidget
|
||||
TagEditWidget, LayoutsWidget, HistoryWidget, RatingWidget, CommentWidget,
|
||||
FavoritesWidget
|
||||
)
|
||||
from metadatamanager import XattrManager
|
||||
|
||||
@@ -255,16 +256,13 @@ class ShortcutHelpDialog(QDialog):
|
||||
new_mods = new_key_combo.keyboardModifiers()
|
||||
new_key_tuple = (int(new_key), new_mods)
|
||||
|
||||
# Check for conflicts in the same scope
|
||||
if new_key_tuple in source_dict and new_key_tuple != original_key_combo:
|
||||
# Handle different value structures
|
||||
val = source_dict[new_key_tuple]
|
||||
# Global: (action, ignore, desc, category), Viewer: (action, desc)
|
||||
if len(val) == 4:
|
||||
conflict_desc = val[2]
|
||||
else:
|
||||
conflict_desc = val[1]
|
||||
# Check for conflicts globally
|
||||
conflict_desc = self.main_win.shortcut_controller.check_conflict(
|
||||
new_key, new_mods)
|
||||
|
||||
is_same = (new_key_tuple == original_key_combo)
|
||||
|
||||
if conflict_desc and not is_same:
|
||||
QMessageBox.warning(self, UITexts.SHORTCUT_CONFLICT_TITLE,
|
||||
UITexts.SHORTCUT_CONFLICT_TEXT.format(
|
||||
new_sequence.toString(QKeySequence.NativeText),
|
||||
@@ -300,6 +298,7 @@ class AppShortcutController(QObject):
|
||||
self.main_win = main_win
|
||||
self._actions = self._get_actions()
|
||||
self._shortcuts = {}
|
||||
self._favorite_shortcuts = {}
|
||||
self.action_to_shortcut = {}
|
||||
self._register_shortcuts()
|
||||
|
||||
@@ -317,6 +316,44 @@ class AppShortcutController(QObject):
|
||||
key_tuple = (k, Qt.KeyboardModifiers(m))
|
||||
self._shortcuts[key_tuple] = (act, ignore, desc, cat)
|
||||
self.action_to_shortcut[act] = key_tuple
|
||||
self.refresh_favorite_shortcuts()
|
||||
|
||||
def refresh_favorite_shortcuts(self):
|
||||
"""Loads dynamic shortcuts assigned to favorite queries."""
|
||||
self._favorite_shortcuts.clear()
|
||||
if not os.path.exists(FAVORITES_PATH):
|
||||
return
|
||||
try:
|
||||
with open(FAVORITES_PATH, 'r', encoding='utf-8') as f:
|
||||
favorites = json.load(f)
|
||||
for fav in favorites:
|
||||
sc_str = fav.get('shortcut', '')
|
||||
if sc_str:
|
||||
seq = QKeySequence(sc_str)
|
||||
if not seq.isEmpty():
|
||||
self._favorite_shortcuts[
|
||||
(seq[0].key(), seq[0].keyboardModifiers())
|
||||
] = fav.get('query')
|
||||
except (json.JSONDecodeError, OSError):
|
||||
pass
|
||||
|
||||
def check_conflict(self, key, mods):
|
||||
"""Checks if a shortcut is already assigned and returns its description."""
|
||||
key_tuple = (int(key), mods)
|
||||
|
||||
# Global
|
||||
if key_tuple in self._shortcuts:
|
||||
return self._shortcuts[key_tuple][2]
|
||||
|
||||
# Viewer
|
||||
if key_tuple in self.main_win.viewer_shortcuts:
|
||||
return self.main_win.viewer_shortcuts[key_tuple][1]
|
||||
|
||||
# Favorites
|
||||
if key_tuple in self._favorite_shortcuts:
|
||||
return f"{UITexts.FAVORITES_TAB}: {self._favorite_shortcuts[key_tuple]}"
|
||||
|
||||
return None
|
||||
|
||||
def _get_actions(self):
|
||||
"""Returns a dictionary mapping action strings to callable functions."""
|
||||
@@ -375,6 +412,12 @@ class AppShortcutController(QObject):
|
||||
if is_typing:
|
||||
return False
|
||||
|
||||
# 1. Check Favorite Shortcuts FIRST (Priority Override)
|
||||
if (key, mods) in self._favorite_shortcuts:
|
||||
query = self._favorite_shortcuts[(key, mods)]
|
||||
self.main_win.process_term(query)
|
||||
return True
|
||||
|
||||
# Check if we have a handler for this combination
|
||||
if (key, mods) in self._shortcuts:
|
||||
action_name, ignore_if_typing, _, _ = self._shortcuts[(key, mods)]
|
||||
@@ -1172,16 +1215,26 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self.tags_tabs.addTab(self.filter_widget, UITexts.TAG_FILTER_TAB)
|
||||
|
||||
# Tab 4: Layouts
|
||||
# Tab 4: Favorites
|
||||
self.favorites_tab = FavoritesWidget(self)
|
||||
self.tags_tabs.addTab(self.favorites_tab, UITexts.FAVORITES_TAB)
|
||||
|
||||
# Tab 5: Layouts
|
||||
self.is_xcb = QApplication.platformName() == "xcb"
|
||||
if self.is_xcb:
|
||||
self.layouts_tab = LayoutsWidget(self)
|
||||
self.tags_tabs.addTab(self.layouts_tab, UITexts.LAYOUTS_TAB)
|
||||
|
||||
# Tab 5: History
|
||||
# Tab 6: History
|
||||
self.history_tab = HistoryWidget(self)
|
||||
self.tags_tabs.addTab(self.history_tab, UITexts.HISTORY_TAB)
|
||||
|
||||
# Initialize the shortcut controller
|
||||
self.shortcut_controller = AppShortcutController(self)
|
||||
|
||||
self.favorites_tab.favorites_changed.connect(
|
||||
self.shortcut_controller.refresh_favorite_shortcuts)
|
||||
|
||||
self.main_dock.setWidget(self.tags_tabs)
|
||||
self.addDockWidget(Qt.RightDockWidgetArea, self.main_dock)
|
||||
|
||||
@@ -1233,6 +1286,11 @@ class MainWindow(QMainWindow):
|
||||
self.load_config()
|
||||
self.load_full_history()
|
||||
|
||||
# Initialize the shortcut controller (after config is loaded)
|
||||
self.shortcut_controller = AppShortcutController(self)
|
||||
self.favorites_tab.favorites_changed.connect(
|
||||
self.shortcut_controller.refresh_favorite_shortcuts)
|
||||
|
||||
self._apply_global_stylesheet()
|
||||
# Set the initial thumbnail generation tier based on the loaded config size
|
||||
self._current_thumb_tier = self._get_tier_for_size(self.current_thumb_size)
|
||||
@@ -1558,15 +1616,23 @@ class MainWindow(QMainWindow):
|
||||
# Actions to show different tabs in the dock
|
||||
show_tags_action = menu.addAction(QIcon.fromTheme("document-properties"),
|
||||
UITexts.MENU_SHOW_TAGS)
|
||||
show_tags_action.triggered.connect(lambda: self.open_sidebar_tab(0))
|
||||
show_tags_action.triggered.connect(
|
||||
lambda: self.open_sidebar_tab(self.tags_tabs.indexOf(self.tag_edit_widget)))
|
||||
|
||||
show_info_action = menu.addAction(QIcon.fromTheme("dialog-information"),
|
||||
UITexts.MENU_SHOW_INFO)
|
||||
show_info_action.triggered.connect(lambda: self.open_sidebar_tab(1))
|
||||
show_info_action.triggered.connect(
|
||||
lambda: self.open_sidebar_tab(self.tags_tabs.indexOf(self.info_widget)))
|
||||
|
||||
show_favorites_action = menu.addAction(QIcon.fromTheme("bookmarks"),
|
||||
UITexts.MENU_SHOW_FAVORITES)
|
||||
f_idx = self.tags_tabs.indexOf(self.favorites_tab)
|
||||
show_favorites_action.triggered.connect(lambda: self.open_sidebar_tab(f_idx))
|
||||
|
||||
show_filter_action = menu.addAction(QIcon.fromTheme("view-filter"),
|
||||
UITexts.MENU_SHOW_FILTER)
|
||||
show_filter_action.triggered.connect(lambda: self.open_sidebar_tab(2))
|
||||
show_filter_action.triggered.connect(
|
||||
lambda: self.open_sidebar_tab(self.tags_tabs.indexOf(self.filter_widget)))
|
||||
|
||||
if self.is_xcb:
|
||||
show_layouts_action = menu.addAction(QIcon.fromTheme("view-grid"),
|
||||
@@ -2911,6 +2977,8 @@ class MainWindow(QMainWindow):
|
||||
self.update_tag_list()
|
||||
elif widget == self.info_widget:
|
||||
self.update_info_widget()
|
||||
elif widget == self.favorites_tab:
|
||||
self.favorites_tab.refresh_list()
|
||||
|
||||
def update_tag_edit_widget(self):
|
||||
"""Updates the tag editor widget with data from the currently selected files."""
|
||||
@@ -3852,7 +3920,7 @@ class MainWindow(QMainWindow):
|
||||
self.proxy_model.data(index_at_pos, ITEM_TYPE_ROLE) == 'header':
|
||||
group_name = self.proxy_model.data(index_at_pos, GROUP_NAME_ROLE)
|
||||
if group_name:
|
||||
action_toggle = menu.addAction("Collapse/Expand Group")
|
||||
action_toggle = menu.addAction(UITexts.COLLAPSE_EXPAND_GROUP)
|
||||
action_toggle.triggered.connect(
|
||||
lambda: self.toggle_group_collapse(group_name))
|
||||
menu.exec(self.thumbnail_view.mapToGlobal(pos))
|
||||
@@ -4006,7 +4074,7 @@ class MainWindow(QMainWindow):
|
||||
self.on_high_res_generation_finished)
|
||||
self.thumbnail_generator.progress.connect(
|
||||
lambda p, t: self.status_lbl.setText(
|
||||
f"Regenerating thumbnail: {p}/{t}")
|
||||
UITexts.THUMBNAILS_REGENERATE_PROGRESS.format(p, t))
|
||||
)
|
||||
self.thumbnail_generator.start()
|
||||
|
||||
@@ -4397,9 +4465,7 @@ def main():
|
||||
path = path[6:]
|
||||
|
||||
win = MainWindow(cache, args, thread_pool_manager)
|
||||
shortcut_controller = AppShortcutController(win)
|
||||
win.shortcut_controller = shortcut_controller
|
||||
app.installEventFilter(shortcut_controller)
|
||||
app.installEventFilter(win.shortcut_controller)
|
||||
|
||||
sys.exit(app.exec())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user