Skip to content

Commit bf8ee46

Browse files
Add files via upload
1 parent 1baad76 commit bf8ee46

1 file changed

Lines changed: 86 additions & 9 deletions

File tree

Secure_Pass_Pro4.0.pyw

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ LANGUAGES: Dict[str, Dict[str, str]] = {
123123
"sound_on": "Звук: ВКЛ", "sound_off": "Звук: ВЫКЛ",
124124
"theme_sys": "Системная", "theme_dark": "Тёмная", "theme_light": "Светлая",
125125
"about_text": "Secure Pass Pro v4.0\n\nПрофессиональный инструмент для генерации паролей.\nИспользует криптографически стойкие алгоритмы.",
126-
"copied": "Скопировано! (60с)",
126+
"copied": "Скопировано! ({0}с)",
127127
"strength": "Стойкость: ~{0} вариантов",
128128
"crack_time": "{0}",
129129
"time_sec": "Несколько секунд на взлом",
@@ -179,6 +179,8 @@ LANGUAGES: Dict[str, Dict[str, str]] = {
179179
"integrity_fail": "🚨 КРИТИЧЕСКАЯ ОШИБКА: Файл повреждён или подменён!\nКонтрольная сумма не совпадает. Открытие отменено.",
180180
"integrity_ok": "✅ Целостность файла подтверждена.",
181181
"tt_eye": "Показать / скрыть пароль",
182+
"clip_timeout": "Очистка буфера: {0} сек",
183+
"tt_clip_timeout": "Через сколько секунд буфер обмена будет очищен после копирования",
182184
},
183185
"EN": {
184186
"win_title": "Secure Pass Pro v4.0",
@@ -207,7 +209,7 @@ LANGUAGES: Dict[str, Dict[str, str]] = {
207209
"sound_on": "Sound: ON", "sound_off": "Sound: OFF",
208210
"theme_sys": "System", "theme_dark": "Dark", "theme_light": "Light",
209211
"about_text": "Secure Pass Pro v4.0\n\nProfessional password generation tool.\nUses cryptographically secure algorithms.",
210-
"copied": "Copied! (60s)",
212+
"copied": "Copied! ({0}s)",
211213
"strength": "Strength: ~{0} combos",
212214
"crack_time": "{0}",
213215
"time_sec": "A few seconds to crack",
@@ -263,6 +265,8 @@ LANGUAGES: Dict[str, Dict[str, str]] = {
263265
"integrity_fail": "🚨 CRITICAL ERROR: File is corrupted or tampered!\nChecksum mismatch. Opening cancelled.",
264266
"integrity_ok": "✅ File integrity verified.",
265267
"tt_eye": "Show / hide password",
268+
"clip_timeout": "Clipboard clear: {0} sec",
269+
"tt_clip_timeout": "Seconds before clipboard is cleared after copying",
266270
},
267271
"UA": {
268272
"win_title": "Secure Pass Pro v4.0",
@@ -291,7 +295,7 @@ LANGUAGES: Dict[str, Dict[str, str]] = {
291295
"sound_on": "Звук: ВКЛ", "sound_off": "Звук: ВИКЛ",
292296
"theme_sys": "Системна", "theme_dark": "Темна", "theme_light": "Світла",
293297
"about_text": "Secure Pass Pro v4.0\n\nПрофесійний інструмент для генерації паролів.\nВикористовує криптографічно стійкі алгоритми.",
294-
"copied": "Скопійовано! (60с)",
298+
"copied": "Скопійовано! ({0}с)",
295299
"strength": "Стійкість: ~{0} варіантів",
296300
"crack_time": "{0}",
297301
"time_sec": "Кілька секунд на злам",
@@ -347,6 +351,8 @@ LANGUAGES: Dict[str, Dict[str, str]] = {
347351
"integrity_fail": "🚨 КРИТИЧНА ПОМИЛКА: Файл пошкоджений або підмінений!\nКонтрольна сума не збігається. Відкриття скасовано.",
348352
"integrity_ok": "✅ Цілісність файлу підтверджена.",
349353
"tt_eye": "Показати / приховати пароль",
354+
"clip_timeout": "Очищення буфера: {0} сек",
355+
"tt_clip_timeout": "Через скільки секунд буфер обміну буде очищено після копіювання",
350356
}
351357
}
352358

@@ -480,6 +486,7 @@ class SecurePassPro(ctk.CTk):
480486
self.history = deque(maxlen=HISTORY_MAX)
481487
self._radius_widgets = []
482488
self._clipboard_timer = None
489+
self.clipboard_timeout = 60 # секунд / seconds / секунд (10–120)
483490
self._tooltips = {}
484491
self._icon_image = None
485492
self._pdf_font_path = self._get_resource_path("DejaVuSans.ttf")
@@ -646,6 +653,37 @@ class SecurePassPro(ctk.CTk):
646653
elif line.startswith("SOUND="):
647654
sound_val = line.strip().split("=")[1].lower() == "true"
648655
self.sound_enabled.set(sound_val)
656+
elif line.startswith("CLIP_TIMEOUT="):
657+
try:
658+
t = int(line.strip().split("=")[1])
659+
if 10 <= t <= 120:
660+
self.clipboard_timeout = t
661+
except ValueError:
662+
pass
663+
except:
664+
pass
665+
666+
def _save_clipboard_timeout(self, seconds: int):
667+
"""
668+
Сохраняет таймаут ТОЛЬКО если config.txt уже существует.
669+
Saves timeout ONLY if config.txt already exists — never creates the file.
670+
Зберігає таймаут ТІЛЬКИ якщо config.txt вже існує.
671+
"""
672+
try:
673+
config_dir = os.path.join(os.path.expanduser("~"), ".securepasspro")
674+
config_file = os.path.join(config_dir, "config.txt")
675+
if not os.path.exists(config_file):
676+
return # Файл не существует — не создаём / Don't create
677+
existing = {}
678+
with open(config_file, "r", encoding="utf-8") as f:
679+
for line in f:
680+
if "=" in line:
681+
key, val = line.strip().split("=", 1)
682+
existing[key] = val
683+
existing["CLIP_TIMEOUT"] = str(seconds)
684+
with open(config_file, "w", encoding="utf-8") as f:
685+
for key, val in existing.items():
686+
f.write(f"{key}={val}\n")
649687
except:
650688
pass
651689

@@ -1050,7 +1088,7 @@ class SecurePassPro(ctk.CTk):
10501088
self.settings_window.focus_force()
10511089
self.settings_window.grab_set()
10521090

1053-
self._center_window_relative_to_parent(self.settings_window, 420, 480)
1091+
self._center_window_relative_to_parent(self.settings_window, 420, 580)
10541092
self._apply_window_rounding(self.settings_window)
10551093

10561094
self.settings_window.protocol("WM_DELETE_WINDOW", self._close_settings)
@@ -1162,8 +1200,27 @@ class SecurePassPro(ctk.CTk):
11621200
corner_radius=10
11631201
)
11641202
close_btn.pack(pady=(5, 10))
1165-
1166-
# --- Секция мастер-пароля / Master password section / Секція майстер-пароля ---
1203+
1204+
# --- Секция таймаута буфера / Clipboard timeout section / Секція таймауту буфера ---
1205+
sep_clip = ctk.CTkFrame(main_frame, height=2, fg_color="gray")
1206+
sep_clip.pack(fill="x", pady=8)
1207+
1208+
clip_timeout_label = ctk.CTkLabel(
1209+
main_frame,
1210+
text=L["clip_timeout"].format(self.clipboard_timeout),
1211+
font=("Segoe UI", 16, "bold")
1212+
)
1213+
clip_timeout_label.pack(pady=(8, 5))
1214+
self._clip_timeout_label_ref = clip_timeout_label
1215+
1216+
clip_slider = ctk.CTkSlider(
1217+
main_frame, from_=10, to=120,
1218+
number_of_steps=110,
1219+
width=300,
1220+
command=self._on_clip_timeout_change
1221+
)
1222+
clip_slider.set(self.clipboard_timeout)
1223+
clip_slider.pack(pady=(0, 10))
11671224
sep4 = ctk.CTkFrame(main_frame, height=2, fg_color="gray")
11681225
sep4.pack(fill="x", pady=8)
11691226

@@ -1193,6 +1250,23 @@ class SecurePassPro(ctk.CTk):
11931250
'radius_slider': radius_slider
11941251
}
11951252

1253+
def _on_clip_timeout_change(self, val):
1254+
"""
1255+
Обработчик слайдера таймаута буфера обмена.
1256+
Clipboard timeout slider handler.
1257+
Обробник слайдера таймауту буфера обміну.
1258+
"""
1259+
seconds = int(val)
1260+
self.clipboard_timeout = seconds
1261+
if hasattr(self, '_clip_timeout_label_ref') and \
1262+
self._clip_timeout_label_ref and \
1263+
self._clip_timeout_label_ref.winfo_exists():
1264+
L = LANGUAGES[self.current_lang]
1265+
self._clip_timeout_label_ref.configure(
1266+
text=L["clip_timeout"].format(seconds)
1267+
)
1268+
self._save_clipboard_timeout(seconds)
1269+
11961270
def _on_radius_change(self, val):
11971271
"""Handle radius slider change"""
11981272
rad = int(val)
@@ -1491,10 +1565,13 @@ class SecurePassPro(ctk.CTk):
14911565
self.after_cancel(self._clipboard_timer)
14921566
except:
14931567
pass
1494-
self._clipboard_timer = self.after(60000, lambda value=pwd: self._clear_clipboard_if_current(value))
1495-
1568+
self._clipboard_timer = self.after(
1569+
self.clipboard_timeout * 1000,
1570+
lambda value=pwd: self._clear_clipboard_if_current(value)
1571+
)
1572+
14961573
old_text = L["btn_copy"]
1497-
self.btn_copy.configure(text=L["copied"])
1574+
self.btn_copy.configure(text=L["copied"].format(self.clipboard_timeout))
14981575
self.after(2000, lambda: self.btn_copy.configure(text=old_text))
14991576

15001577
def _clear_clipboard_if_current(self, expected):

0 commit comments

Comments
 (0)