Initial commit
Dieser Commit ist enthalten in:
1
views/components/__init__.py
Normale Datei
1
views/components/__init__.py
Normale Datei
@ -0,0 +1 @@
|
||||
# Components for the main UI
|
||||
448
views/components/accounts_overview_view.py
Normale Datei
448
views/components/accounts_overview_view.py
Normale Datei
@ -0,0 +1,448 @@
|
||||
"""
|
||||
Accounts Overview View - Account-Übersicht im Mockup-Style
|
||||
"""
|
||||
|
||||
import logging
|
||||
from PyQt5.QtWidgets import (
|
||||
QWidget, QHBoxLayout, QVBoxLayout, QLabel, QPushButton,
|
||||
QScrollArea, QGridLayout, QFrame, QMessageBox
|
||||
)
|
||||
from PyQt5.QtCore import Qt, pyqtSignal
|
||||
from PyQt5.QtGui import QFont
|
||||
|
||||
from views.widgets.account_card import AccountCard
|
||||
|
||||
logger = logging.getLogger("accounts_overview")
|
||||
|
||||
|
||||
class SidebarFilter(QWidget):
|
||||
"""Sidebar mit Plattform-Filter nach Styleguide"""
|
||||
filter_changed = pyqtSignal(str)
|
||||
|
||||
def __init__(self, language_manager=None):
|
||||
super().__init__()
|
||||
self.language_manager = language_manager
|
||||
self.filter_buttons = []
|
||||
self.account_counts = {}
|
||||
self.init_ui()
|
||||
|
||||
if self.language_manager:
|
||||
self.language_manager.language_changed.connect(self.update_texts)
|
||||
self.update_texts()
|
||||
|
||||
def init_ui(self):
|
||||
"""Initialisiert die UI nach Styleguide"""
|
||||
self.setMaximumWidth(260) # Styleguide: Sidebar-Breite
|
||||
self.setStyleSheet("""
|
||||
QWidget {
|
||||
background-color: #FFFFFF;
|
||||
border-right: 1px solid #E2E8F0;
|
||||
}
|
||||
""")
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(20, 20, 20, 20)
|
||||
layout.setSpacing(8)
|
||||
|
||||
# Title removed - no longer needed
|
||||
|
||||
# Filter Buttons
|
||||
self.filters = [
|
||||
("Alle", "all"),
|
||||
("Instagram", "instagram"),
|
||||
("TikTok", "tiktok"),
|
||||
("Facebook", "facebook"),
|
||||
("X (Twitter)", "x"),
|
||||
("VK", "vk"),
|
||||
("OK.ru", "ok"),
|
||||
("Gmail", "gmail")
|
||||
]
|
||||
|
||||
for name, key in self.filters:
|
||||
btn = self._create_filter_button(name, key)
|
||||
self.filter_buttons.append((btn, key))
|
||||
layout.addWidget(btn)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
def _create_filter_button(self, name, key):
|
||||
"""Erstellt einen Filter-Button"""
|
||||
btn = QPushButton(f"{name} (0)")
|
||||
btn.setObjectName(key)
|
||||
btn.setCursor(Qt.PointingHandCursor)
|
||||
btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
text-align: left;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
color: #4A5568;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #F7FAFC;
|
||||
color: #2D3748;
|
||||
}
|
||||
QPushButton[selected="true"] {
|
||||
background-color: #E6F2FF;
|
||||
color: #1E40AF;
|
||||
font-weight: 500;
|
||||
border-left: 3px solid #3182CE;
|
||||
padding-left: 13px;
|
||||
}
|
||||
""")
|
||||
btn.clicked.connect(lambda: self._on_filter_clicked(key))
|
||||
|
||||
# Erste Option als aktiv setzen
|
||||
if key == "all":
|
||||
btn.setProperty("selected", "true")
|
||||
btn.setStyle(btn.style())
|
||||
|
||||
return btn
|
||||
|
||||
def _on_filter_clicked(self, key):
|
||||
"""Behandelt Filter-Klicks"""
|
||||
# Update button states
|
||||
for btn, btn_key in self.filter_buttons:
|
||||
btn.setProperty("selected", "true" if btn_key == key else "false")
|
||||
btn.setStyle(btn.style())
|
||||
|
||||
self.filter_changed.emit(key)
|
||||
|
||||
def update_counts(self, counts):
|
||||
"""Aktualisiert die Account-Anzahlen"""
|
||||
self.account_counts = counts
|
||||
|
||||
for btn, key in self.filter_buttons:
|
||||
count = counts.get(key, 0)
|
||||
name = next(name for name, k in self.filters if k == key)
|
||||
btn.setText(f"{name} ({count})")
|
||||
|
||||
def update_texts(self):
|
||||
"""Aktualisiert die Texte gemäß der aktuellen Sprache"""
|
||||
if not self.language_manager:
|
||||
return
|
||||
|
||||
# Title removed - no text update needed
|
||||
|
||||
|
||||
class AccountsOverviewView(QWidget):
|
||||
"""
|
||||
Account-Übersicht im Mockup-Style mit:
|
||||
- Sidebar-Filter
|
||||
- Grid-Layout mit Account-Karten
|
||||
"""
|
||||
|
||||
# Signals
|
||||
account_login_requested = pyqtSignal(dict)
|
||||
account_export_requested = pyqtSignal(dict)
|
||||
account_delete_requested = pyqtSignal(dict)
|
||||
export_requested = pyqtSignal() # Für Kompatibilität
|
||||
|
||||
def __init__(self, db_manager=None, language_manager=None):
|
||||
super().__init__()
|
||||
self.db_manager = db_manager
|
||||
self.language_manager = language_manager
|
||||
self.current_filter = "all"
|
||||
self.accounts = []
|
||||
self.init_ui()
|
||||
|
||||
if self.language_manager:
|
||||
self.language_manager.language_changed.connect(self.update_texts)
|
||||
self.update_texts()
|
||||
|
||||
def init_ui(self):
|
||||
"""Initialisiert die UI nach Styleguide"""
|
||||
self.setStyleSheet("""
|
||||
QWidget {
|
||||
background-color: #F8FAFC;
|
||||
}
|
||||
""")
|
||||
|
||||
# Hauptlayout
|
||||
main_layout = QHBoxLayout(self)
|
||||
main_layout.setContentsMargins(0, 0, 0, 0)
|
||||
main_layout.setSpacing(0)
|
||||
|
||||
# Sidebar
|
||||
self.sidebar = SidebarFilter(self.language_manager)
|
||||
self.sidebar.filter_changed.connect(self._on_filter_changed)
|
||||
main_layout.addWidget(self.sidebar)
|
||||
|
||||
# Content Area
|
||||
content_widget = QWidget()
|
||||
content_widget.setStyleSheet("background-color: #F8FAFC;")
|
||||
content_layout = QVBoxLayout(content_widget)
|
||||
content_layout.setContentsMargins(40, 30, 40, 30)
|
||||
content_layout.setSpacing(20)
|
||||
|
||||
# Header
|
||||
header_layout = QHBoxLayout()
|
||||
|
||||
self.title = QLabel("Alle Accounts")
|
||||
title_font = QFont("Poppins", 24)
|
||||
title_font.setBold(True)
|
||||
self.title.setFont(title_font)
|
||||
self.title.setStyleSheet("""
|
||||
color: #1A365D;
|
||||
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
""")
|
||||
header_layout.addWidget(self.title)
|
||||
|
||||
header_layout.addStretch()
|
||||
|
||||
content_layout.addLayout(header_layout)
|
||||
|
||||
# Scroll Area für Accounts
|
||||
self.scroll = QScrollArea()
|
||||
self.scroll.setWidgetResizable(True)
|
||||
self.scroll.setStyleSheet("""
|
||||
QScrollArea {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
QScrollBar:vertical {
|
||||
background-color: #F1F5F9;
|
||||
width: 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QScrollBar::handle:vertical {
|
||||
background-color: #CBD5E0;
|
||||
min-height: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QScrollBar::handle:vertical:hover {
|
||||
background-color: #A0AEC0;
|
||||
}
|
||||
QScrollBar::add-line:vertical,
|
||||
QScrollBar::sub-line:vertical {
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
""")
|
||||
|
||||
# Grid Container
|
||||
self.container = QWidget()
|
||||
self.container.setStyleSheet("background-color: transparent;")
|
||||
self.grid_layout = QGridLayout(self.container)
|
||||
self.grid_layout.setSpacing(24) # Styleguide Grid-Gap
|
||||
self.grid_layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.scroll.setWidget(self.container)
|
||||
content_layout.addWidget(self.scroll)
|
||||
|
||||
main_layout.addWidget(content_widget)
|
||||
|
||||
# Initial load
|
||||
self.load_accounts()
|
||||
|
||||
def load_accounts(self):
|
||||
"""Lädt Accounts aus der Datenbank"""
|
||||
if not self.db_manager:
|
||||
return
|
||||
|
||||
try:
|
||||
# Hole alle Accounts aus der Datenbank
|
||||
self.accounts = self.db_manager.get_all_accounts()
|
||||
self._update_display()
|
||||
self._update_sidebar_counts()
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Laden der Accounts: {e}")
|
||||
self.accounts = []
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Fehler",
|
||||
f"Fehler beim Laden der Accounts:\n{str(e)}"
|
||||
)
|
||||
|
||||
def _update_display(self):
|
||||
"""Aktualisiert die Anzeige basierend auf dem aktuellen Filter"""
|
||||
# Clear existing widgets
|
||||
while self.grid_layout.count():
|
||||
child = self.grid_layout.takeAt(0)
|
||||
if child.widget():
|
||||
child.widget().deleteLater()
|
||||
|
||||
# Filter accounts
|
||||
if self.current_filter == "all":
|
||||
filtered_accounts = self.accounts
|
||||
else:
|
||||
filtered_accounts = [
|
||||
acc for acc in self.accounts
|
||||
if acc.get("platform", "").lower() == self.current_filter
|
||||
]
|
||||
|
||||
# Gruppiere nach Plattform wenn "Alle" ausgewählt
|
||||
if self.current_filter == "all":
|
||||
self._display_grouped_accounts(filtered_accounts)
|
||||
else:
|
||||
self._display_accounts_grid(filtered_accounts)
|
||||
|
||||
def _display_grouped_accounts(self, accounts):
|
||||
"""Zeigt Accounts gruppiert nach Plattform"""
|
||||
# Gruppiere Accounts nach Plattform
|
||||
platforms = {}
|
||||
for acc in accounts:
|
||||
platform = acc.get("platform", "unknown").lower()
|
||||
if platform not in platforms:
|
||||
platforms[platform] = []
|
||||
platforms[platform].append(acc)
|
||||
|
||||
row = 0
|
||||
for platform, platform_accounts in sorted(platforms.items()):
|
||||
if not platform_accounts:
|
||||
continue
|
||||
|
||||
# Platform Header
|
||||
header = QLabel(platform.capitalize())
|
||||
header_font = QFont("Poppins", 18)
|
||||
header_font.setWeight(QFont.DemiBold)
|
||||
header.setFont(header_font)
|
||||
header.setStyleSheet("""
|
||||
color: #1A365D;
|
||||
padding: 8px 0;
|
||||
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
""")
|
||||
self.grid_layout.addWidget(header, row, 0, 1, 3)
|
||||
row += 1
|
||||
|
||||
# Accounts
|
||||
col = 0
|
||||
for acc in platform_accounts:
|
||||
card = self._create_account_card(acc)
|
||||
self.grid_layout.addWidget(card, row, col)
|
||||
col += 1
|
||||
if col > 2: # 3 columns
|
||||
col = 0
|
||||
row += 1
|
||||
|
||||
if col > 0:
|
||||
row += 1
|
||||
row += 1 # Extra space between platforms
|
||||
|
||||
# Add stretch
|
||||
self.grid_layout.setRowStretch(row, 1)
|
||||
|
||||
def _display_accounts_grid(self, accounts):
|
||||
"""Zeigt Accounts in einem einfachen Grid"""
|
||||
row = 0
|
||||
col = 0
|
||||
|
||||
for acc in accounts:
|
||||
card = self._create_account_card(acc)
|
||||
self.grid_layout.addWidget(card, row, col)
|
||||
col += 1
|
||||
if col > 2: # 3 columns
|
||||
col = 0
|
||||
row += 1
|
||||
|
||||
# Add stretch
|
||||
self.grid_layout.setRowStretch(row + 1, 1)
|
||||
|
||||
def _create_account_card(self, account_data):
|
||||
"""Erstellt eine Account-Karte"""
|
||||
card = AccountCard(account_data, self.language_manager)
|
||||
|
||||
# Verbinde Signals
|
||||
card.login_requested.connect(self.account_login_requested.emit)
|
||||
card.export_requested.connect(self.account_export_requested.emit)
|
||||
card.delete_requested.connect(self._on_delete_requested)
|
||||
|
||||
return card
|
||||
|
||||
def _on_delete_requested(self, account_data):
|
||||
"""Behandelt Delete-Anfragen mit Bestätigung"""
|
||||
msg_box = QMessageBox(self)
|
||||
msg_box.setWindowTitle("Account löschen")
|
||||
msg_box.setText(f"Möchten Sie den Account '{account_data.get('username', '')}' wirklich löschen?")
|
||||
msg_box.setIcon(QMessageBox.Question)
|
||||
|
||||
# Custom Buttons hinzufügen
|
||||
delete_button = msg_box.addButton("Löschen", QMessageBox.YesRole)
|
||||
cancel_button = msg_box.addButton("Abbrechen", QMessageBox.NoRole)
|
||||
msg_box.setDefaultButton(cancel_button) # Abbrechen als Standard
|
||||
|
||||
# Explizites Styling für den Löschen-Button
|
||||
delete_button.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #F44336;
|
||||
color: #FFFFFF;
|
||||
border: 1px solid #D32F2F;
|
||||
border-radius: 4px;
|
||||
padding: 6px 20px;
|
||||
min-width: 80px;
|
||||
min-height: 26px;
|
||||
font-weight: 500;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #D32F2F;
|
||||
border-color: #B71C1C;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #B71C1C;
|
||||
}
|
||||
""")
|
||||
|
||||
msg_box.exec_()
|
||||
|
||||
if msg_box.clickedButton() == delete_button:
|
||||
self.account_delete_requested.emit(account_data)
|
||||
# Reload accounts nach Löschung
|
||||
self.load_accounts()
|
||||
|
||||
def _on_filter_changed(self, filter_key):
|
||||
"""Behandelt Filter-Änderungen"""
|
||||
self.current_filter = filter_key
|
||||
|
||||
# Update title
|
||||
if filter_key == "all":
|
||||
self.title.setText("Alle Accounts")
|
||||
else:
|
||||
platform_name = filter_key.capitalize()
|
||||
if filter_key == "x":
|
||||
platform_name = "X (Twitter)"
|
||||
self.title.setText(f"{platform_name} Accounts")
|
||||
|
||||
self._update_display()
|
||||
|
||||
def _update_sidebar_counts(self):
|
||||
"""Aktualisiert die Account-Anzahlen in der Sidebar"""
|
||||
counts = {"all": len(self.accounts)}
|
||||
|
||||
# Zähle Accounts pro Plattform
|
||||
for acc in self.accounts:
|
||||
platform = acc.get("platform", "").lower()
|
||||
if platform:
|
||||
counts[platform] = counts.get(platform, 0) + 1
|
||||
|
||||
self.sidebar.update_counts(counts)
|
||||
|
||||
def update_texts(self):
|
||||
"""Aktualisiert die Texte gemäß der aktuellen Sprache"""
|
||||
if not self.language_manager:
|
||||
return
|
||||
|
||||
# Update title based on current filter
|
||||
if self.current_filter == "all":
|
||||
self.title.setText(
|
||||
self.language_manager.get_text("accounts_overview.all_accounts", "Alle Accounts")
|
||||
)
|
||||
else:
|
||||
platform_name = self.current_filter.capitalize()
|
||||
if self.current_filter == "x":
|
||||
platform_name = "X (Twitter)"
|
||||
self.title.setText(
|
||||
self.language_manager.get_text(
|
||||
f"accounts_overview.{self.current_filter}_accounts",
|
||||
f"{platform_name} Accounts"
|
||||
)
|
||||
)
|
||||
|
||||
def update_session_status(self, account_id, status):
|
||||
"""
|
||||
Session-Status-Update deaktiviert (Session-Funktionalität entfernt).
|
||||
"""
|
||||
# Session-Funktionalität wurde entfernt - diese Methode macht nichts mehr
|
||||
pass
|
||||
121
views/components/platform_grid_view.py
Normale Datei
121
views/components/platform_grid_view.py
Normale Datei
@ -0,0 +1,121 @@
|
||||
"""
|
||||
Platform Grid View - Zeigt die Plattform-Kacheln in einem Grid
|
||||
"""
|
||||
|
||||
import os
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGridLayout, QLabel
|
||||
from PyQt5.QtCore import pyqtSignal, Qt
|
||||
from PyQt5.QtGui import QFont
|
||||
|
||||
from views.widgets.platform_button import PlatformButton
|
||||
|
||||
|
||||
class PlatformGridView(QWidget):
|
||||
"""
|
||||
Grid-Ansicht der Plattform-Kacheln
|
||||
Wiederverwendung der existierenden PlatformButton-Komponente
|
||||
"""
|
||||
|
||||
# Signal wird ausgelöst, wenn eine Plattform ausgewählt wird
|
||||
platform_selected = pyqtSignal(str)
|
||||
|
||||
def __init__(self, language_manager=None):
|
||||
super().__init__()
|
||||
self.language_manager = language_manager
|
||||
self.init_ui()
|
||||
|
||||
if self.language_manager:
|
||||
self.language_manager.language_changed.connect(self.update_texts)
|
||||
self.update_texts()
|
||||
|
||||
def init_ui(self):
|
||||
"""Initialisiert die UI nach Styleguide"""
|
||||
# Hauptlayout mit Container-Padding
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(40, 40, 40, 40)
|
||||
layout.setSpacing(32)
|
||||
|
||||
# Titel
|
||||
self.title_label = QLabel("AccountForger")
|
||||
self.title_label.setAlignment(Qt.AlignCenter)
|
||||
self.title_label.setObjectName("platform_title")
|
||||
|
||||
# Poppins Font für Titel
|
||||
title_font = QFont("Poppins", 32)
|
||||
title_font.setBold(True)
|
||||
self.title_label.setFont(title_font)
|
||||
|
||||
self.title_label.setStyleSheet("""
|
||||
QLabel {
|
||||
color: #1A365D;
|
||||
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
""")
|
||||
|
||||
layout.addWidget(self.title_label)
|
||||
|
||||
# Container für Plattform-Grid
|
||||
platforms_container = QWidget()
|
||||
platforms_container.setStyleSheet("background: transparent;")
|
||||
grid_layout = QGridLayout(platforms_container)
|
||||
grid_layout.setSpacing(24) # Styleguide Grid-Gap
|
||||
|
||||
# Definiere verfügbare Plattformen
|
||||
platforms = [
|
||||
{"name": "Instagram", "enabled": True},
|
||||
{"name": "Facebook", "enabled": True},
|
||||
{"name": "TikTok", "enabled": True},
|
||||
{"name": "X", "enabled": True},
|
||||
{"name": "VK", "enabled": True},
|
||||
{"name": "OK.ru", "enabled": True},
|
||||
{"name": "Gmail", "enabled": True}
|
||||
]
|
||||
|
||||
# Icon-Pfade
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
parent_dir = os.path.dirname(os.path.dirname(current_dir))
|
||||
icons_dir = os.path.join(parent_dir, "resources", "icons")
|
||||
|
||||
# Platziere Buttons in einem 2x4 Grid
|
||||
for i, platform in enumerate(platforms):
|
||||
row = i // 4
|
||||
col = i % 4
|
||||
|
||||
# Icon-Pfad erstellen
|
||||
platform_icon_name = platform['name'].lower()
|
||||
if platform['name'] == "X":
|
||||
platform_icon_name = "twitter"
|
||||
elif platform['name'] == "OK.ru":
|
||||
platform_icon_name = "ok"
|
||||
icon_path = os.path.join(icons_dir, f"{platform_icon_name}.svg")
|
||||
|
||||
if not os.path.exists(icon_path):
|
||||
icon_path = None
|
||||
|
||||
# Platform Button erstellen
|
||||
button = PlatformButton(
|
||||
platform["name"],
|
||||
icon_path,
|
||||
platform["enabled"]
|
||||
)
|
||||
|
||||
# Signal verbinden
|
||||
platform_signal_name = "x" if platform["name"] == "X" else platform["name"]
|
||||
button.clicked.connect(
|
||||
lambda checked=False, p=platform_signal_name: self.platform_selected.emit(p.lower())
|
||||
)
|
||||
|
||||
grid_layout.addWidget(button, row, col, Qt.AlignCenter)
|
||||
|
||||
layout.addWidget(platforms_container)
|
||||
layout.addStretch()
|
||||
|
||||
def update_texts(self):
|
||||
"""Aktualisiert die Texte gemäß der aktuellen Sprache"""
|
||||
if not self.language_manager:
|
||||
return
|
||||
|
||||
self.title_label.setText(
|
||||
self.language_manager.get_text("main.title", "AccountForger")
|
||||
)
|
||||
130
views/components/tab_navigation.py
Normale Datei
130
views/components/tab_navigation.py
Normale Datei
@ -0,0 +1,130 @@
|
||||
"""
|
||||
Tab Navigation Component nach Styleguide
|
||||
"""
|
||||
|
||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QPushButton, QLabel
|
||||
from PyQt5.QtCore import pyqtSignal, Qt
|
||||
from PyQt5.QtGui import QFont
|
||||
|
||||
|
||||
class TabNavigation(QWidget):
|
||||
"""
|
||||
Tab-Navigation nach Styleguide mit zwei Modi:
|
||||
- Plattformen (Standard)
|
||||
- Accounts
|
||||
"""
|
||||
|
||||
# Signal wird ausgelöst wenn Tab gewechselt wird (0=Plattformen, 1=Accounts)
|
||||
tab_changed = pyqtSignal(int)
|
||||
|
||||
def __init__(self, language_manager=None):
|
||||
super().__init__()
|
||||
self.language_manager = language_manager
|
||||
self.current_tab = 0
|
||||
self.init_ui()
|
||||
|
||||
if self.language_manager:
|
||||
self.language_manager.language_changed.connect(self.update_texts)
|
||||
self.update_texts()
|
||||
|
||||
def init_ui(self):
|
||||
"""Initialisiert die UI nach Styleguide"""
|
||||
# Feste Höhe nach Styleguide
|
||||
self.setFixedHeight(48)
|
||||
|
||||
# Basis-Styling
|
||||
self.setStyleSheet("""
|
||||
QWidget {
|
||||
background-color: #FFFFFF;
|
||||
border-bottom: 1px solid #E2E8F0;
|
||||
}
|
||||
""")
|
||||
|
||||
# Layout
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(40, 0, 40, 0)
|
||||
layout.setSpacing(24)
|
||||
|
||||
# Tab Buttons erstellen
|
||||
self.platform_tab = self._create_tab_button("Plattformen", True)
|
||||
self.platform_tab.clicked.connect(lambda: self._on_tab_clicked(0))
|
||||
layout.addWidget(self.platform_tab)
|
||||
|
||||
# Accounts Tab (ohne Badge)
|
||||
self.accounts_tab = self._create_tab_button("Accounts", False)
|
||||
self.accounts_tab.clicked.connect(lambda: self._on_tab_clicked(1))
|
||||
layout.addWidget(self.accounts_tab)
|
||||
|
||||
# Spacer
|
||||
layout.addStretch()
|
||||
|
||||
def _create_tab_button(self, text, active=False):
|
||||
"""Erstellt einen Tab-Button nach Styleguide"""
|
||||
btn = QPushButton(text)
|
||||
btn.setCheckable(True)
|
||||
btn.setChecked(active)
|
||||
btn.setCursor(Qt.PointingHandCursor)
|
||||
|
||||
# Poppins Font
|
||||
font = QFont("Poppins", 15)
|
||||
font.setWeight(QFont.Medium)
|
||||
btn.setFont(font)
|
||||
|
||||
btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-bottom: 2px solid transparent;
|
||||
padding: 12px 24px;
|
||||
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #4A5568;
|
||||
min-width: 100px;
|
||||
}
|
||||
QPushButton:checked {
|
||||
color: #1A365D;
|
||||
border-bottom-color: #3182CE;
|
||||
}
|
||||
QPushButton:hover:!checked {
|
||||
color: #2D3748;
|
||||
background-color: #F7FAFC;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
color: #1A365D;
|
||||
}
|
||||
""")
|
||||
|
||||
return btn
|
||||
|
||||
def _on_tab_clicked(self, index):
|
||||
"""Behandelt Tab-Klicks"""
|
||||
if self.current_tab != index:
|
||||
self.current_tab = index
|
||||
|
||||
# Update button states
|
||||
self.platform_tab.setChecked(index == 0)
|
||||
self.accounts_tab.setChecked(index == 1)
|
||||
|
||||
# Emit signal
|
||||
self.tab_changed.emit(index)
|
||||
|
||||
def set_active_tab(self, index):
|
||||
"""Setzt den aktiven Tab programmatisch"""
|
||||
self._on_tab_clicked(index)
|
||||
|
||||
def update_account_count(self, count):
|
||||
"""Deprecated: Account-Anzahl wird nicht mehr im Tab angezeigt"""
|
||||
pass
|
||||
|
||||
def update_texts(self):
|
||||
"""Aktualisiert die Texte gemäß der aktuellen Sprache"""
|
||||
if not self.language_manager:
|
||||
return
|
||||
|
||||
self.platform_tab.setText(
|
||||
self.language_manager.get_text("platform_selector.platforms_tab", "Plattformen")
|
||||
)
|
||||
self.accounts_tab.setText(
|
||||
self.language_manager.get_text("platform_selector.accounts_tab", "Accounts")
|
||||
)
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren