diff --git a/gui/__main__.py b/gui/__main__.py index 7ca9ee3..a0b7dd9 100644 --- a/gui/__main__.py +++ b/gui/__main__.py @@ -1,5 +1,5 @@ from PyQt6.QtWidgets import QComboBox,QButtonGroup, QLineEdit,QMainWindow, QLabel, QWidget, QVBoxLayout, QStackedWidget, QApplication, QPushButton, QTextEdit, QFrame, QHBoxLayout, QVBoxLayout, QScrollArea, QSystemTrayIcon, QMessageBox, QGridLayout, QCheckBox, QStackedLayout, QGroupBox, QDialog -from PyQt6.QtGui import QIcon, QPixmap,QIcon, QPixmap, QTransform, QPainter, QColor, QFont, QPen +from PyQt6.QtGui import QIcon, QPixmap,QIcon, QPixmap, QTransform, QPainter, QColor, QFont, QFontDatabase from PyQt6 import QtGui from PyQt6 import QtCore from PyQt6.QtCore import Qt,QSize,QThread,pyqtSignal, QTimer, QPointF, QRect, QMutex, QMutexLocker, QObject @@ -232,6 +232,7 @@ class WorkerThread(QThread): all_location_codes = [f"{location.country_code}_{location.code}" for location in locations] self.sync_output.emit(all_location_codes, True, False, locations, False) except Exception as e: + print(e) self.sync_output.emit([], False, False, [], False) @@ -296,6 +297,20 @@ class CustomWindow(QMainWindow): self.setWindowFlags( Qt.WindowType.Window ) + + font_id = QFontDatabase.addApplicationFont('gui/resources/fonts/retro-gaming.ttf') + font_family = QFontDatabase.applicationFontFamilies(font_id)[0] + app_font = QFont(font_family) + app_font.setPointSize(10) + QApplication.setFont(app_font) + + self.open_sans_family = None + open_sans_path = 'gui/resources/fonts/open-sans.ttf' + if os.path.exists(open_sans_path): + open_sans_id = QFontDatabase.addApplicationFont(open_sans_path) + if open_sans_id != -1: + self.open_sans_family = QFontDatabase.applicationFontFamilies(open_sans_id)[0] + self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) self.setAttribute(Qt.WidgetAttribute.WA_NoSystemBackground) self.setWindowTitle("HydraVeil VPN") @@ -370,7 +385,7 @@ class CustomWindow(QMainWindow): self.scroll_speed = 1 self.tor_text = QLabel("Billing & Browsers", self) - self.tor_text.setGeometry(522, 542, 150, 20) + self.tor_text.setGeometry(515, 542, 150, 20) self.tor_text.setStyleSheet(""" QLabel { color: cyan; @@ -1087,7 +1102,6 @@ class Worker(QObject): except CommandNotFoundError as e : self.update_signal.emit(str(e), False, -1, None, None) except Exception as e: - print('exception inside thread') print(e) self.update_signal.emit("An unknown error occurred", False, None, None, None) @@ -1679,7 +1693,6 @@ class MenuPage(Page): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(Settings))) def eliminacion(self): - current_state = { 'is_tor_mode': self.is_tor_mode, 'is_animating': self.is_animating, @@ -2563,7 +2576,10 @@ class ProtocolPage(Page): def go_selected(self): if self.selected_page_class: selected_page = self.selected_page_class - self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(selected_page))) + if selected_page == HidetorPage: + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ResidentialPage))) + else: + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(selected_page))) self.display.clear() for boton in self.buttons: @@ -2760,7 +2776,6 @@ class HidetorPage(Page): def update_swarp_json(self): inserted_data = { "location": self.selected_location_icon, - "connection": 'tor' } self.update_status.write_data(inserted_data) @@ -2782,6 +2797,7 @@ class ResidentialPage(Page): super().__init__("Wireguard", page_stack, main_window, parent) self.title.setGeometry(585, 40, 185, 40); self.title.setText("Pick a Protocol") self.update_status = main_window + self.connection_choice = None self.button_reverse.setVisible(True) self.button_reverse.clicked.connect(self.reverse) self.button_go.clicked.connect(self.go_selected) @@ -2796,8 +2812,6 @@ class ResidentialPage(Page): - - def showEvent(self, event): super().showEvent(event) self.create_interface_elements() @@ -2808,8 +2822,8 @@ class ResidentialPage(Page): self.buttons = [] for j, (object_type, icon_name, page_class, geometry) in enumerate([ - (QPushButton, "tor", TorPage, (585, 90, 185, 75)), - (QPushButton, "just proxy", TorPage, (585, 90+30+75+30+75, 185, 75)), + (QPushButton, "tor", self.set_connection_choice('tor'), (585, 90, 185, 75)), + (QPushButton, "just proxy", self.set_connection_choice('just proxy'), (585, 90+30+75+30+75, 185, 75)), (QLabel, None, None, (570, 170, 210, 105)), (QLabel, None, None, (570, 385, 210, 115)) ]): @@ -2840,6 +2854,9 @@ class ResidentialPage(Page): label.setText(text2) + def set_connection_choice(self, connection_choice): + self.connection_choice = connection_choice + def show_residential(self, icon_name,page_class): self.selected_page_class = page_class @@ -2849,17 +2866,12 @@ class ResidentialPage(Page): self.label.hide() self.button_go.setVisible(True) - self.update_swarp_json(icon_name) + + def go_selected(self): - if self.selected_page_class: - selected_page = self.selected_page_class - self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(selected_page))) - - - for boton in self.buttons: - boton.setChecked(False) - - self.button_go.setVisible(False) + self.update_swarp_json(self.connection_choice) + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(HidetorPage))) + self.button_go.setVisible(False) def update_swarp_json(self, icon_name): inserted_data = { @@ -2870,6 +2882,7 @@ class ResidentialPage(Page): def reverse(self): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage))) + class TorPage(Page): def __init__(self, page_stack, main_window, parent=None): super().__init__("TorPage", page_stack, main_window, parent) @@ -2904,14 +2917,9 @@ class TorPage(Page): self.data_profile = {} profile = self.update_status.read_data() profile_1 = profile.get('Profile_1') - self.data_profile['connection'] = profile_1.get('connection') - for key, value in self.data_profile.items(): - print(f"{key}: {value}") + self.verificate() - - self.verificate(value) - - def verificate(self, value): + def verificate(self, value= 'tor'): # Verificar el valor de key if value == "just proxy": self.display0.show() @@ -2956,11 +2964,10 @@ class TorPage(Page): self.update_status.write_data(inserted_data) - def reverse_selected(self): - self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ResidentialPage))) - def go_selected(self): + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ResidentialPage))) + def go_selected(self): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(BrowserPage))) @@ -3064,7 +3071,6 @@ class LocationPage(Page): inserted_data = { "location": self.selected_location_icon } - self.update_status.write_data(inserted_data) @@ -3583,19 +3589,16 @@ class ResumePage(Page): else: application = '' - print(profile.get('location')) parts = profile.get('location').split('_') country_code = parts[0] location_code = parts[1] if profile.get('protocol') == 'wireguard': connection_type = 'wireguard' - elif profile.get('protocol') == 'residential': + elif profile.get('protocol') == 'hidetor' or profile.get('protocol') == 'residential': if profile.get('connection') == 'tor': connection_type = 'tor' elif profile.get('connection') == 'just proxy': connection_type = 'system' - elif profile.get('protocol') == 'hidetor': - connection_type = 'tor' else: self.update_status.update_status('Connection type not supported') return @@ -3609,7 +3612,6 @@ class ResumePage(Page): 'connection_type': connection_type, 'resolution': profile.get('dimentions', ''), } - profile_type = 'system' if profile.get('connection') == 'system-wide' else 'session' action = f'CREATE_{profile_type.upper()}_PROFILE' @@ -3664,6 +3666,10 @@ class EditorPage(Page): self.button_apply.clicked.connect(self.go_selected) self.button_back.setVisible(True) + try: + self.button_back.clicked.disconnect() + except TypeError: + pass self.button_back.clicked.connect(self.go_back) self.name_handle = QLabel(self) @@ -3671,7 +3677,7 @@ class EditorPage(Page): self.name_handle.setText("Profile Name:") self.name = QLineEdit(self) - self.name.setGeometry(250, 68, 400, 30) + self.name.setGeometry(275, 70, 400, 30) self.name.setStyleSheet("border: transparent;") @@ -4111,6 +4117,8 @@ class EditorPage(Page): class Settings(Page): def __init__(self, page_stack, main_window, parent=None): super().__init__("Settings", page_stack, main_window, parent) + self.font_style = f"font-family: '{self.custom_window.open_sans_family}';" + self.update_status = main_window self.update_logging = main_window self.button_reverse.setVisible(True) @@ -4150,6 +4158,8 @@ class Settings(Page): ("Error Logs", self.show_logs_page) ] + + self.menu_buttons = [] for text, callback in menu_items: btn = QPushButton(text) @@ -4158,22 +4168,24 @@ class Settings(Page): btn.setCheckable(True) btn.clicked.connect(callback) - btn.setStyleSheet(""" - QPushButton { + btn.setStyleSheet(f""" + QPushButton {{ text-align: left; padding-left: 20px; border: none; background: transparent; color: #808080; - } - QPushButton:checked { + font-size: 15px; + {self.font_style} + }} + QPushButton:checked {{ background: rgba(255, 255, 255, 0.1); color: white; border-left: 3px solid #007AFF; - } - QPushButton:hover:!checked { + }} + QPushButton:hover:!checked {{ background: rgba(255, 255, 255, 0.05); - } + }} """) self.left_layout.addWidget(btn) @@ -4202,7 +4214,7 @@ class Settings(Page): layout.setSpacing(15) title = QLabel("DELETE PROFILE") - title.setStyleSheet("color: #808080; font-size: 12px; font-weight: bold;") + title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}") layout.addWidget(title) grid = QGridLayout() @@ -4222,21 +4234,22 @@ class Settings(Page): btn = QPushButton(f"Profile {profile_id}\n{profile.name}") btn.setCheckable(True) btn.setFixedSize(180, 60) - btn.setStyleSheet(""" - QPushButton { + btn.setStyleSheet(f""" + QPushButton {{ background: rgba(255, 255, 255, 0.1); border: none; color: white; border-radius: 5px; text-align: center; - } - QPushButton:checked { + {self.font_style} + }} + QPushButton:checked {{ background: rgba(255, 255, 255, 0.3); border: 2px solid #007AFF; - } - QPushButton:hover:!checked { + }} + QPushButton:hover:!checked {{ background: rgba(255, 255, 255, 0.2); - } + }} """) self.profile_buttons.addButton(btn, profile_id) else: @@ -4250,23 +4263,23 @@ class Settings(Page): self.delete_button = QPushButton("Delete") self.delete_button.setEnabled(False) self.delete_button.setFixedSize(120, 40) - self.delete_button.setStyleSheet(""" - QPushButton { + self.delete_button.setStyleSheet(f""" + QPushButton {{ background: #ff4d4d; color: white; border: none; border-radius: 5px; font-weight: bold; - } - QPushButton:disabled { + {self.font_style} + }} + QPushButton:disabled {{ background: #666666; - } - QPushButton:hover:!disabled { + }} + QPushButton:hover:!disabled {{ background: #ff3333; - } + }} """) self.delete_button.clicked.connect(self.delete_selected_profile) - self.profile_buttons.buttonClicked.connect(self.on_profile_selected) button_layout = QHBoxLayout() @@ -4313,8 +4326,8 @@ class Settings(Page): def get_combobox_style(self) -> str: - return """ - QComboBox { + return f""" + QComboBox {{ color: black; background: #f0f0f0; padding: 5px 30px 5px 10px; @@ -4322,41 +4335,44 @@ class Settings(Page): border-radius: 4px; min-width: 120px; margin-bottom: 10px; - } - QComboBox:disabled { + {self.font_style} + }} + QComboBox:disabled {{ color: #666; background: #e0e0e0; - } - QComboBox::drop-down { + }} + QComboBox::drop-down {{ border: none; width: 30px; - } - QComboBox::down-arrow { + }} + QComboBox::down-arrow {{ image: url(assets/down_arrow.png); width: 12px; height: 12px; - } - QComboBox QAbstractItemView { + }} + QComboBox QAbstractItemView {{ color: black; background: white; selection-background-color: #007bff; selection-color: white; border: 1px solid #ccc; - } + {self.font_style} + }} """ def get_checkbox_style(self) -> str: - return """ - QCheckBox { + return f""" + QCheckBox {{ color: white; spacing: 10px; margin-top: 10px; margin-bottom: 10px; - } - QCheckBox::indicator { + {self.font_style} + }} + QCheckBox::indicator {{ width: 18px; height: 18px; - } + }} """ def populate_wireguard_profiles(self) -> None: @@ -4423,24 +4439,25 @@ class Settings(Page): layout.setContentsMargins(20, 20, 20, 20) title = QLabel("Subscription Info") - title.setStyleSheet("color: #808080; font-size: 12px; font-weight: bold;") + title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}") layout.addWidget(title) profile_group = QGroupBox("Profile Selection") - profile_group.setStyleSheet(""" - QGroupBox { + profile_group.setStyleSheet(f""" + QGroupBox {{ color: white; font-weight: bold; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; padding: 15px; margin-top: 15px; - } - QGroupBox::title { + {self.font_style} + }} + QGroupBox::title {{ subcontrol-origin: margin; left: 10px; padding: 0 5px; - } + }} """) profile_layout = QVBoxLayout(profile_group) @@ -4454,20 +4471,21 @@ class Settings(Page): layout.addWidget(profile_group) subscription_group = QGroupBox("Subscription Details") - subscription_group.setStyleSheet(""" - QGroupBox { + subscription_group.setStyleSheet(f""" + QGroupBox {{ color: white; font-weight: bold; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; padding: 15px; margin-top: 15px; - } - QGroupBox::title { + {self.font_style} + }} + QGroupBox::title {{ subcontrol-origin: margin; left: 10px; padding: 0 5px; - } + }} """) subscription_layout = QGridLayout(subscription_group) subscription_layout.setSpacing(10) @@ -4490,7 +4508,7 @@ class Settings(Page): value_label = ClickableValueLabel("N/A", stat_widget) value_label.setObjectName("value_label") - value_label.setStyleSheet("color: #00ffff; font-size: 13px; font-weight: bold;") + value_label.setStyleSheet(f"color: #00ffff; font-size: 13px; font-weight: bold; {self.font_style}") value_label.setAlignment(Qt.AlignmentFlag.AlignCenter) stat_widget.layout().insertWidget(0, value_label) @@ -4565,19 +4583,19 @@ class Settings(Page): layout.setContentsMargins(20, 20, 20, 20) title = QLabel("Account Overview") - title.setStyleSheet("color: #808080; font-size: 12px; font-weight: bold;") + title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}") layout.addWidget(title) scroll_area = QScrollArea() scroll_area.setWidgetResizable(True) - scroll_area.setStyleSheet(""" - QScrollArea { + scroll_area.setStyleSheet(f""" + QScrollArea {{ border: none; background: transparent; - } - QScrollArea > QWidget > QWidget { + }} + QScrollArea > QWidget > QWidget {{ background: transparent; - } + }} """) scroll_content = QWidget() @@ -4591,20 +4609,21 @@ class Settings(Page): for section_title, content_widget in info_sections: group = QGroupBox(section_title) - group.setStyleSheet(""" - QGroupBox { + group.setStyleSheet(f""" + QGroupBox {{ color: white; font-weight: bold; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; padding: 15px; margin-top: 15px; - } - QGroupBox::title { + {self.font_style} + }} + QGroupBox::title {{ subcontrol-origin: margin; left: 10px; padding: 0 5px; - } + }} """) group_layout = QVBoxLayout(group) group_layout.addWidget(content_widget) @@ -4659,7 +4678,7 @@ class Settings(Page): for i, (label, value) in enumerate(stats): info_widget = QLabel(f"{label}: {value}") - info_widget.setStyleSheet("color: white; padding: 5px;") + info_widget.setStyleSheet(f"color: white; padding: 5px; {self.font_style}") info_widget.setWordWrap(True) layout.addWidget(info_widget, i, 0) @@ -4667,22 +4686,23 @@ class Settings(Page): def create_stat_widget(self, label, value): widget = QFrame() - widget.setStyleSheet(""" - QFrame { + widget.setStyleSheet(f""" + QFrame {{ background: rgba(255, 255, 255, 0.05); border-radius: 8px; padding: 10px; - } + {self.font_style} + }} """) layout = QVBoxLayout(widget) value_label = QLabel(str(value)) value_label.setObjectName("value_label") - value_label.setStyleSheet("color: #00ffff; font-size: 24px; font-weight: bold;") + value_label.setStyleSheet("color: #00ffff; font-size: 24px; font-weight: bold") value_label.setAlignment(Qt.AlignmentFlag.AlignCenter) desc_label = QLabel(label) - desc_label.setStyleSheet("color: white; font-size: 12px;") + desc_label.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}") desc_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(value_label) @@ -4695,7 +4715,7 @@ class Settings(Page): layout.setContentsMargins(0, 5, 0, 5) text_label = QLabel(f"{label}") - text_label.setStyleSheet("color: white; font-size: 12px;") + text_label.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}") text_label.setFixedWidth(100) progress = QFrame() @@ -4709,7 +4729,7 @@ class Settings(Page): progress.setFixedSize(int(200 * (percentage / 100)), 20) value_label = QLabel(f"{value} ({percentage:.1f}%)") - value_label.setStyleSheet("color: white; font-size: 12px;") + value_label.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}") value_label.setAlignment(Qt.AlignmentFlag.AlignRight) progress_container = QFrame() @@ -4752,15 +4772,15 @@ class Settings(Page): layout.setContentsMargins(20, 20, 20, 20) title = QLabel("LOGGING SETTINGS") - title.setStyleSheet("color: #808080; font-size: 12px; font-weight: bold;") + title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}") layout.addWidget(title) - log_text = QLabel(f"If enabled, these Error Logs would be stored locally on your computer\nat {Constants.HV_DATA_HOME}/gui") - log_text.setStyleSheet("color: white; font-size: 14px;") + log_text = QLabel(f"If enabled, these Error Logs would be stored locally on your computer\nat {Constants.HV_DATA_HOME}/gui") + log_text.setStyleSheet(f"color: white; font-size: 14px; {self.font_style}") layout.addWidget(log_text) logs_group = QGroupBox("Log Configuration") - logs_group.setStyleSheet("QGroupBox { color: white; padding: 15px; }") + logs_group.setStyleSheet(f"QGroupBox {{ color: white; padding: 15px; {self.font_style} }}") logs_layout = QVBoxLayout(logs_group) self.enable_gui_logging = QCheckBox("Enable GUI logging") @@ -4975,7 +4995,6 @@ class PaymentPage(Page): self.on_request_invoice() def on_request_invoice(self): - raise UnknownConnectionTypeError('The connection type is unknown') total_hours = self.fetch_invoice_duration() selected_currency = self.get_selected_currency() if selected_currency is None: @@ -5612,16 +5631,26 @@ class SyncScreen(Page): self.heading_label = QLabel("You're about to fetch data from\nSimplified Privacy.", self) - self.heading_label.setGeometry(15, 80, 750, 100) - self.heading_label.setStyleSheet("font-size: 36px; font-weight: bold; color: white;") + self.heading_label.setGeometry(15, 80, 750, 120) + font_style = "font-size: 34px; font-weight: bold; color: white;" + if self.custom_window.open_sans_family: + print('open sans found') + font_style += f" font-family: '{self.custom_window.open_sans_family}';" + self.heading_label.setStyleSheet(font_style) self.data_description = QLabel("This data includes what plans, countries,\nbrowsers, and version upgrades are\navailable. As well as coordinating billing.", self) - self.data_description.setGeometry(22, 190, 750, 100) - self.data_description.setStyleSheet("font-size: 26px; font-weight: bold; color: #ffff00;") + self.data_description.setGeometry(22, 190, 750, 120) + font_style = "font-size: 24px; font-weight: bold; color: #ffff00;" + if self.custom_window.open_sans_family: + font_style += f" font-family: '{self.custom_window.open_sans_family}';" + self.data_description.setStyleSheet(font_style) self.instructions = QLabel("Use the toggle in the bottom right to\ndecide if you want to use Tor or not.\nThen hit \"Next\"", self) self.instructions.setGeometry(22, 345, 750, 120) - self.instructions.setStyleSheet("font-size: 30px; font-weight: bold; color: white;") + font_style = "font-size: 28px; font-weight: bold; color: white;" + if self.custom_window.open_sans_family: + font_style += f" font-family: '{self.custom_window.open_sans_family}';" + self.instructions.setStyleSheet(font_style) self.arrow_label = QLabel(self) self.arrow_label.setGeometry(520, 400, 180, 130) @@ -5852,3 +5881,4 @@ if __name__ == "__main__": window.show() sys.exit(app.exec()) + diff --git a/gui/resources/fonts/open-sans.ttf b/gui/resources/fonts/open-sans.ttf new file mode 100644 index 0000000..ac587b4 Binary files /dev/null and b/gui/resources/fonts/open-sans.ttf differ diff --git a/gui/resources/fonts/retro-gaming.ttf b/gui/resources/fonts/retro-gaming.ttf new file mode 100644 index 0000000..0dca996 Binary files /dev/null and b/gui/resources/fonts/retro-gaming.ttf differ