You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h

515 lines
18 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <QCoreApplication>
#include <AzCore/Serialization/Json/StackedString.h>
#include <AzCore/std/string/conversions.h>
#include <ScriptCanvas/Core/Slot.h>
#include <GraphCanvas/Types/TranslationTypes.h>
namespace ScriptCanvasEditor
{
enum class TranslationContextGroup : AZ::u32
{
EbusSender,
EbusHandler,
ClassMethod,
GlobalMethod,
Invalid
};
enum class TranslationItemType : AZ::u32
{
Node,
Wrapper,
ExecutionInSlot,
ExecutionOutSlot,
ParamDataSlot,
ReturnDataSlot,
BusIdSlot,
Invalid
};
enum class TranslationKeyId : AZ::u32
{
Name,
Tooltip,
Category,
Invalid
};
namespace TranslationContextGroupParts
{
const char* const ebusSender = "EBus";
const char* const ebusHandler = "Handler";
const char* const classMethod = "Method";
constexpr const char* const globalMethod = "GlobalMethod";
};
namespace TranslationKeyParts
{
const char* const handler = "HANDLER_";
const char* const name = "NAME";
const char* const tooltip = "TOOLTIP";
const char* const category = "CATEGORY";
const char* const in = "IN";
const char* const out = "OUT";
const char* const param = "PARAM";
const char* const output = "OUTPUT";
const char* const busid = "BUSID";
}
// The context name and keys generated by TranslationHelper should match the keys
// being exported by the TSGenerateAction.cpp in the ScriptCanvasDeveloper Gem.
class TranslationHelper
{
public:
static AZStd::string GetContextName(TranslationContextGroup group, AZStd::string_view keyBase)
{
if (group == TranslationContextGroup::Invalid || keyBase.empty())
{
// Missing information
return AZStd::string();
}
const char* groupPart;
switch (group)
{
case TranslationContextGroup::EbusSender:
groupPart = TranslationContextGroupParts::ebusSender;
break;
case TranslationContextGroup::EbusHandler:
groupPart = TranslationContextGroupParts::ebusHandler;
break;
case TranslationContextGroup::ClassMethod:
groupPart = TranslationContextGroupParts::classMethod;
break;
case TranslationContextGroup::GlobalMethod:
groupPart = TranslationContextGroupParts::globalMethod;
break;
default:
AZ_Warning("TranslationComponent", false, "Invalid translation group ID.");
groupPart = "";
}
AZStd::string fullKey = AZStd::string::format("%s: %.*s", groupPart,
aznumeric_cast<int>(keyBase.size()), keyBase.data());
return fullKey;
}
// UserDefined
static AZStd::string GetUserDefinedContext(AZStd::string_view contextName)
{
return GetContextName(TranslationContextGroup::ClassMethod, contextName);
}
static AZStd::string GetUserDefinedKey(AZStd::string_view contextName, TranslationKeyId keyId)
{
return GetClassKey(TranslationContextGroup::ClassMethod, contextName, keyId);
}
static AZStd::string GetUserDefinedNodeKey(AZStd::string_view contextName, AZStd::string_view nodeName, TranslationKeyId keyId)
{
return GetKey(TranslationContextGroup::ClassMethod, contextName, nodeName, TranslationItemType::Node, keyId);
}
static AZStd::string GetUserDefinedNodeSlotKey(AZStd::string_view contextName, AZStd::string_view nodeName, TranslationItemType itemType, TranslationKeyId keyId, int slotIndex)
{
return GetKey(TranslationContextGroup::ClassMethod, contextName, nodeName, itemType, keyId, slotIndex);
}
////
// EBusEvent
static AZStd::string GetEbusHandlerContext(AZStd::string_view busName)
{
return GetContextName(TranslationContextGroup::EbusHandler, busName);
}
static AZStd::string GetEbusHandlerKey(AZStd::string_view busName, TranslationKeyId keyId)
{
return GetClassKey(TranslationContextGroup::EbusHandler, busName, keyId);
}
static AZStd::string GetEbusHandlerEventKey(AZStd::string_view busName, AZStd::string_view eventName, TranslationKeyId keyId)
{
return GetKey(TranslationContextGroup::EbusHandler, busName, eventName, TranslationItemType::Node, keyId);
}
static AZStd::string GetEBusHandlerSlotKey(AZStd::string_view busName, AZStd::string_view eventName, TranslationItemType type, TranslationKeyId keyId, int paramIndex)
{
return GetKey(TranslationContextGroup::EbusHandler, busName, eventName, type, keyId, paramIndex);
}
////
static AZStd::string GetKey(TranslationContextGroup group, AZStd::string_view keyBase, AZStd::string_view keyName, TranslationItemType type, TranslationKeyId keyId, int paramIndex = 0)
{
if (group == TranslationContextGroup::Invalid || keyBase.empty()
|| type == TranslationItemType::Invalid || keyId == TranslationKeyId::Invalid)
{
// Missing information
return AZStd::string();
}
if (type != TranslationItemType::Wrapper && keyName.empty())
{
// Missing information
return AZStd::string();
}
AZStd::string fullKey;
const char* prefix = "";
if (group == TranslationContextGroup::EbusHandler)
{
prefix = TranslationKeyParts::handler;
}
const char* keyPart = GetKeyPart(keyId);
switch (type)
{
case TranslationItemType::Node:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
keyPart
);
break;
case TranslationItemType::Wrapper:
fullKey = GetClassKey(group, keyBase, keyId);
break;
case TranslationItemType::ExecutionInSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::in,
keyPart
);
break;
case TranslationItemType::ExecutionOutSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::out,
keyPart
);
break;
case TranslationItemType::ParamDataSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::param,
paramIndex,
keyPart
);
break;
case TranslationItemType::ReturnDataSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::output,
paramIndex,
keyPart
);
break;
case TranslationItemType::BusIdSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::busid,
keyPart
);
break;
default:
AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation item type.");
}
AZStd::to_upper(fullKey.begin(), fullKey.end());
return fullKey;
}
static AZStd::string GetClassKey(TranslationContextGroup group, AZStd::string_view keyBase, TranslationKeyId keyId)
{
const char* prefix = "";
if (group == TranslationContextGroup::EbusHandler)
{
prefix = TranslationKeyParts::handler;
}
const char* keyPart = GetKeyPart(keyId);
AZStd::string fullKey = AZStd::string::format("%s%.*s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
keyPart
);
AZStd::to_upper(fullKey.begin(), fullKey.end());
return fullKey;
}
static AZStd::string GetGlobalMethodKey(AZStd::string_view keyName, TranslationItemType keyType,
TranslationKeyId keyId, int paramIndex = 0)
{
const char* keyPart = GetKeyPart(keyId);
AZStd::string fullKey;
switch (keyType)
{
case TranslationItemType::Node:
fullKey = AZStd::string::format("%.*s_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
keyPart
);
break;
case TranslationItemType::ExecutionInSlot:
fullKey = AZStd::string::format("%.*s_%s_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::in,
keyPart
);
break;
case TranslationItemType::ExecutionOutSlot:
fullKey = AZStd::string::format("%.*s_%s_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::out,
keyPart
);
break;
case TranslationItemType::ParamDataSlot:
fullKey = AZStd::string::format("%.*s_%s%d_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::param,
paramIndex,
keyPart
);
break;
case TranslationItemType::ReturnDataSlot:
fullKey = AZStd::string::format("%.*s_%s%d_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::output,
paramIndex,
keyPart
);
break;
default:
AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation item type.");
}
AZStd::to_upper(fullKey.begin(), fullKey.end());
return fullKey;
}
static const char* GetKeyPart(TranslationKeyId keyId)
{
const char* keyPart = "";
switch (keyId)
{
case TranslationKeyId::Name:
keyPart = TranslationKeyParts::name;
break;
case TranslationKeyId::Tooltip:
keyPart = TranslationKeyParts::tooltip;
break;
case TranslationKeyId::Category:
keyPart = TranslationKeyParts::category;
break;
default:
AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation key ID.");
}
return keyPart;
}
static TranslationItemType GetItemType(ScriptCanvas::SlotDescriptor slotDescriptor)
{
if (slotDescriptor == ScriptCanvas::SlotDescriptors::ExecutionIn())
{
return TranslationItemType::ExecutionInSlot;
}
else if (slotDescriptor == ScriptCanvas::SlotDescriptors::ExecutionOut())
{
return TranslationItemType::ExecutionOutSlot;
}
else if (slotDescriptor == ScriptCanvas::SlotDescriptors::DataIn())
{
return TranslationItemType::ParamDataSlot;
}
else if (slotDescriptor == ScriptCanvas::SlotDescriptors::DataOut())
{
return TranslationItemType::ReturnDataSlot;
}
return TranslationItemType::Invalid;
}
static AZStd::string GetSafeTypeName(ScriptCanvas::Data::Type dataType)
{
if (!dataType.IsValid())
{
return "";
}
return ScriptCanvas::Data::GetName(dataType);
}
static AZStd::string GetKeyTranslation(TranslationContextGroup group, AZStd::string_view keyBase, AZStd::string_view keyName, TranslationItemType type, TranslationKeyId keyId, int paramIndex = 0)
{
AZStd::string translationContext = TranslationHelper::GetContextName(group, keyBase);
AZStd::string translationKey = TranslationHelper::GetKey(group, keyBase, keyName, type, keyId, paramIndex);
AZStd::string translated = QCoreApplication::translate(translationContext.c_str(), translationKey.c_str()).toUtf8().data();
if (translated == translationKey)
{
return AZStd::string();
}
return translated;
}
static AZStd::string GetClassKeyTranslation(TranslationContextGroup group, AZStd::string_view keyBase, TranslationKeyId keyId)
{
AZStd::string translationContext = TranslationHelper::GetContextName(group, keyBase);
AZStd::string translationKey = TranslationHelper::GetClassKey(group, keyBase, keyId);
AZStd::string translated = QCoreApplication::translate(translationContext.c_str(), translationKey.c_str()).toUtf8().data();
if (translated == translationKey)
{
return AZStd::string();
}
return translated;
}
static AZStd::string GetGlobalMethodKeyTranslation(AZStd::string_view keyName,
TranslationItemType keyType, TranslationKeyId keyId, int paramIndex = 0)
{
AZStd::string translationKey = TranslationHelper::GetGlobalMethodKey(keyName, keyType, keyId, paramIndex);
AZStd::string translated = QCoreApplication::translate(TranslationContextGroupParts::globalMethod, translationKey.c_str()).toUtf8().data();
if (translated == translationKey)
{
return AZStd::string();
}
return translated;
}
static GraphCanvas::TranslationKeyedString GetEBusHandlerBusIdNameKey()
{
GraphCanvas::TranslationKeyedString keyedString;
keyedString.m_context = "Globals";
keyedString.m_key = "DEFAULTS_EBUSHANDLER_BUSID_NAME";
keyedString.SetFallback("BusId");
return keyedString;
}
static GraphCanvas::TranslationKeyedString GetEBusHandlerBusIdTooltipKey()
{
GraphCanvas::TranslationKeyedString keyedString;
keyedString.m_context = "Globals";
keyedString.m_key = "DEFAULTS_EBUSHANDLER_BUSID_TOOLTIP";
keyedString.SetFallback("BusId");
return keyedString;
}
static GraphCanvas::TranslationKeyedString GetEBusHandlerOnEventTriggeredNameKey()
{
GraphCanvas::TranslationKeyedString keyedString;
keyedString.m_context = "Globals";
keyedString.m_key = "DEFAULTS_EBUSHANDLER_ONTRIGGERED_NAME";
keyedString.SetFallback("Out");
return keyedString;
}
static GraphCanvas::TranslationKeyedString GetEBusHandlerOnEventTriggeredTooltipKey()
{
GraphCanvas::TranslationKeyedString keyedString;
keyedString.m_context = "Globals";
keyedString.m_key = "DEFAULTS_EBUSHANDLER_ONTRIGGERED_TOOLTIP";
keyedString.SetFallback("Out");
return keyedString;
}
static GraphCanvas::TranslationKeyedString GetEBusSenderBusIdNameKey()
{
GraphCanvas::TranslationKeyedString keyedString;
keyedString.m_context = "Globals";
keyedString.m_key = "DEFAULTS_EBUSSENDER_BUSID_NAME";
keyedString.SetFallback("BusId");
return keyedString;
}
static GraphCanvas::TranslationKeyedString GetEBusSenderBusIdTooltipKey()
{
GraphCanvas::TranslationKeyedString keyedString;
keyedString.m_context = "Globals";
keyedString.m_key = "DEFAULTS_EBUSSENDER_BUSID_TOOLTIP";
keyedString.SetFallback("BusId");
return keyedString;
}
// Use the StackedString to index the translation keys as a Json Pointer
static constexpr AZStd::string_view GetAzEventHandlerContextKey()
{
return { "AzEventHandler" };
}
// Use the StackedString to index the translation keys as a Json Pointer
static AZ::StackedString GetAzEventHandlerRootPointer(AZStd::string_view eventName)
{
AZ::StackedString path(AZ::StackedString::Format::JsonPointer);
path.Push(eventName);
return path;
}
};
}