frontengine 1.0.51__tar.gz → 1.0.52__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. {frontengine-1.0.51 → frontengine-1.0.52}/PKG-INFO +11 -1
  2. {frontengine-1.0.51 → frontengine-1.0.52}/README.md +10 -0
  3. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/app_profile_dialog.py +4 -0
  4. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/clipboard_dialog.py +7 -0
  5. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/reminder_dialog.py +4 -0
  6. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/remote_control_dialog.py +7 -0
  7. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/screen_privacy_dialog.py +15 -7
  8. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/screen_text_dialog.py +3 -0
  9. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/signage_dialog.py +6 -0
  10. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/smart_pause_dialog.py +5 -0
  11. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/usage_report_dialog.py +5 -0
  12. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/window_pin_dialog.py +12 -5
  13. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/main_ui.py +18 -2
  14. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/menu/help_menu.py +11 -9
  15. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/menu/how_to_menu.py +9 -9
  16. frontengine-1.0.52/frontengine/ui/menu/language_menu.py +64 -0
  17. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/menu/preset_menu.py +3 -0
  18. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/menu/settings_menu.py +20 -5
  19. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/control_center/control_center_ui.py +30 -31
  20. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/focus/focus_setting_ui.py +7 -0
  21. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/gif/gif_setting_ui.py +11 -0
  22. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/image/image_setting_ui.py +15 -0
  23. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/particle/particle_setting_ui.py +12 -0
  24. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/pet/pet_setting_ui.py +22 -0
  25. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/presentation/presentation_setting_ui.py +18 -0
  26. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_manager.py +6 -0
  27. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +11 -4
  28. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/gif.py +3 -0
  29. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/image.py +3 -0
  30. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/sound.py +3 -0
  31. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/text.py +3 -0
  32. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/video.py +3 -0
  33. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/web.py +3 -0
  34. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/screen_care/screen_care_setting_ui.py +13 -0
  35. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +16 -8
  36. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/text/text_setting_ui.py +18 -0
  37. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/tools/tools_setting_ui.py +28 -3
  38. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/video/video_setting_ui.py +12 -0
  39. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/wallpaper/wallpaper_setting_ui.py +14 -0
  40. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/web/web_setting_ui.py +13 -0
  41. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/widgets/widgets_setting_ui.py +12 -0
  42. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/language_wrapper.py +20 -2
  43. frontengine-1.0.52/frontengine/utils/multi_language/retranslate.py +143 -0
  44. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine.egg-info/PKG-INFO +11 -1
  45. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine.egg-info/SOURCES.txt +1 -0
  46. {frontengine-1.0.51 → frontengine-1.0.52}/pyproject.toml +1 -1
  47. frontengine-1.0.51/frontengine/ui/menu/language_menu.py +0 -57
  48. {frontengine-1.0.51 → frontengine-1.0.52}/LICENSE +0 -0
  49. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/__init__.py +0 -0
  50. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/__main__.py +0 -0
  51. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/__init__.py +0 -0
  52. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/base_widget.py +0 -0
  53. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/camera/__init__.py +0 -0
  54. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/camera/camera_widget.py +0 -0
  55. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/canvas/__init__.py +0 -0
  56. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/canvas/whiteboard_widget.py +0 -0
  57. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/capture/__init__.py +0 -0
  58. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/capture/region_capture.py +0 -0
  59. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/focus_shield/__init__.py +0 -0
  60. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/focus_shield/focus_shield_widget.py +0 -0
  61. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/gif/__init__.py +0 -0
  62. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/gif/paint_gif.py +0 -0
  63. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/image/__init__.py +0 -0
  64. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/image/paint_image.py +0 -0
  65. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/load/__init__.py +0 -0
  66. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/load/load_someone_make_ui.py +0 -0
  67. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/measure/__init__.py +0 -0
  68. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/measure/measure_widget.py +0 -0
  69. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/monitor/__init__.py +0 -0
  70. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/monitor/monitor_widget.py +0 -0
  71. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/notes/__init__.py +0 -0
  72. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/notes/sticky_note_widget.py +0 -0
  73. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/overlay_factory.py +0 -0
  74. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/particle/__init__.py +0 -0
  75. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/particle/particle_ui.py +0 -0
  76. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/pet/__init__.py +0 -0
  77. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/pet/desktop_pet.py +0 -0
  78. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/presentation/__init__.py +0 -0
  79. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/presentation/annotation_overlay.py +0 -0
  80. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/presentation/cursor_effects.py +0 -0
  81. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/presentation/keystroke_display.py +0 -0
  82. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/presentation/magnifier.py +0 -0
  83. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/scene/__init__.py +0 -0
  84. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/scene/extend_graphic_scene.py +0 -0
  85. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/scene/extend_graphic_view.py +0 -0
  86. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/scene/scene.py +0 -0
  87. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/screen_care/__init__.py +0 -0
  88. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/screen_care/color_vision_widget.py +0 -0
  89. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/screen_care/screen_filter.py +0 -0
  90. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/sound_player/__init__.py +0 -0
  91. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/sound_player/sound_effect.py +0 -0
  92. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/sound_player/sound_player.py +0 -0
  93. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/spectrum/__init__.py +0 -0
  94. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/spectrum/spectrum_widget.py +0 -0
  95. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/text/__init__.py +0 -0
  96. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/text/draw_text.py +0 -0
  97. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/toast/__init__.py +0 -0
  98. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/toast/toast_widget.py +0 -0
  99. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/video/__init__.py +0 -0
  100. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/video/video_player.py +0 -0
  101. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/wallpaper/__init__.py +0 -0
  102. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/wallpaper/wallpaper_widget.py +0 -0
  103. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/web/__init__.py +0 -0
  104. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/web/webview.py +0 -0
  105. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/show/window_helpers.py +0 -0
  106. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/system_tray/__init__.py +0 -0
  107. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/system_tray/extend_system_tray.py +0 -0
  108. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/__init__.py +0 -0
  109. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/color/__init__.py +0 -0
  110. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/color/global_color.py +0 -0
  111. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/__init__.py +0 -0
  112. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
  113. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
  114. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/menu/__init__.py +0 -0
  115. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/__init__.py +0 -0
  116. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/control_center/__init__.py +0 -0
  117. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/focus/__init__.py +0 -0
  118. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/gif/__init__.py +0 -0
  119. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/image/__init__.py +0 -0
  120. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/particle/__init__.py +0 -0
  121. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/pet/__init__.py +0 -0
  122. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/presentation/__init__.py +0 -0
  123. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/__init__.py +0 -0
  124. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
  125. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
  126. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
  127. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/screen_care/__init__.py +0 -0
  128. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/sound_player/__init__.py +0 -0
  129. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/text/__init__.py +0 -0
  130. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/tools/__init__.py +0 -0
  131. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/utils.py +0 -0
  132. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/video/__init__.py +0 -0
  133. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/wallpaper/__init__.py +0 -0
  134. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/web/__init__.py +0 -0
  135. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/ui/page/widgets/__init__.py +0 -0
  136. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/user_setting/__init__.py +0 -0
  137. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/user_setting/preset_repository.py +0 -0
  138. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/user_setting/scene_setting.py +0 -0
  139. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/user_setting/user_setting_file.py +0 -0
  140. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/__init__.py +0 -0
  141. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/app_profile/__init__.py +0 -0
  142. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/app_profile/app_profile_service.py +0 -0
  143. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/audio_meter/__init__.py +0 -0
  144. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/audio_meter/audio_envelope.py +0 -0
  145. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/audio_meter/loopback_capture.py +0 -0
  146. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/audio_meter/microphone_meter.py +0 -0
  147. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/audio_meter/screen_audio.py +0 -0
  148. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/audio_meter/spectrum_analyzer.py +0 -0
  149. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/audio_meter/system_audio_meter.py +0 -0
  150. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/autostart/__init__.py +0 -0
  151. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/autostart/autostart_service.py +0 -0
  152. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/break_reminder/__init__.py +0 -0
  153. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/break_reminder/break_reminder.py +0 -0
  154. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/browser/__init__.py +0 -0
  155. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/browser/browser.py +0 -0
  156. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/clipboard/__init__.py +0 -0
  157. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/clipboard/clipboard_history.py +0 -0
  158. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/clipboard/clipboard_watcher.py +0 -0
  159. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/color_vision/__init__.py +0 -0
  160. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/color_vision/color_vision.py +0 -0
  161. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/critical_exit/__init__.py +0 -0
  162. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
  163. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/critical_exit/critical_exit.py +0 -0
  164. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/critical_exit/win32_vk.py +0 -0
  165. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/exception/__init__.py +0 -0
  166. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/exception/exception_tags.py +0 -0
  167. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/exception/exceptions.py +0 -0
  168. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/focus_shield/__init__.py +0 -0
  169. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/focus_shield/focus_shield.py +0 -0
  170. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/focus_timer/__init__.py +0 -0
  171. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/focus_timer/focus_timer.py +0 -0
  172. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/hotkey/__init__.py +0 -0
  173. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/hotkey/hotkey_service.py +0 -0
  174. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/input_watch/__init__.py +0 -0
  175. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/input_watch/input_watch_service.py +0 -0
  176. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/json/__init__.py +0 -0
  177. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/json/json_file.py +0 -0
  178. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/json/json_repository.py +0 -0
  179. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/logging/__init__.py +0 -0
  180. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/logging/loggin_instance.py +0 -0
  181. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/measure/__init__.py +0 -0
  182. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/measure/measure.py +0 -0
  183. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/midi/__init__.py +0 -0
  184. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/midi/midi_input.py +0 -0
  185. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/__init__.py +0 -0
  186. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/english.py +0 -0
  187. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/france.py +0 -0
  188. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/germany.py +0 -0
  189. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/italy.py +0 -0
  190. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/russian.py +0 -0
  191. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
  192. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/multi_language/traditional_chinese.py +0 -0
  193. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/now_playing/__init__.py +0 -0
  194. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/now_playing/now_playing.py +0 -0
  195. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/pet_chat/__init__.py +0 -0
  196. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/pet_chat/pet_chat_service.py +0 -0
  197. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/platform_info/__init__.py +0 -0
  198. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/platform_info/platform_info.py +0 -0
  199. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/playlist/__init__.py +0 -0
  200. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/playlist/playlist.py +0 -0
  201. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/plugins/__init__.py +0 -0
  202. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/plugins/plugin_loader.py +0 -0
  203. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/power_mode/__init__.py +0 -0
  204. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/power_mode/power_mode.py +0 -0
  205. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/preset_schedule/__init__.py +0 -0
  206. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
  207. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/recording/__init__.py +0 -0
  208. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/recording/frame_recorder.py +0 -0
  209. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/recording/gif_writer.py +0 -0
  210. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/redirect_manager/__init__.py +0 -0
  211. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
  212. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/reminder/__init__.py +0 -0
  213. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/reminder/reminder_service.py +0 -0
  214. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/remote/__init__.py +0 -0
  215. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/remote/remote_server.py +0 -0
  216. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/screen_privacy/__init__.py +0 -0
  217. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/screen_privacy/capture_affinity.py +0 -0
  218. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/screen_privacy/share_watch.py +0 -0
  219. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/screen_text/__init__.py +0 -0
  220. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/screen_text/screen_text_service.py +0 -0
  221. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/signage/__init__.py +0 -0
  222. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/signage/signage_service.py +0 -0
  223. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/smart_pause/__init__.py +0 -0
  224. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/smart_pause/pause_rules.py +0 -0
  225. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
  226. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/system_stats/__init__.py +0 -0
  227. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/system_stats/system_stats.py +0 -0
  228. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/text_source/__init__.py +0 -0
  229. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/text_source/text_source.py +0 -0
  230. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/theme_schedule/__init__.py +0 -0
  231. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
  232. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/usage_tracking/__init__.py +0 -0
  233. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/usage_tracking/usage_service.py +0 -0
  234. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/usage_tracking/usage_tracker.py +0 -0
  235. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/virtual_camera/__init__.py +0 -0
  236. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/virtual_camera/camera_feed.py +0 -0
  237. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/virtual_camera/virtual_camera.py +0 -0
  238. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/weather/__init__.py +0 -0
  239. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/weather/weather_service.py +0 -0
  240. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/web_url.py +0 -0
  241. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/window_pin/__init__.py +0 -0
  242. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/window_pin/window_layout.py +0 -0
  243. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/window_pin/window_pin.py +0 -0
  244. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/workshop/__init__.py +0 -0
  245. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine/utils/workshop/workshop_content.py +0 -0
  246. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine.egg-info/dependency_links.txt +0 -0
  247. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine.egg-info/entry_points.txt +0 -0
  248. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine.egg-info/requires.txt +0 -0
  249. {frontengine-1.0.51 → frontengine-1.0.52}/frontengine.egg-info/top_level.txt +0 -0
  250. {frontengine-1.0.51 → frontengine-1.0.52}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frontengine
