check links copy path
1.7.7 - feat: add copy path to `check link` ops with multiple path representation choicesgpv2
parent
204553ed47
commit
9389faed22
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
1.7.7
|
||||
|
||||
- feat: add copy path to `check link` ops with multiple path representation choices
|
||||
|
||||
1.7.6
|
||||
|
||||
- ui: expose (almost) all keymap added by the addon to allow user for customize/disable as needed
|
||||
|
|
|
@ -240,6 +240,80 @@ class GPTB_OT_file_checker(bpy.types.Operator):
|
|||
return {"FINISHED"}
|
||||
|
||||
|
||||
class GPTB_OT_copy_string_to_clipboard(bpy.types.Operator):
|
||||
bl_idname = "gp.copy_string_to_clipboard"
|
||||
bl_label = "Copy String"
|
||||
bl_description = "Copy passed string to clipboard"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
string : bpy.props.StringProperty(options={'SKIP_SAVE'})
|
||||
|
||||
def execute(self, context):
|
||||
if not self.string:
|
||||
# self.report({'ERROR'}, 'Nothing to copy')
|
||||
return {"CANCELLED"}
|
||||
bpy.context.window_manager.clipboard = self.string
|
||||
self.report({'INFO'}, f'Copied: {self.string}')
|
||||
return {"FINISHED"}
|
||||
|
||||
class GPTB_OT_copy_multipath_clipboard(bpy.types.Operator):
|
||||
bl_idname = "gp.copy_multipath_clipboard"
|
||||
bl_label = "Choose Path to Copy"
|
||||
bl_description = "Copy Chosen Path"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
string : bpy.props.StringProperty(options={'SKIP_SAVE'})
|
||||
|
||||
def invoke(self, context, event):
|
||||
if not self.string:
|
||||
return {"CANCELLED"}
|
||||
self.pathes = []
|
||||
|
||||
try:
|
||||
absolute = os.path.abspath(bpy.path.abspath(self.string))
|
||||
abs_parent = os.path.dirname(os.path.abspath(bpy.path.abspath(self.string)))
|
||||
path_abs = str(Path(bpy.path.abspath(self.string)).resolve())
|
||||
|
||||
except:
|
||||
# case of invalid / non-accessable path
|
||||
bpy.context.window_manager.clipboard = self.string
|
||||
return context.window_manager.invoke_props_dialog(self, width=800)
|
||||
|
||||
self.pathes.append(('Raw Path', self.string))
|
||||
self.pathes.append(('Parent', os.path.dirname(self.string)))
|
||||
|
||||
if absolute != self.string:
|
||||
self.pathes.append(('Absolute', absolute))
|
||||
|
||||
if absolute != self.string:
|
||||
self.pathes.append(('Absolute Parent', abs_parent))
|
||||
|
||||
if absolute != path_abs:
|
||||
self.pathes.append(('Resolved',path_abs))
|
||||
|
||||
self.pathes.append(('File name', os.path.basename(self.string)))
|
||||
|
||||
maxlen = max(len(l[1]) for l in self.pathes)
|
||||
popup_width = 800
|
||||
if maxlen < 50:
|
||||
popup_width = 500
|
||||
elif maxlen > 100:
|
||||
popup_width = 1000
|
||||
return context.window_manager.invoke_props_dialog(self, width=popup_width)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.separator()
|
||||
col = layout.column()
|
||||
for l in self.pathes:
|
||||
split=col.split(factor=0.2, align=True)
|
||||
split.operator('gp.copy_string_to_clipboard', text=l[0], icon='COPYDOWN').string = l[1]
|
||||
split.label(text=l[1])
|
||||
|
||||
def execute(self, context):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class GPTB_OT_links_checker(bpy.types.Operator):
|
||||
bl_idname = "gp.links_checker"
|
||||
|
@ -267,14 +341,28 @@ class GPTB_OT_links_checker(bpy.types.Operator):
|
|||
|
||||
|
||||
layout.separator()
|
||||
# layout = layout.column() # thinner linespace
|
||||
for l in self.all_lnks:
|
||||
if l[1] == 'LIBRARY_DATA_BROKEN':
|
||||
if l[1] == 'CANCEL':
|
||||
layout.label(text=l[0], icon=l[1])
|
||||
else:
|
||||
split=layout.split(factor=0.75)
|
||||
continue
|
||||
|
||||
if l[1] == 'LIBRARY_DATA_BROKEN':
|
||||
split=layout.split(factor=0.85)
|
||||
split.label(text=l[0], icon=l[1])
|
||||
split.operator('wm.path_open', text='Open folder', icon='FILE_FOLDER').filepath = Path(bpy.path.abspath(l[0])).resolve().parent.as_posix()
|
||||
split.operator('wm.path_open', text='Open file', icon='FILE_TICK').filepath = Path(bpy.path.abspath(l[0])).resolve().as_posix()#os.path.abspath(bpy.path.abspath(dirname(l[0])))
|
||||
# layout.label(text=l[0], icon=l[1])
|
||||
else:
|
||||
split=layout.split(factor=0.75, align=True)
|
||||
split.label(text=l[0], icon=l[1])
|
||||
## resolve() return somethin different than os.path.abspath.
|
||||
# split.operator('wm.path_open', text='Open folder', icon='FILE_FOLDER').filepath = Path(bpy.path.abspath(l[0])).resolve().parent.as_posix()
|
||||
# split.operator('wm.path_open', text='Open file', icon='FILE_TICK').filepath = Path(bpy.path.abspath(l[0])).resolve().as_posix()
|
||||
|
||||
split.operator('wm.path_open', text='Open Folder', icon='FILE_FOLDER').filepath = Path(os.path.abspath(bpy.path.abspath(l[0]))).parent.as_posix()
|
||||
split.operator('wm.path_open', text='Open File', icon='FILE_TICK').filepath = Path(os.path.abspath(bpy.path.abspath(l[0]))).as_posix()
|
||||
|
||||
split.operator('gp.copy_multipath_clipboard', text='Copy Path', icon='COPYDOWN').string = l[0]
|
||||
# split.operator('gp.copy_string_to_clipboard', text='Copy Path', icon='COPYDOWN').string = l[0] # copy blend path directly
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.all_lnks = []
|
||||
|
@ -283,19 +371,32 @@ class GPTB_OT_links_checker(bpy.types.Operator):
|
|||
abs_ct = 0
|
||||
rel_ct = 0
|
||||
## check for broken links
|
||||
viewed = []
|
||||
for current, lib in zip(bpy.utils.blend_paths(local=True), bpy.utils.blend_paths(absolute=True, local=True)):
|
||||
lfp = Path(lib)
|
||||
realib = Path(current)
|
||||
if not lfp.exists():
|
||||
self.broke_ct += 1
|
||||
self.all_lnks.append( (f"{realib.as_posix()}", 'LIBRARY_DATA_BROKEN') )#lfp.as_posix()
|
||||
else:
|
||||
if realib.as_posix().startswith('//'):
|
||||
rel_ct += 1
|
||||
self.all_lnks.append( (f"{realib.as_posix()}", 'LINKED') )#lfp.as_posix()
|
||||
# avoid relisting same path mutliple times
|
||||
if current in viewed:
|
||||
continue
|
||||
# TODO find a proper way to show the number of user of this path...
|
||||
viewed.append(current)
|
||||
|
||||
realib = Path(current) # path as-is
|
||||
lfp = Path(lib) # absolute path
|
||||
|
||||
try: # Try because some path may fail parsing
|
||||
if not lfp.exists():
|
||||
self.broke_ct += 1
|
||||
self.all_lnks.append( (f"{realib.as_posix()}", 'LIBRARY_DATA_BROKEN') )
|
||||
else:
|
||||
abs_ct += 1
|
||||
self.all_lnks.append( (f"{realib.as_posix()}", 'LIBRARY_DATA_INDIRECT') )#lfp.as_posix()
|
||||
if realib.as_posix().startswith('//'):
|
||||
rel_ct += 1
|
||||
self.all_lnks.append( (f"{realib.as_posix()}", 'LINKED') )
|
||||
else:
|
||||
abs_ct += 1
|
||||
self.all_lnks.append( (f"{realib.as_posix()}", 'LIBRARY_DATA_INDIRECT') )
|
||||
except:
|
||||
self.broke_ct += 1
|
||||
self.all_lnks.append( (f"{current}" , 'CANCEL') ) # error accessing file
|
||||
|
||||
|
||||
if not self.all_lnks:
|
||||
self.report({'INFO'}, 'No external links in files')
|
||||
|
@ -317,14 +418,20 @@ class GPTB_OT_links_checker(bpy.types.Operator):
|
|||
print(p[0])
|
||||
# Show in viewport
|
||||
|
||||
maxlen = max(len(x) for x in viewed)
|
||||
|
||||
# if broke_ct == 0:
|
||||
# show_message_box(self.all_lnks, _title = self.title, _icon = 'INFO')# Links
|
||||
# return {"FINISHED"}
|
||||
try:
|
||||
self.proj = context.preferences.addons['pipe_sync'].preferences['local_folder']
|
||||
except:
|
||||
self.proj = None
|
||||
return context.window_manager.invoke_props_dialog(self, width=800)
|
||||
popup_width = 800
|
||||
if maxlen < 50:
|
||||
popup_width = 500
|
||||
elif maxlen > 100:
|
||||
popup_width = 1000
|
||||
|
||||
self.proj = os.environ.get('PROJECT_ROOT')
|
||||
return context.window_manager.invoke_props_dialog(self, width=popup_width)
|
||||
|
||||
|
||||
""" OLD links checker with show_message_box
|
||||
class GPTB_OT_links_checker(bpy.types.Operator):
|
||||
|
@ -501,6 +608,8 @@ classes = (
|
|||
# GPTB_OT_check_scene,
|
||||
GPTB_OT_list_object_visibility,
|
||||
GPTB_OT_list_modifier_visibility,
|
||||
GPTB_OT_copy_string_to_clipboard,
|
||||
GPTB_OT_copy_multipath_clipboard,
|
||||
GPTB_OT_file_checker,
|
||||
GPTB_OT_links_checker,
|
||||
)
|
||||
|
|
|
@ -15,7 +15,7 @@ bl_info = {
|
|||
"name": "GP toolbox",
|
||||
"description": "Set of tools for Grease Pencil in animation production",
|
||||
"author": "Samuel Bernou, Christophe Seux",
|
||||
"version": (1, 7, 6),
|
||||
"version": (1, 7, 7),
|
||||
"blender": (2, 91, 0),
|
||||
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
||||
"warning": "",
|
||||
|
|
Loading…
Reference in New Issue