Last active
October 13, 2023 09:50
-
-
Save Andrej730/ffe91117fea88c84f28df000463447a5 to your computer and use it in GitHub Desktop.
Blender - Automatically reload texts which has changed externally
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ***** BEGIN GPL LICENSE BLOCK ***** | |
# | |
# | |
# This program is free software; you can redistribute it and/or | |
# modify it under the terms of the GNU General Public License | |
# as published by the Free Software Foundation; either version 2 | |
# of the License, or (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software Foundation, | |
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
# | |
# ***** END GPL LICENCE BLOCK ***** | |
bl_info = { | |
"name": "Reload if Modified", | |
"author": "Dany Lebel (Axon_D), updated by @Andrej730", | |
"version": (1,0), | |
"blender": (2, 80, 0), | |
"location": "Text Editor -> Header Bar -> Reload if Modified", | |
"description": "Determine if a text datablock must be reloaded from file in the case that it has changed", | |
"warning": "", | |
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Text_Editor/Reload_if_Modified", | |
"tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25277&group_id=153&atid=467", | |
"category": "Text Editor" | |
} | |
# https://archive.blender.org/wiki/index.php/Extensions:2.5/Py/Scripts/Text_Editor/Reload_if_Modified/ | |
""" | |
This addon will automatically reload a text datablock if its source file | |
does not corresponds to the last blendfile version. This must be checked | |
for each file wanted to be updated automatically. It has no effect on internal datablock. | |
""" | |
import bpy | |
def check_texts_every_second(): | |
for text in bpy.data.texts: | |
if text.is_in_memory: | |
continue | |
if text.is_modified and text.reload_if_modified: | |
# using reloading operators causes crashes, therefore we reload the text manually | |
# saving text to file afterwards as it's the only way to flip `.is_modified` | |
# since reload doesn't work - https://projects.blender.org/blender/blender/issues/113644 | |
with open(text.filepath, 'r') as fi: | |
new_text = fi.read() | |
text.from_string(new_text) | |
def get_area(): | |
for screen in bpy.data.screens: | |
for area in screen.areas: | |
if area.type == "TEXT_EDITOR": | |
return area | |
context_override = {} | |
context_override["edit_text"] = text | |
space = next(space for space in get_area().spaces if space.type == "TEXT_EDITOR") | |
context_override["space_data"] = space | |
with bpy.context.temp_override(**context_override): | |
bpy.ops.text.save() | |
return 1 # every second | |
def draw_header(self, context): | |
text = context.space_data.text | |
if not text: | |
return | |
if text.is_in_memory: | |
return | |
layout = self.layout | |
row = layout.row() | |
row.prop(text, "reload_if_modified") | |
def register(): | |
bpy.types.Text.reload_if_modified = bpy.props.BoolProperty( | |
name='Reload if Modified', | |
description= | |
'Automatically reload text file if it has changed', | |
default=False, | |
) | |
# tried `bpy.msgbus.subscribe_rna(key=bpy.data.texts.path_resolve("is_modified", False))` | |
# and didn't worked, therefore going to timer approach as depsgraph update won't be often enough | |
# maybe there is more clever way to do this | |
bpy.types.TEXT_HT_header.append(draw_header) | |
bpy.app.timers.register(check_texts_every_second) | |
def unregister(): | |
del bpy.types.Text.reload_if_modified | |
bpy.types.TEXT_HT_header.remove(draw_header) | |
bpy.app.timers.register(check_texts_every_second) | |
if __name__ == '__main__': | |
register() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment