hydraveil-gui/gui/v2/ui/pages/Page.py

170 lines
5.9 KiB
Python
Executable file

from core.models.Result import Result, ResultError
from core.errors.logger import logger
from gui.v2.ui.popups.error_popup import ErrorPopup
from gui.v2.infrastructure.ThreadSafetyTool import ThreadSafetyTool
mainthread = ThreadSafetyTool()
import os
from typing import Any
from PyQt6.QtWidgets import QWidget, QLabel, QPushButton
from PyQt6.QtGui import QIcon
from PyQt6 import QtCore
from enum import Enum
# For formatting errors graphically:
class DataError(Enum):
FORMAT: "format"
BLANK: "blank"
class Page(QWidget):
def __init__(self, name, page_stack, custom_window, parent=None):
super().__init__(parent)
self.custom_window = custom_window
self.btn_path = custom_window.btn_path
self.name = name
self.page_stack = page_stack
self._prepared = None
self.init_ui()
self.selected_profiles = []
self.selected_wireguard = []
self.selected_residential = []
self.buttons = []
@staticmethod
def prepare_data(custom_window):
return None
def _prepared_value(self, key, loader):
if self._prepared is not None and key in self._prepared:
return self._prepared[key]
return loader()
def add_selected_profile(self, profile):
self.selected_profiles.clear()
self.selected_wireguard.clear()
self.selected_residential.clear()
self.selected_profiles.append(profile)
def init_ui(self):
self.title = QLabel(self)
self.title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.title.setObjectName("titles")
self.display = QLabel(self)
self.display.setObjectName("display")
self.display.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
buttons_info = [
(QPushButton, "button_back", "back", (660, 534, 48, 35)),
(QPushButton, "button_next", "next", (720, 534, 48, 35)),
(QPushButton, "button_reverse", "back", (660, 534, 48, 35)),
(QPushButton, "button_go", "next", (720, 534, 48, 35)),
(QPushButton, "button_apply", "apply", (720, 534, 48, 35)),
]
for button_type, object_name, icon_name, geometry in buttons_info:
button = button_type(self)
button.setObjectName(object_name)
button.setGeometry(*geometry)
button.setIcon(
QIcon(os.path.join(self.btn_path, f"{icon_name}.png")))
button.setIconSize(QtCore.QSize(48, 35))
button.setVisible(False)
if object_name == "button_back":
self.button_back = button
self.button_back.clicked.connect(self.gestionar_back)
if object_name == "button_next":
self.button_next = button
self.button_next.clicked.connect(self.gestionar_next)
if object_name == "button_reverse":
self.button_reverse = button
self.button_reverse.clicked.connect(self.limpiar)
if object_name == "button_go":
self.button_go = button
self.button_go.clicked.connect(self.limpiar)
if object_name == "button_apply":
self.button_apply = button
def gestionar_back(self):
current_index = self.page_stack.currentIndex()
if current_index == 18:
return
if current_index > 0:
self.page_stack.setCurrentIndex(current_index - 1)
def gestionar_next(self):
current_index = self.page_stack.currentIndex()
next_index = (current_index + 1) % self.page_stack.count()
self.page_stack.setCurrentIndex(next_index)
self.limpiar()
def limpiar(self):
self.display.clear()
for boton in self.buttons:
boton.setChecked(False)
self.button_next.setVisible(False)
def replace_click_handler(self, button, handler):
try:
button.clicked.disconnect()
except TypeError:
pass
button.clicked.connect(handler)
@mainthread
def show_a_popup(self, message: str, title: str = "Error"):
"""Display a popup with an error"""
# MISTAKE CATCHER:
if isinstance(message, Result):
final_message = message.message
title = message.error_type.value
else:
final_message = message
# FINAL REAL CHECK
if isinstance(final_message, str) and isinstance(title, str):
error_popup = ErrorPopup(
choice=False,
title=title,
message=final_message,
end_app = False,
on_answer = None,
passed_result = None,
)
error_popup.show()
else:
logger.error("Show a popup was sent non valid strings to display.")
def display_error(self, whats_wrong: DataError, whats_it_called: str, the_thing: Any):
"""Generic re-usable error prompt for various data related issues"""
# Diagnosis
if whats_wrong == DataError.FORMAT:
error_msg = f"The {whats_it_called} is in the wrong format"
status_update = f'Error: Bad {whats_it_called} Format'
elif whats_wrong == DataError.BLANK:
error_msg = f"The {whats_it_called} is blank! But you need a {whats_it_called} to continue!"
status_update = f'Error: Blank {whats_it_called}'
else:
error_msg = f"The {whats_it_called} has unknown errors!"
status_update = f'Unknown Error with {whats_it_called}'
# Display
if the_thing and isinstance(the_thing, str):
self.show_a_popup(f"{error_msg}: {the_thing}")
elif the_thing and isinstance(the_thing, dict):
message = the_thing.get('message', "!")
self.show_a_popup(f"{error_msg} {message}")
else:
self.show_a_popup(error_msg)
self.update_status.update_status(status_update)