/* * 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 #include #include #include #include #include #include #include namespace Translation { namespace GlobalKeys { static constexpr const char* EBusSenderIDKey = "Globals.EBusSenderBusId"; static constexpr const char* EBusHandlerIDKey = "Globals.EBusHandlerBusId"; static constexpr const char* MissingFunctionKey = "Globals.MissingFunction"; static constexpr const char* EBusHandlerOutSlot = "Globals.EBusHandler.OutSlot"; } static inline bool GetValue(const AZStd::string key, AZStd::string& value) { GraphCanvas::TranslationKey tkey; tkey = key; bool result = false; GraphCanvas::TranslationRequestBus::BroadcastResult(result, &GraphCanvas::TranslationRequests::Get, key, value); return result; } } namespace GraphCanvasAttributeHelper { template AZStd::string GetStringAttribute(const T* source, const AZ::Crc32& attribute) { AZStd::string attributeValue = ""; if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, source->m_attributes))) { attributeValue = attributeItem->Get(nullptr); } return attributeValue; } inline AZStd::string ReadStringAttribute(const AZ::AttributeArray& attributes, const AZ::Crc32& attribute) { AZStd::string attributeValue = ""; if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, attributes))) { attributeValue = attributeItem->Get(nullptr); return attributeValue; } if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, attributes))) { attributeValue = attributeItem->Get(nullptr); return attributeValue; } return {}; } } 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 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"; } namespace TranslationContextGroupParts { const char* const ebusSender = "EBus"; const char* const ebusHandler = "Handler"; const char* const classMethod = "Method"; constexpr const char* const globalMethod = "GlobalMethod"; }; // 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(keyBase.size()), keyBase.data()); return fullKey; } // UserDefined 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 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(keyBase.size()), keyBase.data(), aznumeric_cast(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(keyBase.size()), keyBase.data(), aznumeric_cast(keyName.size()), keyName.data(), TranslationKeyParts::in, keyPart ); break; case TranslationItemType::ExecutionOutSlot: fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s", prefix, aznumeric_cast(keyBase.size()), keyBase.data(), aznumeric_cast(keyName.size()), keyName.data(), TranslationKeyParts::out, keyPart ); break; case TranslationItemType::ParamDataSlot: fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s", prefix, aznumeric_cast(keyBase.size()), keyBase.data(), aznumeric_cast(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(keyBase.size()), keyBase.data(), aznumeric_cast(keyName.size()), keyName.data(), TranslationKeyParts::output, paramIndex, keyPart ); break; case TranslationItemType::BusIdSlot: fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s", prefix, aznumeric_cast(keyBase.size()), keyBase.data(), aznumeric_cast(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(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(keyName.size()), keyName.data(), keyPart ); break; case TranslationItemType::ExecutionInSlot: fullKey = AZStd::string::format("%.*s_%s_%s", aznumeric_cast(keyName.size()), keyName.data(), TranslationKeyParts::in, keyPart ); break; case TranslationItemType::ExecutionOutSlot: fullKey = AZStd::string::format("%.*s_%s_%s", aznumeric_cast(keyName.size()), keyName.data(), TranslationKeyParts::out, keyPart ); break; case TranslationItemType::ParamDataSlot: fullKey = AZStd::string::format("%.*s_%s%d_%s", aznumeric_cast(keyName.size()), keyName.data(), TranslationKeyParts::param, paramIndex, keyPart ); break; case TranslationItemType::ReturnDataSlot: fullKey = AZStd::string::format("%.*s_%s%d_%s", aznumeric_cast(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; } // 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; } }; }