Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified Content/ELTEditorWidget_BP.uasset
Binary file not shown.
94 changes: 94 additions & 0 deletions Source/EasyLocalizationToolEditor/Private/ELTEditor.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
// Copyright (c) 2026 Damian Nowakowski. All rights reserved.

#include "ELTEditor.h"
#include "AssetToolsModule.h"
#include "Internationalization/TextLocalizationResource.h"
#include "Internationalization/TextLocalizationManager.h"
#include "Internationalization/StringTableCore.h"
#include "Internationalization/StringTable.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Misc/MessageDialog.h"
#include "ELTEditorSettings.h"
#include "ELTEditorWidget.h"
#include "ELTSettings.h"
#include "UObject/SavePackage.h"

#if ((ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION >= 1))
#include "AssetRegistry/AssetRegistryModule.h"
Expand Down Expand Up @@ -162,6 +166,7 @@ void UELTEditor::InitializeTheWidget()
EditorWidget->OnGlobalNamespaceChangedDelegate.BindUObject(this, &UELTEditor::OnGlobalNamespaceChanged);
EditorWidget->OnSeparatorChangedDelegate.BindUObject(this, &UELTEditor::OnSeparatorChanged);
EditorWidget->OnFallbackWhenEmptyChangedDelegate.BindUObject(this, &UELTEditor::OnFallbackWhenEmptyChanged);
EditorWidget->OnGenerateKeyReferenceStringTableChangedDelegate.BindUObject(this, &UELTEditor::OnGenerateKeyReferenceStringTableChanged);
EditorWidget->OnLogDebugChangedDelegate.BindUObject(this, &UELTEditor::OnLogDebugChanged);
EditorWidget->OnPreviewInUIChangedDelegate.BindUObject(this, &UELTEditor::OnPreviewInUIChanged);

Expand Down Expand Up @@ -198,6 +203,9 @@ void UELTEditor::InitializeTheWidget()
EditorWidget->CallSetLocalizationOnFirstRun(UELTSettings::GetOverrideLanguageAtFirstLaunch());
EditorWidget->CallSetLocalizationOnFirstRunLang(UELTSettings::GetLanguageToOverrideAtFirstLaunch());

// Set the Generate Key Reference String Table current value to the Widget.
EditorWidget->CallSetGenerateKeyReferenceStringTable(UELTEditorSettings::GetGenerateKeyReferenceStringTable());

// Set LogDebug value to the Widget.
EditorWidget->CallSetLogDebug(UELTEditorSettings::GetLogDebug());

Expand Down Expand Up @@ -357,6 +365,11 @@ void UELTEditor::OnFallbackWhenEmptyChanged(const FString& NewFallback)
UELTEditorSettings::SetFallbackWhenEmpty(NewFallback);
}

void UELTEditor::OnGenerateKeyReferenceStringTableChanged(bool bNewGenerateKeyReferenceStringTable)
{
UELTEditorSettings::SetGenerateKeyReferenceStringTable(bNewGenerateKeyReferenceStringTable);
}

void UELTEditor::OnLogDebugChanged(bool bNewLogDebug)
{
// "Log Debug" flag has been changed in the Widget. Save this setting.
Expand Down Expand Up @@ -502,8 +515,12 @@ bool UELTEditor::GenerateLocFilesImpl(const TArray<FString>& CSVPaths, const FSt

const FString MetaFileName = LocPath / LocName + TEXT(".locmeta");
const bool bLogDebug = UELTEditorSettings::GetLogDebug();
const bool bGenerateStringTable = UELTEditorSettings::GetGenerateKeyReferenceStringTable();

bool bFirstCSV = true;
TMap<FString, FTextLocalizationResource> LocReses;
TMap<FString, TSet<FString>> NamespaceToKeysMap;

for (const FString& CSVPath : CSVPaths)
{
const FString CSVFilePath = FPaths::ConvertRelativePathToFull(CSVPath);
Expand Down Expand Up @@ -636,6 +653,11 @@ bool UELTEditor::GenerateLocFilesImpl(const TArray<FString>& CSVPaths, const FSt
Keys.Values[Key],
LocalizedString,
0);

if (bGenerateStringTable && !Keys.Values[Key].IsEmpty())
{
NamespaceToKeysMap.FindOrAdd(Namespace).Add(Keys.Values[Key]);
}
}
}
}
Expand Down Expand Up @@ -674,6 +696,78 @@ bool UELTEditor::GenerateLocFilesImpl(const TArray<FString>& CSVPaths, const FSt
LocRes.Value.SaveToFile(LocFileName);
}

