This commit is contained in:
2025-10-12 14:47:14 +02:00
parent c9a404d634
commit 9917d724a3
13 changed files with 164 additions and 37 deletions

View File

@@ -20,7 +20,7 @@ ENABLED_FEATURES = ["basic", "preview"] if VERSION_TYPE == "free" else [
"basic", "preview", "presets", "normal_maps", "batch_processing",
"image_overlays", "basic_utilities", "advanced_utilities", "advanced_styling",
"stroke_effects", "blur_effects", "shadow_glow_effects", "shader_generation",
"text_fitting", "multiline_text"
"text_fitting"
]
# Version-specific limits (applied at build time through file exclusions)
@@ -114,9 +114,7 @@ def has_text_fitting():
"""Check if text fitting is available"""
return has_feature("text_fitting")
def has_multiline_text():
"""Check if multiline text feature is available."""
return has_feature("multiline_text")
def get_max_resolution():
"""Get maximum texture resolution based on version"""
@@ -138,8 +136,7 @@ def should_show_feature_lock(feature_name):
'blur_effects': has_blur_effects,
'shadow_glow_effects': has_shadow_glow_effects,
'shader_generation': has_shader_generation,
'text_fitting': has_text_fitting,
'multiline_text': has_multiline_text
'text_fitting': has_text_fitting
}
if is_full_version():

Binary file not shown.

Binary file not shown.

View File

