Prevent traceback on trying to edit a tag with the same name as another tag. Various other tweaks. Bump version
This commit is contained in:
parent
02a60ca656
commit
1becb7900e
15 changed files with 153 additions and 83 deletions
|
|
@ -23,6 +23,20 @@ _TAG_COLORS = [
|
|||
"#BAFFC9", # soft green
|
||||
"#BAE1FF", # soft blue
|
||||
"#E0BAFF", # soft purple
|
||||
"#FFC4B3", # soft coral
|
||||
"#FFD8B1", # soft peach
|
||||
"#FFF1BA", # soft light yellow
|
||||
"#E9FFBA", # soft lime
|
||||
"#CFFFE5", # soft mint
|
||||
"#BAFFF5", # soft aqua
|
||||
"#BAF0FF", # soft cyan
|
||||
"#C7E9FF", # soft sky blue
|
||||
"#C7CEFF", # soft periwinkle
|
||||
"#F0BAFF", # soft lavender pink
|
||||
"#FFBAF2", # soft magenta
|
||||
"#FFD1F0", # soft pink
|
||||
"#EBD5C7", # soft beige
|
||||
"#EAEAEA", # soft gray
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -554,16 +568,22 @@ class DBManager:
|
|||
name = name.strip()
|
||||
color = color.strip() or "#CCCCCC"
|
||||
|
||||
with self.conn:
|
||||
cur = self.conn.cursor()
|
||||
cur.execute(
|
||||
"""
|
||||
UPDATE tags
|
||||
SET name = ?, color = ?
|
||||
WHERE id = ?;
|
||||
""",
|
||||
(name, color, tag_id),
|
||||
)
|
||||
try:
|
||||
with self.conn:
|
||||
cur = self.conn.cursor()
|
||||
cur.execute(
|
||||
"""
|
||||
UPDATE tags
|
||||
SET name = ?, color = ?
|
||||
WHERE id = ?;
|
||||
""",
|
||||
(name, color, tag_id),
|
||||
)
|
||||
except sqlite.IntegrityError as e:
|
||||
if "UNIQUE constraint failed: tags.name" in str(e):
|
||||
raise sqlite.IntegrityError(
|
||||
strings._("tag_already_exists_with_that_name")
|
||||
) from e
|
||||
|
||||
def delete_tag(self, tag_id: int) -> None:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -112,13 +112,14 @@
|
|||
"toolbar_heading": "Heading",
|
||||
"toolbar_toggle_checkboxes": "Toggle checkboxes",
|
||||
"tags": "Tags",
|
||||
"tag": "Tag",
|
||||
"manage_tags": "Manage tags",
|
||||
"add_tag_placeholder": "Add a tag and press Enter",
|
||||
"tag_browser_title": "Tag Browser",
|
||||
"tag_browser_instructions": "Click a tag to expand and see all pages with that tag. Click a date to open it. Select a tag to edit its name, change its color, or delete it globally.",
|
||||
"tag_name": "Tag name",
|
||||
"tag_color_hex": "Hex colour",
|
||||
"color_hex": "Color",
|
||||
"color_hex": "Colour",
|
||||
"date": "Date",
|
||||
"pick_color": "Pick colour",
|
||||
"invalid_color_title": "Invalid colour",
|
||||
|
|
@ -130,5 +131,6 @@
|
|||
"new_tag_name": "New tag name:",
|
||||
"change_color": "Change colour",
|
||||
"delete_tag": "Delete tag",
|
||||
"delete_tag_confirm": "Are you sure you want to delete the tag '{name}'? This will remove it from all pages."
|
||||
"delete_tag_confirm": "Are you sure you want to delete the tag '{name}'? This will remove it from all pages.",
|
||||
"tag_already_exists_with_that_name": "A tag already exists with that name"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,12 +111,13 @@
|
|||
"toolbar_code_block": "Bloc de code",
|
||||
"toolbar_heading": "Titre",
|
||||
"toolbar_toggle_checkboxes": "Cocher/Décocher les cases",
|
||||
"tags": "Tags",
|
||||
"manage_tags": "Gérer les tags",
|
||||
"add_tag_placeholder": "Ajouter un tag et appuyez sur Entrée",
|
||||
"tag_browser_title": "Navigateur de tags",
|
||||
"tag_browser_instructions": "Cliquez sur un tag pour l'étendre et voir toutes les pages avec ce tag. Cliquez sur une date pour l'ouvrir. Sélectionnez un tag pour modifier son nom, changer sa couleur ou le supprimer globalement.",
|
||||
"tag_name": "Nom du tag",
|
||||
"tags": "Étiquettes",
|
||||
"tag": "Étiquette",
|
||||
"manage_tags": "Gérer les étiquettes",
|
||||
"add_tag_placeholder": "Ajouter une étiquette et appuyez sur Entrée",
|
||||
"tag_browser_title": "Navigateur de étiquettes",
|
||||
"tag_browser_instructions": "Cliquez sur une étiquette pour l'étendre et voir toutes les pages avec cette étiquette. Cliquez sur une date pour l'ouvrir. Sélectionnez une étiquette pour modifier son nom, changer sa couleur ou la supprimer globalement.",
|
||||
"tag_name": "Nom de l'étiquette",
|
||||
"tag_color_hex": "Couleur hexadécimale",
|
||||
"color_hex": "Couleur",
|
||||
"date": "Date",
|
||||
|
|
@ -126,9 +127,10 @@
|
|||
"add": "Ajouter",
|
||||
"remove": "Supprimer",
|
||||
"ok": "OK",
|
||||
"edit_tag_name": "Modifier le nom du tag",
|
||||
"new_tag_name": "Nouveau nom du tag :",
|
||||
"edit_tag_name": "Modifier le nom de l'étiquette",
|
||||
"new_tag_name": "Nouveau nom de l'étiquette :",
|
||||
"change_color": "Changer la couleur",
|
||||
"delete_tag": "Supprimer le tag",
|
||||
"delete_tag_confirm": "Êtes-vous sûr de vouloir supprimer le tag '{name}' ? Cela le supprimera de toutes les pages."
|
||||
"delete_tag": "Supprimer l'étiquette",
|
||||
"delete_tag_confirm": "Êtes-vous sûr de vouloir supprimer l'étiquette '{name}' ? Cela la supprimera de toutes les pages.",
|
||||
"tag_already_exists_with_that_name": "Une étiquette portant ce nom existe déjà"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,5 +130,6 @@
|
|||
"new_tag_name": "Nuovo nome tag:",
|
||||
"change_color": "Cambia colore",
|
||||
"delete_tag": "Elimina tag",
|
||||
"delete_tag_confirm": "Sei sicuro di voler eliminare il tag '{name}'? Questo lo rimuoverà da tutte le pagine."
|
||||
"delete_tag_confirm": "Sei sicuro di voler eliminare il tag '{name}'? Questo lo rimuoverà da tutte le pagine.",
|
||||
"tag_already_exists_with_that_name": "Esiste già un tag con questo nome"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1077,8 +1077,17 @@ class MainWindow(QMainWindow):
|
|||
|
||||
dlg = TagBrowserDialog(self.db, self, focus_tag=tag_name_or_date)
|
||||
dlg.openDateRequested.connect(self._load_selected_date)
|
||||
dlg.tagsModified.connect(self._refresh_current_page_tags)
|
||||
dlg.exec()
|
||||
|
||||
def _refresh_current_page_tags(self):
|
||||
"""Refresh the tag chips for the current page (after tag browser changes)"""
|
||||
if hasattr(self, "tags") and hasattr(self.editor, "current_date"):
|
||||
date_iso = self.editor.current_date.toString("yyyy-MM-dd")
|
||||
self.tags.set_current_date(date_iso)
|
||||
if self.tags.toggle_btn.isChecked():
|
||||
self.tags._reload_tags()
|
||||
|
||||
# ----------- Settings handler ------------#
|
||||
def _open_settings(self):
|
||||
dlg = SettingsDialog(self.cfg, self.db, self)
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ class MarkdownHighlighter(QSyntaxHighlighter):
|
|||
self.setFormat(end - 2, 2, self.syntax_format)
|
||||
self.setFormat(content_start, content_end - content_start, self.bold_format)
|
||||
|
||||
# --- Italic (*) or (_): skip if it overlaps any triple, keep your guards
|
||||
# --- Italic (*) or (_): skip if it overlaps any triple
|
||||
for m in re.finditer(
|
||||
r"(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)|(?<!_)_(?!_)(.+?)(?<!_)_(?!_)", text
|
||||
):
|
||||
|
|
|
|||
|
|
@ -14,11 +14,13 @@ from PySide6.QtWidgets import (
|
|||
)
|
||||
|
||||
from .db import DBManager
|
||||
from sqlcipher3.dbapi2 import IntegrityError
|
||||
from . import strings
|
||||
|
||||
|
||||
class TagBrowserDialog(QDialog):
|
||||
openDateRequested = Signal(str)
|
||||
tagsModified = Signal()
|
||||
|
||||
def __init__(self, db: DBManager, parent=None, focus_tag: str | None = None):
|
||||
super().__init__(parent)
|
||||
|
|
@ -43,6 +45,8 @@ class TagBrowserDialog(QDialog):
|
|||
self.tree.setColumnWidth(1, 100)
|
||||
self.tree.itemActivated.connect(self._on_item_activated)
|
||||
self.tree.itemClicked.connect(self._on_item_clicked)
|
||||
self.tree.setSortingEnabled(True)
|
||||
self.tree.sortByColumn(0, Qt.AscendingOrder)
|
||||
layout.addWidget(self.tree)
|
||||
|
||||
# Tag management buttons
|
||||
|
|
@ -77,6 +81,9 @@ class TagBrowserDialog(QDialog):
|
|||
self._populate(focus_tag)
|
||||
|
||||
def _populate(self, focus_tag: str | None):
|
||||
# Disable sorting during population for better performance
|
||||
was_sorting = self.tree.isSortingEnabled()
|
||||
self.tree.setSortingEnabled(False)
|
||||
self.tree.clear()
|
||||
tags = self._db.list_tags()
|
||||
focus_item = None
|
||||
|
|
@ -91,7 +98,18 @@ class TagBrowserDialog(QDialog):
|
|||
)
|
||||
|
||||
# Set background color for the second column to show the tag color
|
||||
root.setBackground(1, QColor(color))
|
||||
bg_color = QColor(color)
|
||||
root.setBackground(1, bg_color)
|
||||
|
||||
# Calculate luminance and set contrasting text color
|
||||
# Using relative luminance formula (ITU-R BT.709)
|
||||
luminance = (
|
||||
0.2126 * bg_color.red()
|
||||
+ 0.7152 * bg_color.green()
|
||||
+ 0.0722 * bg_color.blue()
|
||||
) / 255.0
|
||||
text_color = QColor(0, 0, 0) if luminance > 0.5 else QColor(255, 255, 255)
|
||||
root.setForeground(1, text_color)
|
||||
root.setText(1, color) # Also show the hex code
|
||||
root.setTextAlignment(1, Qt.AlignCenter)
|
||||
|
||||
|
|
@ -112,6 +130,9 @@ class TagBrowserDialog(QDialog):
|
|||
self.tree.expandItem(focus_item)
|
||||
self.tree.setCurrentItem(focus_item)
|
||||
|
||||
# Re-enable sorting after population
|
||||
self.tree.setSortingEnabled(was_sorting)
|
||||
|
||||
def _on_item_clicked(self, item: QTreeWidgetItem, column: int):
|
||||
"""Enable/disable buttons based on selection"""
|
||||
data = item.data(0, Qt.ItemDataRole.UserRole)
|
||||
|
|
@ -156,8 +177,12 @@ class TagBrowserDialog(QDialog):
|
|||
)
|
||||
|
||||
if ok and new_name and new_name != old_name:
|
||||
self._db.update_tag(tag_id, new_name, color)
|
||||
self._populate(None)
|
||||
try:
|
||||
self._db.update_tag(tag_id, new_name, color)
|
||||
self._populate(None)
|
||||
self.tagsModified.emit()
|
||||
except IntegrityError as e:
|
||||
QMessageBox.critical(self, strings._("db_database_error"), str(e))
|
||||
|
||||
def _change_tag_color(self):
|
||||
"""Change the color of the selected tag"""
|
||||
|
|
@ -175,8 +200,12 @@ class TagBrowserDialog(QDialog):
|
|||
|
||||
color = QColorDialog.getColor(QColor(current_color), self)
|
||||
if color.isValid():
|
||||
self._db.update_tag(tag_id, name, color.name())
|
||||
self._populate(None)
|
||||
try:
|
||||
self._db.update_tag(tag_id, name, color.name())
|
||||
self._populate(None)
|
||||
self.tagsModified.emit()
|
||||
except IntegrityError as e:
|
||||
QMessageBox.critical(self, strings._("db_database_error"), str(e))
|
||||
|
||||
def _delete_tag(self):
|
||||
"""Delete the selected tag"""
|
||||
|
|
@ -203,3 +232,4 @@ class TagBrowserDialog(QDialog):
|
|||
if reply == QMessageBox.Yes:
|
||||
self._db.delete_tag(tag_id)
|
||||
self._populate(None)
|
||||
self.tagsModified.emit()
|
||||
|
|
|
|||
|
|
@ -70,7 +70,10 @@ class TagChip(QFrame):
|
|||
def mouseReleaseEvent(self, ev):
|
||||
if ev.button() == Qt.LeftButton:
|
||||
self.clicked.emit(self._name)
|
||||
super().mouseReleaseEvent(ev)
|
||||
try:
|
||||
super().mouseReleaseEvent(ev)
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
|
||||
class PageTagsWidget(QFrame):
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ class ThemeManager(QObject):
|
|||
)
|
||||
|
||||
if is_dark:
|
||||
# Use the link color as the accent (you set this to ORANGE in dark palette)
|
||||
# Use the link color as the accent
|
||||
accent = pal.color(QPalette.Link)
|
||||
r, g, b = accent.red(), accent.green(), accent.blue()
|
||||
accent_hex = accent.name()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue