def __init__(self): super().__init__() self.qscrollarea = QScrollArea(self) self.qscrollarea.setWidget(ScrollableSettingsWidget()) self.qscrollarea.setAlignment(Qt.AlignCenter) self.qscrollarea.setWidgetResizable(True) self.open_settings = PushButton("Open Advanced Settings") self.open_settings.clicked.connect(self._open_settings) self.sync_settings = PushButton("Sync Settings") self.sync_settings.clicked.connect(self._sync_settings) self.info = QLabel(self) # multiple spaces get shrunk to one space in rich text mode # https://groups.google.com/forum/#!topic/qtcontribs/VDOQFUj-eIA self.info.setText( f"circleguard v{__version__} | " "<a href=\"https://discord.gg/wj35ehD\">Discord</a>" " | <a href=\"https://github.com/circleguard/circleguard/\">Github</a>" ) self.info.setTextFormat(Qt.RichText) self.info.setTextInteractionFlags(Qt.TextBrowserInteraction) self.info.setOpenExternalLinks(True) self.info.setAlignment(Qt.AlignCenter) self.setting_buttons = WidgetCombiner(self.open_settings, self.sync_settings, self) layout = QGridLayout() layout.addWidget(self.info, 0, 0, 1, 1, alignment=Qt.AlignLeft) layout.addWidget(self.setting_buttons, 0, 1, 1, 1, alignment=Qt.AlignRight) layout.addWidget(self.qscrollarea, 1, 0, 1, 2) self.setLayout(layout)
def __init__(self, app): if CircleguardWindow.INSTANCE is not None: raise Exception("CirclegaurdWindow may only be instantiated once!") QMainWindow.__init__(self) LinkableSetting.__init__(self, ["log_save", "theme"]) # the circleguard window is our main window and it is sometimes useful # for other widgets to be able to interact with the main window # instance. Save ourself as a static var so other classes can access us. CircleguardWindow.INSTANCE = self # our QApplication, so we can set the theme from our widgets self.app = app # set the theme before initializing anything so it gets applied self.on_setting_changed("theme", self.setting_values["theme"]) self.clipboard = QApplication.clipboard() self.progressbar = QProgressBar() self.progressbar.setFixedWidth(250) self.current_state_label = QLabel("Idle") self.current_state_label.setTextFormat(Qt.RichText) self.current_state_label.setTextInteractionFlags( Qt.TextBrowserInteraction) self.current_state_label.setOpenExternalLinks(True) # statusBar() is a qt function that will create a status bar tied to the window # if it doesnt exist, and access the existing one if it does. self.statusBar().addWidget( WidgetCombiner(self.progressbar, self.current_state_label, self)) self.statusBar().setSizeGripEnabled(False) self.statusBar().setContentsMargins(8, 2, 10, 2) self.main_window = MainWidget() self.main_window.analysis_selection.set_progressbar_signal.connect( self.set_progressbar) self.main_window.analysis_selection.increment_progressbar_signal.connect( self.increment_progressbar) self.main_window.analysis_selection.update_label_signal.connect( self.update_label) # we reference this widget a lot, so shorten its reference as a # convenience self.cg_classic = self.main_window.cg_classic self.cg_classic.main_tab.set_progressbar_signal.connect( self.set_progressbar) self.cg_classic.main_tab.increment_progressbar_signal.connect( self.increment_progressbar) self.cg_classic.main_tab.update_label_signal.connect(self.update_label) self.cg_classic.main_tab.add_result_signal.connect(self.add_result) self.cg_classic.main_tab.add_url_analysis_result_signal.connect( self.add_url_analysis_result) self.cg_classic.main_tab.add_run_to_queue_signal.connect( self.add_run_to_queue) self.cg_classic.main_tab.update_run_status_signal.connect( self.update_run_status) self.cg_classic.queue_tab.cancel_run_signal.connect(self.cancel_run) self.cg_classic.queue_tab.run_priorities_updated.connect( self.update_run_priority) self.setCentralWidget(self.main_window) QShortcut(Qt.CTRL + Qt.Key_Right, self, self.tab_right) QShortcut(Qt.CTRL + Qt.Key_Left, self, self.tab_left) QShortcut(Qt.CTRL + Qt.Key_Q, self, app.quit) self.setWindowTitle(f"Circleguard v{__version__}") self.setWindowIcon(QIcon(resource_path("logo/logo.ico"))) self.start_timer() self.debug_window = None formatter = logging.Formatter(get_setting("log_format"), datefmt=get_setting("timestamp_format")) handler = Handler() handler.setFormatter(formatter) handler.new_message.connect(self.log) log_dir = get_setting("log_dir") log_file = os.path.join(log_dir, "circleguard.log") # 1 mb max file size, with 3 rotating files. self.file_handler = RotatingFileHandler(log_file, maxBytes=10**6, backupCount=3) self.file_handler.setFormatter(formatter) logging.getLogger("circleguard").addHandler(handler) logging.getLogger("circleguard").addHandler(self.file_handler) logging.getLogger("ossapi").addHandler(handler) logging.getLogger("ossapi").addHandler(self.file_handler) logging.getLogger("circleguard_gui").addHandler(handler) logging.getLogger("circleguard_gui").addHandler(self.file_handler) self.on_setting_changed("log_save", self.setting_values["log_save"]) self.thread = threading.Thread(target=self.run_update_check) self.thread.start() geometry = get_setting_raw("CircleguardWindow/geometry") if geometry: self.restoreGeometry(geometry) else: # if we don't know what size we were before, use 960x750 self.resize(960, 750)
def __init__(self): QFrame.__init__(self) SingleLinkableSetting.__init__(self, "api_key") # lazy loaded, see self#library self._library = None self.print_results_signal.connect(self.print_results) self.write_to_terminal_signal.connect(self.write) self.q = Queue() # `AnalysisResult`s get put here when we get a url scheme event, we need # to create the visualizer from the main thread so we use a queue to # kick back the work to the main thread. This is checked at the same # time `self.q` is self.url_analysis_q = Queue() # reset at the beginning of every run, used to print something after # every run only if a cheat wasn't found self.show_no_cheat_found = True self.print_results_event = threading.Event() self.cg_q = Queue() self.helper_thread_running = False self.runs = [] # Run objects for cancelling runs self.run_id = 0 self.visualizer = None terminal = QTextEdit(self) terminal.setFocusPolicy(Qt.ClickFocus) terminal.setReadOnly(True) terminal.ensureCursorVisible() self.terminal = terminal self.run_button = RunButton() self.run_button.setFixedHeight(30) self.run_button.setText("Run") font = self.run_button.font() font.setPointSize(15) self.run_button.setFont(font) self.run_button.clicked.connect(self.add_circleguard_run) # disable button if no api_key is stored self.on_setting_changed("api_key", get_setting("api_key")) investigate_label = QLabel("Investigate For:") investigate_label.setFixedWidth(130) investigate_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.investigation_checkboxes = InvestigationCheckboxes() investigations = WidgetCombiner(investigate_label, self.investigation_checkboxes, self) investigations.setFixedHeight(25) self.loadable_creation = LoadableCreation() self.investigation_checkboxes.similarity_cb.checkbox.stateChanged.connect(self.loadable_creation.similarity_cb_state_changed) layout = QGridLayout() layout.addWidget(investigations, 0, 0, 1, 16) layout.addWidget(self.loadable_creation, 1, 0, 4, 16) layout.addWidget(self.terminal, 5, 0, 2, 16) layout.addWidget(self.run_button, 7, 0, 1, 16) self.setLayout(layout)
def __init__(self, app): QMainWindow.__init__(self) LinkableSetting.__init__(self, ["log_save", "dark_theme"]) # our QApplication, so we can set the theme from our widgets self.app = app self.clipboard = QApplication.clipboard() self.progressbar = QProgressBar() self.progressbar.setFixedWidth(250) self.current_state_label = QLabel("Idle") self.current_state_label.setTextFormat(Qt.RichText) self.current_state_label.setTextInteractionFlags( Qt.TextBrowserInteraction) self.current_state_label.setOpenExternalLinks(True) # statusBar() is a qt function that will create a status bar tied to the window # if it doesnt exist, and access the existing one if it does. self.statusBar().addWidget( WidgetCombiner(self.progressbar, self.current_state_label, self)) self.statusBar().setSizeGripEnabled(False) self.statusBar().setContentsMargins(8, 2, 10, 2) self.main_window = MainWindow(self) self.main_window.main_tab.set_progressbar_signal.connect( self.set_progressbar) self.main_window.main_tab.increment_progressbar_signal.connect( self.increment_progressbar) self.main_window.main_tab.update_label_signal.connect( self.update_label) self.main_window.main_tab.add_result_signal.connect(self.add_result) self.main_window.main_tab.add_run_to_queue_signal.connect( self.add_run_to_queue) self.main_window.main_tab.update_run_status_signal.connect( self.update_run_status) self.main_window.queue_tab.cancel_run_signal.connect(self.cancel_run) self.setCentralWidget(self.main_window) QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Right), self, self.tab_right) QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Left), self, self.tab_left) QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q), self, app.quit) self.setWindowTitle(f"Circleguard v{__version__}") self.setWindowIcon(QIcon(resource_path("logo/logo.ico"))) self.start_timer() self.debug_window = None formatter = logging.Formatter(get_setting("log_format"), datefmt=get_setting("timestamp_format")) handler = Handler() handler.setFormatter(formatter) handler.new_message.connect(self.log) log_dir = get_setting("log_dir") log_file = os.path.join(log_dir, "circleguard.log") # 1 mb max file size, with 3 rotating files. self.file_handler = RotatingFileHandler(log_file, maxBytes=10**6, backupCount=3) self.file_handler.setFormatter(formatter) logging.getLogger("circleguard").addHandler(handler) logging.getLogger("circleguard").addHandler(self.file_handler) logging.getLogger("ossapi").addHandler(handler) logging.getLogger("ossapi").addHandler(self.file_handler) logging.getLogger(__name__).addHandler(handler) logging.getLogger(__name__).addHandler(self.file_handler) # apply setting values on application start self.on_setting_changed("log_save", self.setting_values["log_save"]) self.on_setting_changed("dark_theme", self.setting_values["dark_theme"]) self.thread = threading.Thread(target=self.run_update_check) self.thread.start()
def __init__(self): QFrame.__init__(self) SingleLinkableSetting.__init__(self, "api_key") # lazy loaded, see self#library self._library = None self.print_results_signal.connect(self.print_results) self.write_to_terminal_signal.connect(self.write) self.q = Queue() # `AnalysisResult`s get put here when we get a url scheme event, we need # to create the visualizer from the main thread so we use a queue to # kick back the work to the main thread. This is checked at the same # time `self.q` is self.url_analysis_q = Queue() # reset at the beginning of every run, used to print something after # every run only if a cheat wasn't found self.show_no_cheat_found = True self.print_results_event = threading.Event() self.cg_q = Queue() self.helper_thread_running = False # all run objects - finished, running, and queued. Kept for cancelling # runs and maybe a few other things like reordering runs. self.runs = [] self.run_id = 0 self.visualizer = None # okay this is definitely a hack, let me explain. We pass runs to our # helper thread via a queue, where we add items to the queue in the # order the runs are added to the queue. However, we allow users to # change the order of runs in the queue, which means their order in the # queue need to change so they got processed in the right order. # Queues don't offer any way to modify order of items in the queue, so # instead we have this hack: the helper thread takes all runs out from # the queue every time it checks the queue, and stores them in this # list. Then it checks against the priorities dictionary # ``run_priorities`` to see which run should be processed first. It # processes that run and removes it from the list. # A few notes: the runs list is ONLY for the helper thread and is never # touched by the main thread. The priorities dict is read-only from the # helper thread - only the main thread writes to it. self.helper_thread_runs = [] # mapping of run_id to run priority (int to int) self.run_priorities = {} terminal = QTextBrowser(self) terminal.setFocusPolicy(Qt.ClickFocus) terminal.setReadOnly(True) terminal.ensureCursorVisible() terminal.setOpenExternalLinks(True) self.terminal = terminal self.run_button = RunButton() self.run_button.setFixedHeight(30) self.run_button.setText("Run") font = self.run_button.font() font.setPointSize(15) self.run_button.setFont(font) self.run_button.clicked.connect(self.add_circleguard_run) # disable button if no api_key is stored self.on_setting_changed("api_key", get_setting("api_key")) investigate_label = QLabel("Investigate For:") investigate_label.setFixedWidth(130) investigate_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.investigation_checkboxes = InvestigationCheckboxes() investigations = WidgetCombiner(investigate_label, self.investigation_checkboxes, self) investigations.setFixedHeight(25) self.loadable_creation = LoadableCreation() self.investigation_checkboxes.similarity_cb.checkbox.stateChanged.connect( self.loadable_creation.similarity_cb_state_changed) layout = QGridLayout() layout.addWidget(investigations, 0, 0, 1, 16) layout.addWidget(self.loadable_creation, 1, 0, 4, 16) layout.addWidget(self.terminal, 5, 0, 2, 16) layout.addWidget(self.run_button, 7, 0, 1, 16) self.setLayout(layout)