Skip to content

Commit

Permalink
Update translations for Chinese, English, French, Norwegian, and UI c…
Browse files Browse the repository at this point in the history
…ode, add Mistake Percentage
  • Loading branch information
LyubomirT committed Aug 4, 2024
1 parent 0684dd3 commit 96c9802
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 12 deletions.
43 changes: 36 additions & 7 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
import time
import random
import string
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal
from ui import Ui_MainWindow
Expand All @@ -10,13 +11,14 @@ class TypingThread(QThread):
progress = pyqtSignal(int)
finished = pyqtSignal()

def __init__(self, text, interval, type_enter, chars_per_stroke, randomize_interval):
def __init__(self, text, interval, type_enter, chars_per_stroke, randomize_interval, mistake_percentage):
super().__init__()
self.text = text
self.interval = interval
self.type_enter = type_enter
self.chars_per_stroke = chars_per_stroke
self.randomize_interval = randomize_interval
self.mistake_percentage = mistake_percentage
self.running = True
self.keyboard = Controller()

Expand All @@ -29,7 +31,7 @@ def run(self):
i += 1
else:
chunk = self.text[i:i + self.chars_per_stroke]
self.keyboard.type(chunk)
self.type_with_mistake(chunk)
i += self.chars_per_stroke

if self.randomize_interval:
Expand All @@ -41,6 +43,32 @@ def run(self):
self.progress.emit(int(i / len(self.text) * 100))
self.finished.emit()

def type_with_mistake(self, chunk):
for char in chunk:
if random.random() < self.mistake_percentage / 100:
# Make a typo
wrong_char = random.choice(string.ascii_lowercase)
self.keyboard.type(wrong_char)
time.sleep(self.interval * 2) # Pause after typo

# Type a few more characters
extra_chars = ''.join(random.choices(string.ascii_lowercase, k=random.randint(1, 3)))
self.keyboard.type(extra_chars)
time.sleep(self.interval * 3) # Pause after extra chars

# Backspace to correct the mistake
for _ in range(len(extra_chars) + 1):
self.keyboard.press(Key.backspace)
self.keyboard.release(Key.backspace)
time.sleep(self.interval * 0.5)

# Type the correct character
self.keyboard.type(char)
else:
# Type normally
self.keyboard.type(char)
time.sleep(self.interval)

def stop(self):
self.running = False

Expand All @@ -64,19 +92,20 @@ def start_typing(self):
type_enter = self.enterCheckBox.isChecked()
chars_per_stroke = int(self.charPerStrokeSpinBox.value())
randomize_interval = self.randomizeIntervalCheckBox.isChecked()
mistake_percentage = int(self.mistakePercentageSpinBox.value())
except ValueError:
QMessageBox.critical(self, "Error", "Invalid input for delay, interval, or chars per stroke.")
QMessageBox.critical(self, "Error", "Invalid input for delay, interval, chars per stroke, or mistake percentage.")
return

self.startButton.setEnabled(False)
self.stopButton.setEnabled(True)
if delay > 0:
QTimer.singleShot(delay * 1000, lambda: self.initiate_typing(text, interval, type_enter, chars_per_stroke, randomize_interval))
QTimer.singleShot(delay * 1000, lambda: self.initiate_typing(text, interval, type_enter, chars_per_stroke, randomize_interval, mistake_percentage))
else:
self.initiate_typing(text, interval, type_enter, chars_per_stroke, randomize_interval)
self.initiate_typing(text, interval, type_enter, chars_per_stroke, randomize_interval, mistake_percentage)

def initiate_typing(self, text, interval, type_enter, chars_per_stroke, randomize_interval):
self.thread = TypingThread(text, interval, type_enter, chars_per_stroke, randomize_interval)
def initiate_typing(self, text, interval, type_enter, chars_per_stroke, randomize_interval, mistake_percentage):
self.thread = TypingThread(text, interval, type_enter, chars_per_stroke, randomize_interval, mistake_percentage)
self.thread.progress.connect(self.update_progress)
self.thread.finished.connect(self.typing_finished)
self.progressBar.setValue(0)
Expand Down
4 changes: 4 additions & 0 deletions src/translations/Chinese.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
{
"component": "randomizeIntervalCheckBox",
"text": "随机化间隔"
},
{
"component": "mistakePercentageLabel",
"text": "错误百分比:"
}
]
}
4 changes: 4 additions & 0 deletions src/translations/English.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
{
"component": "randomizeIntervalCheckBox",
"text": "Randomize Interval"
},
{
"component": "mistakePercentageLabel",
"text": "Mistake Percentage:"
}
]
}
4 changes: 4 additions & 0 deletions src/translations/French.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
{
"component": "randomizeIntervalCheckBox",
"text": "Intervalle Aléatoire"
},
{
"component": "mistakePercentageLabel",
"text": "Pourcentage d'erreur :"
}
]
}
4 changes: 4 additions & 0 deletions src/translations/Norwegian.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
{
"component": "randomizeIntervalCheckBox",
"text": "Tilfeldig Intervall"
},
{
"component": "mistakePercentageLabel",
"text": "Feilprosent:"
}
]
}
18 changes: 13 additions & 5 deletions src/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ def __init__(self):

def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(600, 500)
MainWindow.setMinimumSize(QtCore.QSize(600, 500))
MainWindow.setMaximumSize(QtCore.QSize(600, 500))
MainWindow.resize(600, 600)
MainWindow.setMinimumSize(QtCore.QSize(600, 600))
MainWindow.setMaximumSize(QtCore.QSize(600, 600))
MainWindow.setWindowIcon(QtGui.QIcon("logo.png"))
if sys.platform == "win32" and hasattr(ctypes.windll, "shell32"):
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("Chainsaw Human Typing")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")

self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 561, 461))
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 560, 560))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")

self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
Expand Down Expand Up @@ -74,6 +74,15 @@ def setupUi(self, MainWindow):
self.charPerStrokeSpinBox.setObjectName("charPerStrokeSpinBox")
self.settingsLayout.addWidget(self.charPerStrokeSpinBox)

self.mistakePercentageLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
self.mistakePercentageLabel.setObjectName("mistakePercentageLabel")
self.settingsLayout.addWidget(self.mistakePercentageLabel)

self.mistakePercentageSpinBox = QtWidgets.QSpinBox(self.horizontalLayoutWidget)
self.mistakePercentageSpinBox.setRange(0, 100)
self.mistakePercentageSpinBox.setObjectName("mistakePercentageSpinBox")
self.settingsLayout.addWidget(self.mistakePercentageSpinBox)

self.randomizeIntervalCheckBox = QtWidgets.QCheckBox(self.horizontalLayoutWidget)
self.randomizeIntervalCheckBox.setObjectName("randomizeIntervalCheckBox")
self.settingsLayout.addWidget(self.randomizeIntervalCheckBox)
Expand Down Expand Up @@ -150,7 +159,6 @@ def change_language(self):
f.write(self.current_language)
self.update_ui_text()


def update_ui_text(self):
translation = self.translations.get(self.current_language, self.translations["English"])
for item in translation["MainWindow"]:
Expand Down

0 comments on commit 96c9802

Please sign in to comment.