appTranslation.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. # ##########################################################
  2. # FlatCAM: 2D Post-processing for Manufacturing #
  3. # File Author: Marius Adrian Stanciu (c) #
  4. # Date: 3/10/2019 #
  5. # MIT Licence #
  6. # ##########################################################
  7. import os
  8. import sys
  9. import logging
  10. from pathlib import Path
  11. from PyQt5 import QtWidgets, QtGui
  12. from PyQt5.QtCore import QSettings
  13. import gettext
  14. log = logging.getLogger('base')
  15. # import builtins
  16. #
  17. # if '_' not in builtins.__dict__:
  18. # _ = gettext.gettext
  19. # ISO639-1 codes from here: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
  20. languages_dict = {
  21. 'zh': 'Chinese',
  22. 'de': 'German',
  23. 'en': 'English',
  24. 'es': 'Spanish',
  25. 'fr': 'French',
  26. 'hu': 'Hungarian',
  27. 'it': 'Italian',
  28. 'pt_BR': 'Brazilian Portuguese',
  29. 'ro': 'Romanian',
  30. 'ru': 'Russian',
  31. 'tr': 'Turkish',
  32. }
  33. translations = {}
  34. languages_path_search = ''
  35. def load_languages():
  36. available_translations = []
  37. languages_path_search = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'locale')
  38. try:
  39. available_translations = next(os.walk(languages_path_search))[1]
  40. except StopIteration:
  41. if not available_translations:
  42. languages_path_search = os.path.join(str(Path(__file__).parents[1]), 'locale')
  43. try:
  44. available_translations = next(os.walk(languages_path_search))[1]
  45. except StopIteration:
  46. pass
  47. for lang in available_translations:
  48. try:
  49. if lang in languages_dict.keys():
  50. translations[lang] = languages_dict[lang]
  51. except KeyError as e:
  52. log.debug("FlatCAMTranslations.load_languages() --> %s" % str(e))
  53. return translations
  54. def languages_dir():
  55. return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'locale')
  56. def languages_dir_cx_freeze():
  57. return os.path.join(Path(__file__).parents[1], 'locale')
  58. def on_language_apply_click(app, restart=False):
  59. """
  60. Using instructions from here:
  61. https://inventwithpython.com/blog/2014/12/20/translate-your-python-3-program-with-the-gettext-module/
  62. :return:
  63. """
  64. name = app.ui.general_defaults_form.general_app_group.language_cb.currentText()
  65. theme_settings = QSettings("Open Source", "FlatCAM")
  66. if theme_settings.contains("theme"):
  67. theme = theme_settings.value('theme', type=str)
  68. else:
  69. theme = 'white'
  70. if theme == 'white':
  71. resource_loc = 'assets/resources'
  72. else:
  73. resource_loc = 'assets/resources'
  74. # do nothing if trying to apply the language that is the current language (already applied).
  75. settings = QSettings("Open Source", "FlatCAM")
  76. if settings.contains("language"):
  77. current_language = settings.value('language', type=str)
  78. if current_language == name:
  79. return
  80. if restart:
  81. msgbox = QtWidgets.QMessageBox()
  82. msgbox.setText(_("The application will restart."))
  83. msgbox.setInformativeText('%s %s?' %
  84. (_("Are you sure do you want to change the current language to"), name.capitalize()))
  85. msgbox.setWindowTitle(_("Apply Language ..."))
  86. msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/language32.png'))
  87. msgbox.setIcon(QtWidgets.QMessageBox.Question)
  88. bt_yes = msgbox.addButton(_("Yes"), QtWidgets.QMessageBox.YesRole)
  89. bt_no = msgbox.addButton(_("No"), QtWidgets.QMessageBox.NoRole)
  90. msgbox.setDefaultButton(bt_yes)
  91. msgbox.exec_()
  92. response = msgbox.clickedButton()
  93. if response == bt_no:
  94. return
  95. else:
  96. settings = QSettings("Open Source", "FlatCAM")
  97. saved_language = name
  98. settings.setValue('language', saved_language)
  99. # This will write the setting to the platform specific storage.
  100. del settings
  101. restart_program(app=app)
  102. def apply_language(domain, lang=None):
  103. lang_code = ''
  104. if lang is None:
  105. settings = QSettings("Open Source", "FlatCAM")
  106. if settings.contains("language"):
  107. name = settings.value('language')
  108. else:
  109. name = 'English'
  110. # in case the 'language' parameter is not in QSettings add it to QSettings and it's value is
  111. # the default language, English
  112. settings.setValue('language', 'English')
  113. # This will write the setting to the platform specific storage.
  114. del settings
  115. else:
  116. name = str(lang)
  117. for lang_code, lang_usable in load_languages().items():
  118. if lang_usable == name:
  119. # break and then use the current key as language
  120. break
  121. if lang_code == '':
  122. return "no language"
  123. else:
  124. try:
  125. current_lang = gettext.translation(str(domain), localedir=languages_dir(), languages=[lang_code])
  126. current_lang.install()
  127. except Exception as e:
  128. log.debug("FlatCAMTranslation.apply_language() --> %s. Perhaps is Cx_freeze-ed?" % str(e))
  129. try:
  130. current_lang = gettext.translation(str(domain),
  131. localedir=languages_dir_cx_freeze(),
  132. languages=[lang_code])
  133. current_lang.install()
  134. except Exception as e:
  135. log.debug("FlatCAMTranslation.apply_language() --> %s" % str(e))
  136. return name
  137. def restart_program(app, ask=None):
  138. """Restarts the current program.
  139. Note: this function does not return. Any cleanup action (like
  140. saving data) must be done before calling this function.
  141. """
  142. log.debug("FlatCAMTranslation.restart_program()")
  143. theme_settings = QSettings("Open Source", "FlatCAM")
  144. if theme_settings.contains("theme"):
  145. theme = theme_settings.value('theme', type=str)
  146. else:
  147. theme = 'white'
  148. if theme == 'white':
  149. resource_loc = 'assets/resources'
  150. else:
  151. resource_loc = 'assets/resources'
  152. # try to quit the Socket opened by ArgsThread class
  153. try:
  154. app.new_launch.stop.emit()
  155. # app.new_launch.thread_exit = True
  156. # app.new_launch.listener.close()
  157. except Exception as err:
  158. log.debug("FlatCAMTranslation.restart_program() --> %s" % str(err))
  159. # try to quit the QThread that run ArgsThread class
  160. try:
  161. app.listen_th.quit()
  162. except Exception as err:
  163. log.debug("FlatCAMTranslation.restart_program() --> %s" % str(err))
  164. if app.should_we_save and app.collection.get_list() or ask is True:
  165. msgbox = QtWidgets.QMessageBox()
  166. msgbox.setText(_("There are files/objects modified in FlatCAM. "
  167. "\n"
  168. "Do you want to Save the project?"))
  169. msgbox.setWindowTitle(_("Save changes"))
  170. msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/save_as.png'))
  171. msgbox.setIcon(QtWidgets.QMessageBox.Question)
  172. bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.YesRole)
  173. bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.NoRole)
  174. msgbox.setDefaultButton(bt_yes)
  175. msgbox.exec_()
  176. response = msgbox.clickedButton()
  177. if response == bt_yes:
  178. app.on_file_saveprojectas(use_thread=True, quit_action=True)
  179. app.preferencesUiManager.save_defaults()
  180. python = sys.executable
  181. os.execl(python, python, *sys.argv)