Extensions: Quick access to add-on folder
All checks were successful
buildbot/vdev-code-daily-lint Build done.
buildbot/vdev-code-daily-linux-x86_64 Build done.
buildbot/vdev-code-daily-windows-amd64 Build done.
buildbot/vdev-code-daily-darwin-arm64 Build done.
buildbot/vdev-code-daily-darwin-x86_64 Build done.
buildbot/vdev-code-daily-coordinator Build done.

When developing and testing add-ons it can be useful to get to the
folder containing such add-on.

When Developer Extras is enabled, show a folder icon next to the
extension's path to quickly open it using the system file browser.

Also display it in the list of duplicate add-ons, if any, so user can
access them more conveniently.

Pull Request: #128474
This commit is contained in:
Pablo Vazquez 2025-01-30 11:18:53 +01:00 committed by Pablo Vazquez
parent 600ffd3568
commit 6ea8297477
2 changed files with 39 additions and 6 deletions

View File

@ -223,6 +223,7 @@ def addon_draw_item_expanded(
item_warnings, # `list[str]`
item_doc_url, # `str`
item_tracker_url, # `str`
show_developer_ui, # `bool`
):
from bpy.app.translations import (
contexts as i18n_contexts,
@ -295,7 +296,13 @@ def addon_draw_item_expanded(
if addon_type != ADDON_TYPE_LEGACY_CORE:
col_a.label(text="File")
col_b.label(text=mod.__file__, translate=False)
row = col_b.row()
row.label(text=mod.__file__, translate=False)
# Add a button to quickly open the add-on's folder for accessing its files and assets.
if show_developer_ui:
import os
row.operator("wm.path_open", text="", icon='FILE_FOLDER').filepath = os.path.dirname(mod.__file__)
# NOTE: this can be removed once upgrading from 4.1 is no longer relevant.
@ -435,6 +442,7 @@ def addons_panel_draw_items(
addon_extension_block_map, # `dict[str, PkgBlock_Normalized]`
show_development, # `bool`
show_developer_ui, # `bool`
): # `-> set[str]`
# NOTE: this duplicates logic from `USERPREF_PT_addons` eventually this logic should be used instead.
# Don't de-duplicate the logic as this is a temporary state - as long as extensions remains experimental.
@ -592,6 +600,7 @@ def addons_panel_draw_items(
item_doc_url=item_doc_url,
# pylint: disable-next=used-before-assignment
item_tracker_url=item_tracker_url,
show_developer_ui=show_developer_ui,
)
if is_enabled:
@ -603,6 +612,8 @@ def addons_panel_draw_items(
def addons_panel_draw_error_duplicates(layout):
import addon_utils
import os
box = layout.box()
row = box.row()
row.label(text="Multiple add-ons with the same name found!")
@ -612,8 +623,14 @@ def addons_panel_draw_error_duplicates(layout):
box.separator()
sub_col = box.column(align=True)
sub_col.label(text=addon_name + ":")
sub_col.label(text=" " + addon_file)
sub_col.label(text=" " + addon_path)
sub_row = sub_col.row()
sub_row.label(text=" " + addon_file)
sub_row.operator("wm.path_open", text="", icon='FILE_FOLDER').filepath = os.path.dirname(addon_file)
sub_row = sub_col.row()
sub_row.label(text=" " + addon_path)
sub_row.operator("wm.path_open", text="", icon='FILE_FOLDER').filepath = os.path.dirname(addon_path)
def addons_panel_draw_error_generic(layout, lines):
@ -633,6 +650,7 @@ def addons_panel_draw_impl(
enabled_only, # `bool`
*,
show_development, # `bool`
show_developer_ui, # `bool`
):
"""
Show all the items... we may want to paginate at some point.
@ -722,6 +740,7 @@ def addons_panel_draw_impl(
addon_extension_manifest_map=addon_extension_manifest_map,
addon_extension_block_map=addon_extension_block_map,
show_development=show_development,
show_developer_ui=show_developer_ui,
)
# Append missing scripts.
@ -797,6 +816,7 @@ def addons_panel_draw(panel, context):
addon_tags_exclude,
view.show_addons_enabled_only,
show_development=prefs.experimental.use_extensions_debug,
show_developer_ui=prefs.view.show_developer_ui,
)
@ -1259,6 +1279,7 @@ def extension_draw_item(
repo_item, # `RepoItem`
operation_in_progress, # `bool`
extensions_warnings, # `dict[str, list[str]]`
show_developer_ui, # `bool`
):
item = item_local or item_remote
is_installed = item_local is not None
@ -1429,7 +1450,12 @@ def extension_draw_item(
if is_installed:
col_a.label(text="Path")
col_b.label(text=os.path.join(repo_item.directory, pkg_id), translate=False)
row = col_b.row()
dirpath = os.path.join(repo_item.directory, pkg_id)
row.label(text=dirpath, translate=False)
if show_developer_ui:
row.operator("wm.path_open", text="", icon='FILE_FOLDER').filepath = dirpath
def extensions_panel_draw_impl(
@ -1710,6 +1736,7 @@ def extensions_panel_draw_impl(
repo_item=params.repos_all[ext_ui.repo_index],
operation_in_progress=operation_in_progress,
extensions_warnings=extensions_warnings,
show_developer_ui=prefs.view.show_developer_ui,
)
# Finally show any errors in a single panel which can be dismissed.

View File

@ -2471,8 +2471,14 @@ class USERPREF_PT_addons(AddOnPanel, Panel):
box.separator()
sub_col = box.column(align=True)
sub_col.label(text=addon_name + ":")
sub_col.label(text=" " + addon_file)
sub_col.label(text=" " + addon_path)
sub_row = sub_col.row()
sub_row.label(text=" " + addon_file)
sub_row.operator("wm.path_open", text="", icon='FILE_FOLDER').filepath = os.path.dirname(addon_file)
sub_row = sub_col.row()
sub_row.label(text=" " + addon_path)
sub_row.operator("wm.path_open", text="", icon='FILE_FOLDER').filepath = os.path.dirname(addon_path)
if addon_utils.error_encoding:
self.draw_error(