Skip to content

Commit

Permalink
feat: show add-on compatibility warning
Browse files Browse the repository at this point in the history
  • Loading branch information
saturday06 committed Jul 19, 2024
1 parent 4c61312 commit 7c6c48b
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 43 deletions.
16 changes: 14 additions & 2 deletions src/io_scene_vrm/common/ops/vrm.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,31 @@ def model_validate(
)


def show_blend_file_vrm_addon_compatibility_warning(
def show_blend_file_addon_compatibility_warning(
execution_context: str = "EXEC_DEFAULT",
/,
*,
file_addon_version: str = "",
installed_addon_version: str = "",
) -> set[str]:
return bpy.ops.vrm.show_blend_file_vrm_addon_compatibility_warning( # type: ignore[attr-defined, no-any-return]
return bpy.ops.vrm.show_blend_file_addon_compatibility_warning( # type: ignore[attr-defined, no-any-return]
execution_context,
file_addon_version=file_addon_version,
installed_addon_version=installed_addon_version,
)


def show_blend_file_compatibility_warning(
execution_context: str = "EXEC_DEFAULT",
/,
*,
file_version: str = "",
app_version: str = "",
) -> set[str]:
return bpy.ops.vrm.show_blend_file_compatibility_warning( # type: ignore[attr-defined, no-any-return]
execution_context,
file_version=file_version,
app_version=app_version,
)


Expand Down
1 change: 1 addition & 0 deletions src/io_scene_vrm/editor/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
@persistent
def load_post(_unsed: object) -> None:
migration.state.blend_file_compatibility_warning_shown = False
migration.state.blend_file_addon_compatibility_warning_shown = False
76 changes: 69 additions & 7 deletions src/io_scene_vrm/editor/migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
@dataclass
class State:
blend_file_compatibility_warning_shown: bool = False
blend_file_addon_compatibility_warning_shown: bool = False


state: Final = State()
Expand Down Expand Up @@ -124,7 +125,8 @@ def migrate_all_objects(
context, context.scene.name
)
mtoon1_migration.migrate(context)
validate_blend_file_version_compatibility(context)
validate_blend_file_compatibility(context)
validate_blend_file_addon_compatibility(context)

preferences = get_preferences(context)

Expand All @@ -137,7 +139,7 @@ def migrate_all_objects(
preferences.addon_version = updated_addon_version


def validate_blend_file_version_compatibility(context: Context) -> None:
def validate_blend_file_compatibility(context: Context) -> None:
"""新しいBlenderで作成されたファイルを古いBlenderで編集しようとした場合に警告をする.
アドオンの対応バージョンの事情で新しいBlenderで編集されたファイルを古いBlenderで編集しようとし、
Expand All @@ -156,23 +158,83 @@ def validate_blend_file_version_compatibility(context: Context) -> None:
if blend_file_major_minor_version <= current_major_minor_version:
return

file_version_str = ".".join(map(str, blend_file_major_minor_version))
app_version_str = ".".join(map(str, current_major_minor_version))

logger.error(
"Opening incompatible file: file_blender_version=%s running_blender_version=%s",
context.blend_data.version,
bpy.app.version,
file_version_str,
app_version_str,
)

if not state.blend_file_compatibility_warning_shown:
state.blend_file_compatibility_warning_shown = True
# Blender 4.2.0ではtimerで実行しないとダイアログが自動で消えるのでタイマーを使う
bpy.app.timers.register(
functools.partial(
show_blend_file_compatibility_warning,
file_version_str,
app_version_str,
),
first_interval=0.1,
)


def show_blend_file_compatibility_warning(file_version: str, app_version: str) -> None:
ops.vrm.show_blend_file_compatibility_warning(
"INVOKE_DEFAULT",
file_version=file_version,
app_version=app_version,
)


def validate_blend_file_addon_compatibility(context: Context) -> None:
"""新しいVRMアドオンで作成されたファイルを古いVRMアドオンで編集しようとした場合に警告をする."""
if not context.blend_data.filepath:
return
installed_addon_version = addon_version()

# TODO: これはSceneあたりにバージョンを生やしたほうが良いかも
up_to_date = True
file_addon_version: tuple[int, ...] = (0, 0, 0)
for armature in context.blend_data.armatures:
file_addon_version = tuple(get_armature_extension(armature).addon_version)
if file_addon_version > installed_addon_version:
up_to_date = False
break
if up_to_date:
return

file_addon_version_str = ".".join(map(str, file_addon_version))
installed_addon_version_str = ".".join(map(str, installed_addon_version))

logger.error(
"Opening incompatible VRM add-on version: file=%s installed=%s",
file_addon_version_str,
installed_addon_version_str,
)

if not state.blend_file_compatibility_warning_shown:
state.blend_file_compatibility_warning_shown = True
# Blender 4.2.0ではtimerで実行しないとダイアログが自動で消えるのでタイマーを使う
bpy.app.timers.register(
show_blend_file_compatibility_warning,
functools.partial(
show_blend_file_addon_compatibility_warning,
file_addon_version_str,
installed_addon_version_str,
),
first_interval=0.1,
)


def show_blend_file_compatibility_warning() -> None:
ops.vrm.show_blend_file_compatibility_warning("INVOKE_DEFAULT")
def show_blend_file_addon_compatibility_warning(
file_addon_version: str, installed_addon_version: str
) -> None:
ops.vrm.show_blend_file_addon_compatibility_warning(
"INVOKE_DEFAULT",
file_addon_version=file_addon_version,
installed_addon_version=installed_addon_version,
)


def have_vrm_model(context: Context) -> bool:
Expand Down
60 changes: 34 additions & 26 deletions src/io_scene_vrm/editor/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,28 +358,25 @@ class VRM_OT_show_blend_file_compatibility_warning(Operator):
bl_description = "Show Blend File Compatibility Warning"
bl_options: AbstractSet[str] = {"REGISTER"}

file_version: StringProperty(options={"HIDDEN"}) # type: ignore[valid-type]
app_version: StringProperty(options={"HIDDEN"}) # type: ignore[valid-type]

def execute(self, _context: Context) -> set[str]:
return {"FINISHED"}

def invoke(self, context: Context, _event: Event) -> set[str]:
return context.window_manager.invoke_props_dialog(self, width=500)

def draw(self, context: Context) -> None:
app_version = str(bpy.app.version[0]) + "." + str(bpy.app.version[1])
file_version = (
str(context.blend_data.version[0])
+ "."
+ str(context.blend_data.version[1])
)
def draw(self, _context: Context) -> None:
column = self.layout.row(align=True).column()
text = pgettext(
"The current file is not compatible with the running Blender.\n"
+ "The file was created in Blender {file_version}, but the running Blender"
+ " version is {app_version}.\n"
+ "The current file was created in Blender {file_version}, but the running"
+ " Blender version is {app_version}.\n"
+ "So it is not compatible. As a result some data may be lost or corrupted."
).format(
app_version=app_version,
file_version=file_version,
app_version=self.app_version,
file_version=self.file_version,
)
description_outer_column = column.column()
description_outer_column.emboss = "NONE"
Expand All @@ -395,35 +392,40 @@ def draw(self, context: Context) -> None:
)
open_url.url = "https://developer.blender.org/docs/handbook/guidelines/compatibility_handling_for_blend_files/#forward-compatibility"

if TYPE_CHECKING:
# This code is auto generated.
# `poetry run python tools/property_typing.py`
file_version: str # type: ignore[no-redef]
app_version: str # type: ignore[no-redef]


class VRM_OT_show_blend_file_vrm_addon_compatibility_warning(Operator):
bl_idname = "vrm.show_blend_file_vrm_addon_compatibility_warning"
class VRM_OT_show_blend_file_addon_compatibility_warning(Operator):
bl_idname = "vrm.show_blend_file_addon_compatibility_warning"
bl_label = "VRM Add-on Compatibility Warning"
bl_description = "Show Blend File and VRM Add-on Compatibility Warning"
bl_options: AbstractSet[str] = {"REGISTER"}

file_addon_version: StringProperty(options={"HIDDEN"}) # type: ignore[valid-type]
installed_addon_version: StringProperty(options={"HIDDEN"}) # type: ignore[valid-type]

def execute(self, _context: Context) -> set[str]:
return {"FINISHED"}

def invoke(self, context: Context, _event: Event) -> set[str]:
return context.window_manager.invoke_props_dialog(self, width=500)

def draw(self, context: Context) -> None:
app_version = str(bpy.app.version[0]) + "." + str(bpy.app.version[1])
file_version = (
str(context.blend_data.version[0])
+ "."
+ str(context.blend_data.version[1])
)
def draw(self, _context: Context) -> None:
column = self.layout.row(align=True).column()
text = pgettext(
"The current file is not compatible with the current VRM Add-on.\n"
+ "The file was created in VRM Add-on {file_version}, but the current"
+ " VRM Add-on version is {app_version}.\n"
+ "So it is not compatible. As a result some data may be lost or corrupted."
"The current file is not compatible with the installed VRM Add-on.\n"
+ "The current file was created in VRM Add-on {file_addon_version}, but the"
+ " installed\n"
+ "VRM Add-on version is {installed_addon_version}. So it is not"
+ " compatible. As a result some\n"
+ "data may be lost or corrupted."
).format(
current_version=app_version,
file_version=file_version,
file_addon_version=self.file_addon_version,
installed_addon_version=self.installed_addon_version,
)
description_outer_column = column.column()
description_outer_column.emboss = "NONE"
Expand All @@ -432,6 +434,12 @@ def draw(self, context: Context) -> None:
icon = "ERROR" if i == 0 else "NONE"
description_column.label(text=line, translate=False, icon=icon)

if TYPE_CHECKING:
# This code is auto generated.
# `poetry run python tools/property_typing.py`
file_addon_version: str # type: ignore[no-redef]
installed_addon_version: str # type: ignore[no-redef]


__Operator = TypeVar("__Operator", bound=Operator)

Expand Down
24 changes: 17 additions & 7 deletions src/io_scene_vrm/locale/ja_jp.py
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,8 @@
(
"*",
"The current file is not compatible with the running Blender.\n"
+ "The file was created in Blender {file_version}, but the running Blender"
+ " version is {app_version}.\n"
+ "The current file was created in Blender {file_version}, but the running"
+ " Blender version is {app_version}.\n"
+ "So it is not compatible. As a result some data may be lost or corrupted.",
): "現在のファイルは実行中のBlenderと互換性がありません。\n"
+ "現在のファイルはBlender {file_version}で作られたファイルですが、"
Expand All @@ -609,9 +609,19 @@
("VrmAddon", "Open Documentation"): "関連ドキュメントを開く",
(
"*",
"The current file is not compatible with the current VRM Add-on.\n"
+ "The file was created in VRM Add-on {file_version}, but the current"
+ " VRM Add-on version is {app_version}.\n"
+ "So it is not compatible. As a result some data may be lost or corrupted.",
): "VRMアドオンのバージョンが合ってないっす {file_version} vs {app_version}",
"The current file is not compatible with the installed VRM Add-on.\n"
+ "The current file was created in VRM Add-on {file_addon_version}, but the"
+ " installed\n"
+ "VRM Add-on version is {installed_addon_version}. So it is not"
+ " compatible. As a result some\n"
+ "data may be lost or corrupted.",
): "現在のファイルはインストール済みのVRMアドオンと互換性がありません。\n"
+ "現在のファイルはVRMアドオンのバージョン{file_addon_version}で作られた"
+ "ファイルですが、\nインストール済みのVRMアドオンのバージョンは"
+ "{installed_addon_version}のため互換性がありません。\n"
+ "そのため、一部のデータが消えたり壊れたりすることがあります。",
(
"Operator",
"VRM Add-on Compatibility Warning",
): "VRMアドオンの互換性の警告",
}
2 changes: 1 addition & 1 deletion src/io_scene_vrm/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ def save_pre(_unused: object) -> None:
ops.VRM_OT_save_human_bone_mappings,
ops.VRM_OT_load_human_bone_mappings,
ops.VRM_OT_show_blend_file_compatibility_warning,
ops.VRM_OT_show_blend_file_vrm_addon_compatibility_warning,
ops.VRM_OT_show_blend_file_addon_compatibility_warning,
validation.VrmValidationError,
validation.WM_OT_vrm_validator,
export_scene.WM_OT_vrm_export_human_bones_assignment,
Expand Down

0 comments on commit 7c6c48b

Please sign in to comment.