Blender SVN: New Features #273

Open
Demeter Dzadik wants to merge 13 commits from New-SVN-features into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 80 additions and 33 deletions
Showing only changes of commit 57af4abb36 - Show all commits

View File

@ -124,7 +124,7 @@ DEPTH_ENUM = bpy.props.EnumProperty(
name="Depth",
description="The depth to which this directory should be updated", # For non-directory entries, this property is not used.
items=[
('INFINITY', 'Recursive (Default)', "Default update behaviour: Updates will recursively pull in any files or subdirectories not already present", 'OUTLINER', 3),
('INFINITY', 'Recursive (Default)', "Updates will recursively pull in any files or subdirectories not already present", 'OUTLINER', 3),
('IMMEDIATES', 'Non-Recursive', "Updates will pull in any files or subdirectories not already present; those subdirectories' will be left empty", 'PRESET', 2),
('FILES', 'Files Only', "Updates will pull in any files not already present, but not subdirectories", 'FILE', 1),
('EMPTY', 'Empty', "Updates will not pull in any files or subdirectories not already present", 'SELECT_SET', 0),

View File

@ -187,7 +187,7 @@ class SVN_file(PropertyGroup):
repo = context.scene.svn.get_repo(context)
repo.external_files_active_index = repo.external_files.find(self.name)
repo.refresh_ui_lists(context)
is_expanded: BoolProperty(update=update_is_expanded, description="Whether this directory's contents should be shown in file tree view")
is_expanded: BoolProperty(name="Show Contents", update=update_is_expanded, description="Whether this directory's contents should be shown in file tree view")
tree_depth: IntProperty(description="Number of indentations in the tree, ie. number of parents. Set automatically when svn_path is set")
has_children: BoolProperty(description="Whether this is a directory with any children. Updated whenever a new file entry is added")
@ -303,6 +303,9 @@ class SVN_repository(PropertyGroup):
dir_path = Path(self.directory)
# TODO: This property is checked pretty often, so we run `svn info` pretty often. Might not be a big deal, but maybe it's a bit overkill?
root_dir, base_url = get_svn_info(self.directory)
if not hasattr(self, 'directory'):
# This can happen when running Reload Scripts, resulting in a console error.
return False
return (
dir_path.exists() and
dir_path.is_dir() and
@ -475,7 +478,7 @@ class SVN_repository(PropertyGroup):
return svn_dir / svn_path
def get_file_by_absolute_path(self, abs_path: str or Path) -> Optional[SVN_file]:
rel_path = str(self.absolute_to_svn_path(abs_path))
rel_path = str(self.absolute_to_svn_path(abs_path).as_posix())
if rel_path:
return self.external_files.get(rel_path)
@ -578,8 +581,9 @@ class SVN_repository(PropertyGroup):
return svn_file
@property
def current_blend_file(self) -> SVN_file:
return self.get_file_by_absolute_path(bpy.data.filepath)
def current_blend_file(self) -> Optional[SVN_file]:
if bpy.data.filepath:
return self.get_file_by_absolute_path(bpy.data.filepath)
### File List UIList filter properties ###
def refresh_ui_lists(self, context):
@ -602,15 +606,17 @@ class SVN_repository(PropertyGroup):
)
filter_list = [bool(val) for val in filter_list]
self.external_files.foreach_set('show_in_filelist', filter_list)
if self.use_file_tree_display:
if self.display_mode == 'TREE':
for file in self.external_files:
if file.show_in_filelist:
parent = self.get_parent_file(file)
while parent:
parent.show_in_filelist = True
parent = self.get_parent_file(parent)
else:
self.external_files.foreach_set('show_in_filelist', [True] * len(self.external_files))
if self.use_file_tree_display:
if self.display_mode == 'TREE':
for file in self.external_files:
parent = self.get_parent_file(file)
while parent:
@ -620,10 +626,9 @@ class SVN_repository(PropertyGroup):
parent = self.get_parent_file(parent)
elif not self.file_search_filter:
for file in self.external_files:
if file == self.current_blend_file:
file.show_in_filelist = True
continue
file.show_in_filelist = not file.has_default_status
if self.current_blend_file:
self.current_blend_file.show_in_filelist = True
# Make sure the active file isn't now being filtered out.
# If it is, change the active file to the first visible one.
@ -640,11 +645,24 @@ class SVN_repository(PropertyGroup):
update=refresh_ui_lists
)
use_file_tree_display: BoolProperty(
show_file_paths: BoolProperty(
name="Show File Paths",
description="Show file paths relative to the SVN root, instead of just the file name"
)
def update_tree_display(self, context):
if self.display_mode == 'TREE':
self.show_file_paths = False
self.refresh_ui_lists(context)
display_mode: EnumProperty(
name="File Display Mode",
description="Whether the full file tree sould be drawn instead of just modified files as a flat list",
default=False,
update=refresh_ui_lists
items=[
('FLAT', "Modifications", "Display only modified files as a flat list", 'PRESET', 0),
('TREE', "Tree View", "Display the full tree of the entire repository", 'OUTLINER', 1),
],
update=update_tree_display
)

View File

@ -38,6 +38,9 @@ def execute_svn_command(
So any file paths that are part of the command should be relative to the
SVN root.
"""
if not hasattr(context.scene, 'svn'):
# This can happen during Reload Scripts, throwing a console error.
return
repo = context.scene.svn.get_repo(context)
if "svn" not in command:
command.insert(0, "svn")

View File

@ -16,14 +16,8 @@ class SVN_UL_file_list(UIList):
# Value that indicates that this item has passed the filter process successfully. See rna_ui.c.
UILST_FLT_ITEM = 1 << 30
show_file_paths: BoolProperty(
name="Show File Paths",
description="Show file paths relative to the SVN root, instead of just the file name"
)
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
# As long as there are any items, always draw the filters.
self.use_filter_show = True
# As long as there are any items, and a search term is typed in, always draw the filter.
repo = context.scene.svn.get_repo(context)
if self.layout_type != 'DEFAULT':
@ -43,8 +37,8 @@ class SVN_UL_file_list(UIList):
ops_ui.enabled = file_entry.status_prediction_type == 'NONE' and not prefs.is_busy
if repo.use_file_tree_display:
split = filepath_ui.split(factor=0.02 * file_entry.tree_depth + 0.00001)
if repo.display_mode == 'TREE':
split = filepath_ui.split(factor=0.05 * file_entry.tree_depth + 0.00001)
split.row()
row = split.row(align=True)
filepath_ui = row.row(align=True)
@ -54,7 +48,7 @@ class SVN_UL_file_list(UIList):
else:
filepath_ui.label(text="", icon='BLANK1')
if self.show_file_paths:
if repo.show_file_paths:
filepath_ui.label(text=file_entry.name, icon=file_entry.file_icon)
else:
filepath_ui.label(text=file_entry.file_name, icon=file_entry.file_icon)
@ -155,6 +149,10 @@ class SVN_UL_file_list(UIList):
return flt_flags, flt_neworder
def filter_items(self, context, data, propname):
# As long as a search term is typed in, draw the filter.
repo = context.scene.svn.get_repo(context)
if repo.file_search_filter:
self.use_filter_show = True
return type(self).cls_filter_items(context, data, propname)
def draw_filter(self, context, layout):
@ -164,15 +162,7 @@ class SVN_UL_file_list(UIList):
repo = context.scene.svn.get_repo(context)
if not repo:
return
main_row = layout.row()
row = main_row.row(align=True)
row.prop(repo, 'use_file_tree_display', text="", expand=True, icon='OUTLINER' if repo.use_file_tree_display else 'PRESET')
file_paths = row.row()
file_paths.enabled = not repo.use_file_tree_display
file_paths.prop(self, 'show_file_paths', text="", toggle=True, icon="FILE_FOLDER")
row.prop(repo, 'file_search_filter', text="")
layout.prop(repo, 'file_search_filter', text="")
def draw_process_info(context, layout):
@ -206,6 +196,33 @@ def draw_process_info(context, layout):
", ".join([p.name for p in Processes.running_processes]))
class SVN_PT_filelist_options(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW'
bl_label = "Options"
bl_options = {'INSTANCED'}
def draw(self, context):
layout = self.layout
prefs = get_addon_prefs(context)
repo = context.scene.svn.get_repo(context)
layout.label(text="Display Mode:")
layout.prop(repo, 'display_mode', text=" ", expand=True)
layout.use_property_split=True
layout.use_property_decorate=False
file_paths = layout.row()
file_paths.enabled = repo.display_mode == 'FLAT'
file_paths.prop(repo, 'show_file_paths')
layout.separator()
layout.prop(prefs, 'do_auto_updates', icon='TEMP')
def draw_file_list(context, layout):
prefs = get_addon_prefs(context)
repo = prefs.active_repo
@ -243,14 +260,22 @@ def draw_file_list(context, layout):
col = row.column()
col.popover(
panel="SVN_PT_filelist_options",
text="",
icon='PREFERENCES',
)
col.separator()
col.operator("svn.commit", icon='EXPORT', text="")
col.prop(prefs, 'do_auto_updates', icon='TEMP', text="")
if not prefs.do_auto_updates:
col.operator("svn.update_all", icon='IMPORT', text="").revision = 0
if prefs.is_busy:
col.operator('svn.cancel', text="", icon="X")
else:
col.label(text="", icon='BLANK1')
col.separator()
col.operator("svn.cleanup", icon='BRUSH_DATA', text="")
@ -258,4 +283,5 @@ def draw_file_list(context, layout):
registry = [
SVN_UL_file_list,
SVN_PT_filelist_options,
]