241 lines
10 KiB
Python
241 lines
10 KiB
Python
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
|
QLineEdit, QPushButton, QFrame, QSizePolicy)
|
|
from PyQt6.QtCore import Qt, QThread, pyqtSignal
|
|
from app.core.main_manager import MainManager, NotificationType
|
|
from app.ui.widgets.loading_bar import LoadingBar
|
|
import webbrowser
|
|
import os
|
|
from dotenv import load_dotenv
|
|
import app.utils.paths as paths
|
|
|
|
# Load environment variables
|
|
load_dotenv(paths.resource_path(".env"))
|
|
|
|
class ActivationThread(QThread):
|
|
"""Thread pour l'activation afin de ne pas bloquer l'UI"""
|
|
finished = pyqtSignal(dict)
|
|
progress = pyqtSignal(int)
|
|
|
|
def __init__(self, license_manager, license_key):
|
|
super().__init__()
|
|
self.license_manager = license_manager
|
|
self.license_key = license_key
|
|
|
|
def run(self):
|
|
self.progress.emit(30)
|
|
result = self.license_manager.activate_license(self.license_key)
|
|
self.progress.emit(100)
|
|
self.finished.emit(result)
|
|
|
|
class ActivationWindow(QWidget):
|
|
"""Fenêtre d'activation de licence modernisée"""
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.main_manager = MainManager.get_instance()
|
|
self.license_manager = self.main_manager.get_license_manager()
|
|
self.language_manager = self.main_manager.get_language_manager()
|
|
self.theme_manager = self.main_manager.get_theme_manager()
|
|
self.alert_manager = self.main_manager.get_alert_manager()
|
|
self.observer_manager = self.main_manager.get_observer_manager()
|
|
self.settings_manager = self.main_manager.get_settings_manager()
|
|
|
|
self.observer_manager.subscribe(NotificationType.LANGUAGE, self.update_language)
|
|
self.observer_manager.subscribe(NotificationType.THEME, self.update_theme)
|
|
|
|
self.activation_thread = None
|
|
|
|
self.setup_ui()
|
|
self.update_license_status()
|
|
|
|
def setup_ui(self):
|
|
layout = QVBoxLayout(self)
|
|
layout.setSpacing(20)
|
|
layout.setContentsMargins(20, 20, 20, 20)
|
|
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
|
|
|
# === Section titre ===
|
|
self.title_label = QLabel(self.language_manager.get_text("activate_license"))
|
|
self.title_label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
self.title_label.setWordWrap(True)
|
|
layout.addWidget(self.title_label)
|
|
|
|
# === Spacer flexible ===
|
|
layout.addStretch(1)
|
|
|
|
# === Section clé de licence ===
|
|
key_layout = QHBoxLayout()
|
|
|
|
self.key_title = QLabel(self.language_manager.get_text("license_key_section"))
|
|
self.key_title.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
|
|
key_layout.addWidget(self.key_title)
|
|
|
|
self.key_input = QLineEdit()
|
|
self.key_input.setPlaceholderText("XXXX-XXXX-XXXX-XXXX-XXXX")
|
|
self.key_input.textChanged.connect(self.format_license_key)
|
|
self.key_input.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
|
key_layout.addWidget(self.key_input)
|
|
|
|
layout.addLayout(key_layout)
|
|
# === Barre de progression ===
|
|
self.progress_bar = LoadingBar(self.language_manager.get_text("loading"))
|
|
self.progress_bar.setVisible(False)
|
|
self.progress_bar.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
layout.addWidget(self.progress_bar)
|
|
|
|
# === Spacer flexible ===
|
|
layout.addStretch(1)
|
|
|
|
# === Section statut ===
|
|
self.status_label = QLabel()
|
|
self.status_label.setWordWrap(True)
|
|
self.status_label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
layout.addWidget(self.status_label)
|
|
|
|
# === Spacer flexible ===
|
|
layout.addStretch(1)
|
|
|
|
# === Boutons d'action ===
|
|
button_layout = QHBoxLayout()
|
|
button_layout.setSpacing(10)
|
|
|
|
self.activate_btn = QPushButton(self.language_manager.get_text("activate"))
|
|
self.activate_btn.clicked.connect(self.activate_license)
|
|
self.activate_btn.setDefault(True)
|
|
self.activate_btn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
|
button_layout.addWidget(self.activate_btn)
|
|
|
|
self.buy_btn = QPushButton(self.language_manager.get_text("buy_license"))
|
|
self.buy_btn.clicked.connect(self.open_purchase_page)
|
|
self.buy_btn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
|
button_layout.addWidget(self.buy_btn)
|
|
|
|
self.compare_btn = QPushButton(self.language_manager.get_text("compare_versions"))
|
|
self.compare_btn.clicked.connect(self.show_features_comparison)
|
|
self.compare_btn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
|
button_layout.addWidget(self.compare_btn)
|
|
|
|
layout.addLayout(button_layout)
|
|
|
|
def show_features_comparison(self):
|
|
"""Affiche la comparaison des versions dans une alerte"""
|
|
comparison_text = f"{self.language_manager.get_text('comparaisons')}\n\n"
|
|
|
|
for version in self.settings_manager.get_config("features_by_license").keys():
|
|
comparison_text += f"{self.language_manager.get_text(version+'_version')}:\n"
|
|
features = self.settings_manager.get_config("features_by_license").get(version, [])
|
|
for feature in features:
|
|
feature_desc = self.language_manager.get_text(feature)
|
|
comparison_text += f" • {feature_desc}\n"
|
|
comparison_text += "\n"
|
|
|
|
|
|
self.alert_manager.show_info(comparison_text, parent=self)
|
|
|
|
def update_license_status(self):
|
|
"""Met à jour l'affichage du statut de la licence"""
|
|
if self.license_manager.is_activated():
|
|
license_info = self.license_manager.get_license_info()
|
|
license_type = license_info.get("type", "free").upper()
|
|
|
|
status_text = f"✓ {self.language_manager.get_text('license_active')}\n"
|
|
status_text += f"{self.language_manager.get_text('license_type')}: {license_type}\n"
|
|
if license_info.get("email"):
|
|
status_text += f"{self.language_manager.get_text('license_email')}: {license_info['email']}\n"
|
|
if license_info.get("expires_at"):
|
|
status_text += f"{self.language_manager.get_text('license_expires')}: {license_info['expires_at']}"
|
|
|
|
self.status_label.setText(status_text)
|
|
|
|
self.key_input.setEnabled(False)
|
|
self.activate_btn.setEnabled(False)
|
|
else:
|
|
status_text = f"{self.language_manager.get_text('no_license')}"
|
|
self.status_label.setText(status_text)
|
|
|
|
def format_license_key(self, text):
|
|
"""Formate automatiquement la clé de licence (XXXX-XXXX-...)"""
|
|
text = text.replace("-", "").upper()
|
|
formatted = "-".join([text[i:i+4] for i in range(0, len(text), 4)])
|
|
if len(formatted) > 24:
|
|
formatted = formatted[:24]
|
|
self.key_input.blockSignals(True)
|
|
self.key_input.setText(formatted)
|
|
self.key_input.blockSignals(False)
|
|
self.key_input.setCursorPosition(len(formatted))
|
|
|
|
def activate_license(self):
|
|
"""Lance l'activation de la licence"""
|
|
license_key = self.key_input.text().replace("-", "")
|
|
|
|
if len(license_key) < 16:
|
|
self.alert_manager.show_error("invalid_license_key")
|
|
return
|
|
|
|
# Disable inputs during activation
|
|
self.activate_btn.setEnabled(False)
|
|
self.key_input.setEnabled(False)
|
|
self.buy_btn.setEnabled(False)
|
|
|
|
# Show progress bar with initial message
|
|
self.progress_bar.set_label(self.language_manager.get_text("loading"))
|
|
self.progress_bar.set_progress(0)
|
|
self.progress_bar.setVisible(True)
|
|
|
|
# Start activation thread
|
|
self.activation_thread = ActivationThread(self.license_manager, license_key)
|
|
self.activation_thread.finished.connect(self.on_activation_finished)
|
|
self.activation_thread.progress.connect(self.on_activation_progress)
|
|
self.activation_thread.start()
|
|
|
|
def on_activation_progress(self, value):
|
|
"""Update progress bar during activation"""
|
|
self.progress_bar.set_progress(value)
|
|
|
|
def on_activation_finished(self, result):
|
|
"""Callback quand l'activation est terminée"""
|
|
# Hide progress bar
|
|
self.progress_bar.setVisible(False)
|
|
|
|
# Re-enable inputs
|
|
self.activate_btn.setEnabled(True)
|
|
self.key_input.setEnabled(True)
|
|
self.buy_btn.setEnabled(True)
|
|
|
|
if result["success"]:
|
|
# Show success message using AlertManager
|
|
success_msg = result['message']
|
|
if result.get("data"):
|
|
success_msg += f"\n\n{self.language_manager.get_text('license_type')}: {result['data'].get('type', 'N/A')}"
|
|
success_msg += f"\n{self.language_manager.get_text('license_email')}: {result['data'].get('email', 'N/A')}"
|
|
|
|
self.alert_manager.show_info(success_msg, parent=self)
|
|
self.update_license_status()
|
|
|
|
# Clear the input field
|
|
self.key_input.clear()
|
|
else:
|
|
# Show error message using AlertManager
|
|
self.alert_manager.show_info(f"✗ {result['message']}", parent=self)
|
|
|
|
def open_purchase_page(self):
|
|
"""Ouvre la page d'achat dans le navigateur"""
|
|
purchase_url = os.getenv("PURCHASE_URL")
|
|
if purchase_url:
|
|
webbrowser.open(purchase_url)
|
|
else:
|
|
self.alert_manager.show_error("PURCHASE_URL non définie dans .env", parent=self)
|
|
|
|
def update_language(self):
|
|
"""Met à jour tous les textes selon la nouvelle langue"""
|
|
self.title_label.setText(self.language_manager.get_text("activate_license"))
|
|
self.activate_btn.setText(self.language_manager.get_text("activate"))
|
|
self.buy_btn.setText(self.language_manager.get_text("buy_license"))
|
|
self.compare_btn.setText(self.language_manager.get_text("compare_versions"))
|
|
self.progress_bar.set_label(self.language_manager.get_text("loading"))
|
|
self.key_title.setText(self.language_manager.get_text("license_key_section"))
|
|
self.update_license_status()
|
|
|
|
def update_theme(self):
|
|
"""Met à jour le style selon le nouveau thème"""
|
|
self.update_license_status() |