Skip to content

Instantly share code, notes, and snippets.

@Andrej730
Last active October 13, 2023 09:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Andrej730/ffe91117fea88c84f28df000463447a5 to your computer and use it in GitHub Desktop.
Save Andrej730/ffe91117fea88c84f28df000463447a5 to your computer and use it in GitHub Desktop.
Blender - Automatically reload texts which has changed externally
# ***** 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