from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QTabWidget,
QListWidget, QListWidgetItem, QLabel,
+ QStyledItemDelegate, QApplication,
)
-from PyQt6.QtCore import Qt, pyqtSignal, QSize
-from PyQt6.QtGui import QColor
+from PyQt6.QtCore import Qt, pyqtSignal, QSize, QRect
+from PyQt6.QtGui import QColor, QPainter, QFontMetrics
from core.models import Article
+_LINE2_ROLE = Qt.ItemDataRole.UserRole + 1
+
+
+class ArticleItemDelegate(QStyledItemDelegate):
+ def paint(self, painter: QPainter, option, index):
+ painter.save()
+ self.initStyleOption(option, index)
+ style = option.widget.style() if option.widget else QApplication.style()
+ style.drawPrimitive(style.PrimitiveElement.PE_PanelItemViewItem, option, painter, option.widget)
+
+ rect: QRect = option.rect
+ fm = QFontMetrics(option.font)
+ line_h = fm.height()
+ pad = 4
+
+ line1 = index.data(Qt.ItemDataRole.DisplayRole) or ""
+ line2 = index.data(_LINE2_ROLE) or ""
+ fg = index.data(Qt.ItemDataRole.ForegroundRole)
+
+ painter.setPen(fg.color() if fg else option.palette.text().color())
+ r1 = QRect(rect.left() + pad, rect.top() + pad, rect.width() - pad * 2, line_h)
+ painter.drawText(r1, Qt.TextFlag.TextSingleLine, line1)
+
+ if line2:
+ painter.setPen(QColor("#888"))
+ r2 = QRect(rect.left() + pad, rect.top() + pad + line_h + 2, rect.width() - pad * 2, line_h)
+ painter.drawText(r2, Qt.TextFlag.TextSingleLine, line2)
+
+ painter.restore()
+
+ def sizeHint(self, option, index):
+ fm = QFontMetrics(option.font)
+ line_h = fm.height()
+ pad = 4
+ line2 = index.data(_LINE2_ROLE) or ""
+ height = (line_h * 2 + 2 + pad * 2) if line2 else (line_h + pad * 2)
+ return QSize(0, height)
+
+
class ArticleItem(QListWidgetItem):
def __init__(self, article: Article):
super().__init__()
parts.append(f"[{article.meta_categories}]")
line2 = " ".join(parts) if parts else ""
- text = f"{line1}\n{line2}" if line2 else line1
- self.setText(text)
- self.setSizeHint(QSize(0, 42) if line2 else QSize(0, 26))
+ self.setText(line1)
+ self.setData(_LINE2_ROLE, line2)
if article.draft:
self.setForeground(QColor("#f59e0b"))
elif not article.has_translation:
self.setForeground(QColor("#ff6b6b"))
+
class ArticlesView(QWidget):
article_selected = pyqtSignal(object) # Article
translate_requested = pyqtSignal(object) # Article
self._tabs = QTabWidget()
self._tabs.setStyleSheet("QTabBar::tab { padding: 6px 16px; }")
self._list_it = QListWidget()
- self._list_it.setWordWrap(True)
- self._list_it.setTextElideMode(Qt.TextElideMode.ElideNone)
+ self._list_it.setItemDelegate(ArticleItemDelegate(self._list_it))
self._list_en = QListWidget()
- self._list_en.setWordWrap(True)
- self._list_en.setTextElideMode(Qt.TextElideMode.ElideNone)
+ self._list_en.setItemDelegate(ArticleItemDelegate(self._list_en))
self._tabs.addTab(self._list_it, "🇮🇹 Italiano")
self._tabs.addTab(self._list_en, "🇬🇧 English")
layout.addWidget(self._tabs)
else:
self._list_en.addItem(item)
+
class MissingTranslationView(QWidget):
article_selected = pyqtSignal(object) # Article
translate_requested = pyqtSignal(object) # Article
header.setStyleSheet("color: #ff6b6b; font-weight: bold; font-size: 13px; padding: 10px;")
layout.addWidget(header)
self._list = QListWidget()
- self._list.setWordWrap(True)
- self._list.setTextElideMode(Qt.TextElideMode.ElideNone)
+ self._list.setItemDelegate(ArticleItemDelegate(self._list))
layout.addWidget(self._list)
self._list.itemClicked.connect(lambda item: self.article_selected.emit(item.article))
lang_other = "🇬🇧" if a.lang == "it" else "🇮🇹"
item = ArticleItem(a)
item.setText(f"{a.slug} [manca {lang_other}] ({a.lang.upper()})")
- item.setSizeHint(QSize(0, 26))
+ item.setData(_LINE2_ROLE, "")
self._list.addItem(item)