3
- Version: 1.0.51
3
+ Version: 1.0.52
4
4
  Summary: FrontEngine is use-define frontview or only use like screen saver
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/FrontEngine
@@ -185,6 +185,16 @@ that caps every overlay's refresh rate and drops its render resolution.
185
185
 
186
186
  ---
187
187
 
188
+ ## Languages
189
+
190
+ Seven: English, 繁體中文, 简体中文, Deutsch, Русский, Français, Italiano.
191
+
192
+ Pick one from the **Language** menu and the interface changes **immediately** —
193
+ no restart. Whatever you had open stays open: overlays keep running, and the
194
+ settings on every page are left exactly as they were.
195
+
196
+ ---
197
+
188
198
  ## Signage, whiteboard and lip-sync
189
199
 
190
200
  - **Signage mode** (Settings) — rotate through a list of presets on a timer and
@@ -161,6 +161,16 @@ that caps every overlay's refresh rate and drops its render resolution.
161
161
 
162
162
  ---
163
163
 
164
+ ## Languages
165
+
166
+ Seven: English, 繁體中文, 简体中文, Deutsch, Русский, Français, Italiano.
167
+
168
+ Pick one from the **Language** menu and the interface changes **immediately** —
169
+ no restart. Whatever you had open stays open: overlays keep running, and the
170
+ settings on every page are left exactly as they were.
171
+
172
+ ---
173
+
164
174
  ## Signage, whiteboard and lip-sync
