Spaces:
Build error
Build error
Rename gpt_computer_agent/gpt_computer_assistant.py to gpt_computer_agent/gpt_computer_agent.py
b4dfe59
verified
| try: | |
| from .agent.chat_history import * | |
| from .agent.assistant import * | |
| from .llm import * | |
| from .llm_settings import llm_settings | |
| from .agent.agent import * | |
| from .agent.background import * | |
| from .gui.signal import * | |
| from .gui.button import * | |
| from .gui.settings import settings_popup | |
| from .gui.llmsettings import llmsettings_popup | |
| from .utils.db import * | |
| from .utils.telemetry import my_tracer, os_name | |
| from .audio.wake_word import wake_word | |
| from .audio.tts import text_to_speech | |
| from .character import name, developer | |
| except ImportError: | |
| # This is for running the script directly | |
| # in order to test the GUI without rebuilding the package | |
| from agent.chat_history import * | |
| from agent.assistant import * | |
| from llm import * | |
| from llm_settings import llm_settings | |
| from agent.agent import * | |
| from agent.background import * | |
| from utils.db import * | |
| from gui.signal import * | |
| from gui.button import * | |
| from gui.settings import settings_popup | |
| from gui.llmsettings import llmsettings_popup | |
| from utils.telemetry import my_tracer, os_name | |
| from audio.wake_word import wake_word | |
| from audio.tts import text_to_speech | |
| import platform | |
| import threading | |
| import time | |
| import random | |
| import math | |
| from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QWidget | |
| from PyQt5.QtGui import QMouseEvent, QPainter, QPen, QBrush, QIcon, QColor | |
| from PyQt5.QtCore import Qt, QTimer, QRect, pyqtSignal | |
| from PyQt5.QtGui import QKeySequence | |
| from PyQt5.QtWidgets import QShortcut | |
| from PyQt5.QtWidgets import QSpacerItem, QSizePolicy | |
| from PyQt5.QtWidgets import QDesktopWidget | |
| from PyQt5.QtWidgets import ( | |
| QPushButton, | |
| QLabel, | |
| QHBoxLayout, | |
| ) | |
| from PyQt5.QtCore import QPoint | |
| from PyQt5.QtWidgets import QTextEdit | |
| from PyQt5 import QtGui | |
| from PyQt5.QtCore import QThread | |
| import pygame | |
| print("Imported all libraries") | |
| from PyQt5 import QtCore | |
| try: | |
| import ctypes | |
| myappid = "khulnasoft.gpt_computer_agent.gui.1" | |
| ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) | |
| except: | |
| pass | |
| the_input_box = None | |
| the_input_text = None | |
| the_input_box_pre = None | |
| the_main_window = None | |
| user_id = load_user_id() | |
| os_name_ = os_name() | |
| from PyQt5.QtCore import QRegExp | |
| from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat, QFont | |
| class PythonSyntaxHighlighter(QSyntaxHighlighter): | |
| def __init__(self, parent): | |
| super().__init__(parent) | |
| self.highlighting_rules = [] | |
| # Define different text formats with appropriate colors | |
| keyword_format = QTextCharFormat() | |
| keyword_format.setForeground(QColor(127, 0, 85)) # Dark purple for keywords | |
| built_in_formats = QTextCharFormat() | |
| built_in_formats.setForeground( | |
| QColor(42, 0, 255) | |
| ) # Dark blue for built-ins and constants | |
| string_format = QTextCharFormat() | |
| string_format.setForeground(QColor(0, 128, 0)) # Green for strings | |
| function_format = QTextCharFormat() | |
| function_format.setForeground(QColor(0, 0, 255)) # Blue for function names | |
| comment_format = QTextCharFormat() | |
| comment_format.setForeground(QColor(128, 128, 128)) # Gray for comments | |
| comment_format.setFontItalic(True) | |
| number_format = QTextCharFormat() | |
| number_format.setForeground(QColor(255, 0, 0)) # Red for numbers | |
| decorator_format = QTextCharFormat() | |
| decorator_format.setForeground(QColor(0, 0, 128)) # Navy blue for decorators | |
| # Markdown formatting | |
| header_format = QTextCharFormat() | |
| header_format.setForeground(QColor(0, 128, 128)) # Teal for headers | |
| header_format.setFontWeight(QFont.Bold) | |
| bold_format = QTextCharFormat() | |
| bold_format.setFontWeight(QFont.Bold) | |
| italic_format = QTextCharFormat() | |
| italic_format.setFontItalic(True) | |
| code_format = QTextCharFormat() | |
| code_format.setForeground(QColor(255, 140, 0)) # Dark orange for inline code | |
| code_format.setFontFamily("Courier New") | |
| code_format.setBackground( | |
| QColor(245, 245, 245) | |
| ) # Light gray background for inline code | |
| block_code_format = QTextCharFormat() | |
| block_code_format.setForeground( | |
| QColor(255, 140, 0) | |
| ) # Dark orange for code blocks | |
| block_code_format.setFontFamily("Courier New") | |
| block_code_format.setBackground( | |
| QColor(245, 245, 245) | |
| ) # Light gray background for code blocks | |
| # Define the regular expressions | |
| keywords = [ | |
| "def", | |
| "class", | |
| "if", | |
| "else", | |
| "elif", | |
| "return", | |
| "import", | |
| "from", | |
| "as", | |
| "for", | |
| "while", | |
| "try", | |
| "except", | |
| "finally", | |
| "with", | |
| "async", | |
| "await", | |
| "yield", | |
| "lambda", | |
| "global", | |
| "nonlocal", | |
| "assert", | |
| "del", | |
| "pass", | |
| "break", | |
| "continue", | |
| "and", | |
| "or", | |
| "not", | |
| "is", | |
| "in", | |
| ] | |
| self.highlighting_rules += [ | |
| (QRegExp(r"\b" + word + r"\b"), keyword_format) for word in keywords | |
| ] | |
| built_ins = [ | |
| "True", | |
| "False", | |
| "None", | |
| "__init__", | |
| "self", | |
| "print", | |
| "len", | |
| "range", | |
| "str", | |
| "int", | |
| "float", | |
| "list", | |
| "dict", | |
| "set", | |
| "tuple", | |
| ] | |
| self.highlighting_rules += [ | |
| (QRegExp(r"\b" + word + r"\b"), built_in_formats) for word in built_ins | |
| ] | |
| self.highlighting_rules.append( | |
| (QRegExp(r'"[^"\\]*(\\.[^"\\]*)*"'), string_format) | |
| ) | |
| self.highlighting_rules.append( | |
| (QRegExp(r"'[^'\\]*(\\.[^'\\]*)*'"), string_format) | |
| ) | |
| self.highlighting_rules.append((QRegExp(r"\bdef\b\s*(\w+)"), function_format)) | |
| self.highlighting_rules.append((QRegExp(r"\bclass\b\s*(\w+)"), function_format)) | |
| self.highlighting_rules.append((QRegExp(r"#.*"), comment_format)) | |
| self.highlighting_rules.append((QRegExp(r"\b[0-9]+[lL]?\b"), number_format)) | |
| self.highlighting_rules.append( | |
| (QRegExp(r"\b0[xX][0-9A-Fa-f]+[lL]?\b"), number_format) | |
| ) | |
| self.highlighting_rules.append( | |
| (QRegExp(r"\b0[oO]?[0-7]+[lL]?\b"), number_format) | |
| ) | |
| self.highlighting_rules.append((QRegExp(r"\b0[bB][01]+[lL]?\b"), number_format)) | |
| self.highlighting_rules.append((QRegExp(r"@[^\s]+"), decorator_format)) | |
| # Markdown rules | |
| self.highlighting_rules.append( | |
| (QRegExp(r"^#{1,6} .+"), header_format) | |
| ) # Headers | |
| self.highlighting_rules.append( | |
| (QRegExp(r"\*\*[^*]+\*\*"), bold_format) | |
| ) # **bold** | |
| self.highlighting_rules.append((QRegExp(r"__[^_]+__"), bold_format)) # __bold__ | |
| self.highlighting_rules.append( | |
| (QRegExp(r"\*[^*]+\*"), italic_format) | |
| ) # *italic* | |
| self.highlighting_rules.append((QRegExp(r"_[^_]+_"), italic_format)) # _italic_ | |
| self.highlighting_rules.append( | |
| (QRegExp(r"`[^`]+`"), code_format) | |
| ) # Inline code | |
| def highlightBlock(self, text): | |
| # Handle code blocks separately | |
| if text.strip().startswith("```"): | |
| self.setFormat(0, len(text), self.highlighting_rules[-1][1]) | |
| return | |
| for pattern, format in self.highlighting_rules: | |
| expression = QRegExp(pattern) | |
| index = expression.indexIn(text) | |
| while index >= 0: | |
| length = expression.matchedLength() | |
| self.setFormat(index, length, format) | |
| index = expression.indexIn(text, index + length) | |
| readed_sentences = [] | |
| import re | |
| def split_with_multiple_delimiters(text, delimiters): | |
| """ | |
| Splits the text by any of the given delimiters while keeping the delimiters in the resulting parts. | |
| :param text: The input text to be split. | |
| :param delimiters: A string of delimiters to split the text on. | |
| :return: A list of parts including the delimiters. | |
| """ | |
| # Create a regular expression pattern that matches any of the delimiters | |
| pattern = re.compile(f"(.*?[{re.escape(delimiters)}])") | |
| parts = pattern.findall(text) | |
| # Check if the last part is not complete and remove it if necessary | |
| if ( | |
| parts | |
| and text | |
| and not any(text.endswith(d) for d in delimiters) | |
| and parts | |
| and not any(parts[-1].endswith(d) for d in delimiters) | |
| ): | |
| parts.pop() | |
| return parts | |
| def click_sound(): | |
| pygame.mixer.init() | |
| retro = pygame.mixer.Sound(click_sound_path) | |
| retro.set_volume(0.1) | |
| retro.play() | |
| class Worker(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| self.make_animation = True | |
| self.commited_text = [] | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| last_text = ( | |
| self.commited_text[-1] if len(self.commited_text) > 0 else "" | |
| ) | |
| if self.the_input_text != last_text: | |
| self.commited_text.append(self.the_input_text) | |
| if len(self.the_input_text) > 90 or not self.make_animation: | |
| self.text_to_set.emit(self.the_input_text) | |
| else: | |
| for i in range(len(self.the_input_text)): | |
| self.text_to_set.emit(self.the_input_text[: i + 1]) | |
| self.msleep(10) | |
| return_key_event = None | |
| class CustomTextEdit(QTextEdit): | |
| def __init__(self, parent=None): | |
| super(CustomTextEdit, self).__init__(parent) | |
| def keyPressEvent(self, event): | |
| if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter: | |
| global return_key_event | |
| return_key_event() | |
| super(CustomTextEdit, self).keyPressEvent( | |
| event | |
| ) # Process other key events normally | |
| class Worker_2(QThread): | |
| text_to_set = pyqtSignal(str) | |
| text_to_set_title_bar = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| self.title_bar_text = None | |
| self.prev = None | |
| self.commited_text = [] | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text and ( | |
| self.prev is None or self.prev != self.the_input_text | |
| ): | |
| self.prev = self.the_input_text | |
| self.text_to_set.emit("True") | |
| for i in range(len(self.title_bar_text)): | |
| self.text_to_set_title_bar.emit(self.title_bar_text[: i + 1]) | |
| self.msleep(10) | |
| if not self.the_input_text and self.prev != self.the_input_text: | |
| self.prev = self.the_input_text | |
| self.text_to_set.emit("False") | |
| the_text = " " + name() | |
| for i in range(len(the_text)): | |
| self.text_to_set_title_bar.emit(the_text[: i + 1]) | |
| self.msleep(10) | |
| class Worker_3(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| self.text_to_set.emit("True") | |
| self.the_input_text = None | |
| class Worker_collapse(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| self.text_to_set.emit("True") | |
| self.the_input_text = None | |
| class Worker_uncollapse(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| self.text_to_set.emit("True") | |
| self.the_input_text = None | |
| class Worker_show_logo(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| self.text_to_set.emit("True") | |
| self.the_input_text = None | |
| class Worker_hide_logo(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| self.text_to_set.emit("True") | |
| self.the_input_text = None | |
| class Worker_activate_long_gca(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| self.text_to_set.emit("True") | |
| self.the_input_text = None | |
| class Worker_deactivate_long_gca(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| self.text_to_set.emit("True") | |
| self.the_input_text = None | |
| class Worker_tray_and_task_bar_logo(QThread): | |
| text_to_set = pyqtSignal(str) | |
| def __init__(self): | |
| super().__init__() | |
| self.the_input_text = None | |
| def run(self): | |
| while True: | |
| self.msleep(500) # Simulate a time-consuming task | |
| if self.the_input_text: | |
| self.text_to_set.emit("True") | |
| self.the_input_text = None | |
| class DrawingWidget(QWidget): | |
| def __init__(self, parent=None): | |
| super(DrawingWidget, self).__init__(parent) | |
| # Set widget properties if needed, e.g., size | |
| self.main_ = parent | |
| self.active_button = "" | |
| def paintEvent(self, event): | |
| if llm_settings[load_model_settings()]["vision"] is True: | |
| self.main_.screen_available = True | |
| else: | |
| self.main_.screen_available = False | |
| self.main_.setAutoFillBackground(True) | |
| painter = QPainter(self) | |
| painter = painter | |
| painter.setRenderHint(QPainter.Antialiasing) | |
| painter.setPen(QPen(QColor("#000"), 1)) | |
| painter.setBrush(QBrush(Qt.black, Qt.SolidPattern)) | |
| center_x = 95 | |
| center_y = 40 | |
| if "talking" in self.main_.state: | |
| # Draw a pulsating circle with smooth easing animation | |
| radius_variation = 5 * ( | |
| 1 + math.sin(self.main_.pulse_frame * math.pi / 100) | |
| ) | |
| radius = 70 + radius_variation | |
| painter.drawEllipse( | |
| int(center_x - radius / 2), | |
| int(center_y - radius / 2), | |
| int(radius), | |
| int(radius), | |
| ) | |
| elif self.main_.state == "thinking": | |
| # more slow pulsating circle with smooth easing animation | |
| radius_variation = 5 * ( | |
| 1 + math.sin(self.main_.pulse_frame * math.pi / 100) | |
| ) | |
| radius = 70 + radius_variation | |
| painter.drawEllipse( | |
| int(center_x - radius / 2), | |
| int(center_y - radius / 2), | |
| int(radius), | |
| int(radius), | |
| ) | |
| else: | |
| radius = 70 | |
| if self.main_.screen_available: | |
| painter.drawEllipse( # Main Button | |
| int(center_x - radius / 2), | |
| int(center_y - radius / 2), | |
| int(radius), | |
| int(radius), | |
| ) | |
| self.main_.circle_rect = QRect( | |
| int(center_x - radius / 2), | |
| int(center_y - radius / 2), | |
| int(radius), | |
| int(radius), | |
| ) | |
| if not self.main_.state == "thinking": | |
| painter.setPen(QPen(QColor("#01EE8A"), 1)) | |
| if self.main_.screen_available: | |
| painter.drawEllipse( # Main BUtton Green Border | |
| int(center_x - radius / 2), | |
| int(center_y - radius / 2), | |
| int(radius), | |
| int(radius), | |
| ) | |
| else: | |
| painter.setPen(QPen(QColor("#23538F"), 1)) | |
| painter.drawEllipse( | |
| int(center_x - radius / 2), | |
| int(center_y - radius / 2), | |
| int(radius), | |
| int(radius), | |
| ) | |
| painter.setPen(QPen(QColor("#000"), 1)) | |
| small_center_x = 165 | |
| small_center_y = 25 | |
| small_radius = 30 | |
| painter.drawEllipse( # Microphone bacground black | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ) | |
| self.main_.small_circle_rect = QRect( | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ) | |
| # Draw the icon inside the circle | |
| icon_size = small_radius * 2 // 3 # Adjust the icon size relative to the circle | |
| icon_rect = QRect( | |
| small_center_x - icon_size // 2, | |
| small_center_y - icon_size // 2, | |
| icon_size, | |
| icon_size, | |
| ) | |
| self.main_.small_circle_recticon = QIcon(microphone_icon_path) | |
| self.main_.small_circle_recticon.paint(painter, icon_rect) | |
| small_center_x = 30 | |
| small_center_y = 60 | |
| small_radius = 30 | |
| painter.drawEllipse( | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ) | |
| self.main_.small_circle_left = QRect( | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ) | |
| # Draw the icon inside the circle | |
| icon_size = small_radius * 2 // 3 # Adjust the icon size relative to the circle | |
| icon_rect = QRect( | |
| small_center_x - icon_size // 2, | |
| small_center_y - icon_size // 2, | |
| icon_size, | |
| icon_size, | |
| ) | |
| self.main_.small_circle_lefticon = QIcon(audio_icon_path) | |
| self.main_.small_circle_lefticon.paint(painter, icon_rect) | |
| small_center_x = 30 | |
| small_center_y = 25 | |
| small_radius = 30 | |
| if self.main_.screen_available: | |
| painter.drawEllipse( # ScreenShot BUtton | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ) | |
| self.main_.small_circle_left_top = QRect( | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ) | |
| self.main_.screenshot_button_coordinates_size = [ | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ] | |
| if self.active_button == "screenshot": | |
| self.screenshot_button_border_activate(painter) | |
| self.active_button = "" | |
| if self.main_.screen_available: | |
| # Draw the icon inside the circle | |
| icon_size = ( | |
| small_radius * 2 // 3 | |
| ) # Adjust the icon size relative to the circle | |
| icon_rect = QRect( | |
| small_center_x - icon_size // 2, | |
| small_center_y - icon_size // 2, | |
| icon_size, | |
| icon_size, | |
| ) | |
| self.main_.small_circle_left_topticon = QIcon(screenshot_icon_path) | |
| self.main_.small_circle_left_topticon.paint(painter, icon_rect) | |
| small_center_x = 165 | |
| small_center_y = 60 | |
| small_radius = 30 | |
| painter.drawEllipse( | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ) | |
| self.main_.small_circle_collapse = QRect( | |
| int(small_center_x - small_radius / 2), | |
| int(small_center_y - small_radius / 2), | |
| int(small_radius), | |
| int(small_radius), | |
| ) | |
| # Draw the icon inside the circle | |
| icon_size = small_radius * 2 // 3 # Adjust the icon size relative to the circle | |
| icon_rect = QRect( | |
| small_center_x - icon_size // 2, | |
| small_center_y - icon_size // 2, | |
| icon_size, | |
| icon_size, | |
| ) | |
| if is_collapse_setting_active(): | |
| self.main_.small_circle_collapse_icon = QIcon(down_icon_path) | |
| if not is_collapse_setting_active() and is_long_gca_setting_active(): | |
| self.main_.small_circle_collapse_icon = QIcon(up_icon_path) | |
| if not is_collapse_setting_active() and not is_long_gca_setting_active(): | |
| self.main_.small_circle_collapse_icon = QIcon(down_icon_path) | |
| self.main_.small_circle_collapse_icon.paint(painter, icon_rect) | |
| def screenshot_button_border_activate(self, painter): | |
| # Add an white border to the circle | |
| painter.setPen(QPen(QColor("#FFF"), 1)) | |
| # Draw the ellipse with the specified green border | |
| self.main_.screenshot_button_border = painter.drawEllipse( | |
| self.main_.screenshot_button_coordinates_size[0], | |
| self.main_.screenshot_button_coordinates_size[1], | |
| self.main_.screenshot_button_coordinates_size[2], | |
| self.main_.screenshot_button_coordinates_size[3], | |
| ) | |
| painter.setPen(QPen(QColor("#000"), 1)) | |
| def mousePressEvent(self, event: QMouseEvent): | |
| self.main_.old_position = event.globalPos() | |
| with my_tracer.start_span("mouse_press_event") as span: | |
| span.set_attribute("user_id", user_id) | |
| span.set_attribute("os_name", os_name_) | |
| if self.main_.state == "idle" or "talking" in self.main_.state: | |
| try: | |
| if self.main_.circle_rect.contains(event.pos()): | |
| if self.main_.state == "aitalking": | |
| self.main_.stop_ai_talking() | |
| else: | |
| self.main_.screenshot_and_microphone_button_action() | |
| except: | |
| traceback.print_exc() | |
| try: | |
| if self.main_.small_circle_rect.contains(event.pos()): | |
| if self.main_.state == "aitalking": | |
| self.main_.stop_ai_talking() | |
| else: | |
| click_sound() | |
| self.main_.button_handler.toggle_recording( | |
| no_screenshot=True | |
| ) | |
| except: | |
| traceback.print_exc() | |
| try: | |
| if self.main_.small_circle_left.contains(event.pos()): | |
| if self.main_.state == "aitalking": | |
| self.main_.stop_ai_talking() | |
| else: | |
| click_sound() | |
| self.main_.button_handler.toggle_recording( | |
| take_system_audio=True | |
| ) | |
| except: | |
| traceback.print_exc() | |
| try: | |
| if self.main_.small_circle_left_top.contains(event.pos()): | |
| if self.main_.state == "aitalking": | |
| self.main_.stop_ai_talking() | |
| else: | |
| click_sound() | |
| self.active_button = "screenshot" | |
| self.update() | |
| self.main_.button_handler.just_screenshot() | |
| except: | |
| traceback.print_exc() | |
| try: | |
| if self.main_.small_circle_collapse.contains(event.pos()): | |
| if not is_collapse_setting_active(): | |
| if is_long_gca_setting_active(): | |
| self.main_.deactivate_long_gca() | |
| self.main_.collapse_gca() | |
| else: | |
| self.main_.activate_long_gca() | |
| else: | |
| self.main_.uncollapse_gca() | |
| self.main_.update() | |
| except: | |
| pass | |
| from PyQt5.QtCore import QVariantAnimation | |
| class MainWindow(QMainWindow): | |
| api_enabled = False | |
| tts_available = True | |
| def screenshot_and_microphone_button_action(self): | |
| click_sound() | |
| if llm_settings[load_model_settings()]["vision"] is True: | |
| self.button_handler.toggle_recording(dont_save_image=True) | |
| else: | |
| self.button_handler.toggle_recording(no_screenshot=True) | |
| def stop_ai_talking(self): | |
| self.manuel_stop = True | |
| self.stop_talking = True | |
| def __init__(self): | |
| super().__init__() | |
| self.background_color = "45, 45, 45" | |
| self.opacity = 250 | |
| self.border_radius = 10 | |
| print("API Enabled:", MainWindow.api_enabled) | |
| if MainWindow.api_enabled: | |
| try: | |
| from .api import start_api | |
| start_api() | |
| except: | |
| raise Exception( | |
| "API could not be started, please install gpt-computer-agent[api]" | |
| ) | |
| self.stop_talking = False | |
| self.setWindowFlags( | |
| Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | |
| ) # Remove the default title bar | |
| # Load the San Francisco font | |
| print("Loading font") | |
| print(font_dir) | |
| try: | |
| font_id = QtGui.QFontDatabase.addApplicationFont(font_dir) | |
| font_family = QtGui.QFontDatabase.applicationFontFamilies(font_id)[0] | |
| self.setFont(QtGui.QFont(font_family)) | |
| except: | |
| print("Error loading font") | |
| self.state = "idle" | |
| self.pulse_timer = None | |
| self.button_handler = ButtonHandler(self) | |
| self.initUI() | |
| self.old_position = self.pos() | |
| self.collapse = is_collapse_setting_active() | |
| if self.collapse: | |
| self.collapse_window() | |
| global the_main_window | |
| the_main_window = self | |
| self.general_styling() | |
| if is_dark_mode_active(): | |
| self.dark_mode() | |
| else: | |
| self.light_mode() | |
| self.wake_word_thread = None | |
| self.wake_word_active = False | |
| if load_pvporcupine_api_key() != "CHANGE_ME" and is_wake_word_active(): | |
| self.wake_word_active = True | |
| self.wake_word_trigger() | |
| self.manuel_stop = False | |
| self.border_animation = None | |
| self.complated_answer = False | |
| self.reading_thread = False | |
| self.reading_thread_2 = False | |
| image_layout = QHBoxLayout() | |
| self.the_image = QLabel(self) | |
| self.the_image.setPixmap(QtGui.QPixmap(load_logo_file_path()).scaled(25, 25)) | |
| image_layout.addWidget(self.the_image) | |
| self.layout.addLayout(image_layout) | |
| self.the_image.setAlignment(Qt.AlignCenter) | |
| self.the_image.setFixedHeight(35) | |
| # Logo Adding | |
| if not is_logo_active_setting_active(): | |
| self.the_image.hide() | |
| self.update_screen() | |
| def put_location(self): | |
| if load_location_setting() == "right": | |
| self.put_window_to_right_side_of_screen() | |
| def init_border_animation(self): | |
| # Create a QVariantAnimation to handle color change | |
| border_animation = QVariantAnimation( | |
| self, | |
| valueChanged=self.update_border_color, | |
| startValue=QColor("#303030"), | |
| endValue=QColor("#23538F"), | |
| duration=2000, # Duration for one loop in milliseconds | |
| ) | |
| border_animation.setLoopCount(-1) # Loop indefinitely | |
| return border_animation | |
| def start_border_animation(self, status): | |
| print("FUNCTION TRİGGERED") | |
| if self.border_animation is None: | |
| self.border_animation = self.init_border_animation() | |
| status = status.lower() == "true" | |
| if status: | |
| self.border_animation.start() | |
| else: | |
| self.border_animation.stop() | |
| self.title_bar.setStyleSheet( | |
| "background-color: #2E2E2E; color: white; border-style: solid; border-radius: 15px; border-width: 0px; color: #fff;" | |
| ) | |
| def update_border_color(self, color): | |
| self.title_bar.setStyleSheet( | |
| f"background-color: #2E2E2E; color: white; border-style: solid; border-radius: 15px; border-width: 2px; border-color: {color.name()}; color: #fff;" | |
| ) | |
| self.title_bar.setStyleSheet( | |
| f"background-color: #2E2E2E; color: white; border-style: solid; border-radius: 15px; border-width: 1px; border-color: {color.name()}; color: #fff;" | |
| ) | |
| # Existing methods... | |
| def general_styling(self, a=None): | |
| self.setAttribute(Qt.WA_TranslucentBackground) | |
| self.setStyleSheet( | |
| f"border-radius: {self.border_radius}px; background-color: rgba({self.background_color}, {self.opacity});" | |
| ) | |
| self.central_widget.setStyleSheet( | |
| "border-style: solid; border-width: 1px; border-color: rgb(0,0,0,0);" | |
| ) | |
| self.input_box_style = "border-radius: 10px; border-bottom: 1px solid #01EE8A;" | |
| self.settingsButton_style = ( | |
| "border-radius: 5px; height: 25px; border-style: solid;" | |
| ) | |
| self.llmsettingsButton_style = ( | |
| "border-radius: 5px; height: 25px; border-style: solid;" | |
| ) | |
| self.btn_minimize.setStyleSheet( | |
| "background-color: #2E2E2E; color: white; border-style: none;" | |
| ) | |
| self.btn_close.setStyleSheet( | |
| "background-color: #2E2E2E; color: white; border-style: none;" | |
| ) | |
| def set_background_color(self, color): | |
| self.background_color = color | |
| self.worker_3.the_input_text = "True" | |
| def set_opacity(self, opacity): | |
| self.opacity = opacity | |
| self.worker_3.the_input_text = "True" | |
| def set_border_radius(self, radius): | |
| self.border_radius = radius | |
| self.worker_3.the_input_text = "True" | |
| def wake_word_trigger(self): | |
| self.wake_word_thread = threading.Thread(target=self.wake_word) | |
| self.wake_word_thread.start() | |
| def wake_word(self): | |
| from .agent.process import tts_if_you_can | |
| while True and is_wake_word_active() and self.wake_word_active: | |
| if wake_word(self): | |
| def random_accept_words(): | |
| return random.choice(["Yes", "Sir", "Boss", "Master"]) | |
| tts_if_you_can(random_accept_words(), not_threaded=True) | |
| def trigger_wake_word(): | |
| if ( | |
| is_wake_word_screen_setting_active() | |
| and llm_settings[load_model_settings()]["vision"] | |
| ): | |
| self.button_handler.toggle_recording(dont_save_image=True) | |
| else: | |
| self.button_handler.toggle_recording(no_screenshot=True) | |
| if self.state == "aitalking": | |
| self.manuel_stop = True | |
| self.stop_talking = True | |
| time.sleep(1) | |
| trigger_wake_word() | |
| print("Stop talking") | |
| else: | |
| trigger_wake_word() | |
| def dark_mode(self): | |
| self.setAutoFillBackground(True) | |
| p = self.palette() | |
| p.setColor( | |
| self.backgroundRole(), QColor("#171717") | |
| ) # Set background color to white | |
| self.setPalette(p) | |
| self.input_box.setStyleSheet( | |
| self.input_box_style + "background-color: #2E2E2E; color: white;" | |
| ) | |
| self.settingsButton.setStyleSheet( | |
| self.settingsButton_style + "background-color: #2E2E2E; color: white;" | |
| ) | |
| self.llmsettingsButton.setStyleSheet( | |
| self.llmsettingsButton_style + "background-color: #2E2E2E; color: white;" | |
| ) | |
| def light_mode(self): | |
| self.setAutoFillBackground(True) | |
| p = self.palette() | |
| p.setColor(self.backgroundRole(), QColor("#F0F0F0")) | |
| self.setPalette(p) | |
| self.input_box.setStyleSheet( | |
| self.input_box_style + "background-color: #FFFFFF; color: black;" | |
| ) | |
| self.settingsButton.setStyleSheet( | |
| self.settingsButton_style + "background-color: #FFFFFF; color: black; " | |
| ) | |
| self.llmsettingsButton.setStyleSheet( | |
| self.llmsettingsButton_style + "background-color: #FFFFFF; color: black; " | |
| ) | |
| def collapse_window(self): | |
| the_input_box.hide() | |
| self.settingsButton.hide() | |
| self.llmsettingsButton.hide() | |
| self.update_screen() | |
| def initUI(self): | |
| self.setWindowTitle("GPT") | |
| self.setGeometry(100, 100, 200, 200) | |
| width = 210 | |
| height = 300 | |
| # setting the minimum size | |
| self.setMinimumSize(width, height) | |
| self.first_height = self.height() | |
| self.first_width = self.width() | |
| self.central_widget = QWidget(self) | |
| self.setCentralWidget(self.central_widget) | |
| layout = QVBoxLayout(self.central_widget) | |
| # Custom title bar | |
| self.title_bar = QWidget(self) | |
| self.title_bar.setFixedHeight(30) # Set a fixed height for the title bar | |
| self.title_bar.setStyleSheet( | |
| "background-color: #2E2E2E; color: #fff; border-radius: 15px; border-style: solid; border-width: 1px; border-color: #303030;" | |
| ) | |
| self.title_bar_layout = QHBoxLayout(self.title_bar) | |
| self.title_bar_layout.setContentsMargins(5, 5, 0, 5) | |
| self.title_bar_layout.setSpacing(0) | |
| self.btn_minimize = QPushButton("-", self.title_bar) | |
| self.btn_minimize.setFixedSize(20, 20) | |
| self.btn_minimize.clicked.connect(self.showMinimized) | |
| def stop_app(): | |
| self.stop_talking = True | |
| self.wake_word_active = False | |
| if MainWindow.api_enabled: | |
| from .api import stop_api | |
| stop_api() | |
| self.close() | |
| self.btn_close = QPushButton("×", self.title_bar) | |
| self.btn_close.setFixedSize(20, 20) | |
| self.btn_close.clicked.connect(stop_app) | |
| self.title_label = QLabel(" " + name(), self.title_bar) | |
| # Change font size | |
| font = QtGui.QFont() | |
| font.setPointSize(11) | |
| self.title_label.setFont(font) | |
| self.title_label.setStyleSheet("border: 0px solid blue;") | |
| self.title_bar_layout.addWidget(self.title_label) | |
| self.title_bar_layout.addStretch() | |
| self.title_bar_layout.addWidget(self.btn_minimize) | |
| self.title_bar_layout.addWidget(self.btn_close) | |
| # Create a spacer item with expanding policy | |
| spacer = QSpacerItem(5, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) | |
| self.title_bar_layout.addSpacerItem(spacer) # Add spacer to the layout | |
| layout.addWidget(self.title_bar) | |
| self.drawing_widget = DrawingWidget(self) | |
| layout.addWidget(self.drawing_widget) | |
| self.layout = layout | |
| self.setLayout(layout) | |
| # Add keyboard shortcuts | |
| self.shortcut_screenshot = QShortcut(QKeySequence("Ctrl+1"), self) | |
| self.shortcut_screenshot.activated.connect( | |
| lambda: self.button_handler.just_screenshot() | |
| ) | |
| self.shortcut_screenshot = QShortcut(QKeySequence("Ctrl+2"), self) | |
| self.shortcut_screenshot.activated.connect( | |
| lambda: self.button_handler.toggle_recording(take_system_audio=True) | |
| ) | |
| self.shortcut_no_screenshot = QShortcut(QKeySequence("Ctrl+e"), self) | |
| self.shortcut_no_screenshot.activated.connect( | |
| lambda: self.button_handler.toggle_recording(take_system_audio=True) | |
| ) | |
| self.shortcut_no_screenshot = QShortcut(QKeySequence("Ctrl+3"), self) | |
| self.shortcut_no_screenshot.activated.connect( | |
| lambda: self.button_handler.toggle_recording(no_screenshot=True) | |
| ) | |
| # I want to create an input box to bottom left and a send button to bottom right | |
| input_box = CustomTextEdit(self) | |
| self.input_box = input_box | |
| input_box.setFixedHeight(80) | |
| # Set text wrapping. I dont wat to cut the text | |
| input_box.setWordWrapMode(QtGui.QTextOption.NoWrap) | |
| # Change the font size | |
| font = QtGui.QFont() | |
| font.setPointSize(12) | |
| input_box.setFont(font) | |
| self.highlighter = PythonSyntaxHighlighter(self.input_box.document()) | |
| if load_api_key() == "CHANGE_ME": | |
| input_box.setPlaceholderText("Save your API Key, go to settings") | |
| else: | |
| if platform.system() == "Darwin": | |
| if llm_settings[load_model_settings()]["vision"] is False: | |
| input_box.setPlaceholderText("Type here \nsand ↵ ") | |
| else: | |
| input_box.setPlaceholderText( | |
| "Type here \nand ↵ \nor ⌘ + ↵ (+screenshot)" | |
| ) | |
| else: | |
| if llm_settings[load_model_settings()]["vision"] is False: | |
| input_box.setPlaceholderText("Type here \nand ↵ ") | |
| else: | |
| input_box.setPlaceholderText( | |
| "Type here \nand ↵ \nor Ctrl + ↵ (+screenshot)" | |
| ) | |
| # Add an information and use enter icon to the input box for mac | |
| input_box.setGeometry(30, self.height() - 60, 200, 80) | |
| global the_input_box | |
| the_input_box = input_box | |
| def input_box_send(): | |
| if input_box.toPlainText() != "": | |
| click_sound() | |
| self.button_handler.input_text(input_box.toPlainText()) | |
| def input_box_send_screenshot(): | |
| if input_box.toPlainText() != "": | |
| click_sound() | |
| self.button_handler.input_text_screenshot(input_box.toPlainText()) | |
| self.layout.addWidget(input_box) | |
| self.shortcut_enter = QShortcut(QKeySequence("Ctrl+Return"), self) | |
| self.shortcut_enter.activated.connect(input_box_send_screenshot) | |
| global return_key_event | |
| return_key_event = input_box_send | |
| button_layout_ = QHBoxLayout() | |
| self.settingsButton = QPushButton("Chat Settings", self) | |
| self.settingsButton.clicked.connect(settings_popup) | |
| self.llmsettingsButton = QPushButton("LLM Settings", self) | |
| self.llmsettingsButton.clicked.connect(llmsettings_popup) | |
| button_layout_.addWidget(self.settingsButton) | |
| button_layout_.addWidget(self.llmsettingsButton) | |
| self.layout.addLayout(button_layout_) | |
| self.worker = Worker() | |
| self.worker.text_to_set.connect(self.set_text) | |
| self.worker.start() | |
| self.worker_2 = Worker_2() | |
| self.worker_2.text_to_set.connect(self.start_border_animation) | |
| self.worker_2.text_to_set_title_bar.connect(self.set_title_bar_text) | |
| self.worker_2.start() | |
| self.worker_3 = Worker_3() | |
| self.worker_3.text_to_set.connect(self.general_styling) | |
| self.worker_3.start() | |
| self.worker_collapse = Worker_collapse() | |
| self.worker_collapse.text_to_set.connect(self.collapse_gca) | |
| self.worker_collapse.start() | |
| self.worker_uncollapse = Worker_uncollapse() | |
| self.worker_uncollapse.text_to_set.connect(self.uncollapse_gca) | |
| self.worker_uncollapse.start() | |
| self.worker_show_logo = Worker_show_logo() | |
| self.worker_show_logo.text_to_set.connect(self.show_logo) | |
| self.worker_show_logo.start() | |
| self.worker_hide_logo = Worker_hide_logo() | |
| self.worker_hide_logo.text_to_set.connect(self.hide_logo) | |
| self.worker_hide_logo.start() | |
| self.worker_activate_long_gca = Worker_activate_long_gca() | |
| self.worker_activate_long_gca.text_to_set.connect(self.activate_long_gca) | |
| self.worker_activate_long_gca.start() | |
| self.worker_deactivate_long_gca = Worker_deactivate_long_gca() | |
| self.worker_deactivate_long_gca.text_to_set.connect(self.deactivate_long_gca) | |
| self.worker_deactivate_long_gca.start() | |
| self.worker_tray_and_task_bar_logo = Worker_tray_and_task_bar_logo() | |
| self.worker_tray_and_task_bar_logo.text_to_set.connect( | |
| self.tray_and_task_bar_logo | |
| ) | |
| self.worker_tray_and_task_bar_logo.start() | |
| # print height and width | |
| print(self.height(), self.width()) | |
| self.show() | |
| def set_text(self, text): | |
| global the_input_box | |
| vertical_scrollbar = the_input_box.verticalScrollBar() | |
| scroll_value = vertical_scrollbar.value() | |
| the_input_box.setPlainText(text) | |
| vertical_scrollbar.setValue(scroll_value) | |
| def set_title_bar_text(self, text): | |
| self.title_label.setText(text) | |
| def update_from_thread(self, text, system=True): | |
| self.worker.make_animation = True | |
| if system: | |
| text = "System: " + text | |
| print("Updating from thread", text) | |
| self.worker.the_input_text = text | |
| def read_part_task_generate_only(self): | |
| if not is_just_text_model_active() and the_main_window.tts_available: | |
| threads = {} | |
| the_okey_parts = split_with_multiple_delimiters( | |
| self.worker.the_input_text, ".?!:" | |
| ) | |
| for each in the_okey_parts: | |
| if the_main_window.stop_talking: | |
| break | |
| the_thread = threading.Thread(target=text_to_speech, args=(each,)) | |
| threads[each] = the_thread | |
| the_thread.start() | |
| for each in threads.values(): | |
| each.join() | |
| self.reading_thread_2 = False | |
| def read_part_task(self): | |
| if not is_just_text_model_active() and the_main_window.tts_available: | |
| threads = {} | |
| the_okey_parts = split_with_multiple_delimiters( | |
| self.worker.the_input_text, ".?!:" | |
| ) | |
| will_read_parts = [] | |
| for each in the_okey_parts: | |
| if the_main_window.stop_talking: | |
| break | |
| if each not in readed_sentences: | |
| will_read_parts.append(each) | |
| readed_sentences.append(each) | |
| the_thread = threading.Thread(target=text_to_speech, args=(each,)) | |
| threads[each] = the_thread | |
| the_thread.start() | |
| for each in will_read_parts: | |
| if the_main_window.stop_talking: | |
| break | |
| threads[each].join() | |
| tts_if_you_can(each, not_threaded=True, bypass_other_settings=True) | |
| self.reading_thread = False | |
| def set_text_to_input_box(self, text): | |
| global readed_sentences | |
| self.worker.make_animation = False | |
| if self.worker.the_input_text.startswith("System:") or self.complated_answer: | |
| self.worker.the_input_text = "" | |
| self.complated_answer = False | |
| readed_sentences = [] | |
| if text not in (">", "<>", ">\n", "<", "<\n"): | |
| self.worker.the_input_text += text | |
| if self.reading_thread is not True and len(self.worker.the_input_text) > 40: | |
| self.reading_thread = True | |
| threading.Thread(target=self.read_part_task).start() | |
| if ( | |
| self.reading_thread_2 is not True | |
| and len(self.worker.the_input_text) > 250 | |
| ): | |
| self.reading_thread_2 = True | |
| threading.Thread(target=self.read_part_task_generate_only).start() | |
| else: | |
| print("Problem on text chars") | |
| def set_text_from_api(self, text): | |
| self.worker.make_animation = True | |
| self.worker.the_input_text = text | |
| def active_border_animation(self, title_bar_text=None): | |
| if self.worker_2.title_bar_text is not None: | |
| if self.worker_2.title_bar_text != title_bar_text: | |
| return | |
| self.worker_2.the_input_text = True | |
| if title_bar_text is None: | |
| title_bar_text = " " + name() | |
| else: | |
| title_bar_text = f" {title_bar_text}" | |
| if len(title_bar_text) > 33: | |
| title_bar_text = title_bar_text[:30] + "..." | |
| self.worker_2.title_bar_text = title_bar_text | |
| self.btn_minimize.hide() | |
| self.btn_close.hide() | |
| def deactive_border_animation(self, title_bar_text=None): | |
| if title_bar_text is None: | |
| title_bar_text = " " + name() | |
| else: | |
| title_bar_text = f" {title_bar_text}" | |
| if len(title_bar_text) > 33: | |
| title_bar_text = title_bar_text[:30] + "..." | |
| if self.worker_2.title_bar_text is not None: | |
| if self.worker_2.title_bar_text != title_bar_text: | |
| return | |
| self.worker_2.the_input_text = False | |
| self.worker_2.title_bar_text = None | |
| time.sleep(1) | |
| self.btn_minimize.show() | |
| self.btn_close.show() | |
| def mouseMoveEvent(self, event: QMouseEvent): | |
| delta = QPoint(event.globalPos() - self.old_position) | |
| if event.buttons() == Qt.LeftButton and self.title_bar.underMouse(): | |
| self.move(self.x() + delta.x(), self.y() + delta.y()) | |
| self.old_position = event.globalPos() | |
| def mousePressEvent(self, event: QMouseEvent): | |
| self.old_position = event.globalPos() | |
| def remove_screenshot_button(self): | |
| self.update() | |
| def add_screenshot_button(self): | |
| self.update() | |
| def update_state(self, new_state): | |
| assistant_stopped = False | |
| if self.state == "aitalking" and new_state == "idle": | |
| assistant_stopped = True | |
| if self.manuel_stop: | |
| assistant_stopped = False | |
| self.manuel_stop = False | |
| self.state = new_state | |
| print(f"State updated: {new_state}") | |
| if "talking" in new_state: | |
| self.tray.setIcon(self.tray_active_icon) | |
| self.pulse_frame = 0 | |
| if self.pulse_timer: | |
| self.pulse_timer.stop() | |
| self.pulse_timer = None | |
| self.pulse_timer = QTimer(self) | |
| self.pulse_timer.timeout.connect(self.pulse_circle) | |
| self.pulse_timer.start(5) | |
| elif new_state == "thinking": | |
| the_main_window.update_from_thread("Thinking...") | |
| self.pulse_frame = 0 | |
| if self.pulse_timer: | |
| self.pulse_timer.stop() | |
| self.pulse_timer = None | |
| self.pulse_timer = QTimer(self) | |
| self.pulse_timer.timeout.connect(self.pulse_circle) | |
| self.pulse_timer.start(20) | |
| elif self.pulse_timer: | |
| self.tray.setIcon(self.tray_icon) | |
| self.pulse_timer.stop() | |
| self.pulse_timer = None | |
| self.update() # Trigger a repaint | |
| if assistant_stopped: | |
| global the_input_box | |
| if ( | |
| the_input_box.toPlainText().endswith("?") | |
| and is_continuously_conversations_setting_active() | |
| ): | |
| self.button_handler.toggle_recording( | |
| no_screenshot=True, new_record=True | |
| ) | |
| if new_state == "idle": | |
| click_sound() | |
| def pulse_circle(self): | |
| self.pulse_frame = (self.pulse_frame + 1) % 100 | |
| self.update() | |
| def collapse_gca(self): | |
| self.collapse = True | |
| self.collapse_window() | |
| activate_collapse_setting() | |
| self.update_screen() | |
| def collapse_gca_api(self): | |
| self.worker_collapse.the_input_text = "True" | |
| def uncollapse_gca(self): | |
| self.collapse = False | |
| print() | |
| # hide all buttons and input box | |
| the_input_box.show() | |
| self.settingsButton.show() | |
| self.llmsettingsButton.show() | |
| deactivate_collapse_setting() | |
| self.update_screen() | |
| def uncollapse_gca_api(self): | |
| self.worker_uncollapse.the_input_text = "True" | |
| def show_logo(self): | |
| self.the_image.setPixmap(QtGui.QPixmap(load_logo_file_path()).scaled(25, 25)) | |
| self.the_image.show() | |
| self.update_screen() | |
| def tray_and_task_bar_logo(self): | |
| app_icon = QtGui.QIcon() | |
| app_icon.addFile(load_logo_file_path(), QtCore.QSize(48, 48)) | |
| self.the_app.setWindowIcon(app_icon) | |
| self.tray.setIcon(app_icon) | |
| self.tray_icon = app_icon | |
| self.tray_active_icon = app_icon | |
| print("ICON Set", load_logo_file_path()) | |
| def tray_and_task_bar_logo_api(self): | |
| self.worker_tray_and_task_bar_logo.the_input_text = "True" | |
| def show_logo_api(self): | |
| self.worker_show_logo.the_input_text = "True" | |
| def hide_logo(self): | |
| self.the_image.hide() | |
| self.update_screen() | |
| def hide_logo_api(self): | |
| self.worker_hide_logo.the_input_text = "True" | |
| def activate_long_gca(self): | |
| activate_long_gca_setting() | |
| self.update_screen() | |
| def activate_long_gca_api(self): | |
| self.worker_activate_long_gca.the_input_text = "True" | |
| def deactivate_long_gca(self): | |
| deactivate_long_gca_setting() | |
| self.update_screen() | |
| def deactivate_long_gca_api(self): | |
| self.worker_deactivate_long_gca.the_input_text = "True" | |
| def update_screen(self): | |
| width = 210 | |
| height = 320 | |
| if is_logo_active_setting_active(): | |
| height += 35 | |
| if is_collapse_setting_active(): | |
| height = 150 | |
| if is_logo_active_setting_active(): | |
| height += 35 | |
| if is_long_gca_setting_active(): | |
| if not is_collapse_setting_active(): | |
| height += 500 | |
| self.input_box.setFixedHeight(580) | |
| else: | |
| self.input_box.setFixedHeight(80) | |
| self.setFixedSize(width, height) | |
| self.put_location() | |
| def put_window_to_right_side_of_screen(self): | |
| screen = QDesktopWidget().screenGeometry() | |
| window = self.frameGeometry() | |
| # Calculate x position for the right side of the screen and center vertically | |
| x = screen.width() - window.width() # To right side | |
| y = (screen.height() - window.height()) // 2 # Center vertically | |
| # Add a small offset to the right side | |
| x -= 10 | |
| self.move(x, y) | |