few adjustments
This commit is contained in:
parent
1639c71b56
commit
80492ef08c
@ -7,6 +7,11 @@ class AlertManager:
|
|||||||
self.language_manager = language_manager
|
self.language_manager = language_manager
|
||||||
self.theme_manager = theme_manager
|
self.theme_manager = theme_manager
|
||||||
|
|
||||||
|
def show_info(self, info_text: str, parent=None) -> None:
|
||||||
|
info_title = self.language_manager.get_text("information")
|
||||||
|
|
||||||
|
QMessageBox.information(parent, info_title, info_text)
|
||||||
|
|
||||||
def show_success(self, success_key: str, parent=None) -> None:
|
def show_success(self, success_key: str, parent=None) -> None:
|
||||||
success_title = self.language_manager.get_text("success")
|
success_title = self.language_manager.get_text("success")
|
||||||
success_text = self.language_manager.get_text(success_key)
|
success_text = self.language_manager.get_text(success_key)
|
||||||
@ -64,7 +69,7 @@ class AlertManager:
|
|||||||
box.buttonClicked.connect(on_button_clicked)
|
box.buttonClicked.connect(on_button_clicked)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
result = box.exec()
|
box.exec()
|
||||||
clicked_button = box.clickedButton()
|
clicked_button = box.clickedButton()
|
||||||
|
|
||||||
# Si c'est le bouton détails, on continue la boucle sans fermer
|
# Si c'est le bouton détails, on continue la boucle sans fermer
|
||||||
|
@ -31,15 +31,19 @@ class ThemeManager:
|
|||||||
|
|
||||||
def get_theme(self) -> Theme:
|
def get_theme(self) -> Theme:
|
||||||
return self.current_theme
|
return self.current_theme
|
||||||
|
def get_themes(self) -> List[Theme]:
|
||||||
|
return self.themes
|
||||||
def get_sheet(self) -> str:
|
def get_sheet(self) -> str:
|
||||||
return f"""
|
return f"""
|
||||||
QWidget {{
|
QWidget {{
|
||||||
background-color: {self.current_theme.get_color("background")};
|
background-color: {self.current_theme.get_color("background2")};
|
||||||
color: {self.current_theme.get_color("font_color")};
|
color: {self.current_theme.get_color("font_color")};
|
||||||
}}
|
}}
|
||||||
|
#tab_bar {{
|
||||||
|
background-color: {self.current_theme.get_color("background")};
|
||||||
|
}}
|
||||||
QPushButton {{
|
QPushButton {{
|
||||||
background-color: #0A84FF;
|
background-color: {self.current_theme.get_color("interactive")};
|
||||||
color: {self.current_theme.get_color("font_color")};
|
color: {self.current_theme.get_color("font_color")};
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@ -47,43 +51,36 @@ class ThemeManager:
|
|||||||
border: none;
|
border: none;
|
||||||
}}
|
}}
|
||||||
QPushButton:hover {{
|
QPushButton:hover {{
|
||||||
background-color: #007AFF;
|
background-color: {self.current_theme.get_color("interactive_hover")};
|
||||||
}}
|
}}
|
||||||
QLabel {{
|
QLabel {{
|
||||||
color: {self.current_theme.get_color("font_color")};
|
color: {self.current_theme.get_color("font_color")};
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}}
|
}}
|
||||||
QProgressBar {{
|
QProgressBar {{
|
||||||
border: 1px solid #3C3C3E;
|
border: 1px solid {self.current_theme.get_color("border")};
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: {self.current_theme.get_color("background2")};
|
background-color: {self.current_theme.get_color("background2")};
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: {self.current_theme.get_color("font_color")};
|
color: {self.current_theme.get_color("font_color")};
|
||||||
}}
|
}}
|
||||||
QProgressBar::chunk {{
|
QProgressBar::chunk {{
|
||||||
background-color: #0A84FF;
|
background-color: {self.current_theme.get_color("interactive")};
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}}
|
}}
|
||||||
QFrame {{
|
|
||||||
background-color: {self.current_theme.get_color("background2")};
|
|
||||||
border: none;
|
|
||||||
}}
|
|
||||||
QFrame#indicator_bar {{
|
|
||||||
background-color: #0A84FF;
|
|
||||||
}}
|
|
||||||
QScrollBar:vertical {{
|
QScrollBar:vertical {{
|
||||||
border: none;
|
border: none;
|
||||||
background: #E0E0E0;
|
background: {self.current_theme.get_color("background3")};
|
||||||
width: 8px;
|
width: 8px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}}
|
}}
|
||||||
QScrollBar::handle:vertical {{
|
QScrollBar::handle:vertical {{
|
||||||
background: #0A84FF;
|
background: {self.current_theme.get_color("interactive")};
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
}}
|
}}
|
||||||
QScrollBar::handle:vertical:hover {{
|
QScrollBar::handle:vertical:hover {{
|
||||||
background: #3B9CFF;
|
background: {self.current_theme.get_color("interactive_hover")};
|
||||||
}}
|
}}
|
||||||
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {{
|
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {{
|
||||||
border: none;
|
border: none;
|
||||||
@ -93,17 +90,14 @@ class ThemeManager:
|
|||||||
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {{
|
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {{
|
||||||
background: none;
|
background: none;
|
||||||
}}
|
}}
|
||||||
#drag_area {{
|
|
||||||
border: 2px dashed #3498db; border-radius: 10px;
|
|
||||||
}}
|
|
||||||
QSlider::groove:horizontal {{
|
QSlider::groove:horizontal {{
|
||||||
border: 1px solid #3a9bdc;
|
border: 1px solid {self.current_theme.get_color("interactive")};
|
||||||
height: 10px;
|
height: 10px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}}
|
}}
|
||||||
QSlider::sub-page:horizontal {{
|
QSlider::sub-page:horizontal {{
|
||||||
background: #3a9bdc;
|
background: {self.current_theme.get_color("interactive")};
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}}
|
}}
|
||||||
QSlider::add-page:horizontal {{
|
QSlider::add-page:horizontal {{
|
||||||
@ -112,7 +106,7 @@ class ThemeManager:
|
|||||||
}}
|
}}
|
||||||
QSlider::handle:horizontal {{
|
QSlider::handle:horizontal {{
|
||||||
background: white;
|
background: white;
|
||||||
border: 2px solid #3a9bdc;
|
border: 2px solid {self.current_theme.get_color("interactive")};
|
||||||
width: 14px;
|
width: 14px;
|
||||||
margin: -4px 0;
|
margin: -4px 0;
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
@ -171,6 +165,6 @@ class ThemeManager:
|
|||||||
|
|
||||||
/* Optionnel: indicateur visuel au hover */
|
/* Optionnel: indicateur visuel au hover */
|
||||||
QComboBox:hover {{
|
QComboBox:hover {{
|
||||||
border-color: #0078d4;
|
border-color: {self.current_theme.get_color("interactive_hover")};
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
@ -71,8 +71,7 @@ class UpdateManager:
|
|||||||
if choice:
|
if choice:
|
||||||
folder = QFileDialog.getExistingDirectory(parent, self.language_manager.get_text("choose_update_folder"))
|
folder = QFileDialog.getExistingDirectory(parent, self.language_manager.get_text("choose_update_folder"))
|
||||||
if folder:
|
if folder:
|
||||||
self.download(release["download_url"], release["tag_name"], folder, parent)
|
return self.download(release["download_url"], release["tag_name"], folder, parent)
|
||||||
return True
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def download(self, download_url, version, folder, parent=None):
|
def download(self, download_url, version, folder, parent=None):
|
||||||
@ -89,18 +88,48 @@ class UpdateManager:
|
|||||||
loading_bar = LoadingBar(self.language_manager.get_text("downloading_update"), dialog)
|
loading_bar = LoadingBar(self.language_manager.get_text("downloading_update"), dialog)
|
||||||
layout.addWidget(loading_bar)
|
layout.addWidget(loading_bar)
|
||||||
dialog.setModal(True)
|
dialog.setModal(True)
|
||||||
|
|
||||||
|
# Variable pour tracker si le téléchargement a été annulé
|
||||||
|
download_cancelled = False
|
||||||
|
|
||||||
|
def on_dialog_rejected():
|
||||||
|
nonlocal download_cancelled
|
||||||
|
download_cancelled = True
|
||||||
|
|
||||||
|
dialog.rejected.connect(on_dialog_rejected)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
||||||
downloaded = 0
|
downloaded = 0
|
||||||
with open(local_path, "wb") as f:
|
with open(local_path, "wb") as f:
|
||||||
for chunk in resp.iter_content(chunk_size=8192):
|
for chunk in resp.iter_content(chunk_size=8192):
|
||||||
|
QApplication.processEvents()
|
||||||
|
if download_cancelled:
|
||||||
|
break
|
||||||
|
|
||||||
if chunk:
|
if chunk:
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
downloaded += len(chunk)
|
downloaded += len(chunk)
|
||||||
percent = int(downloaded * 100 / total) if total else 0
|
percent = int(downloaded * 100 / total) if total else 0
|
||||||
loading_bar.set_progress(percent)
|
loading_bar.set_progress(percent)
|
||||||
QApplication.processEvents()
|
|
||||||
dialog.close()
|
dialog.close()
|
||||||
|
|
||||||
|
# Gérer l'annulation après la fermeture du fichier
|
||||||
|
if download_cancelled:
|
||||||
|
# Attendre un peu pour s'assurer que le fichier n'est plus utilisé
|
||||||
|
QApplication.processEvents()
|
||||||
|
import time
|
||||||
|
time.sleep(0.1) # Attendre 100ms pour libérer le handle
|
||||||
|
try:
|
||||||
|
if os.path.exists(local_path):
|
||||||
|
os.remove(local_path)
|
||||||
|
except (OSError, PermissionError):
|
||||||
|
# Si on ne peut pas supprimer le fichier, on continue sans erreur
|
||||||
|
pass
|
||||||
|
self.alert_manager.show_info(self.language_manager.get_text("update_aborted"), parent=parent)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Téléchargement réussi
|
||||||
msg = self.language_manager.get_text("update_downloaded").replace("{local_path}", local_path)
|
msg = self.language_manager.get_text("update_downloaded").replace("{local_path}", local_path)
|
||||||
self.alert_manager.show_success(msg, parent=parent)
|
self.alert_manager.show_success(msg, parent=parent)
|
||||||
# Ouvre le fichier téléchargé
|
# Ouvre le fichier téléchargé
|
||||||
@ -109,8 +138,11 @@ class UpdateManager:
|
|||||||
else:
|
else:
|
||||||
subprocess.Popen(["chmod", "+x", local_path])
|
subprocess.Popen(["chmod", "+x", local_path])
|
||||||
subprocess.Popen([local_path])
|
subprocess.Popen([local_path])
|
||||||
except Exception:
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
self.alert_manager.show_error("update_download_error", parent=parent)
|
self.alert_manager.show_error("update_download_error", parent=parent)
|
||||||
|
return False
|
||||||
|
|
||||||
def show_update_dialog(self, releases: List[Dict], current_version: str, parent=None) -> bool:
|
def show_update_dialog(self, releases: List[Dict], current_version: str, parent=None) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -125,7 +157,7 @@ class UpdateManager:
|
|||||||
parent=parent,
|
parent=parent,
|
||||||
details_callback=lambda: self.show_details_dialog(releases, current_version, parent)
|
details_callback=lambda: self.show_details_dialog(releases, current_version, parent)
|
||||||
)
|
)
|
||||||
print(choice)
|
|
||||||
return choice
|
return choice
|
||||||
|
|
||||||
def show_details_dialog(self, releases: List[Dict], current_version: str, parent=None) -> None:
|
def show_details_dialog(self, releases: List[Dict], current_version: str, parent=None) -> None:
|
||||||
|
@ -99,6 +99,7 @@ class TabsWidget(QWidget):
|
|||||||
self.stacked_widget = QStackedWidget()
|
self.stacked_widget = QStackedWidget()
|
||||||
# Create button container widget
|
# Create button container widget
|
||||||
self.button_container = QWidget()
|
self.button_container = QWidget()
|
||||||
|
self.button_container.setObjectName("tab_bar")
|
||||||
self.button_container.setLayout(self.button_layout)
|
self.button_container.setLayout(self.button_layout)
|
||||||
|
|
||||||
# Remove all margins from button container
|
# Remove all margins from button container
|
||||||
|
@ -9,7 +9,8 @@ class SettingsWindow(QWidget):
|
|||||||
self.main_manager: MainManager = MainManager.get_instance()
|
self.main_manager: MainManager = MainManager.get_instance()
|
||||||
self.language_manager = self.main_manager.get_language_manager()
|
self.language_manager = self.main_manager.get_language_manager()
|
||||||
self.settings_manager = self.main_manager.get_settings_manager()
|
self.settings_manager = self.main_manager.get_settings_manager()
|
||||||
|
self.theme_manager = self.main_manager.get_theme_manager()
|
||||||
|
|
||||||
self.observer_manager = self.main_manager.get_observer_manager()
|
self.observer_manager = self.main_manager.get_observer_manager()
|
||||||
self.observer_manager.subscribe(NotificationType.LANGUAGE, self.update_language)
|
self.observer_manager.subscribe(NotificationType.LANGUAGE, self.update_language)
|
||||||
|
|
||||||
@ -57,6 +58,7 @@ class SettingsWindow(QWidget):
|
|||||||
layout.addLayout(self.theme_layout)
|
layout.addLayout(self.theme_layout)
|
||||||
|
|
||||||
layout.addStretch()
|
layout.addStretch()
|
||||||
|
|
||||||
def createLanguageSelector(self) -> QComboBox:
|
def createLanguageSelector(self) -> QComboBox:
|
||||||
combo: QComboBox = QComboBox()
|
combo: QComboBox = QComboBox()
|
||||||
# Ajouter toutes les langues disponibles
|
# Ajouter toutes les langues disponibles
|
||||||
@ -72,11 +74,10 @@ class SettingsWindow(QWidget):
|
|||||||
|
|
||||||
def createThemeSelector(self) -> QComboBox:
|
def createThemeSelector(self) -> QComboBox:
|
||||||
combo: QComboBox = QComboBox()
|
combo: QComboBox = QComboBox()
|
||||||
|
# Ajouter toutes les options de thème disponibles
|
||||||
# Ajouter les options de thème
|
for theme in self.theme_manager.get_themes():
|
||||||
combo.addItem(self.language_manager.get_text("light_theme"), "light")
|
combo.addItem(self.language_manager.get_text(theme.name+"_theme"), theme.name)
|
||||||
combo.addItem(self.language_manager.get_text("dark_theme"), "dark")
|
|
||||||
|
|
||||||
# Sélectionner le thème actuel
|
# Sélectionner le thème actuel
|
||||||
currentIndex = combo.findData(self.settings_manager.get_theme())
|
currentIndex = combo.findData(self.settings_manager.get_theme())
|
||||||
combo.setCurrentIndex(currentIndex)
|
combo.setCurrentIndex(currentIndex)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"app_name": "Application",
|
"app_name": "HoDA",
|
||||||
"app_os": "Windows",
|
"app_os": "Windows",
|
||||||
"app_version": "1.0.0",
|
"app_version": "1.0.0",
|
||||||
"architecture": "x64",
|
"architecture": "x64",
|
||||||
"icon_path": "data/assets/icon.ico",
|
"icon_path": "data/assets/icon.ico",
|
||||||
"main_script": "main.py",
|
"main_script": "main.py",
|
||||||
"git_repo": "https://gitea.louismazin.ovh/LouisMazin/PythonApplicationTemplate"
|
"git_repo": "https://gitea.louismazin.ovh/LouisMazin/HoDA"
|
||||||
}
|
}
|
@ -28,5 +28,7 @@
|
|||||||
"details": "Details",
|
"details": "Details",
|
||||||
"version": "Version",
|
"version": "Version",
|
||||||
"update_details": "Update Details",
|
"update_details": "Update Details",
|
||||||
"close": "Close"
|
"close": "Close",
|
||||||
|
"update_aborted": "Update aborted by user",
|
||||||
|
"information": "Information"
|
||||||
}
|
}
|
@ -28,5 +28,7 @@
|
|||||||
"details": "Détails",
|
"details": "Détails",
|
||||||
"version": "Version",
|
"version": "Version",
|
||||||
"update_details": "Détails de la mise à jour",
|
"update_details": "Détails de la mise à jour",
|
||||||
"close": "Fermer"
|
"close": "Fermer",
|
||||||
|
"update_aborted": "Mise à jour annulée par l'utilisateur",
|
||||||
|
"information": "Information"
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"theme_name": "dark",
|
"theme_name": "dark",
|
||||||
"colors": {
|
"colors": {
|
||||||
|
"interactive": "#0A84FF",
|
||||||
|
"interactive_hover": "#007AFF",
|
||||||
"border": "#3C3C3E",
|
"border": "#3C3C3E",
|
||||||
"background": "#212121",
|
"background": "#212121",
|
||||||
"background2": "#2C2C2E",
|
"background2": "#2C2C2E",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"theme_name": "light",
|
"theme_name": "light",
|
||||||
"colors": {
|
"colors": {
|
||||||
|
"interactive": "#0A84FF",
|
||||||
|
"interactive_hover": "#007AFF",
|
||||||
"border": "#1f1f20",
|
"border": "#1f1f20",
|
||||||
"background": "#FFFFFF",
|
"background": "#FFFFFF",
|
||||||
"background2": "#F5F5F5",
|
"background2": "#F5F5F5",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user