// Generate Key Reference String Table
if (bGenerateStringTable && NamespaceToKeysMap.Num() > 0)
{
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");

for (const auto& KVP : NamespaceToKeysMap)
{
const FString& Namespace = KVP.Key;
const TSet<FString>& Keys = KVP.Value;

FString AssetName = FString::Printf(TEXT("ELT_KeyReferences_%s_%s"), *LocName, *Namespace);
FString VirtualPath = LocPath.StartsWith(TEXT("/Game")) ? LocPath : FPackageName::FilenameToLongPackageName(LocPath);
FString PackagePath = FPaths::Combine(VirtualPath, AssetName);
FPaths::NormalizeFilename(PackagePath);

if (!PackagePath.StartsWith(TEXT("/")))
{
PackagePath = TEXT("/") + PackagePath;
}

UPackage* Package = CreatePackage(*PackagePath);
if (!Package)
{
OutMessage = FString::Printf(TEXT("ERROR: Failed to create package path for StringTable: %s"), *PackagePath);
return false;
}

UStringTable* StringTableAsset = Cast<UStringTable>(StaticFindObject(UStringTable::StaticClass(), Package, *AssetName));
if (!StringTableAsset)
{
StringTableAsset = Cast<UStringTable>(AssetToolsModule.Get().CreateAsset(
AssetName,
VirtualPath,
UStringTable::StaticClass(),
nullptr
));
}

if (!StringTableAsset)
{
OutMessage = FString::Printf(TEXT("ERROR: Failed to create StringTable asset: %s"), *AssetName);
return false;
}

FStringTableRef StringTableRef = StringTableAsset->GetMutableStringTable();
StringTableRef->SetNamespace(Namespace);

for (const FString& Key : Keys)
{
StringTableRef->SetSourceString(FTextKey(Key), Key);
}

Package->MarkPackageDirty();

FString PackageFileName = FPackageName::LongPackageNameToFilename(PackagePath, FPackageName::GetAssetPackageExtension());
FSavePackageArgs SaveArgs;
SaveArgs.TopLevelFlags = RF_Public | RF_Standalone;
SaveArgs.Error = GError;

if (!UPackage::SavePackage(Package, StringTableAsset, *PackageFileName, SaveArgs))
{
OutMessage = FString::Printf(TEXT("ERROR: Failed to save StringTable package file to disk path: %s"), *PackageFileName);
return false;
}

if (bLogDebug)
{
UE_LOG(ELTEditorLog, Log, TEXT("Saved String Table Asset: %s"), *PackageFileName);
}
}
}

OutMessage = TEXT("SUCCESS: Localization import complete!");
return true;
}
Expand Down
10 changes: 10 additions & 0 deletions Source/EasyLocalizationToolEditor/Private/ELTEditorSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ void UELTEditorSettings::SetReimportAtEditorStartup(bool bNewReimportAtEditorSta
ELTE_SET_SETTING(bReimportAtEditorStartup, bNewReimportAtEditorStartup);
}

bool UELTEditorSettings::GetGenerateKeyReferenceStringTable()
{
ELTE_GET_SETTING(bGenerateKeyReferenceStringTable);
}

void UELTEditorSettings::SetGenerateKeyReferenceStringTable(bool bNewGenerateKeyReferenceStringTable)
{
ELTE_SET_SETTING(bGenerateKeyReferenceStringTable, bNewGenerateKeyReferenceStringTable);
}

