"""
Icon Factory - Zentrale Icon-Verwaltung nach Clean Architecture
"""
from PyQt5.QtWidgets import QLabel
from PyQt5.QtCore import Qt, QByteArray
from PyQt5.QtGui import QIcon, QPixmap, QPainter, QColor
from PyQt5.QtSvg import QSvgRenderer
import os
import logging
from config.paths import PathConfig
logger = logging.getLogger("icon_factory")
class IconFactory:
"""Factory für die Erstellung und Verwaltung von Icons"""
# Cache für geladene Icons
_icon_cache = {}
# Standard SVG Icons
ICONS = {
"mail": '''''',
"key": '''''',
"calendar": '''''',
"copy": '''''',
"eye": '''''',
"eye-slash": ''''''
}
@classmethod
def get_icon(cls, icon_name: str, size: int = 16, color: str = "#718096") -> QIcon:
"""
Erstellt ein QIcon aus SVG
Args:
icon_name: Name des Icons
size: Größe des Icons
color: Farbe des Icons (hex)
Returns:
QIcon Objekt
"""
cache_key = f"{icon_name}_{size}_{color}"
if cache_key in cls._icon_cache:
return cls._icon_cache[cache_key]
# Erstelle Pixmap
pixmap = cls.get_pixmap(icon_name, size, color)
icon = QIcon(pixmap)
# Cache das Icon
cls._icon_cache[cache_key] = icon
return icon
@classmethod
def get_pixmap(cls, icon_name: str, size: int = 16, color: str = "#718096") -> QPixmap:
"""
Erstellt ein QPixmap aus SVG
Args:
icon_name: Name des Icons
size: Größe des Icons
color: Farbe des Icons (hex)
Returns:
QPixmap Objekt
"""
# Versuche zuerst aus Datei zu laden
icon_path = PathConfig.get_icon_path(icon_name)
if PathConfig.file_exists(icon_path):
pixmap = QPixmap(icon_path)
if not pixmap.isNull():
return pixmap.scaled(size, size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
# Fallback auf eingebettete SVGs
svg_content = cls.ICONS.get(icon_name)
if svg_content:
# Ersetze currentColor durch die angegebene Farbe
svg_content = svg_content.replace('currentColor', color)
# Erstelle SVG Renderer
renderer = QSvgRenderer(QByteArray(svg_content.encode()))
# Erstelle Pixmap
pixmap = QPixmap(size, size)
pixmap.fill(Qt.transparent)
# Rendere SVG
painter = QPainter(pixmap)
painter.setRenderHint(QPainter.Antialiasing)
renderer.render(painter)
painter.end()
return pixmap
# Fallback: Erstelle einen farbigen Kreis
logger.warning(f"Icon '{icon_name}' nicht gefunden, verwende Platzhalter")
pixmap = QPixmap(size, size)
pixmap.fill(Qt.transparent)
painter = QPainter(pixmap)
painter.setRenderHint(QPainter.Antialiasing)
painter.setBrush(QColor(color))
painter.setPen(Qt.NoPen)
painter.drawEllipse(0, 0, size, size)
painter.end()
return pixmap
@classmethod
def create_icon_label(cls, icon_name: str, size: int = 16, color: str = "#718096") -> QLabel:
"""
Erstellt ein QLabel mit Icon
Args:
icon_name: Name des Icons
size: Größe des Icons
color: Farbe des Icons (hex)
Returns:
QLabel mit Icon
"""
label = QLabel()
label.setFixedSize(size, size)
# Prüfe ob es eine Plattform ist
platform_names = ["instagram", "facebook", "twitter", "x", "tiktok", "vk", "ok", "gmail"]
if icon_name.lower() in platform_names:
# Verwende get_platform_icon für Plattformen
icon = cls.get_platform_icon(icon_name, size)
pixmap = icon.pixmap(size, size)
else:
# Normale Icons
pixmap = cls.get_pixmap(icon_name, size, color)
label.setPixmap(pixmap)
label.setScaledContents(True)
return label
@classmethod
def get_platform_icon(cls, platform: str, size: int = 18) -> QIcon:
"""
Gibt ein Platform-spezifisches Icon zurück
Args:
platform: Name der Plattform
size: Größe des Icons
Returns:
QIcon für die Plattform
"""
# Spezialbehandlung für Twitter/X
if platform.lower() == "twitter" or platform.lower() == "x":
icon_name = "twitter"
else:
icon_name = platform.lower()
# Platform Icons haben eigene Farben
platform_colors = {
"instagram": "#E4405F",
"facebook": "#1877F2",
"twitter": "#1DA1F2",
"x": "#000000",
"tiktok": "#000000",
"vk": "#0077FF"
}
color = platform_colors.get(icon_name, "#718096")
return cls.get_icon(icon_name, size, color)