v0.9.25
This commit is contained in:
@@ -14,7 +14,7 @@ Classes:
|
|||||||
MainWindow: The main application window containing the thumbnail grid and docks.
|
MainWindow: The main application window containing the thumbnail grid and docks.
|
||||||
"""
|
"""
|
||||||
__appname__ = "BagheeraView"
|
__appname__ = "BagheeraView"
|
||||||
__version__ = "0.9.24"
|
__version__ = "0.9.25"
|
||||||
__author__ = "Ignacio Serantes"
|
__author__ = "Ignacio Serantes"
|
||||||
__email__ = "kde@aynoa.net"
|
__email__ = "kde@aynoa.net"
|
||||||
__license__ = "LGPL"
|
__license__ = "LGPL"
|
||||||
|
|||||||
10
constants.py
10
constants.py
@@ -29,7 +29,7 @@ if FORCE_X11:
|
|||||||
# --- CONFIGURATION ---
|
# --- CONFIGURATION ---
|
||||||
PROG_NAME = "Bagheera Image Viewer"
|
PROG_NAME = "Bagheera Image Viewer"
|
||||||
PROG_ID = "bagheeraview"
|
PROG_ID = "bagheeraview"
|
||||||
PROG_VERSION = "0.9.24"
|
PROG_VERSION = "0.9.25"
|
||||||
PROG_AUTHOR = "Ignacio Serantes"
|
PROG_AUTHOR = "Ignacio Serantes"
|
||||||
|
|
||||||
# --- CACHE SETTINGS ---
|
# --- CACHE SETTINGS ---
|
||||||
@@ -823,6 +823,8 @@ _UI_TEXTS = {
|
|||||||
"TAG_ALL_TAGS": "📂 ALL TAGS",
|
"TAG_ALL_TAGS": "📂 ALL TAGS",
|
||||||
"TAG_NEW_TAG_TITLE": "New Tag",
|
"TAG_NEW_TAG_TITLE": "New Tag",
|
||||||
"SEARCH_BY_TAG": "Search by this tag",
|
"SEARCH_BY_TAG": "Search by this tag",
|
||||||
|
"TAG_ADD_TOOLTIP": "Create a new tag",
|
||||||
|
"TAG_REFRESH_TOOLTIP": "Refresh available tags from Baloo database",
|
||||||
"TAG_NEW_TAG_TEXT": "Enter tag name (use / for hierarchy):",
|
"TAG_NEW_TAG_TEXT": "Enter tag name (use / for hierarchy):",
|
||||||
"SEARCH_ADD_AND": "Add AND this tag to search",
|
"SEARCH_ADD_AND": "Add AND this tag to search",
|
||||||
"SEARCH_ADD_OR": "Add OR this tag to search",
|
"SEARCH_ADD_OR": "Add OR this tag to search",
|
||||||
@@ -1375,6 +1377,9 @@ _UI_TEXTS = {
|
|||||||
"TAG_ALL_TAGS": "📂 TODAS LAS ETIQUETAS",
|
"TAG_ALL_TAGS": "📂 TODAS LAS ETIQUETAS",
|
||||||
"TAG_NEW_TAG_TITLE": "Nueva Etiqueta",
|
"TAG_NEW_TAG_TITLE": "Nueva Etiqueta",
|
||||||
"SEARCH_BY_TAG": "Buscar por esta etiqueta",
|
"SEARCH_BY_TAG": "Buscar por esta etiqueta",
|
||||||
|
"TAG_ADD_TOOLTIP": "Crear una nueva etiqueta",
|
||||||
|
"TAG_REFRESH_TOOLTIP": "Refrescar etiquetas disponibles desde el base de datos "
|
||||||
|
"de Baloo",
|
||||||
"TAG_NEW_TAG_TEXT": "Introduce el nombre de la etiqueta (usa / para "
|
"TAG_NEW_TAG_TEXT": "Introduce el nombre de la etiqueta (usa / para "
|
||||||
"jerarquía):",
|
"jerarquía):",
|
||||||
"SEARCH_ADD_AND": "Añadir AND esta etiqueta a la búsqueda",
|
"SEARCH_ADD_AND": "Añadir AND esta etiqueta a la búsqueda",
|
||||||
@@ -1928,6 +1933,9 @@ _UI_TEXTS = {
|
|||||||
"TAG_ALL_TAGS": "📂 TÓDALAS ETIQUETAS",
|
"TAG_ALL_TAGS": "📂 TÓDALAS ETIQUETAS",
|
||||||
"TAG_NEW_TAG_TITLE": "Nova Etiqueta",
|
"TAG_NEW_TAG_TITLE": "Nova Etiqueta",
|
||||||
"SEARCH_BY_TAG": "Buscar por esta etiqueta",
|
"SEARCH_BY_TAG": "Buscar por esta etiqueta",
|
||||||
|
"TAG_ADD_TOOLTIP": "Crear unha nova etiqueta",
|
||||||
|
"TAG_REFRESH_TOOLTIP": "Refrescar etiquetas dispoñibles dende a base de datos "
|
||||||
|
"de Baloo",
|
||||||
"TAG_NEW_TAG_TEXT": "Introduce o nome da etiqueta (usa / para "
|
"TAG_NEW_TAG_TEXT": "Introduce o nome da etiqueta (usa / para "
|
||||||
"xerarquía):",
|
"xerarquía):",
|
||||||
"SEARCH_ADD_AND": "Engadir AND esta etiqueta á busca",
|
"SEARCH_ADD_AND": "Engadir AND esta etiqueta á busca",
|
||||||
|
|||||||
@@ -689,39 +689,36 @@ class ImageController(QObject):
|
|||||||
if self.pixmap_original.isNull():
|
if self.pixmap_original.isNull():
|
||||||
return QPixmap()
|
return QPixmap()
|
||||||
|
|
||||||
# Ensure pixmap_original is a valid, independent copy before transforming
|
# Start with an identity transform
|
||||||
temp_pixmap = QPixmap(self.pixmap_original)
|
transform = QTransform()
|
||||||
if temp_pixmap.isNull():
|
|
||||||
return QPixmap()
|
|
||||||
|
|
||||||
# Use rotated() which returns a new QTransform, potentially safer
|
# Apply rotation
|
||||||
transform = QTransform() # Initialize to identity transform
|
|
||||||
if self.rotation != 0:
|
if self.rotation != 0:
|
||||||
transform = QTransform().rotated(float(self.rotation))
|
transform.rotate(float(self.rotation))
|
||||||
|
|
||||||
transformed_pixmap = temp_pixmap.transformed(
|
# Apply flips
|
||||||
|
if self.flip_h:
|
||||||
|
transform.scale(-1, 1)
|
||||||
|
if self.flip_v:
|
||||||
|
transform.scale(1, -1)
|
||||||
|
|
||||||
|
# Apply the cumulative transform to the original pixmap
|
||||||
|
transformed_pixmap = self.pixmap_original.transformed(
|
||||||
transform, Qt.TransformationMode.SmoothTransformation)
|
transform, Qt.TransformationMode.SmoothTransformation)
|
||||||
|
|
||||||
# Calculate new size, explicitly converting QSizeF to QSize
|
# Apply scaling (zoom) separately after rotation and flips,
|
||||||
|
# as scaling should be based on the *transformed* dimensions.
|
||||||
|
# This is important: if you scale before rotation, the scaling
|
||||||
|
# factors might be applied to the wrong axes.
|
||||||
|
if self.zoom_factor != 1.0:
|
||||||
new_size_f = transformed_pixmap.size() * self.zoom_factor
|
new_size_f = transformed_pixmap.size() * self.zoom_factor
|
||||||
new_size = QSize(int(new_size_f.width()), int(new_size_f.height()))
|
new_size = QSize(int(new_size_f.width()), int(new_size_f.height()))
|
||||||
|
|
||||||
scaled_pixmap = transformed_pixmap.scaled(
|
scaled_pixmap = transformed_pixmap.scaled(
|
||||||
new_size, Qt.AspectRatioMode.KeepAspectRatio,
|
new_size, Qt.AspectRatioMode.KeepAspectRatio,
|
||||||
Qt.TransformationMode.SmoothTransformation)
|
Qt.TransformationMode.SmoothTransformation)
|
||||||
|
|
||||||
if self.flip_h:
|
|
||||||
t_flip_h = QTransform()
|
|
||||||
t_flip_h.scale(-1, 1)
|
|
||||||
scaled_pixmap = scaled_pixmap.transformed(
|
|
||||||
t_flip_h, Qt.TransformationMode.SmoothTransformation)
|
|
||||||
if self.flip_v:
|
|
||||||
t_flip_v = QTransform()
|
|
||||||
t_flip_v.scale(1, -1)
|
|
||||||
scaled_pixmap = scaled_pixmap.transformed(
|
|
||||||
t_flip_v, Qt.TransformationMode.SmoothTransformation)
|
|
||||||
|
|
||||||
return scaled_pixmap
|
return scaled_pixmap
|
||||||
|
else:
|
||||||
|
return transformed_pixmap
|
||||||
|
|
||||||
def rotate(self, angle):
|
def rotate(self, angle):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -147,10 +147,8 @@ class PropertiesDialog(QDialog):
|
|||||||
self.table = QTableWidget()
|
self.table = QTableWidget()
|
||||||
self.table.setColumnCount(2)
|
self.table.setColumnCount(2)
|
||||||
self.table.setHorizontalHeaderLabels(UITexts.PROPERTIES_TABLE_HEADER)
|
self.table.setHorizontalHeaderLabels(UITexts.PROPERTIES_TABLE_HEADER)
|
||||||
self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive)
|
self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
|
||||||
self.table.horizontalHeader().setSectionResizeMode(1,
|
self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
|
||||||
QHeaderView.ResizeToContents)
|
|
||||||
self.table.setColumnWidth(0, self.width() * 0.4)
|
|
||||||
self.table.verticalHeader().setVisible(False)
|
self.table.verticalHeader().setVisible(False)
|
||||||
self.table.setAlternatingRowColors(True)
|
self.table.setAlternatingRowColors(True)
|
||||||
self.table.setEditTriggers(QAbstractItemView.DoubleClicked |
|
self.table.setEditTriggers(QAbstractItemView.DoubleClicked |
|
||||||
@@ -188,10 +186,8 @@ class PropertiesDialog(QDialog):
|
|||||||
# without a significant architectural change (e.g., a dedicated metadata DB).
|
# without a significant architectural change (e.g., a dedicated metadata DB).
|
||||||
self.exif_table.setColumnCount(2)
|
self.exif_table.setColumnCount(2)
|
||||||
self.exif_table.setHorizontalHeaderLabels(UITexts.PROPERTIES_TABLE_HEADER)
|
self.exif_table.setHorizontalHeaderLabels(UITexts.PROPERTIES_TABLE_HEADER)
|
||||||
self.exif_table.horizontalHeader().setSectionResizeMode(
|
self.exif_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
|
||||||
0, QHeaderView.ResizeToContents)
|
self.exif_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
|
||||||
self.exif_table.horizontalHeader().setSectionResizeMode(
|
|
||||||
1, QHeaderView.ResizeToContents)
|
|
||||||
self.exif_table.verticalHeader().setVisible(False)
|
self.exif_table.verticalHeader().setVisible(False)
|
||||||
self.exif_table.setAlternatingRowColors(True)
|
self.exif_table.setAlternatingRowColors(True)
|
||||||
self.exif_table.setEditTriggers(QAbstractItemView.DoubleClicked |
|
self.exif_table.setEditTriggers(QAbstractItemView.DoubleClicked |
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "bagheeraview"
|
name = "bagheeraview"
|
||||||
version = "0.9.24"
|
version = "0.9.25"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "Ignacio Serantes" }
|
{ name = "Ignacio Serantes" }
|
||||||
]
|
]
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="bagheeraview",
|
name="bagheeraview",
|
||||||
version="0.9.24",
|
version="0.9.25",
|
||||||
author="Ignacio Serantes",
|
author="Ignacio Serantes",
|
||||||
description="Bagheera Image Viewer - An image viewer for KDE with Baloo in mind",
|
description="Bagheera Image Viewer - An image viewer for KDE with Baloo in mind",
|
||||||
long_description="A fast image viewer built with PySide6, featuring search and "
|
long_description="A fast image viewer built with PySide6, featuring search and "
|
||||||
|
|||||||
17
widgets.py
17
widgets.py
@@ -129,11 +129,19 @@ class TagEditWidget(QWidget):
|
|||||||
search_layout = QHBoxLayout()
|
search_layout = QHBoxLayout()
|
||||||
self.search_bar = QLineEdit()
|
self.search_bar = QLineEdit()
|
||||||
self.search_bar.setPlaceholderText(UITexts.TAG_SEARCH_PLACEHOLDER)
|
self.search_bar.setPlaceholderText(UITexts.TAG_SEARCH_PLACEHOLDER)
|
||||||
|
# Obtener la altura preferida del QLineEdit para usarla en los botones
|
||||||
|
line_edit_height = self.search_bar.sizeHint().height()
|
||||||
self.search_bar.setClearButtonEnabled(True)
|
self.search_bar.setClearButtonEnabled(True)
|
||||||
self.btn_add_tag = QPushButton("+")
|
self.btn_add_tag = QPushButton("+")
|
||||||
self.btn_add_tag.setFixedWidth(30)
|
self.btn_add_tag.setFixedSize(30, line_edit_height)
|
||||||
|
self.btn_add_tag.setToolTip(UITexts.TAG_ADD_TOOLTIP)
|
||||||
|
self.btn_refresh_tags = QPushButton()
|
||||||
|
self.btn_refresh_tags.setIcon(QIcon.fromTheme("view-refresh"))
|
||||||
|
self.btn_refresh_tags.setFixedSize(30, line_edit_height)
|
||||||
|
self.btn_refresh_tags.setToolTip(UITexts.TAG_REFRESH_TOOLTIP)
|
||||||
search_layout.addWidget(self.search_bar)
|
search_layout.addWidget(self.search_bar)
|
||||||
search_layout.addWidget(self.btn_add_tag)
|
search_layout.addWidget(self.btn_add_tag)
|
||||||
|
search_layout.addWidget(self.btn_refresh_tags)
|
||||||
layout.addLayout(search_layout)
|
layout.addLayout(search_layout)
|
||||||
|
|
||||||
# Tag tree view setup
|
# Tag tree view setup
|
||||||
@@ -159,6 +167,7 @@ class TagEditWidget(QWidget):
|
|||||||
# Connect signals to slots
|
# Connect signals to slots
|
||||||
self.btn_apply.clicked.connect(self.save_changes)
|
self.btn_apply.clicked.connect(self.save_changes)
|
||||||
self.btn_add_tag.clicked.connect(self.create_new_tag)
|
self.btn_add_tag.clicked.connect(self.create_new_tag)
|
||||||
|
self.btn_refresh_tags.clicked.connect(self.refresh_available_tags)
|
||||||
self.search_bar.textChanged.connect(self.handle_search)
|
self.search_bar.textChanged.connect(self.handle_search)
|
||||||
self.source_model.itemChanged.connect(self.sync_tags)
|
self.source_model.itemChanged.connect(self.sync_tags)
|
||||||
self.tree_view.search_requested.connect(self.on_search_requested)
|
self.tree_view.search_requested.connect(self.on_search_requested)
|
||||||
@@ -177,6 +186,12 @@ class TagEditWidget(QWidget):
|
|||||||
tags in files_data.items()}
|
tags in files_data.items()}
|
||||||
self.refresh_ui()
|
self.refresh_ui()
|
||||||
|
|
||||||
|
def refresh_available_tags(self):
|
||||||
|
"""Manual refresh of available tags from Baloo."""
|
||||||
|
self.load_available_tags()
|
||||||
|
self._load_all = True
|
||||||
|
self.init_data()
|
||||||
|
|
||||||
def load_available_tags(self):
|
def load_available_tags(self):
|
||||||
"""Loads all known tags from the Baloo index database."""
|
"""Loads all known tags from the Baloo index database."""
|
||||||
db_path = os.path.expanduser("~/.local/share/baloo/index")
|
db_path = os.path.expanduser("~/.local/share/baloo/index")
|
||||||
|
|||||||
Reference in New Issue
Block a user