bool UELTEditorSettings::GetPreviewInUIEnabled()
{
ELTE_GET_SETTING(bPreviewInUI);
Expand Down
17 changes: 17 additions & 0 deletions Source/EasyLocalizationToolEditor/Private/ELTEditorWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,18 @@ void UELTEditorWidget::CallSetLocalizationOnFirstRun(bool LocalizationOnFirstRun
#endif
}

void UELTEditorWidget::CallSetGenerateKeyReferenceStringTable(bool bGenerateKeyReferenceStringTable)
{
#if ELTEDITOR_USE_SLATE_EDITOR_UI
if (MyWidget.IsValid())
{
MyWidget->SetGenerateKeyReferenceStringTable(bGenerateKeyReferenceStringTable);
}
#else
SetReimportAtEditorStartup(bReimportAtEditorStartup);
#endif
}

void UELTEditorWidget::CallSetLocalizationOnFirstRunLang(const FString& OnFirstRunLang)
{
#if ELTEDITOR_USE_SLATE_EDITOR_UI
Expand Down Expand Up @@ -281,6 +293,11 @@ void UELTEditorWidget::OnLocalizationOnFirstRunLangChanged(const FString& OnFirs
OnLocalizationOnFirstRunLangChangedDelegate.ExecuteIfBound(OnFirstRunLang);
}

void UELTEditorWidget::OnGenerateKeyReferenceStringTableChanged(bool bGenerateKeyReferenceStringTable)
{
OnGenerateKeyReferenceStringTableChangedDelegate.ExecuteIfBound(bGenerateKeyReferenceStringTable);
}

void UELTEditorWidget::OnGlobalNamespaceChanged(const FString& NewGlobalNamespace)
{
OnGlobalNamespaceChangedDelegate.ExecuteIfBound(NewGlobalNamespace);
Expand Down
42 changes: 42 additions & 0 deletions Source/EasyLocalizationToolEditor/Private/SELTEditorWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,43 @@ KEY - use the key of this entry"))
]
]
]
// > Generate Key Reference String Table on Import Box ================
+SVerticalBox::Slot()
.AutoHeight()
.Padding(FMargin(0.f, 4.f, 0.f, 0.f))
[
SNew(SHorizontalBox)
.ToolTipText(INVTEXT("\
On CSV Import, a String Table filled with Key References will be generated PER namespace.\n\
These String Table can be used to easily assign keys to FText properties.\n\n\
The String Table will be generated in the Localization Folder path and IS OVERRIDDEN if it already exists."))
// >>>> Generate Key Reference String Table CSV Import Label
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Font(FCoreStyle::GetDefaultFontStyle("Light", 12))
.Text(INVTEXT("Generate Key Reference String Table on Import:"))
]
// >>>> Generate Key Reference String Table on Import checkbox
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SCheckBox)
.IsChecked_Lambda([this]() -> ECheckBoxState
{
return bGenerateKeyReferenceStringTable_Chkbox ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
})
.OnCheckStateChanged_Lambda([this](ECheckBoxState InCheckBoxState) -> void
{
bGenerateKeyReferenceStringTable_Chkbox = (InCheckBoxState == ECheckBoxState::Checked);
if (WidgetController.IsValid())
{
WidgetController->OnGenerateKeyReferenceStringTableChanged(bGenerateKeyReferenceStringTable_Chkbox);
}
})
]
]
// > Spacer ================
+SVerticalBox::Slot()
.AutoHeight()
Expand Down Expand Up @@ -819,6 +856,11 @@ void SELTEditorWidget::SetFallbackWhenEmpty(const FString& FallbackWhenEmpty)
}
}

void SELTEditorWidget::SetGenerateKeyReferenceStringTable(bool bGenerateKeyReferenceStringTable)
{
bGenerateKeyReferenceStringTable_Chkbox = bGenerateKeyReferenceStringTable;
}