165
175
 
166
176
  - **Signage mode** (Settings) — rotate through a list of presets on a timer and
@@ -20,6 +20,7 @@ from frontengine.user_setting.user_setting_file import user_setting_dict, write_
20
20
  from frontengine.utils.app_profile.app_profile_service import normalize_profiles
21
21
  from frontengine.utils.logging.loggin_instance import front_engine_logger
22
22
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
23
+ from frontengine.utils.multi_language.retranslate import retranslator
23
24
  from frontengine.utils.smart_pause.pause_rules import normalize_app_name
24
25
 
25
26
 
@@ -50,13 +51,16 @@ class AppProfileDialog(QDialog):
50
51
  self.table.horizontalHeader().setStretchLastSection(True)
51
52
 
52
53
  self.add_button = QPushButton(_t("app_profile_add", "Add"))
54
+ retranslator.bind(self.add_button, "app_profile_add", "Add")
53
55
  self.add_button.clicked.connect(lambda: self.add_row("", ""))
54
56
  self.remove_button = QPushButton(_t("app_profile_remove", "Remove"))
57
+ retranslator.bind(self.remove_button, "app_profile_remove", "Remove")
55
58
  self.remove_button.clicked.connect(self.remove_selected_row)
56
59
  self.hint_label = QLabel(
57
60
  _t("app_profile_hint",
58
61
  "Presets are saved from the Presets menu. Without any saved preset "
59
62
  "there is nothing to apply."))
63
+ retranslator.bind(self.hint_label, "app_profile_hint", "Presets are saved from the Presets menu. Without any saved preset " "there is nothing to apply.")
60
64
  self.hint_label.setWordWrap(True)
61
65
 
62
66
  self.button_box = QDialogButtonBox(
@@ -25,6 +25,7 @@ from frontengine.user_setting.user_setting_file import user_setting_dict, write_
25
25
  from frontengine.utils.clipboard.clipboard_history import ClipboardHistory, preview
26
26
  from frontengine.utils.logging.loggin_instance import front_engine_logger
27
27
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
28
+ from frontengine.utils.multi_language.retranslate import retranslator
28
29
 
29
30
  _PIN_MARK = "📌 "
30
31
 
@@ -51,16 +52,21 @@ class ClipboardDialog(QDialog):
51
52
  self.entry_list.itemDoubleClicked.connect(lambda _item: self.copy_selected())
52
53
 
53
54
  self.copy_button = QPushButton(_t("clipboard_copy", "Copy"))
55
+ retranslator.bind(self.copy_button, "clipboard_copy", "Copy")
54
56
  self.copy_button.clicked.connect(self.copy_selected)
55
57
  self.pin_button = QPushButton(_t("clipboard_pin", "Pin / unpin"))
58
+ retranslator.bind(self.pin_button, "clipboard_pin", "Pin / unpin")
56
59
  self.pin_button.clicked.connect(self.toggle_pin_selected)
57
60
  self.remove_button = QPushButton(_t("clipboard_remove", "Remove"))
61
+ retranslator.bind(self.remove_button, "clipboard_remove", "Remove")
58
62
  self.remove_button.clicked.connect(self.remove_selected)
59
63
  self.clear_button = QPushButton(_t("clipboard_clear", "Clear (keep pinned)"))
64
+ retranslator.bind(self.clear_button, "clipboard_clear", "Clear (keep pinned)")
60
65
  self.clear_button.clicked.connect(self.clear_history)
61
66
 
62
67
  self.persist_checkbox = QCheckBox(
63
68
  _t("clipboard_persist", "Keep this history between sessions"))
69
+ retranslator.bind(self.persist_checkbox, "clipboard_persist", "Keep this history between sessions")
64
70
  self.persist_checkbox.setChecked(bool(user_setting_dict.get("clipboard_persist")))
65
71
  self.persist_checkbox.toggled.connect(self._store_persist)
66
72
  self.hint_label = QLabel(
@@ -68,6 +74,7 @@ class ClipboardDialog(QDialog):
68
74
  "History stays on this machine and is never sent anywhere. Unless you tick "
69
75
  "the box above it is kept in memory only, because clipboards often hold "
70
76
  "passwords."))
77
+ retranslator.bind(self.hint_label, "clipboard_hint", "History stays on this machine and is never sent anywhere. Unless you tick " "the box above it is kept in memory only, because clipboards often hold " "passwords.")
71
78
  self.hint_label.setWordWrap(True)
