helpers.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. # <pep8-80 compliant>
  19. # -----------------------------------------------------------------------------
  20. # AppOverrideState
  21. class AppOverrideState:
  22. """
  23. Utility class to encapsulate overriding the application state
  24. so that settings can be restored afterwards.
  25. """
  26. __slots__ = (
  27. # setup_classes
  28. "_class_store",
  29. # setup_ui_ignore
  30. "_ui_ignore_store",
  31. # setup_addons
  32. "_addon_store",
  33. )
  34. # ---------
  35. # Callbacks
  36. #
  37. # Set as None, to make it simple to check if they're being overridden.
  38. # setup/teardown classes
  39. class_ignore = None
  40. # setup/teardown ui_ignore
  41. ui_ignore_classes = None
  42. ui_ignore_operator = None
  43. ui_ignore_property = None
  44. ui_ignore_menu = None
  45. ui_ignore_label = None
  46. addon_paths = None
  47. addons = None
  48. # End callbacks
  49. def __init__(self):
  50. self._class_store = None
  51. self._addon_store = None
  52. self._ui_ignore_store = None
  53. def _setup_classes(self):
  54. assert(self._class_store is None)
  55. self._class_store = self.class_ignore()
  56. from bpy.utils import unregister_class
  57. for cls in self._class_store:
  58. unregister_class(cls)
  59. def _teardown_classes(self):
  60. assert(self._class_store is not None)
  61. from bpy.utils import register_class
  62. for cls in self._class_store:
  63. register_class(cls)
  64. self._class_store = None
  65. def _setup_ui_ignore(self):
  66. import bl_app_override
  67. self._ui_ignore_store = bl_app_override.ui_draw_filter_register(
  68. ui_ignore_classes=(
  69. None if self.ui_ignore_classes is None
  70. else self.ui_ignore_classes()
  71. ),
  72. ui_ignore_operator=self.ui_ignore_operator,
  73. ui_ignore_property=self.ui_ignore_property,
  74. ui_ignore_menu=self.ui_ignore_menu,
  75. ui_ignore_label=self.ui_ignore_label,
  76. )
  77. def _teardown_ui_ignore(self):
  78. import bl_app_override
  79. bl_app_override.ui_draw_filter_unregister(
  80. self._ui_ignore_store
  81. )
  82. self._ui_ignore_store = None
  83. def _setup_addons(self):
  84. import sys
  85. sys_path = []
  86. if self.addon_paths is not None:
  87. for path in self.addon_paths():
  88. if path not in sys.path:
  89. sys.path.append(path)
  90. import addon_utils
  91. addons = []
  92. if self.addons is not None:
  93. addons.extend(self.addons())
  94. for addon in addons:
  95. addon_utils.enable(addon)
  96. self._addon_store = {
  97. "sys_path": sys_path,
  98. "addons": addons,
  99. }
  100. def _teardown_addons(self):
  101. import sys
  102. sys_path = self._addon_store["sys_path"]
  103. for path in sys_path:
  104. # should always succeed, but if not it doesn't matter
  105. # (someone else was changing the sys.path), ignore!
  106. try:
  107. sys.path.remove(path)
  108. except:
  109. pass
  110. addons = self._addon_store["addons"]
  111. import addon_utils
  112. for addon in addons:
  113. addon_utils.disable(addon)
  114. self._addon_store.clear()
  115. self._addon_store = None
  116. def setup(self):
  117. if self.class_ignore is not None:
  118. self._setup_classes()
  119. if any((self.addon_paths,
  120. self.addons,
  121. )):
  122. self._setup_addons()
  123. if any((self.ui_ignore_operator,
  124. self.ui_ignore_property,
  125. self.ui_ignore_menu,
  126. self.ui_ignore_label,
  127. )):
  128. self._setup_ui_ignore()
  129. def teardown(self):
  130. if self._class_store is not None:
  131. self._teardown_classes()
  132. if self._addon_store is not None:
  133. self._teardown_addons()
  134. if self._ui_ignore_store is not None:
  135. self._teardown_ui_ignore()