33from PyQt6 .QtWidgets import (
44 QApplication ,
55 QComboBox ,
6+ QCheckBox ,
67 QDialog ,
78 QFileDialog ,
89 QFrame ,
910 QHBoxLayout ,
1011 QLabel ,
12+ QLineEdit ,
1113 QMessageBox ,
1214 QPushButton ,
1315 QTextEdit ,
1416 QVBoxLayout ,
1517)
16- from PyQt6 .QtCore import Qt , pyqtSignal
17- from PyQt6 .QtGui import QFont
18+ from PyQt6 .QtCore import Qt , pyqtSignal , QRegularExpression , QUrl
19+ from PyQt6 .QtGui import QFont , QRegularExpressionValidator , QDesktopServices
20+ import sys
1821
1922from lufus import state as states
2023from lufus .gui .constants import THEME_DIR , _find_resource_dir
2124from lufus .gui .scale import Scale
25+ from lufus .lufus_logging import get_logger
2226
2327
2428class LogWindow (QDialog ):
@@ -28,7 +32,6 @@ def __init__(self, parent=None):
2832 self ._T = parent ._T if parent else {}
2933 self ._S : Scale = parent ._S if parent else None
3034 self .setWindowTitle (self ._T .get ("log_window_title" , "Log Window" ))
31-
3235 if self ._S :
3336 # apply scaled dimensions
3437 self .resize (self ._S .px (650 ), self ._S .px (450 ))
@@ -139,13 +142,32 @@ def __init__(self, parent=None):
139142 sep .setFrameShadow (QFrame .Shadow .Sunken )
140143 layout .addWidget (sep )
141144
145+ # version
146+ lbl_ver = QLabel (states .version )
147+ lbl_ver .setStyleSheet (f"font-family: { font_family } ; font-size: { tool_pt } pt;" )
148+ lbl_ver .setAlignment (Qt .AlignmentFlag .AlignCenter )
149+ layout .addWidget (lbl_ver )
150+
142151 # im lying ily (context text something area, whatever)
143152 self .about_text = QTextEdit ()
144153 self .about_text .setReadOnly (True )
145154 self .about_text .setObjectName ("aboutContent" )
146155 self .about_text .setFrameShape (QFrame .Shape .NoFrame )
147156 self .about_text .setStyleSheet (f"font-family: { font_family } ; font-size: { tool_pt } pt;" )
148157 layout .addWidget (self .about_text , 1 )
158+ btn_row0 = QHBoxLayout ()
159+ btn_discord = QPushButton (self ._T .get ("btn_discord" , "Join Discord Server" ))
160+ btn_discord .setFixedWidth (self ._S .px (300 ) if self ._S else 90 )
161+ btn_discord .clicked .connect (self .discord_open )
162+ btn_row0 .addWidget (btn_discord , alignment = Qt .AlignmentFlag .AlignCenter )
163+ layout .addLayout (btn_row0 )
164+
165+ btn_row1 = QHBoxLayout ()
166+ btn_github = QPushButton (self ._T .get ("btn_github" , "Open Github Repo" ))
167+ btn_github .setFixedWidth (self ._S .px (300 ) if self ._S else 90 )
168+ btn_github .clicked .connect (self .github_open )
169+ btn_row1 .addWidget (btn_github , alignment = Qt .AlignmentFlag .AlignCenter )
170+ layout .addLayout (btn_row1 )
149171
150172 btn_row = QHBoxLayout ()
151173 # close button or smth, whatever
@@ -154,9 +176,16 @@ def __init__(self, parent=None):
154176 btn_close .clicked .connect (self .hide )
155177 btn_row .addWidget (btn_close , alignment = Qt .AlignmentFlag .AlignCenter )
156178 layout .addLayout (btn_row )
157-
158179 self .setLayout (layout )
159180
181+ def discord_open (self ):
182+ url = QUrl ("https://discord.gg/4G6FeBwsxb" )
183+ QDesktopServices .openUrl (url )
184+
185+ def github_open (self ):
186+ url = QUrl ("https://github.com/Hog185/Lufus" )
187+ QDesktopServices .openUrl (url )
188+
160189
161190class SettingsDialog (QDialog ):
162191 # signals for when settings change :D
@@ -246,3 +275,102 @@ def _detect_themes():
246275 # user themes follow the same folder structure :D
247276 custom = sorted (p .parent .name for p in user_themes_dir .glob ("*/*_theme.json" ))
248277 return builtin , custom
278+
279+
280+ class WinTweaks (QDialog ):
281+ def __init__ (self , parent = None ):
282+ super ().__init__ (parent )
283+ re = QRegularExpression ("^[a-zA-Z0-9_]*$" )
284+ validator = QRegularExpressionValidator (re )
285+ self .setWindowTitle ("Windows Tweaks (MAY BREAK! USE CAUTION)" )
286+ self .setFixedSize (600 , 300 )
287+ self .ask_label = QLabel ("Do you want to customize your windows installation?" )
288+ self .hardware_checkbox = QCheckBox ("Remove requirement for 4GB+ RAM, Secure Boot and TPM 2.0" )
289+ self .hardware_checkbox .stateChanged .connect (self .update_winhardware )
290+ self .microsoft_checkbox = QCheckBox ("Remove requirement for an online Microsoft Account" )
291+ self .microsoft_checkbox .stateChanged .connect (self .update_winmicrosoftacc )
292+ self .localacc_checkbox = QCheckBox ("Create a local account with username:" )
293+ self .localacc_checkbox .stateChanged .connect (self .update_winlocalaccchk )
294+ self .username_input = QLineEdit ()
295+ self .username_input .setMaxLength (20 )
296+ self .username_input .setValidator (validator )
297+ self .username_input .setPlaceholderText ("Enter username here..." )
298+ self .microsoft_checkbox .toggled .connect (self .localacc_checkbox .setEnabled )
299+ self .localacc_checkbox .toggled .connect (self .username_input .setEnabled )
300+ self .username_input .setEnabled (self .localacc_checkbox .isChecked ())
301+ self .username_input .textChanged .connect (self .sync_username )
302+ self .data_checkbox = QCheckBox ("Disable data collection (skip privacy questions)" )
303+ self .data_checkbox .stateChanged .connect (self .update_winprivacy )
304+ self .applytweaks_btn = QPushButton ("Apply" )
305+ self .applytweaks_btn .clicked .connect (self .applywintweaks )
306+ self .canceltweaks_btn = QPushButton ("Cancel" )
307+ self .canceltweaks_btn .clicked .connect (self .reject ) # closes window
308+ layout = QVBoxLayout ()
309+ layout .setSpacing (15 )
310+ layout .setContentsMargins (20 , 20 , 20 , 20 )
311+ layout .addWidget (self .ask_label , alignment = Qt .AlignmentFlag .AlignCenter )
312+ layout .addWidget (self .hardware_checkbox )
313+ layout .addWidget (self .microsoft_checkbox )
314+ layout .addWidget (self .localacc_checkbox )
315+ layout .addWidget (self .username_input )
316+ layout .addWidget (self .data_checkbox )
317+ button_layout = QHBoxLayout ()
318+ button_layout .addWidget (self .applytweaks_btn )
319+ button_layout .addWidget (self .canceltweaks_btn )
320+ layout .addLayout (button_layout )
321+ layout .addStretch (1 )
322+ self .setLayout (layout )
323+
324+ def log_message (self , msg ):
325+ # delegate logging to parent window if available, otherwise use module logger
326+ parent = self .parent ()
327+ if parent is not None and hasattr (parent , "log_message" ):
328+ parent .log_message (msg )
329+ else :
330+ get_logger ("wintweaks" ).info (msg )
331+
332+ def update_winhardware (self ):
333+ # update winhardware req disable setting
334+ states .win_hardware_bypass = 1 if self .hardware_checkbox .isChecked () else 0
335+ self .log_message (
336+ f"Windows hardware requirement disable: { 'enabled' if self .hardware_checkbox .isChecked () else 'disabled' } "
337+ )
338+
339+ def update_winmicrosoftacc (self ):
340+ # update microsoft acc disable setting
341+ states .win_microsoft_acc = 1 if self .microsoft_checkbox .isChecked () else 0
342+ self .log_message (
343+ f"Microsoft account requirement disable: { 'enabled' if self .microsoft_checkbox .isChecked () else 'disabled' } "
344+ )
345+
346+ def update_winlocalaccchk (self ):
347+ # update local acc setting
348+ states .win_local_acc_chk = 1 if self .localacc_checkbox .isChecked () else 0
349+ self .log_message (
350+ f"Windows Local Account Add: { 'enabled' if self .localacc_checkbox .isChecked () else 'disabled' } "
351+ )
352+
353+ def sync_username (self , new_username ):
354+ # changes local username
355+ states .win_local_acc = new_username
356+
357+ def update_winprivacy (self ):
358+ # update win privacy setting
359+ states .win_privacy = 1 if self .data_checkbox .isChecked () else 0
360+ self .log_message (
361+ f"Windows privacy questions disable: { 'enabled' if self .data_checkbox .isChecked () else 'disabled' } "
362+ )
363+ # main tweaks apply logic function
364+
365+ def applywintweaks (self ):
366+ # closes window
367+ self .accept ()
368+
369+
370+ # for debug
371+ # if __name__ == "__main__":
372+ # # Standard boilerplate for testing the class standalone
373+ # app = QApplication(sys.argv)
374+ # window = WinTweaks()
375+ # window.exec()
376+ # sys.exit(app.exec())
0 commit comments