72
79
 
73
80
  self.button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
@@ -19,6 +19,7 @@ from PySide6.QtWidgets import (
19
19
  from frontengine.user_setting.user_setting_file import user_setting_dict, write_user_setting
20
20
  from frontengine.utils.logging.loggin_instance import front_engine_logger
21
21
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
22
+ from frontengine.utils.multi_language.retranslate import retranslator
22
23
  from frontengine.utils.reminder.reminder_service import (
23
24
  KIND_AT, KIND_EVERY, normalize_reminder, normalize_reminders,
24
25
  )
@@ -55,13 +56,16 @@ class ReminderDialog(QDialog):
55
56
  self.table.horizontalHeader().setStretchLastSection(True)
56
57
 
57
58
  self.add_button = QPushButton(_t("reminder_add", "Add"))
59
+ retranslator.bind(self.add_button, "reminder_add", "Add")
58
60
  self.add_button.clicked.connect(lambda: self.add_row())
59
61
  self.remove_button = QPushButton(_t("reminder_remove", "Remove"))
62
+ retranslator.bind(self.remove_button, "reminder_remove", "Remove")
60
63
  self.remove_button.clicked.connect(self.remove_selected_row)
61
64
  self.hint_label = QLabel(
62
65
  _t("reminder_hint",
63
66
  "Tick a row to keep it active. \"Every\" takes minutes, \"At\" takes a "
64
67
  "24-hour time such as 14:30."))
68
+ retranslator.bind(self.hint_label, "reminder_hint", "Tick a row to keep it active. \"Every\" takes minutes, \"At\" takes a " "24-hour time such as 14:30.")
65
69
  self.hint_label.setWordWrap(True)
66
70
 
67
71
  self.button_box = QDialogButtonBox(
@@ -24,6 +24,7 @@ from frontengine.user_setting.user_setting_file import user_setting_dict, write_
24
24
  from frontengine.utils.logging.loggin_instance import front_engine_logger
25
25
  from frontengine.utils.midi.midi_input import available as midi_available, list_devices
26
26
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
27
+ from frontengine.utils.multi_language.retranslate import retranslator
27
28
  from frontengine.utils.remote.remote_server import ALLOWED_ACTIONS
28
29
 
29
30
  MIDI_KEY = "midi_bindings"
@@ -60,6 +61,7 @@ class RemoteControlDialog(QDialog):
60
61
  self._learning = False
61
62
 
62
63
  self.remote_checkbox = QCheckBox(_t("remote_enable", "Let my phone control FrontEngine"))
64
+ retranslator.bind(self.remote_checkbox, "remote_enable", "Let my phone control FrontEngine")
63
65
  self.remote_checkbox.setChecked(remote_enabled())
64
66
  self.remote_checkbox.toggled.connect(self._toggle_remote)
65
67
  self.remote_url_label = QLabel(self.remote_status())
@@ -67,6 +69,7 @@ class RemoteControlDialog(QDialog):
67
69
  self.remote_url_label.setTextInteractionFlags(
68
70
  self.remote_url_label.textInteractionFlags().TextSelectableByMouse)
69
71
  self.remote_copy_button = QPushButton(_t("remote_copy", "Copy link"))
72
+ retranslator.bind(self.remote_copy_button, "remote_copy", "Copy link")
70
73
  self.remote_copy_button.clicked.connect(self.copy_link)
71
74
  self.remote_hint = QLabel(
72
75
  _t("remote_hint",
@@ -75,18 +78,22 @@ class RemoteControlDialog(QDialog):
75
78
  "page can be triggered - nothing else. It is plain HTTP, so treat it like any "
76
79
  "other device on your network: someone else on the same network could read the "
77
80
  "token and press the same buttons. Leave it off on networks you do not trust."))
81
+ retranslator.bind(self.remote_hint, "remote_hint", "This opens a port on this machine for your local network. The link carries a " "one-time token that changes every time it starts, and only the buttons on the " "page can be triggered - nothing else. It is plain HTTP, so treat it like any " "other device on your network: someone else on the same network could read the " "token and press the same buttons. Leave it off on networks you do not trust.")
78
82
  self.remote_hint.setWordWrap(True)
79
83
 
80
84
  self.midi_label = QLabel(_t("remote_midi_label", "MIDI controller"))
85
+ retranslator.bind(self.midi_label, "remote_midi_label", "MIDI controller")
81
86
  self.midi_combobox = QComboBox()
82
87
  for index, name in list_devices():
83
88
  self.midi_combobox.addItem(name, index)
84
89
  if self.midi_combobox.count() == 0:
85
90
  self.midi_combobox.addItem(_t("remote_midi_none", "No MIDI device found"), -1)
86
91
  self.learn_button = QPushButton(_t("remote_midi_learn", "Learn"))
92
+ retranslator.bind(self.learn_button, "remote_midi_learn", "Learn")
87
93
  self.learn_button.clicked.connect(self.start_learning)
88
94
  self.learn_button.setEnabled(midi_available())
89
95
  self.remove_button = QPushButton(_t("remote_midi_remove", "Remove"))
96
+ retranslator.bind(self.remove_button, "remote_midi_remove", "Remove")
90
97
  self.remove_button.clicked.connect(self.remove_selected)
91
98
 
92
99
  self.table = QTableWidget(0, 2)
@@ -22,6 +22,7 @@ from PySide6.QtWidgets import (
22
22
  from frontengine.user_setting.user_setting_file import user_setting_dict, write_user_setting
23
23
  from frontengine.utils.logging.loggin_instance import front_engine_logger
24
24
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
25
+ from frontengine.utils.multi_language.retranslate import retranslator
25
26
  from frontengine.utils.screen_privacy import capture_affinity
26
27
  from frontengine.utils.screen_privacy.share_watch import DEFAULT_SHARING_APPS
27
28
  from frontengine.utils.smart_pause.pause_rules import parse_app_list
@@ -55,18 +56,25 @@ class ScreenPrivacyDialog(QDialog):
55
56
 
56
57
  self.enable_checkbox = QCheckBox(
57
58
  _t("screen_privacy_enable", "Hide overlays while one of these apps is open"))
59
+ retranslator.bind(self.enable_checkbox, "screen_privacy_enable", "Hide overlays while one of these apps is open")
58
60
  self.enable_checkbox.setChecked(bool(settings.get("enabled")))
59
61
  self.apps_label = QLabel(_t("screen_privacy_apps_label", "Meeting and capture apps:"))
62
+ retranslator.bind(self.apps_label, "screen_privacy_apps_label", "Meeting and capture apps:")
60
63
  self.apps_edit = QLineEdit(", ".join(settings.get("apps", [])))
61
64
  self.apps_edit.setPlaceholderText("zoom, teams, discord")
62
- self.hint_label = QLabel(
63
- _t("screen_privacy_hint",
64
- "Matched against window titles, so a meeting held in a browser tab is caught "
65
- "too. Your overlays stay on your own screen - only the capture is blank. "
66
- "Masks stay visible, since covering something is what they are for.")
65
+ # 提示句取決於平台支不支援,登記的必須是實際選到的那個鍵
66
+ # The hint depends on whether the platform supports this, so register
67
+ # whichever key was actually chosen.
68
+ hint_key, hint_fallback = (
69
+ ("screen_privacy_hint",
70
+ "Matched against window titles, so a meeting held in a browser tab is caught "
71
+ "too. Your overlays stay on your own screen - only the capture is blank. "
72
+ "Masks stay visible, since covering something is what they are for.")
67
73
  if capture_affinity.available() else
68
- _t("screen_privacy_unsupported",
69
- "Hiding overlays from screen capture is Windows only."))
74
+ ("screen_privacy_unsupported",
75
+ "Hiding overlays from screen capture is Windows only."))
76
+ self.hint_label = QLabel(_t(hint_key, hint_fallback))
77
+ retranslator.bind(self.hint_label, hint_key, hint_fallback)
70
78
  self.hint_label.setWordWrap(True)
71
79
 
72
80
  self.button_box = QDialogButtonBox(
@@ -24,6 +24,7 @@ from PySide6.QtWidgets import (
24
24
  from frontengine.user_setting.user_setting_file import user_setting_dict, write_user_setting
25
25
  from frontengine.utils.logging.loggin_instance import front_engine_logger
26
26
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
27
+ from frontengine.utils.multi_language.retranslate import retranslator
27
28
  from frontengine.utils.screen_text.screen_text_service import API_KEY_ENV, api_key
28
29
 
29
30
  CONSENT_KEY = "screen_text_consent"
@@ -78,9 +79,11 @@ class ScreenTextDialog(QDialog):
78
79
  self.text_edit = QPlainTextEdit(str(text))
79
80
  self.text_edit.setReadOnly(False)
80
81
  self.copy_button = QPushButton(_t("screen_text_copy", "Copy"))
82
+ retranslator.bind(self.copy_button, "screen_text_copy", "Copy")
81
83
  self.copy_button.clicked.connect(self.copy_text)
82
84
  self.consent_checkbox = QCheckBox(
83
85
  _t("screen_text_consent_toggle", "Allow sending captures to Anthropic"))
86
+ retranslator.bind(self.consent_checkbox, "screen_text_consent_toggle", "Allow sending captures to Anthropic")
84
87
  self.consent_checkbox.setChecked(has_consent())
85
88
  self.consent_checkbox.toggled.connect(set_consent)
86
89
  self.hint_label = QLabel(self.status_text())
@@ -15,6 +15,7 @@ from PySide6.QtWidgets import (
15
15
  from frontengine.user_setting.user_setting_file import user_setting_dict, write_user_setting
16
16
  from frontengine.utils.logging.loggin_instance import front_engine_logger
17
17
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
18
+ from frontengine.utils.multi_language.retranslate import retranslator
18
19
  from frontengine.utils.signage.signage_service import (
19
20
  DEFAULT_INTERVAL_MINUTES, MAX_INTERVAL_MINUTES, MIN_INTERVAL_MINUTES, clamp_interval,
20
21
  normalize_playlist,
@@ -52,20 +53,25 @@ class SignageDialog(QDialog):
52
53
  settings = current_settings()
53
54
 
54
55
  self.enable_checkbox = QCheckBox(_t("signage_enable", "Rotate presets"))
56
+ retranslator.bind(self.enable_checkbox, "signage_enable", "Rotate presets")
55
57
  self.enable_checkbox.setChecked(bool(settings.get("enabled")))
56
58
  self.presets_label = QLabel(_t("signage_presets_label", "Presets, one per line:"))
59
+ retranslator.bind(self.presets_label, "signage_presets_label", "Presets, one per line:")
57
60
  self.presets_edit = QPlainTextEdit("\n".join(settings.get("presets", [])))
58
61
  self.interval_label = QLabel(_t("signage_interval_label", "Change every (minutes)"))
62
+ retranslator.bind(self.interval_label, "signage_interval_label", "Change every (minutes)")
59
63
  self.interval_spinbox = QSpinBox()
60
64
  self.interval_spinbox.setRange(MIN_INTERVAL_MINUTES, MAX_INTERVAL_MINUTES)
61
65
  self.interval_spinbox.setValue(settings.get("interval_minutes"))
62
66
  self.hide_checkbox = QCheckBox(
63
67
  _t("signage_hide_window", "Hide the main window while rotating"))
68
+ retranslator.bind(self.hide_checkbox, "signage_hide_window", "Hide the main window while rotating")
64
69
  self.hide_checkbox.setChecked(bool(settings.get("hide_window", True)))
65
70
  self.hint_label = QLabel(
66
71
  _t("signage_hint",
67
72
  "Presets are saved from the Presets menu. The rotation wraps at the end, so a "
68
73
  "machine left running keeps cycling."))
74
+ retranslator.bind(self.hint_label, "signage_hint", "Presets are saved from the Presets menu. The rotation wraps at the end, so a " "machine left running keeps cycling.")
69
75
  self.hint_label.setWordWrap(True)
70
76
 
71
77
  self.button_box = QDialogButtonBox(
@@ -16,6 +16,7 @@ from PySide6.QtWidgets import (
16
16
  from frontengine.user_setting.user_setting_file import user_setting_dict, write_user_setting
17
17
  from frontengine.utils.logging.loggin_instance import front_engine_logger
18
18
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
19
+ from frontengine.utils.multi_language.retranslate import retranslator
19
20
  from frontengine.utils.smart_pause.pause_rules import DEFAULT_RULES, parse_app_list
20
21
 
21
22
 
@@ -44,17 +45,21 @@ class SmartPauseDialog(QDialog):
44
45
 
45
46
  self.fullscreen_checkbox = QCheckBox(
46
47
  _t("smart_pause_fullscreen", "Pause while a fullscreen app is running"))
48
+ retranslator.bind(self.fullscreen_checkbox, "smart_pause_fullscreen", "Pause while a fullscreen app is running")
47
49
  self.fullscreen_checkbox.setChecked(bool(rules.get("fullscreen", True)))
48
50
  self.battery_checkbox = QCheckBox(
49
51
  _t("smart_pause_battery", "Pause while running on battery"))
52
+ retranslator.bind(self.battery_checkbox, "smart_pause_battery", "Pause while running on battery")
50
53
  self.battery_checkbox.setChecked(bool(rules.get("battery", False)))
51
54
  self.apps_label = QLabel(
52
55
  _t("smart_pause_apps_label", "Pause while these apps have focus:"))
56
+ retranslator.bind(self.apps_label, "smart_pause_apps_label", "Pause while these apps have focus:")
53
57
  self.apps_edit = QLineEdit(", ".join(rules.get("apps", [])))
54
58
  self.apps_edit.setPlaceholderText("photoshop, premiere, blender")
55
59
  self.hint_label = QLabel(
56
60
  _t("smart_pause_hint",
57
61
  "Names are matched without the folder or .exe, so \"photoshop\" is enough."))
62
+ retranslator.bind(self.hint_label, "smart_pause_hint", "Names are matched without the folder or .exe, so \"photoshop\" is enough.")
58
63
  self.hint_label.setWordWrap(True)
59
64
 
60
65
  self.button_box = QDialogButtonBox(
@@ -20,6 +20,7 @@ from PySide6.QtWidgets import (
20
20
 
21
21
  from frontengine.utils.logging.loggin_instance import front_engine_logger
22
22
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
23
+ from frontengine.utils.multi_language.retranslate import retranslator
23
24
  from frontengine.utils.usage_tracking.usage_tracker import UsageTracker, format_duration
24
25
 
25
26
 
@@ -47,6 +48,7 @@ class UsageReportDialog(QDialog):
47
48
  self._on_clear = on_clear
48
49
 
49
50
  self.enable_checkbox = QCheckBox(_t("usage_enable", "Track which apps I use"))
51
+ retranslator.bind(self.enable_checkbox, "usage_enable", "Track which apps I use")
50
52
  self.enable_checkbox.setChecked(bool(enabled))
51
53
  self.enable_checkbox.toggled.connect(self._toggle)
52
54
 
@@ -64,13 +66,16 @@ class UsageReportDialog(QDialog):
64
66
  self.week_label = QLabel()
65
67
  self.week_label.setWordWrap(True)
66
68
  self.refresh_button = QPushButton(_t("usage_refresh", "Refresh"))
69
+ retranslator.bind(self.refresh_button, "usage_refresh", "Refresh")
67
70
  self.refresh_button.clicked.connect(self.reload_report)
68
71
  self.clear_button = QPushButton(_t("usage_clear", "Clear history"))
72
+ retranslator.bind(self.clear_button, "usage_clear", "Clear history")
69
73
  self.clear_button.clicked.connect(self.clear_history)
70
74
  self.hint_label = QLabel(
71
75
  _t("usage_hint",
72
76
  "This is stored on this machine only and is never sent anywhere. "
73
77
  "Clearing deletes the file itself."))
78
+ retranslator.bind(self.hint_label, "usage_hint", "This is stored on this machine only and is never sent anywhere. " "Clearing deletes the file itself.")
74
79
  self.hint_label.setWordWrap(True)
75
80
 
76
81
  self.button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
@@ -17,6 +17,7 @@ from PySide6.QtWidgets import (
17
17
 
18
18
  from frontengine.utils.logging.loggin_instance import front_engine_logger
19
19
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
20
+ from frontengine.utils.multi_language.retranslate import retranslator
20
21
  from frontengine.utils.window_pin import window_pin
21
22
 
22
23
 
@@ -37,25 +38,31 @@ class WindowPinDialog(QDialog):
37
38
  self.window_list = QListWidget()
38
39
  self.window_list.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
39
40
  self.refresh_button = QPushButton(_t("window_pin_refresh", "Refresh"))
41
+ retranslator.bind(self.refresh_button, "window_pin_refresh", "Refresh")
40
42
  self.refresh_button.clicked.connect(self.reload_windows)
41
43
  self.pin_button = QPushButton(_t("window_pin_pin", "Keep on top"))
44
+ retranslator.bind(self.pin_button, "window_pin_pin", "Keep on top")
42
45
  self.pin_button.clicked.connect(lambda: self.apply_pin(True))
43
46
  self.unpin_button = QPushButton(_t("window_pin_unpin", "Release"))
47
+ retranslator.bind(self.unpin_button, "window_pin_unpin", "Release")
44
48
  self.unpin_button.clicked.connect(lambda: self.apply_pin(False))
45
49
 
46
50
  self.opacity_label = QLabel(_t("window_pin_opacity", "Opacity"))
51
+ retranslator.bind(self.opacity_label, "window_pin_opacity", "Opacity")
47
52
  self.opacity_slider = QSlider(Qt.Orientation.Horizontal)
48
53
  self.opacity_slider.setRange(window_pin.MIN_OPACITY_PERCENT,
49
54
  window_pin.MAX_OPACITY_PERCENT)
50
55
  self.opacity_slider.setValue(window_pin.MAX_OPACITY_PERCENT)
51
56
  self.opacity_slider.valueChanged.connect(self.apply_opacity)
52
57
 
53
- self.hint_label = QLabel(
54
- _t("window_pin_hint",
55
- "Pinning changes how a window is stacked and how see-through it is. "
56
- "Windows only - other systems do not allow it.")
58
+ hint_key, hint_fallback = (
59
+ ("window_pin_hint",
60
+ "Pinning changes how a window is stacked and how see-through it is. "
61
+ "Windows only - other systems do not allow it.")
57
62
  if window_pin.available() else
58
- _t("window_pin_unsupported", "Pinning other windows is Windows only."))
63
+ ("window_pin_unsupported", "Pinning other windows is Windows only."))
64
+ self.hint_label = QLabel(_t(hint_key, hint_fallback))
65
+ retranslator.bind(self.hint_label, hint_key, hint_fallback)
59
66
  self.hint_label.setWordWrap(True)
60
67
 
61
68
  self.button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
@@ -46,6 +46,7 @@ from frontengine.utils.critical_exit.win32_vk import keyboard_keys_table
46
46
  from frontengine.utils.hotkey.hotkey_service import HotkeyService
47
47
  from frontengine.utils.logging.loggin_instance import front_engine_logger
48
48
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
49
+ from frontengine.utils.multi_language.retranslate import retranslator, translate
49
50
  from frontengine.utils.plugins.plugin_loader import load_plugins
50
51
  from frontengine.utils.preset_schedule.preset_schedule_service import PresetScheduleService
51
52
  from frontengine.ui.dialog.remote_control_dialog import (
@@ -382,8 +383,11 @@ class FrontEngineMainUI(QMainWindow):
382
383
  (self.control_center_ui, "tab_control_center_text"),
383
384
  ]
384
385
 
385
- for widget, lang_key in tabs:
386
- self.tab_widget.addTab(widget, language_wrapper.language_word_dict.get(lang_key))
386
+ for index, (widget, lang_key) in enumerate(tabs):
387
+ self.tab_widget.addTab(widget, translate(lang_key))
388
+ # setTabText 需要索引,所以索引跟著這筆登記一起記下來
389
+ # setTabText needs the index, so it travels with the entry.
390
+ retranslator.bind(self.tab_widget, lang_key, "", "setTabText", index)
387
391
 
388
392
  # 加入外部擴充 Tab
389
393
  # Add external extension tabs
@@ -442,6 +446,18 @@ class FrontEngineMainUI(QMainWindow):
442
446
  except Exception as error:
443
447
  front_engine_logger.warning(f"[FrontEngineMainUI] save geometry failed: {error!r}")
444
448
 
449
+ def retranslate(self) -> int:
450
+ """
451
+ 用目前語言把畫面上的文字重寫一遍,回傳重寫了幾條。
452
+ 換語言不必重開程式,所以開著的覆蓋層與各分頁的設定都留在原地。
453
+ Rewrite the interface in the current language and return how many
454
+ strings were rewritten. Changing language needs no restart, so open
455
+ overlays and the settings on every page stay exactly where they are.
456
+ """
457
+ applied = retranslator.apply()
458
+ front_engine_logger.info(f"[FrontEngineMainUI] retranslate | {applied} strings")
459
+ return applied
460
+
445
461
  def set_style(self) -> None:
446
462
  """更新使用者選擇的主題 / Update user-selected theme"""
447
463
  user_setting_dict.update({"theme": self.sender().text()})
@@ -8,6 +8,7 @@ from PySide6.QtWidgets import QMessageBox
8
8
  from frontengine.utils.browser.browser import open_browser
9
9
  from frontengine.utils.logging.loggin_instance import front_engine_logger
10
10
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
11
+ from frontengine.utils.multi_language.retranslate import retranslator, translate
11
12
 
12
13
  if TYPE_CHECKING:
13
14
  from frontengine.ui.main_ui import FrontEngineMainUI
@@ -20,31 +21,32 @@ def build_help_menu(ui_we_want_to_set: FrontEngineMainUI) -> None:
20
21
  """
21
22
  front_engine_logger.info(f"[HelpMenu] build_help_menu | ui={ui_we_want_to_set}")
22
23
 
23
- help_menu = ui_we_want_to_set.menu_bar.addMenu(
24
- language_wrapper.language_word_dict.get("help_menu_label")
25
- )
24
+ help_menu = ui_we_want_to_set.menu_bar.addMenu(translate("help_menu_label", "Help menu"))
25
+ retranslator.bind(help_menu, "help_menu_label", "Help menu", "setTitle")
26
26
  ui_we_want_to_set.help_menu = help_menu
27
27
 
28
28
  # --- 建立動作 / Create actions ---
29
29
  _add_action(
30
30
  help_menu,
31
- language_wrapper.language_word_dict.get("help_menu_open_issue"),
31
+ "help_menu_open_issue",
32
32
  lambda: open_browser("https://github.com/Integration-Automation/FrontEngine/issues")
33
33
  )
34
34
 
35
35
  _add_action(
36
36
  help_menu,
37
- language_wrapper.language_word_dict.get("how_to_critical_exit_action"),
37
+ "how_to_critical_exit_action",
38
38
  lambda: how_to_critical_exit(ui_we_want_to_set)
39
39
  )
40
40
 
41
41
 
42
- def _add_action(menu, label: str, callback) -> QAction:
42
+ def _add_action(menu, key: str, callback, fallback: str = "") -> QAction:
43
43
  """
44
- 建立 QAction 並加入選單
45
- Create a QAction and add it to the menu
44
+ 建立 QAction 並加入選單,同時記住它的文字來自哪個鍵,換語言時才跟得上。
45
+ Create a QAction, add it to the menu, and remember which key its text came
46
+ from so a language change reaches it.
46
47
  """
47
- action = QAction(label, menu)
48
+ action = QAction(translate(key, fallback), menu)
49
+ retranslator.bind(action, key, fallback)
48
50
  action.triggered.connect(callback)
49
51
  menu.addAction(action)
50
52
  return action
@@ -6,7 +6,7 @@ from PySide6.QtGui import QAction
6
6
 
7
7
  from frontengine.utils.browser.browser import open_browser
8
8
  from frontengine.utils.logging.loggin_instance import front_engine_logger
9
- from frontengine.utils.multi_language.language_wrapper import language_wrapper
9
+ from frontengine.utils.multi_language.retranslate import retranslator, translate
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from frontengine.ui.main_ui import FrontEngineMainUI
@@ -20,25 +20,25 @@ def build_how_to_menu(ui_we_want_to_set: FrontEngineMainUI) -> None:
20
20
  front_engine_logger.info(f"[HowToMenu] build_how_to_menu | ui={ui_we_want_to_set}")
21
21
 
22
22
  # 建立選單 / Create menu
23
- how_to_menu = ui_we_want_to_set.menu_bar.addMenu(
24
- language_wrapper.language_word_dict.get("doc_menu_label")
25
- )
23
+ how_to_menu = ui_we_want_to_set.menu_bar.addMenu(translate("doc_menu_label", "Doc menu"))
24
+ retranslator.bind(how_to_menu, "doc_menu_label", "Doc menu", "setTitle")
26
25
  ui_we_want_to_set.how_to_menu = how_to_menu
27
26
 
28
27
  # 建立「開啟文件」動作 / Create "Open Documentation" action
29
28
  _add_action(
30
29
  how_to_menu,
31
- language_wrapper.language_word_dict.get("doc_menu_open_doc"),
30
+ "doc_menu_open_doc",
32
31
  lambda: open_browser("https://frontengine.readthedocs.io/en/latest/")
33
32
  )
34
33
 
35
34
 
36
- def _add_action(menu, label: str, callback) -> QAction:
35
+ def _add_action(menu, key: str, callback, fallback: str = "") -> QAction:
37
36
  """
38
- 建立 QAction 並加入選單
39
- Create a QAction and add it to the menu
37
+ 建立 QAction 並加入選單,同時記住它的文字來自哪個鍵。
38
+ Create a QAction, add it to the menu, and remember the key behind its text.
40
39
  """
41
- action = QAction(label, menu)
40
+ action = QAction(translate(key, fallback), menu)
41
+ retranslator.bind(action, key, fallback)
42
42
  action.triggered.connect(callback)
43
43
  menu.addAction(action)
44
44
  return action
@@ -0,0 +1,64 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, List, Tuple
4
+
5
+ from PySide6.QtGui import QAction
6
+
7
+ from frontengine.user_setting.user_setting_file import user_setting_dict
8
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
9
+ from frontengine.utils.multi_language.language_wrapper import language_wrapper
10
+ from frontengine.utils.multi_language.retranslate import retranslator, translate
11
+
12
+ if TYPE_CHECKING:
13
+ from frontengine.ui.main_ui import FrontEngineMainUI
14
+
15
+ # (顯示用的鍵, 語言代碼)。代碼必須是 language_wrapper 註冊過的名字——這裡原本寫
16
+ # "French" / "Italian",而註冊的是 "France" / "Italy",reset_language() 找不到就
17
+ # 默默 return,所以那兩個選項按下去完全沒有反應。
18
+ # (label key, language code). The code must be a name language_wrapper
19
+ # registered: this list used to say "French" / "Italian" while the registry
20
+ # said "France" / "Italy", and reset_language() returns quietly on a name it
21
+ # does not know - so those two entries did nothing at all.
22
+ LANGUAGES: List[Tuple[str, str]] = [
23
+ ("language_menu_bar_english", "English"),
24
+ ("language_menu_bar_traditional_chinese", "Traditional_Chinese"),
25
+ ("language_menu_bar_simplified_chinese", "Simplified_Chinese"),
26
+ ("language_menu_bar_germany", "Deutsch"),
27
+ ("language_menu_bar_russian", "Russian"),
28
+ ("language_menu_bar_french", "France"),
29
+ ("language_menu_bar_italian", "Italy"),
30
+ ]
31
+
32
+
33
+ def build_language_menu(ui_we_want_to_set: FrontEngineMainUI) -> None:
34
+ """
35
+ 建立語言選單
36
+ Build the language menu for the main UI
37
+ """
38
+ front_engine_logger.info(f"[LanguageMenu] build_language_menu | ui={ui_we_want_to_set}")
39
+
40
+ language_menu = ui_we_want_to_set.menu_bar.addMenu(translate("menu_bar_language", "Language"))
41
+ retranslator.bind(language_menu, "menu_bar_language", "Language", "setTitle")
42
+ ui_we_want_to_set.language_menu = language_menu
43
+
44
+ for label_key, language_code in LANGUAGES:
45
+ action = QAction(translate(label_key, language_code), language_menu)
46
+ retranslator.bind(action, label_key, language_code)
47
+ action.triggered.connect(
48
+ lambda _, code=language_code: set_language(code, ui_we_want_to_set))
49
+ language_menu.addAction(action)
50
+
51
+
52
+ def set_language(language: str, ui_we_want_to_set: FrontEngineMainUI) -> bool:
53
+ """
54
+ 切換語言並立刻重寫畫面上的文字,不必重新啟動。
55
+ 回傳是否真的換成功(語言代碼不認得就是 False)。
56
+ Switch language and rewrite the interface immediately - no restart needed.
57
+ Returns whether the switch actually happened; an unknown code gives False.
58
+ """
59
+ front_engine_logger.info(f"[LanguageMenu] set_language | language={language}")
60
+ if not language_wrapper.reset_language(language):
61
+ return False
62
+ user_setting_dict.update({"language": language})
63
+ ui_we_want_to_set.retranslate()
64
+ return True
@@ -13,6 +13,7 @@ from frontengine.utils.workshop.workshop_content import (
13
13
  from frontengine.user_setting.user_setting_file import user_setting_dict, write_user_setting
14
14
  from frontengine.utils.logging.loggin_instance import front_engine_logger
15
15
  from frontengine.utils.multi_language.language_wrapper import language_wrapper
16
+ from frontengine.utils.multi_language.retranslate import retranslator
16
17
 
17
18
  if TYPE_CHECKING:
18
19
  from frontengine.ui.main_ui import FrontEngineMainUI
@@ -365,6 +366,7 @@ def build_preset_menu(ui: "FrontEngineMainUI") -> None:
365
366
  """
366
367
  front_engine_logger.info(f"[PresetMenu] build_preset_menu | ui={ui}")
367
368
  menu = ui.menu_bar.addMenu(_t("menu_bar_presets", "Presets"))
369
+ retranslator.bind(menu, "menu_bar_presets", "Presets", "setTitle")
368
370
  ui.preset_menu = menu
369
371
 
370
372
  for label_key, fallback, callback_factory in (
@@ -380,5 +382,6 @@ def build_preset_menu(ui: "FrontEngineMainUI") -> None:
380
382
  ("workshop_menu_import", "Import Workshop content...", _workshop_action),
381
383
  ):
382
384
  action = QAction(_t(label_key, fallback), menu)
385
+ retranslator.bind(action, label_key, fallback)
383
386
  action.triggered.connect(callback_factory(ui))
384
387
  menu.addAction(action)