bool FStructureEditorUtils::AddVariable(UBlueprint* Blueprint, FName StructName, const FEdGraphPinType& VarType)
{
	if (NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("AddVariable", "Add Variable") );
		Blueprint->Modify();

		FBPStructureDescription* StructureDesc = Blueprint->UserDefinedStructures.FindByPredicate(FFindByNameHelper(StructName));
		if (StructureDesc)
		{
			FString ErrorMessage;
			if (!CanHaveAMemberVariableOfType(StructureDesc->CompiledStruct, VarType, &ErrorMessage))
			{
				UE_LOG(LogBlueprint, Warning, TEXT("%s"), *ErrorMessage);
				return false;
			}

			const FName VarName = FMemberVariableNameHelper::Generate(StructureDesc->CompiledStruct, FString());
			check(NULL == StructureDesc->Fields.FindByPredicate(FFindByNameHelper(VarName)));
			const FString DisplayName = VarName.ToString();
			check(IsUniqueVariableDisplayName(Blueprint, StructName, DisplayName));

			FBPVariableDescription NewVar;
			NewVar.VarName = VarName;
			NewVar.FriendlyName = DisplayName;
			NewVar.VarType = VarType;
			NewVar.VarGuid = FGuid::NewGuid();
			StructureDesc->Fields.Add(NewVar);

			OnStructureChanged(*StructureDesc, Blueprint);
			return true;
		}
	}
	return false;
}
bool FStructureEditorUtils::ChangeVariableType(UUserDefinedStruct* Struct, FGuid VarGuid, const FEdGraphPinType& NewType)
{
    if (Struct)
    {
        FString ErrorMessage;
        if(!CanHaveAMemberVariableOfType(Struct, NewType, &ErrorMessage))
        {
            UE_LOG(LogBlueprint, Warning, TEXT("%s"), *ErrorMessage);
            return false;
        }

        auto VarDesc = GetVarDescByGuid(Struct, VarGuid);
        if(VarDesc)
        {
            const bool bChangedType = (VarDesc->ToPinType() != NewType);
            if (bChangedType)
            {
                const FScopedTransaction Transaction(LOCTEXT("ChangeVariableType", "Change Variable Type"));
                ModifyStructData(Struct);

                VarDesc->VarName = FMemberVariableNameHelper::Generate(Struct, VarDesc->FriendlyName, VarDesc->VarGuid);
                VarDesc->DefaultValue = FString();
                VarDesc->SetPinType(NewType);

                OnStructureChanged(Struct);
                return true;
            }
        }
    }
    return false;
}
bool FStructureEditorUtils::AddVariable(UUserDefinedStruct* Struct, const FEdGraphPinType& VarType)
{
    if (Struct)
    {
        const FScopedTransaction Transaction( LOCTEXT("AddVariable", "Add Variable") );
        ModifyStructData(Struct);

        FString ErrorMessage;
        if (!CanHaveAMemberVariableOfType(Struct, VarType, &ErrorMessage))
        {
            UE_LOG(LogBlueprint, Warning, TEXT("%s"), *ErrorMessage);
            return false;
        }

        const FGuid Guid = FGuid::NewGuid();
        FString DisplayName;
        const FName VarName = FMemberVariableNameHelper::Generate(Struct, FString(), Guid, &DisplayName);
        check(NULL == GetVarDesc(Struct).FindByPredicate(FStructureEditorUtils::FFindByNameHelper<FStructVariableDescription>(VarName)));
        check(IsUniqueVariableDisplayName(Struct, DisplayName));

        FStructVariableDescription NewVar;
        NewVar.VarName = VarName;
        NewVar.FriendlyName = DisplayName;
        NewVar.SetPinType(VarType);
        NewVar.VarGuid = Guid;
        NewVar.bDontEditoOnInstance = false;
        NewVar.bInvalidMember = false;
        GetVarDesc(Struct).Add(NewVar);

        OnStructureChanged(Struct);
        return true;
    }
    return false;
}
bool FStructureEditorUtils::ChangeVariableType(UBlueprint* Blueprint, FName StructName, FGuid VarGuid, const FEdGraphPinType& NewType)
{
	if(NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("ChangeVariableType", "Change Variable Type") );
		Blueprint->Modify();

		FBPStructureDescription* StructureDesc = Blueprint->UserDefinedStructures.FindByPredicate(FFindByNameHelper(StructName));
		if(StructureDesc)
		{
			FString ErrorMessage;
			if(!CanHaveAMemberVariableOfType(StructureDesc->CompiledStruct, NewType, &ErrorMessage))
			{
				UE_LOG(LogBlueprint, Warning, TEXT("%s"), *ErrorMessage);
				return false;
			}

			FBPVariableDescription* VarDesc = StructureDesc->Fields.FindByPredicate(FFindByGuidHelper(VarGuid));
			if(VarDesc && (NewType != VarDesc->VarType))
			{
				VarDesc->VarName = FMemberVariableNameHelper::Generate(StructureDesc->CompiledStruct, VarDesc->FriendlyName);
				VarDesc->DefaultValue = FString();
				VarDesc->VarType = NewType;

				OnStructureChanged(*StructureDesc, Blueprint);
				return true;
			}
		}
	}
	return false;
}