void SELTEditorWidget::SetLogDebug(bool bLogDebug)
{
bLogDebug_Chkbox = bLogDebug;
Expand Down
5 changes: 5 additions & 0 deletions Source/EasyLocalizationToolEditor/Public/ELTEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ class EASYLOCALIZATIONTOOLEDITOR_API UELTEditor : public UObject
*/
void OnFallbackWhenEmptyChanged(const FString& NewFallback);

/**
* Called when "GenerateKeyReferenceStringTable" option has been changed in the Widget.
*/
void OnGenerateKeyReferenceStringTableChanged(bool bNewGenerateKeyReferenceStringTable);

/**
* Called when "LogDebug" option has been changed in the Widget.
*/
Expand Down
8 changes: 7 additions & 1 deletion Source/EasyLocalizationToolEditor/Public/ELTEditorSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class EASYLOCALIZATIONTOOLEDITOR_API UELTEditorSettings : public UObject
static bool GetReimportAtEditorStartup();
static void SetReimportAtEditorStartup(bool bNewReimportAtEditorStartup);

static bool GetGenerateKeyReferenceStringTable();
static void SetGenerateKeyReferenceStringTable(bool bNewGenerateKeyReferenceStringTable);

/**
* Get/Set if the preview should be displayed on UI.
*/
Expand Down Expand Up @@ -99,7 +102,10 @@ class EASYLOCALIZATIONTOOLEDITOR_API UELTEditorSettings : public UObject

UPROPERTY(config)
bool bReimportAtEditorStartup = false;


UPROPERTY(config)
bool bGenerateKeyReferenceStringTable = false;

UPROPERTY(config)
bool bPreviewInUI = true;

Expand Down
16 changes: 16 additions & 0 deletions Source/EasyLocalizationToolEditor/Public/ELTEditorWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ DECLARE_DELEGATE_OneParam(FOnLocalizationPreviewLangChanged, const FString&);
DECLARE_DELEGATE_OneParam(FManuallySetLastLanguageChanged, bool);
DECLARE_DELEGATE_OneParam(FOnLocalizationOnFirstRunChanged, bool);
DECLARE_DELEGATE_OneParam(FOnLocalizationOnFirstRunLangChanged, const FString&);
DECLARE_DELEGATE_OneParam(FOnGenerateKeyReferenceStringTableChanged, bool);
DECLARE_DELEGATE_OneParam(FOnGlobalNamespaceChanged, const FString&);
DECLARE_DELEGATE_OneParam(FOnSeparatorChanged, const FString&);
DECLARE_DELEGATE_OneParam(FOnFallbackWhenEmptyChanged, const FString&);
Expand Down Expand Up @@ -196,6 +197,20 @@ class EASYLOCALIZATIONTOOLEDITOR_API UELTEditorWidget : public UEditorUtilityWid



/**
* Set "Generate Key Reference String Table On CSV Import" to the Widget.
*/
UFUNCTION(BlueprintImplementableEvent, Category = "Easy Localization Tool Editor")
void SetGenerateKeyReferenceStringTable(bool bGenerateKeyReferenceStringTable);
void CallSetGenerateKeyReferenceStringTable(bool bGenerateKeyReferenceStringTable);

/**
* "Generate Key Reference String Table On CSV Import" option has been changed on the Widget.
*/
UFUNCTION(BlueprintCallable, Category = "Easy Localization Tool Editor")
void OnGenerateKeyReferenceStringTableChanged(bool bGenerateKeyReferenceStringTable);


/**
* Set "Global Namespace" option to the Widget.
*/
Expand Down Expand Up @@ -287,6 +302,7 @@ class EASYLOCALIZATIONTOOLEDITOR_API UELTEditorWidget : public UEditorUtilityWid
FManuallySetLastLanguageChanged OnManuallySetLastLanguageChangedDelegate;
FOnLocalizationOnFirstRunChanged OnLocalizationOnFirstRunChangedDelegate;
FOnLocalizationOnFirstRunLangChanged OnLocalizationOnFirstRunLangChangedDelegate;
FOnGenerateKeyReferenceStringTableChanged OnGenerateKeyReferenceStringTableChangedDelegate;
FOnGlobalNamespaceChanged OnGlobalNamespaceChangedDelegate;
FOnSeparatorChanged OnSeparatorChangedDelegate;
FOnFallbackWhenEmptyChanged OnFallbackWhenEmptyChangedDelegate;
Expand Down
2 changes: 2 additions & 0 deletions Source/EasyLocalizationToolEditor/Public/SELTEditorWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class EASYLOCALIZATIONTOOLEDITOR_API SELTEditorWidget : public SUserWidget
void SetGlobalNamespace(const FString& GlobalNamespace);
void SetSeparator(const FString& Separator);
void SetFallbackWhenEmpty(const FString& FallbackWhenEmpty);
void SetGenerateKeyReferenceStringTable(bool bGenerateKeyReferenceStringTable);
void SetLogDebug(bool bLogDebug);
void SetPreviewInUI(bool bPreviewInUI);

Expand All @@ -54,6 +55,7 @@ class EASYLOCALIZATIONTOOLEDITOR_API SELTEditorWidget : public SUserWidget
bool bIsLocalisationPreviewEnabled_Chkbox = false;
bool bManuallySetLastLanguage_Chkbox = false;
bool bOverrideLanguageOnStartup_Chkbox = false;
bool bGenerateKeyReferenceStringTable_Chkbox = false;
bool bLogDebug_Chkbox = false;
bool bPreviewInUI_Chkbox = false;

Expand Down