from __future__ import annotations from PyQt6.QtWidgets import ( QDialog, QVBoxLayout, QHBoxLayout, QFormLayout, QLabel, QLineEdit, QComboBox, QPushButton, QCompleter, QWidget, QScrollArea, ) from PyQt6.QtCore import Qt from pathlib import Path from core.models import Article, ARTICLE_TYPES from core.frontmatter import parse_frontmatter, write_frontmatter from core.taxonomy import load_taxonomy class FrontmatterEditor(QDialog): def __init__(self, article: Article, blog_root: Path, parent=None): super().__init__(parent) self.setWindowTitle(f"Frontmatter — {article.slug}") self.setMinimumWidth(520) self._article = article self._blog_root = blog_root self._fields: dict[str, QWidget] = {} self._build_ui() def _build_ui(self): layout = QVBoxLayout(self) scroll = QScrollArea() scroll.setWidgetResizable(True) inner = QWidget() form = QFormLayout(inner) scroll.setWidget(inner) layout.addWidget(scroll) lang = self._article.lang tags_it = self._blog_root / "docs" / "tags-it.txt" tags_en = self._blog_root / "docs" / "tags-en.txt" taxonomy = load_taxonomy(tags_it, tags_en) known_tags = list(taxonomy.it_to_en.keys()) if lang == "it" else list(taxonomy.it_to_en.values()) for key, val in self._article.frontmatter.items(): if key == "type": widget = QComboBox() widget.addItems(ARTICLE_TYPES) if str(val) in ARTICLE_TYPES: widget.setCurrentText(str(val)) self._fields[key] = widget elif key == "tags": widget = QLineEdit(", ".join(str(v) for v in val) if isinstance(val, list) else str(val)) completer = QCompleter(known_tags) completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive) widget.setCompleter(completer) self._fields[key] = widget else: widget = QLineEdit(str(val)) self._fields[key] = widget form.addRow(QLabel(key), widget) btns = QHBoxLayout() save_btn = QPushButton("Salva") save_btn.clicked.connect(self._save) cancel_btn = QPushButton("Annulla") cancel_btn.clicked.connect(self.reject) btns.addStretch() btns.addWidget(cancel_btn) btns.addWidget(save_btn) layout.addLayout(btns) def _save(self): updated = dict(self._article.frontmatter) for key, widget in self._fields.items(): if isinstance(widget, QComboBox): updated[key] = widget.currentText() elif isinstance(widget, QLineEdit): val = widget.text().strip() if key == "tags": updated[key] = [t.strip() for t in val.split(",") if t.strip()] else: updated[key] = val try: _, body = parse_frontmatter(self._article.path) write_frontmatter(self._article.path, updated, body) self._article.frontmatter.update(updated) self.accept() except Exception as e: from PyQt6.QtWidgets import QMessageBox QMessageBox.critical(self, "Errore", str(e))