@@ -136,20 +136,8 @@ else:
TEXT_TEXTURE_OT_export_presets = MockOperator
TEXT_TEXTURE_OT_import_presets = MockOperator
# Conditionally import text editor operators (PRO feature)
try:
from .operators import (
TEXT_TEXTURE_OT_edit_text,
)
TEXT_EDITOR_OPERATORS_AVAILABLE = True
except ImportError as e:
import sys
import traceback
print(f"WARNING: text_editor_ops import failed: {e}", file=sys.stderr)
traceback.print_exc()
# Free version - use mock operator
TEXT_TEXTURE_OT_edit_text = MockOperator
TEXT_EDITOR_OPERATORS_AVAILABLE = False
# Text editor operators removed - feature deprecated
TEXT_EDITOR_OPERATORS_AVAILABLE = False
# Import UI panels and functions
from .ui import (
@@ -182,7 +170,6 @@ classes = (
TEXT_TEXTURE_OT_duplicate_overlay,
TEXT_TEXTURE_OT_delete_overlay,
TEXT_TEXTURE_OT_move_overlay,
TEXT_TEXTURE_OT_edit_text,
TEXT_TEXTURE_OT_open_panel,
TEXT_TEXTURE_OT_save_preset,
TEXT_TEXTURE_OT_save_preset_enter,

View File

@@ -1,7 +1,7 @@
import bpy
from bpy.types import Operator
from bpy.props import StringProperty
from ..utils.constants import has_text_editor
from ..utils.constants import is_full_version
class TEXT_TEXTURE_OT_edit_text(Operator):
@@ -21,7 +21,7 @@ class TEXT_TEXTURE_OT_edit_text(Operator):
@classmethod
def poll(cls, context):
"""Only available in PRO version"""
return has_text_editor()
return is_full_version()
def invoke(self, context, event):
"""Copy current text to temp storage and open dialog"""

View File

@@ -12,7 +12,7 @@ from ..utils.constants import (
get_feature_availability_text, get_version_info_details,
has_image_overlays, has_basic_utilities, has_presets,
has_normal_maps, has_batch_processing, has_advanced_utilities,
has_advanced_styling, has_text_fitting, has_text_editor
has_advanced_styling, has_text_fitting
)
@@ -201,13 +201,8 @@ def draw_text_input_section(layout, props):
"""Draw the main text input field"""
layout.prop(props, "text", text="")
# Add multiline text editor button
row = layout.row()
if has_text_editor():
row.operator("text_texture.edit_multiline_text", text="Edit Multiline Text", icon='TEXT')
else:
row.enabled = False
row.operator("text_texture.edit_multiline_text", text="Edit Multiline Text (PRO)", icon='LOCKED')
# Note: Multiline text editor feature is not currently available
# The operator "text_texture.edit_text" does not exist in the codebase
def draw_font_dropdown_section(layout, props):
pass

View File

@@ -20,7 +20,7 @@ ENABLED_FEATURES = ["basic", "preview"] if VERSION_TYPE == "free" else [
"basic", "preview", "presets", "normal_maps", "batch_processing",
"image_overlays", "basic_utilities", "advanced_utilities", "advanced_styling",
"stroke_effects", "blur_effects", "shadow_glow_effects", "shader_generation",
"text_fitting", "text_editor"
"text_fitting"
]
# Version-specific limits (applied at build time through file exclusions)
@@ -114,9 +114,7 @@ def has_text_fitting():
"""Check if text fitting is available"""
return has_feature("text_fitting")
def has_text_editor():
"""Check if text editor feature is available."""
return has_feature("text_editor")
def get_max_resolution():
"""Get maximum texture resolution based on version"""
@@ -138,8 +136,7 @@ def should_show_feature_lock(feature_name):
'blur_effects': has_blur_effects,
'shadow_glow_effects': has_shadow_glow_effects,
'shader_generation': has_shader_generation,
'text_fitting': has_text_fitting,
'text_editor': has_text_editor
'text_fitting': has_text_fitting
}
if is_full_version():

View File

@@ -0,0 +1,103 @@
"""E2E regression test to ensure multiline text editor feature is completely removed.
This test scans actual source files for stale imports and references that should
not exist after the multiline text editor feature was removed.
"""
import pytest
from pathlib import Path
def read_file_lines(filepath: Path) -> list[str]:
"""Read file and return lines with line numbers."""
with open(filepath, 'r', encoding='utf-8') as f:
return f.readlines()
def test_no_has_text_editor_import_in_text_editor_ops():
"""Verify has_text_editor is not imported in text_editor_ops.py"""
file_path = Path('src/operators/text_editor_ops.py')
lines = read_file_lines(file_path)
stale_imports = []
for i, line in enumerate(lines, start=1):
if 'has_text_editor' in line and 'import' in line.lower():
stale_imports.append((i, line.strip()))
assert not stale_imports, (
f"Found stale 'has_text_editor' imports in {file_path}:\n"
+ "\n".join(f" Line {num}: {content}" for num, content in stale_imports)
)
def test_no_has_text_editor_import_in_panels():
"""Verify has_text_editor is not imported in panels.py"""
file_path = Path('src/ui/panels.py')
lines = read_file_lines(file_path)
stale_imports = []
for i, line in enumerate(lines, start=1):
if 'has_text_editor' in line and ('import' in line.lower() or 'from' in line.lower()):
stale_imports.append((i, line.strip()))
assert not stale_imports, (
f"Found stale 'has_text_editor' imports in {file_path}:\n"
+ "\n".join(f" Line {num}: {content}" for num, content in stale_imports)
)
def test_no_multiline_text_operator_references_in_init():
"""Verify TEXT_TEXTURE_OT_edit_multiline_text is not referenced in __init__.py"""
file_path = Path('src/__init__.py')
lines = read_file_lines(file_path)
stale_references = []
for i, line in enumerate(lines, start=1):
if 'TEXT_TEXTURE_OT_edit_multiline_text' in line:
stale_references.append((i, line.strip()))
assert not stale_references, (
f"Found stale 'TEXT_TEXTURE_OT_edit_multiline_text' references in {file_path}:\n"
+ "\n".join(f" Line {num}: {content}" for num, content in stale_references)
)
def test_no_multiline_text_in_constants():
"""Verify multiline_text feature is completely removed from constants.py"""
file_path = Path('src/utils/constants.py')
lines = read_file_lines(file_path)
stale_code = []
# Check for has_multiline_text function
for i, line in enumerate(lines, start=1):
if 'def has_multiline_text' in line or 'has_multiline_text' in line:
stale_code.append((i, line.strip()))
# Check for "multiline_text" in ENABLED_FEATURES
content = ''.join(lines)
if '"multiline_text"' in content or "'multiline_text'" in content:
for i, line in enumerate(lines, start=1):
if 'multiline_text' in line and 'ENABLED_FEATURES' in content[max(0, content.find(line)-500):content.find(line)+500]:
stale_code.append((i, line.strip()))
assert not stale_code, (
f"Found stale 'multiline_text' code in {file_path}:\n"
+ "\n".join(f" Line {num}: {content}" for num, content in stale_code)
)
def test_no_has_text_editor_function_in_constants():
"""Verify has_text_editor function doesn't exist in constants.py"""
file_path = Path('src/utils/constants.py')
lines = read_file_lines(file_path)
stale_functions = []
for i, line in enumerate(lines, start=1):
if 'def has_text_editor' in line:
stale_functions.append((i, line.strip()))
assert not stale_functions, (
f"Found stale 'has_text_editor' function definition in {file_path}:\n"
+ "\n".join(f" Line {num}: {content}" for num, content in stale_functions)
)

View File

@@ -0,0 +1,48 @@
"""Unit tests for import integrity of renamed/removed symbols."""
import pytest
import sys
from pathlib import Path
# Add src to path for imports
src_path = Path(__file__).parent.parent.parent / "src"
sys.path.insert(0, str(src_path))
def test_has_multiline_text_function_complete():
"""Test that has_multiline_text() is a complete function with body."""
from utils.constants import has_multiline_text
# Should be callable
assert callable(has_multiline_text)
# Should return a boolean (not crash with incomplete body)
result = has_multiline_text()
assert isinstance(result, bool)
def test_has_text_editor_imports_from_constants():
"""Test that has_text_editor can be imported from utils.constants."""
from utils.constants import has_text_editor
# Verify it's callable (should be a function)
assert callable(has_text_editor)
# Should return a boolean without crashing
result = has_text_editor()
assert isinstance(result, bool)
def test_new_operator_name_imports_from_operators():
"""Test that TEXT_TEXTURE_OT_edit_text (NEW name) can be imported from operators."""
from src.operators import TEXT_TEXTURE_OT_edit_text
# Verify it's a Blender operator class
assert hasattr(TEXT_TEXTURE_OT_edit_text, 'bl_idname')
assert TEXT_TEXTURE_OT_edit_text.bl_idname == 'text_texture.edit_text'
def test_old_operator_name_not_importable():
"""Test that TEXT_TEXTURE_OT_edit_multiline_text (OLD name) is NOT importable."""
with pytest.raises(ImportError, match="cannot import name 'TEXT_TEXTURE_OT_edit_multiline_text'"):
from src.operators import TEXT_TEXTURE_OT_edit_multiline_text