2014-12-07 19:09:38 -05:00
|
|
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
#include "TranslationEditorPrivatePCH.h"
|
|
|
|
|
|
|
|
|
|
#include "TranslationEditor.h"
|
|
|
|
|
#include "Toolkits/IToolkitHost.h"
|
|
|
|
|
#include "WorkspaceMenuStructureModule.h"
|
2014-04-23 19:14:07 -04:00
|
|
|
#include "MessageLog.h"
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
#include "Editor/PropertyEditor/Public/PropertyEditorModule.h"
|
|
|
|
|
#include "Editor/PropertyEditor/Public/IPropertyTable.h"
|
|
|
|
|
#include "Editor/PropertyEditor/Public/IPropertyTableColumn.h"
|
|
|
|
|
#include "Editor/PropertyEditor/Public/IPropertyTableRow.h"
|
|
|
|
|
#include "Editor/PropertyEditor/Public/IPropertyTableCell.h"
|
|
|
|
|
#include "Editor/PropertyEditor/Public/PropertyHandle.h"
|
|
|
|
|
#include "Editor/PropertyEditor/Public/PropertyPath.h"
|
|
|
|
|
#include "CustomFontColumn.h"
|
|
|
|
|
#include "DesktopPlatformModule.h"
|
|
|
|
|
#include "IPropertyTableWidgetHandle.h"
|
|
|
|
|
|
2014-04-23 19:06:27 -04:00
|
|
|
#include "TranslationUnit.h"
|
2014-04-23 18:48:34 -04:00
|
|
|
#include "SSearchBox.h"
|
2014-10-14 22:50:06 -04:00
|
|
|
#include "SDockTab.h"
|
2014-04-23 19:06:27 -04:00
|
|
|
#include "InternationalizationExportSettings.h"
|
2014-04-23 18:48:34 -04:00
|
|
|
|
2014-04-23 18:20:15 -04:00
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LocalizationExport, Log, All);
|
|
|
|
|
|
2014-03-14 14:13:41 -04:00
|
|
|
#define LOCTEXT_NAMESPACE "TranslationEditor"
|
|
|
|
|
|
Initial support for composite fonts for Slate, UMG, and Canvas
Slate now has the concept of composite fonts and font families (via FCompositeFont and FTypeface). A composite font is a font that contains a default font family, as well as any number of sub-font families which should be used for a given set of character ranges. This change will greatly improve the localization support for fonts.
UFont assets can now use two forms of caching "offline" (which is the way they have always worked historically), and "runtime" (which utilizes the Slate font cache to cache glyphs on demand). These runtime cached UFont assets are now the only way to specify which font to use for a UMG widget, and address the previous issues about ensuring that the required font files were staged for your game.
The Slate font cache now works on FFontData instances, rather than filenames. This allows the UFont asset to embed a blob of TTF or OTF font data inside it, rather than require the fonts be loaded from files on disk.
The Canvas text renderer has been updated to support runtime cached UFont assets. This gives our legacy Canvas based tools the same improved font localization support as the rest of the Slate-based editor UI.
UFont asset creation has been changed to use runtime caching by default, and additionally, you can now import a TTF or OTF file via the Content Browser and it will automatically create a UFont asset. If you still want an offline cached UFont asset, you can just change the cache type in the font editor, and the usual font picker dialog will appear and allow you to generate a font texture atlas.
[CL 2342203 by Jamie Dale in Main branch]
2014-10-28 09:02:03 -04:00
|
|
|
namespace TranslationEditorUtils
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/** Get the filename used by the given font info */
|
|
|
|
|
FString GetFontFilename(const FSlateFontInfo& InFontInfo)
|
|
|
|
|
{
|
|
|
|
|
const FCompositeFont* const ResolvedCompositeFont = InFontInfo.GetCompositeFont();
|
|
|
|
|
return (ResolvedCompositeFont && ResolvedCompositeFont->DefaultTypeface.Fonts.Num() > 0)
|
|
|
|
|
? ResolvedCompositeFont->DefaultTypeface.Fonts[0].Font.FontFilename
|
|
|
|
|
: "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace TranslationEditorUtils
|
|
|
|
|
|
2014-03-14 14:13:41 -04:00
|
|
|
const FName FTranslationEditor::UntranslatedTabId( TEXT( "TranslationEditor_Untranslated" ) );
|
|
|
|
|
const FName FTranslationEditor::ReviewTabId( TEXT( "TranslationEditor_Review" ) );
|
|
|
|
|
const FName FTranslationEditor::CompletedTabId( TEXT( "TranslationEditor_Completed" ) );
|
|
|
|
|
const FName FTranslationEditor::PreviewTabId( TEXT( "TranslationEditor_Preview" ) );
|
|
|
|
|
const FName FTranslationEditor::ContextTabId( TEXT( "TranslationEditor_Context" ) );
|
|
|
|
|
const FName FTranslationEditor::HistoryTabId( TEXT( "TranslationEditor_History" ) );
|
2014-04-23 18:48:34 -04:00
|
|
|
const FName FTranslationEditor::SearchTabId( TEXT( "TranslationEditor_Search" ) );
|
2014-04-23 19:14:07 -04:00
|
|
|
const FName FTranslationEditor::ChangedOnImportTabId( TEXT( "TranslationEditor_ChangedOnImport" ) );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
void FTranslationEditor::Initialize()
|
|
|
|
|
{
|
|
|
|
|
// Set up delegate functions for the buttons/spinboxes in the custom font columns' headers
|
|
|
|
|
SourceColumn->SetOnChangeFontButtonClicked(FOnClicked::CreateSP(this, &FTranslationEditor::ChangeSourceFont_FReply));
|
|
|
|
|
SourceColumn->SetOnFontSizeValueCommitted(FOnInt32ValueCommitted::CreateSP(this, &FTranslationEditor::OnSourceFontSizeCommitt));
|
|
|
|
|
TranslationColumn->SetOnChangeFontButtonClicked(FOnClicked::CreateSP(this, &FTranslationEditor::ChangeTranslationTargetFont_FReply));
|
|
|
|
|
TranslationColumn->SetOnFontSizeValueCommitted(FOnInt32ValueCommitted::CreateSP(this, &FTranslationEditor::OnTranslationTargetFontSizeCommitt));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::RegisterTabSpawners(const TSharedRef<class FTabManager>& TabManager)
|
|
|
|
|
{
|
2014-10-23 15:11:28 -04:00
|
|
|
WorkspaceMenuCategory = TabManager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenu_TranslationEditor", "Translation Editor"));
|
2014-10-09 12:34:55 -04:00
|
|
|
auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef();
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-10-09 12:34:55 -04:00
|
|
|
FAssetEditorToolkit::RegisterTabSpawners(TabManager);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
TabManager->RegisterTabSpawner( UntranslatedTabId, FOnSpawnTab::CreateSP(this, &FTranslationEditor::SpawnTab_Untranslated) )
|
|
|
|
|
.SetDisplayName( LOCTEXT("UntranslatedTab", "Untranslated") )
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetGroup( WorkspaceMenuCategoryRef );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
TabManager->RegisterTabSpawner( ReviewTabId, FOnSpawnTab::CreateSP(this, &FTranslationEditor::SpawnTab_Review) )
|
|
|
|
|
.SetDisplayName( LOCTEXT("ReviewTab", "Needs Review") )
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetGroup( WorkspaceMenuCategoryRef );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
TabManager->RegisterTabSpawner( CompletedTabId, FOnSpawnTab::CreateSP(this, &FTranslationEditor::SpawnTab_Completed) )
|
|
|
|
|
.SetDisplayName( LOCTEXT("CompletedTab", "Completed") )
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetGroup( WorkspaceMenuCategoryRef );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
TabManager->RegisterTabSpawner( PreviewTabId, FOnSpawnTab::CreateSP(this, &FTranslationEditor::SpawnTab_Preview) )
|
|
|
|
|
.SetDisplayName( LOCTEXT("PreviewTab", "Preview") )
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetGroup( WorkspaceMenuCategoryRef );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
TabManager->RegisterTabSpawner( ContextTabId, FOnSpawnTab::CreateSP(this, &FTranslationEditor::SpawnTab_Context) )
|
|
|
|
|
.SetDisplayName( LOCTEXT("ContextTab", "Context") )
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetGroup( WorkspaceMenuCategoryRef );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
TabManager->RegisterTabSpawner( HistoryTabId, FOnSpawnTab::CreateSP(this, &FTranslationEditor::SpawnTab_History) )
|
|
|
|
|
.SetDisplayName( LOCTEXT("HistoryTab", "History") )
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetGroup( WorkspaceMenuCategoryRef );
|
2014-04-23 18:48:34 -04:00
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
TabManager->RegisterTabSpawner( SearchTabId, FOnSpawnTab::CreateSP(this, &FTranslationEditor::SpawnTab_Search) )
|
2014-04-23 18:48:34 -04:00
|
|
|
.SetDisplayName(LOCTEXT("SearchTab", "Search"))
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetGroup( WorkspaceMenuCategoryRef );
|
2014-04-23 19:14:07 -04:00
|
|
|
|
|
|
|
|
TabManager->RegisterTabSpawner( ChangedOnImportTabId, FOnSpawnTab::CreateSP(this, &FTranslationEditor::SpawnTab_ChangedOnImport) )
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetDisplayName(LOCTEXT("ChangedOnImportTab", "Changed On Import"))
|
|
|
|
|
.SetGroup( WorkspaceMenuCategoryRef );
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::UnregisterTabSpawners(const TSharedRef<class FTabManager>& TabManager)
|
|
|
|
|
{
|
|
|
|
|
TabManager->UnregisterTabSpawner( UntranslatedTabId );
|
|
|
|
|
TabManager->UnregisterTabSpawner( ReviewTabId );
|
|
|
|
|
TabManager->UnregisterTabSpawner( CompletedTabId );
|
|
|
|
|
TabManager->UnregisterTabSpawner( PreviewTabId );
|
|
|
|
|
TabManager->UnregisterTabSpawner( ContextTabId );
|
2014-04-23 18:48:34 -04:00
|
|
|
TabManager->UnregisterTabSpawner(HistoryTabId);
|
|
|
|
|
TabManager->UnregisterTabSpawner(SearchTabId);
|
2014-04-23 19:14:07 -04:00
|
|
|
TabManager->UnregisterTabSpawner(ChangedOnImportTabId);
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
void FTranslationEditor::InitTranslationEditor( const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost )
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
|
|
|
|
TSharedRef<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::NewLayout( "Standalone_TranslationEditor_Layout" )
|
|
|
|
|
->AddArea
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewPrimaryArea()
|
|
|
|
|
->SetOrientation(Orient_Vertical)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack()
|
|
|
|
|
->SetSizeCoefficient(0.1f)
|
|
|
|
|
->SetHideTabWell( true )
|
|
|
|
|
->AddTab(GetToolbarTabId(), ETabState::OpenedTab)
|
2014-04-23 18:48:34 -04:00
|
|
|
)
|
2014-03-14 14:13:41 -04:00
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack()
|
|
|
|
|
->SetSizeCoefficient(0.5)
|
|
|
|
|
->SetHideTabWell( false )
|
|
|
|
|
->AddTab( UntranslatedTabId, ETabState::OpenedTab )
|
|
|
|
|
->AddTab( ReviewTabId, ETabState::OpenedTab )
|
|
|
|
|
->AddTab( CompletedTabId, ETabState::OpenedTab )
|
2014-04-23 18:48:34 -04:00
|
|
|
->AddTab( SearchTabId, ETabState::ClosedTab )
|
2014-04-23 19:14:07 -04:00
|
|
|
->AddTab( ChangedOnImportTabId, ETabState::ClosedTab )
|
2014-03-14 14:13:41 -04:00
|
|
|
)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack()
|
|
|
|
|
->SetSizeCoefficient(0.5)
|
|
|
|
|
->SetHideTabWell(false)
|
|
|
|
|
->AddTab(PreviewTabId, ETabState::OpenedTab)
|
|
|
|
|
)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewSplitter()
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack()
|
|
|
|
|
->SetHideTabWell(false)
|
|
|
|
|
->AddTab(ContextTabId, ETabState::OpenedTab)
|
|
|
|
|
)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack()
|
|
|
|
|
->SetHideTabWell(false)
|
|
|
|
|
->AddTab(HistoryTabId, ETabState::OpenedTab)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Register the UI COMMANDS and map them to our functions
|
|
|
|
|
MapActions();
|
|
|
|
|
|
|
|
|
|
const bool bCreateDefaultStandaloneMenu = true;
|
|
|
|
|
const bool bCreateDefaultToolbar = true;
|
2014-04-23 18:47:10 -04:00
|
|
|
// Need editing object to not be null
|
|
|
|
|
UTranslationUnit* EditingObject;
|
2014-05-01 00:16:11 -04:00
|
|
|
if (DataManager->GetAllTranslationsArray().Num() > 0 && DataManager->GetAllTranslationsArray()[0] != NULL)
|
2014-04-23 18:47:10 -04:00
|
|
|
{
|
|
|
|
|
EditingObject = DataManager->GetAllTranslationsArray()[0];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
EditingObject = NewObject<UTranslationUnit>();
|
|
|
|
|
}
|
|
|
|
|
FAssetEditorToolkit::InitAssetEditor(Mode, InitToolkitHost, FTranslationEditorModule::TranslationEditorAppIdentifier, StandaloneDefaultLayout, bCreateDefaultStandaloneMenu, bCreateDefaultToolbar, EditingObject);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
FTranslationEditorModule& TranslationEditorModule = FModuleManager::LoadModuleChecked<FTranslationEditorModule>( "TranslationEditor" );
|
|
|
|
|
AddMenuExtender(TranslationEditorModule.GetMenuExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
|
|
|
|
|
TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender);
|
|
|
|
|
FTranslationEditorMenu::SetupTranslationEditorMenu( MenuExtender, *this );
|
|
|
|
|
AddMenuExtender(MenuExtender);
|
|
|
|
|
|
|
|
|
|
AddToolbarExtender(TranslationEditorModule.GetToolbarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
|
|
|
|
|
TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
|
|
|
|
|
FTranslationEditorMenu::SetupTranslationEditorToolbar( ToolbarExtender, *this );
|
|
|
|
|
AddToolbarExtender(ToolbarExtender);
|
|
|
|
|
|
|
|
|
|
RegenerateMenusAndToolbars();
|
|
|
|
|
|
|
|
|
|
// @todo toolkit world centric editing
|
|
|
|
|
/*// Setup our tool's layout
|
|
|
|
|
if( IsWorldCentricAssetEditor() )
|
|
|
|
|
{
|
|
|
|
|
const FString TabInitializationPayload(TEXT("")); // NOTE: Payload not currently used for table properties
|
|
|
|
|
SpawnToolkitTab( UntranslatedTabId, TabInitializationPayload, EToolkitTabSpot::Details );
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
// NOTE: Could fill in asset editor commands here!
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FName FTranslationEditor::GetToolkitFName() const
|
|
|
|
|
{
|
|
|
|
|
return FName("TranslationEditor");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FText FTranslationEditor::GetBaseToolkitName() const
|
|
|
|
|
{
|
|
|
|
|
return LOCTEXT( "AppLabel", "Translation Editor" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FText FTranslationEditor::GetToolkitName() const
|
|
|
|
|
{
|
|
|
|
|
const UObject* EditingObject = GetEditingObject();
|
|
|
|
|
|
|
|
|
|
check (EditingObject != NULL);
|
|
|
|
|
|
|
|
|
|
// This doesn't correctly indicate dirty status for Translation Editor currently...
|
|
|
|
|
const bool bDirtyState = EditingObject->GetOutermost()->IsDirty();
|
|
|
|
|
|
|
|
|
|
FFormatNamedArguments Args;
|
2014-04-23 19:06:27 -04:00
|
|
|
Args.Add(TEXT("Language"), FText::FromString(FPaths::GetBaseFilename(FPaths::GetPath(ArchiveFilePath))));
|
|
|
|
|
Args.Add(TEXT("ProjectName"), FText::FromString(FPaths::GetBaseFilename(ManifestFilePath)));
|
2014-03-14 14:13:41 -04:00
|
|
|
Args.Add( TEXT("DirtyState"), bDirtyState ? FText::FromString( TEXT( "*" ) ) : FText::GetEmpty() );
|
|
|
|
|
Args.Add( TEXT("ToolkitName"), GetBaseToolkitName() );
|
|
|
|
|
return FText::Format( LOCTEXT("TranslationEditorAppLabel", "{Language}{DirtyState} - {ProjectName} - {ToolkitName}"), Args );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FString FTranslationEditor::GetWorldCentricTabPrefix() const
|
|
|
|
|
{
|
|
|
|
|
return LOCTEXT("WorldCentricTabPrefix", "Translation ").ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLinearColor FTranslationEditor::GetWorldCentricTabColorScale() const
|
|
|
|
|
{
|
|
|
|
|
return FLinearColor( 0.0f, 0.0f, 0.2f, 0.5f );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> FTranslationEditor::SpawnTab_Untranslated( const FSpawnTabArgs& Args )
|
|
|
|
|
{
|
|
|
|
|
check( Args.GetTabId().TabType == UntranslatedTabId );
|
|
|
|
|
|
|
|
|
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>( "PropertyEditor" );
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
UProperty* SourceProperty = FindField<UProperty>( UTranslationUnit::StaticClass(), "Source");
|
|
|
|
|
UProperty* TranslationProperty = FindField<UProperty>( UTranslationUnit::StaticClass(), "Translation");
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// create empty property table
|
|
|
|
|
UntranslatedPropertyTable = PropertyEditorModule.CreatePropertyTable();
|
|
|
|
|
UntranslatedPropertyTable->SetIsUserAllowedToChangeRoot( false );
|
|
|
|
|
UntranslatedPropertyTable->SetOrientation( EPropertyTableOrientation::AlignPropertiesInColumns );
|
|
|
|
|
UntranslatedPropertyTable->SetShowRowHeader( true );
|
|
|
|
|
UntranslatedPropertyTable->SetShowObjectName( false );
|
2014-04-23 18:54:03 -04:00
|
|
|
UntranslatedPropertyTable->OnSelectionChanged()->AddSP( this, &FTranslationEditor::UpdateUntranslatedSelection );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// we want to customize some columns
|
|
|
|
|
TArray< TSharedRef<class IPropertyTableCustomColumn>> CustomColumns;
|
|
|
|
|
SourceColumn->AddSupportedProperty(SourceProperty);
|
|
|
|
|
TranslationColumn->AddSupportedProperty(TranslationProperty);
|
|
|
|
|
CustomColumns.Add( SourceColumn );
|
|
|
|
|
CustomColumns.Add(TranslationColumn);
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
UntranslatedPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetUntranslatedArray());
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// Add the columns we want to display
|
|
|
|
|
UntranslatedPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)SourceProperty);
|
|
|
|
|
UntranslatedPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)TranslationProperty);
|
|
|
|
|
|
|
|
|
|
// Freeze columns, don't want user to remove them
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = UntranslatedPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UntranslatedPropertyTableWidgetHandle = PropertyEditorModule.CreatePropertyTableWidgetHandle( UntranslatedPropertyTable.ToSharedRef(), CustomColumns);
|
|
|
|
|
TSharedRef<SWidget> PropertyTableWidget = UntranslatedPropertyTableWidgetHandle->GetWidget();
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> NewDockTab = SNew(SDockTab)
|
2015-03-18 06:03:00 -04:00
|
|
|
//.Icon( FEditorStyle::GetBrush("TranslationEditor.Tabs.Properties") )
|
2014-03-14 14:13:41 -04:00
|
|
|
.Label( LOCTEXT("UntranslatedTabTitle", "Untranslated") )
|
|
|
|
|
.TabColorScale( GetTabColorScale() )
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage( FEditorStyle::GetBrush("ToolPanel.GroupBorder") )
|
|
|
|
|
.Padding(0.0f)
|
|
|
|
|
[
|
|
|
|
|
PropertyTableWidget
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
UntranslatedTab = NewDockTab;
|
|
|
|
|
|
|
|
|
|
return NewDockTab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> FTranslationEditor::SpawnTab_Review( const FSpawnTabArgs& Args )
|
|
|
|
|
{
|
|
|
|
|
check( Args.GetTabId().TabType == ReviewTabId );
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
UProperty* SourceProperty = FindField<UProperty>( UTranslationUnit::StaticClass(), "Source");
|
|
|
|
|
UProperty* TranslationProperty = FindField<UProperty>( UTranslationUnit::StaticClass(), "Translation");
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>( "PropertyEditor" );
|
|
|
|
|
|
|
|
|
|
// create empty property table
|
|
|
|
|
ReviewPropertyTable = PropertyEditorModule.CreatePropertyTable();
|
|
|
|
|
ReviewPropertyTable->SetIsUserAllowedToChangeRoot( false );
|
|
|
|
|
ReviewPropertyTable->SetOrientation( EPropertyTableOrientation::AlignPropertiesInColumns );
|
|
|
|
|
ReviewPropertyTable->SetShowRowHeader( true );
|
|
|
|
|
ReviewPropertyTable->SetShowObjectName( false );
|
2014-04-23 18:54:03 -04:00
|
|
|
ReviewPropertyTable->OnSelectionChanged()->AddSP( this, &FTranslationEditor::UpdateNeedsReviewSelection );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// we want to customize some columns
|
|
|
|
|
TArray< TSharedRef< class IPropertyTableCustomColumn > > CustomColumns;
|
|
|
|
|
SourceColumn->AddSupportedProperty(SourceProperty);
|
|
|
|
|
TranslationColumn->AddSupportedProperty(TranslationProperty);
|
|
|
|
|
CustomColumns.Add( SourceColumn );
|
|
|
|
|
CustomColumns.Add( TranslationColumn );
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
ReviewPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetReviewArray());
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// Add the columns we want to display
|
2014-04-23 18:47:10 -04:00
|
|
|
ReviewPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>( UTranslationUnit::StaticClass(), "Source"));
|
|
|
|
|
ReviewPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>( UTranslationUnit::StaticClass(), "Translation"));
|
|
|
|
|
ReviewPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>( UTranslationUnit::StaticClass(), "HasBeenReviewed"));
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = ReviewPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
2014-04-02 18:09:23 -04:00
|
|
|
FString ColumnId = Column->GetId().ToString();
|
|
|
|
|
if (ColumnId == "HasBeenReviewed")
|
|
|
|
|
{
|
|
|
|
|
Column->SetWidth(120);
|
|
|
|
|
Column->SetSizeMode(EPropertyTableColumnSizeMode::Fixed);
|
|
|
|
|
}
|
|
|
|
|
// Freeze columns, don't want user to remove them
|
2014-03-14 14:13:41 -04:00
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReviewPropertyTableWidgetHandle = PropertyEditorModule.CreatePropertyTableWidgetHandle( ReviewPropertyTable.ToSharedRef(), CustomColumns);
|
|
|
|
|
TSharedRef<SWidget> PropertyTableWidget = ReviewPropertyTableWidgetHandle->GetWidget();
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> NewDockTab = SNew(SDockTab)
|
2015-03-18 06:03:00 -04:00
|
|
|
//.Icon( FEditorStyle::GetBrush("TranslationEditor.Tabs.Properties") )
|
2014-03-14 14:13:41 -04:00
|
|
|
.Label( LOCTEXT("ReviewTabTitle", "Needs Review") )
|
|
|
|
|
.TabColorScale( GetTabColorScale() )
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage( FEditorStyle::GetBrush("ToolPanel.GroupBorder") )
|
|
|
|
|
.Padding(0.0f)
|
|
|
|
|
[
|
|
|
|
|
PropertyTableWidget
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
ReviewTab = NewDockTab;
|
|
|
|
|
|
|
|
|
|
return NewDockTab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> FTranslationEditor::SpawnTab_Completed( const FSpawnTabArgs& Args )
|
|
|
|
|
{
|
|
|
|
|
check( Args.GetTabId().TabType == CompletedTabId );
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
UProperty* SourceProperty = FindField<UProperty>( UTranslationUnit::StaticClass(), "Source");
|
|
|
|
|
UProperty* TranslationProperty = FindField<UProperty>( UTranslationUnit::StaticClass(), "Translation");
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>( "PropertyEditor" );
|
|
|
|
|
|
|
|
|
|
// create empty property table
|
|
|
|
|
CompletedPropertyTable = PropertyEditorModule.CreatePropertyTable();
|
|
|
|
|
CompletedPropertyTable->SetIsUserAllowedToChangeRoot( false );
|
|
|
|
|
CompletedPropertyTable->SetOrientation( EPropertyTableOrientation::AlignPropertiesInColumns );
|
|
|
|
|
CompletedPropertyTable->SetShowRowHeader( true );
|
|
|
|
|
CompletedPropertyTable->SetShowObjectName( false );
|
2014-04-23 18:54:03 -04:00
|
|
|
CompletedPropertyTable->OnSelectionChanged()->AddSP( this, &FTranslationEditor::UpdateCompletedSelection );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// we want to customize some columns
|
|
|
|
|
TArray< TSharedRef< class IPropertyTableCustomColumn > > CustomColumns;
|
|
|
|
|
SourceColumn->AddSupportedProperty(SourceProperty);
|
|
|
|
|
TranslationColumn->AddSupportedProperty(TranslationProperty);
|
|
|
|
|
CustomColumns.Add( SourceColumn );
|
|
|
|
|
CustomColumns.Add( TranslationColumn );
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
CompletedPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetCompleteArray());
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// Add the columns we want to display
|
2014-04-23 18:47:10 -04:00
|
|
|
CompletedPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>( UTranslationUnit::StaticClass(), "Source"));
|
|
|
|
|
CompletedPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>( UTranslationUnit::StaticClass(), "Translation"));
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// Freeze columns, don't want user to remove them
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = CompletedPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CompletedPropertyTableWidgetHandle = PropertyEditorModule.CreatePropertyTableWidgetHandle( CompletedPropertyTable.ToSharedRef(), CustomColumns);
|
|
|
|
|
TSharedRef<SWidget> PropertyTableWidget = CompletedPropertyTableWidgetHandle->GetWidget();
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> NewDockTab = SNew(SDockTab)
|
2015-03-18 06:03:00 -04:00
|
|
|
//.Icon( FEditorStyle::GetBrush("TranslationEditor.Tabs.Properties") )
|
2014-03-14 14:13:41 -04:00
|
|
|
.Label( LOCTEXT("CompletedTabTitle", "Completed") )
|
|
|
|
|
.TabColorScale( GetTabColorScale() )
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage( FEditorStyle::GetBrush("ToolPanel.GroupBorder") )
|
|
|
|
|
.Padding(0.0f)
|
|
|
|
|
[
|
|
|
|
|
PropertyTableWidget
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
CompletedTab = NewDockTab;
|
|
|
|
|
|
|
|
|
|
return NewDockTab;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 18:48:34 -04:00
|
|
|
TSharedRef<SDockTab> FTranslationEditor::SpawnTab_Search(const FSpawnTabArgs& Args)
|
|
|
|
|
{
|
|
|
|
|
check(Args.GetTabId().TabType == SearchTabId);
|
|
|
|
|
|
|
|
|
|
UProperty* SourceProperty = FindField<UProperty>(UTranslationUnit::StaticClass(), "Source");
|
|
|
|
|
UProperty* TranslationProperty = FindField<UProperty>(UTranslationUnit::StaticClass(), "Translation");
|
|
|
|
|
|
|
|
|
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
|
|
|
|
|
|
|
|
|
// create empty property table
|
|
|
|
|
SearchPropertyTable = PropertyEditorModule.CreatePropertyTable();
|
|
|
|
|
SearchPropertyTable->SetIsUserAllowedToChangeRoot(false);
|
|
|
|
|
SearchPropertyTable->SetOrientation(EPropertyTableOrientation::AlignPropertiesInColumns);
|
|
|
|
|
SearchPropertyTable->SetShowRowHeader(true);
|
|
|
|
|
SearchPropertyTable->SetShowObjectName(false);
|
2014-04-23 18:54:03 -04:00
|
|
|
SearchPropertyTable->OnSelectionChanged()->AddSP(this, &FTranslationEditor::UpdateSearchSelection);
|
2014-04-23 18:48:34 -04:00
|
|
|
|
|
|
|
|
// we want to customize some columns
|
|
|
|
|
TArray< TSharedRef< class IPropertyTableCustomColumn > > CustomColumns;
|
|
|
|
|
SourceColumn->AddSupportedProperty(SourceProperty);
|
|
|
|
|
TranslationColumn->AddSupportedProperty(TranslationProperty);
|
|
|
|
|
CustomColumns.Add(SourceColumn);
|
|
|
|
|
CustomColumns.Add(TranslationColumn);
|
|
|
|
|
|
|
|
|
|
SearchPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetSearchResultsArray());
|
|
|
|
|
|
|
|
|
|
// Add the columns we want to display
|
|
|
|
|
SearchPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Source"));
|
|
|
|
|
SearchPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Translation"));
|
|
|
|
|
|
|
|
|
|
// Freeze columns, don't want user to remove them
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = SearchPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SearchPropertyTableWidgetHandle = PropertyEditorModule.CreatePropertyTableWidgetHandle(SearchPropertyTable.ToSharedRef(), CustomColumns);
|
|
|
|
|
TSharedRef<SWidget> PropertyTableWidget = SearchPropertyTableWidgetHandle->GetWidget();
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> NewDockTab = SNew(SDockTab)
|
|
|
|
|
//.Icon(FEditorStyle::GetBrush("TranslationEditor.Tabs.Properties"))
|
|
|
|
|
.Label(LOCTEXT("SearchTabTitle", "Search"))
|
|
|
|
|
.TabColorScale(GetTabColorScale())
|
|
|
|
|
[
|
|
|
|
|
SNew(SVerticalBox)
|
|
|
|
|
+ SVerticalBox::Slot()
|
|
|
|
|
.HAlign(HAlign_Fill)
|
|
|
|
|
.VAlign(VAlign_Top)
|
|
|
|
|
.AutoHeight()
|
|
|
|
|
.Padding(0.0f, 0.0f, 0.0f, 4.0f)
|
|
|
|
|
[
|
|
|
|
|
SAssignNew(SearchBox, SSearchBox)
|
|
|
|
|
.HintText(LOCTEXT("FilterSearch", "Search..."))
|
2015-01-08 11:35:01 -05:00
|
|
|
.ToolTipText(LOCTEXT("FilterSearchHint", "Type here to search"))
|
2014-04-23 18:48:34 -04:00
|
|
|
.OnTextChanged(this, &FTranslationEditor::OnFilterTextChanged)
|
|
|
|
|
.OnTextCommitted(this, &FTranslationEditor::OnFilterTextCommitted)
|
|
|
|
|
]
|
|
|
|
|
+ SVerticalBox::Slot()
|
|
|
|
|
.HAlign(HAlign_Fill)
|
|
|
|
|
.VAlign(VAlign_Top)
|
|
|
|
|
.FillHeight(10.f)
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
|
|
|
.Padding(0.0f)
|
|
|
|
|
.VAlign(VAlign_Top)
|
|
|
|
|
[
|
|
|
|
|
PropertyTableWidget
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
SearchTab = NewDockTab;
|
|
|
|
|
|
|
|
|
|
return NewDockTab;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
TSharedRef<SDockTab> FTranslationEditor::SpawnTab_ChangedOnImport(const FSpawnTabArgs& Args)
|
|
|
|
|
{
|
|
|
|
|
check(Args.GetTabId().TabType == ChangedOnImportTabId);
|
|
|
|
|
|
|
|
|
|
UProperty* SourceProperty = FindField<UProperty>(UTranslationUnit::StaticClass(), "Source");
|
|
|
|
|
UProperty* TranslationBeforeImportProperty = FindField<UProperty>(UTranslationUnit::StaticClass(), "TranslationBeforeImport");
|
|
|
|
|
UProperty* TranslationProperty = FindField<UProperty>(UTranslationUnit::StaticClass(), "Translation");
|
|
|
|
|
|
|
|
|
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
|
|
|
|
|
|
|
|
|
// create empty property table
|
|
|
|
|
ChangedOnImportPropertyTable = PropertyEditorModule.CreatePropertyTable();
|
|
|
|
|
ChangedOnImportPropertyTable->SetIsUserAllowedToChangeRoot(false);
|
|
|
|
|
ChangedOnImportPropertyTable->SetOrientation(EPropertyTableOrientation::AlignPropertiesInColumns);
|
|
|
|
|
ChangedOnImportPropertyTable->SetShowRowHeader(true);
|
|
|
|
|
ChangedOnImportPropertyTable->SetShowObjectName(false);
|
|
|
|
|
ChangedOnImportPropertyTable->OnSelectionChanged()->AddSP(this, &FTranslationEditor::UpdateSearchSelection);
|
|
|
|
|
|
|
|
|
|
// we want to customize some columns
|
|
|
|
|
TArray< TSharedRef< class IPropertyTableCustomColumn > > CustomColumns;
|
|
|
|
|
SourceColumn->AddSupportedProperty(SourceProperty);
|
|
|
|
|
TranslationColumn->AddSupportedProperty(TranslationProperty);
|
|
|
|
|
CustomColumns.Add(SourceColumn);
|
|
|
|
|
CustomColumns.Add(TranslationColumn);
|
|
|
|
|
|
|
|
|
|
ChangedOnImportPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetSearchResultsArray());
|
|
|
|
|
|
|
|
|
|
// Add the columns we want to display
|
|
|
|
|
ChangedOnImportPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Source"));
|
|
|
|
|
ChangedOnImportPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "TranslationBeforeImport"));
|
|
|
|
|
ChangedOnImportPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Translation"));
|
|
|
|
|
|
|
|
|
|
// Freeze columns, don't want user to remove them
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = ChangedOnImportPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SearchPropertyTableWidgetHandle = PropertyEditorModule.CreatePropertyTableWidgetHandle(ChangedOnImportPropertyTable.ToSharedRef(), CustomColumns);
|
|
|
|
|
TSharedRef<SWidget> PropertyTableWidget = SearchPropertyTableWidgetHandle->GetWidget();
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> NewDockTab = SNew(SDockTab)
|
2015-03-18 06:03:00 -04:00
|
|
|
//.Icon(FEditorStyle::GetBrush("TranslationEditor.Tabs.Properties"))
|
2014-04-23 19:14:07 -04:00
|
|
|
.Label(LOCTEXT("ChangedOnImportTabTitle", "Changed on Import"))
|
|
|
|
|
.TabColorScale(GetTabColorScale())
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
|
|
|
.Padding(0.0f)
|
|
|
|
|
[
|
|
|
|
|
PropertyTableWidget
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
ChangedOnImportTab = NewDockTab;
|
|
|
|
|
|
|
|
|
|
return NewDockTab;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-14 14:13:41 -04:00
|
|
|
TSharedRef<SDockTab> FTranslationEditor::SpawnTab_Preview( const FSpawnTabArgs& Args )
|
|
|
|
|
{
|
|
|
|
|
check( Args.GetTabId().TabType == PreviewTabId );
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> NewDockTab = SNew(SDockTab)
|
2015-03-18 06:03:00 -04:00
|
|
|
//.Icon( FEditorStyle::GetBrush("TranslationEditor.Tabs.Properties") )
|
2014-03-14 14:13:41 -04:00
|
|
|
.Label( LOCTEXT("PreviewTabTitle", "Preview") )
|
|
|
|
|
.TabColorScale( GetTabColorScale() )
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage( FEditorStyle::GetBrush("ToolPanel.GroupBorder") )
|
|
|
|
|
.Padding(0.0f)
|
|
|
|
|
[
|
|
|
|
|
SNew(SHorizontalBox)
|
|
|
|
|
+SHorizontalBox::Slot()
|
|
|
|
|
.HAlign(HAlign_Center)
|
|
|
|
|
.VAlign(VAlign_Center)
|
|
|
|
|
[
|
|
|
|
|
PreviewTextBlock
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return NewDockTab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> FTranslationEditor::SpawnTab_Context( const FSpawnTabArgs& Args )
|
|
|
|
|
{
|
|
|
|
|
check( Args.GetTabId().TabType == ContextTabId );
|
|
|
|
|
|
|
|
|
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>( "PropertyEditor" );
|
|
|
|
|
|
|
|
|
|
// create empty property table
|
|
|
|
|
ContextPropertyTable = PropertyEditorModule.CreatePropertyTable();
|
|
|
|
|
ContextPropertyTable->SetIsUserAllowedToChangeRoot( false );
|
|
|
|
|
ContextPropertyTable->SetOrientation( EPropertyTableOrientation::AlignPropertiesInColumns );
|
|
|
|
|
ContextPropertyTable->SetShowRowHeader( true );
|
|
|
|
|
ContextPropertyTable->SetShowObjectName( false );
|
|
|
|
|
ContextPropertyTable->OnSelectionChanged()->AddSP( this, &FTranslationEditor::UpdateContextSelection );
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
if (DataManager->GetAllTranslationsArray().Num() > 0)
|
|
|
|
|
{
|
|
|
|
|
TArray<UObject*> Objects;
|
|
|
|
|
Objects.Add(DataManager->GetAllTranslationsArray()[0]);
|
|
|
|
|
ContextPropertyTable->SetObjects(Objects);
|
|
|
|
|
}
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// Build the Path to the data we want to show
|
2014-04-23 18:47:10 -04:00
|
|
|
UProperty* ContextProp = FindField<UProperty>( UTranslationUnit::StaticClass(), "Contexts" );
|
2014-03-14 14:13:41 -04:00
|
|
|
FPropertyInfo ContextPropInfo;
|
|
|
|
|
ContextPropInfo.Property = ContextProp;
|
|
|
|
|
ContextPropInfo.ArrayIndex = INDEX_NONE;
|
2014-04-23 18:47:10 -04:00
|
|
|
TSharedRef<FPropertyPath> Path = FPropertyPath::CreateEmpty();
|
2014-03-14 14:13:41 -04:00
|
|
|
Path = Path->ExtendPath(ContextPropInfo);
|
|
|
|
|
ContextPropertyTable->SetRootPath(Path);
|
|
|
|
|
|
|
|
|
|
// Add the columns we want to display
|
|
|
|
|
ContextPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>( FTranslationContextInfo::StaticStruct(), "Key"));
|
|
|
|
|
ContextPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>( FTranslationContextInfo::StaticStruct(), "Context"));
|
|
|
|
|
|
|
|
|
|
// Freeze columns, don't want user to remove them
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = ContextPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ContextPropertyTableWidgetHandle = PropertyEditorModule.CreatePropertyTableWidgetHandle( ContextPropertyTable.ToSharedRef() );
|
|
|
|
|
TSharedRef<SWidget> PropertyTableWidget = ContextPropertyTableWidgetHandle->GetWidget();
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> NewDockTab = SNew(SDockTab)
|
2015-03-18 06:03:00 -04:00
|
|
|
//.Icon( FEditorStyle::GetBrush("TranslationEditor.Tabs.Properties") )
|
2014-03-14 14:13:41 -04:00
|
|
|
.Label( LOCTEXT("ContextTabTitle", "Context") )
|
|
|
|
|
.TabColorScale( GetTabColorScale() )
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage( FEditorStyle::GetBrush("ToolPanel.GroupBorder") )
|
|
|
|
|
.Padding(0.0f)
|
|
|
|
|
[
|
|
|
|
|
SNew(SVerticalBox)
|
|
|
|
|
+SVerticalBox::Slot()
|
|
|
|
|
.HAlign(HAlign_Left)
|
|
|
|
|
.VAlign(VAlign_Center)
|
2014-11-18 03:20:09 -05:00
|
|
|
.AutoHeight()
|
2014-03-14 14:13:41 -04:00
|
|
|
[
|
2014-11-18 03:20:09 -05:00
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
|
|
|
.Padding(5.0f)
|
|
|
|
|
[
|
|
|
|
|
NamespaceTextBlock
|
|
|
|
|
]
|
2014-03-14 14:13:41 -04:00
|
|
|
]
|
|
|
|
|
+SVerticalBox::Slot()
|
|
|
|
|
.HAlign(HAlign_Fill)
|
|
|
|
|
.VAlign(VAlign_Fill)
|
|
|
|
|
[
|
|
|
|
|
PropertyTableWidget
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return NewDockTab;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-18 03:20:09 -05:00
|
|
|
TSharedRef<SDockTab> FTranslationEditor::SpawnTab_History(const FSpawnTabArgs& Args)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-11-18 03:20:09 -05:00
|
|
|
check(Args.GetTabId().TabType == HistoryTabId);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-11-18 03:20:09 -05:00
|
|
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-11-18 03:20:09 -05:00
|
|
|
UProperty* SourceProperty = FindField<UProperty>(FTranslationChange::StaticStruct(), "Source");
|
|
|
|
|
UProperty* TranslationProperty = FindField<UProperty>(FTranslationChange::StaticStruct(), "Translation");
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// create empty property table
|
|
|
|
|
HistoryPropertyTable = PropertyEditorModule.CreatePropertyTable();
|
2014-11-18 03:20:09 -05:00
|
|
|
HistoryPropertyTable->SetIsUserAllowedToChangeRoot(false);
|
|
|
|
|
HistoryPropertyTable->SetOrientation(EPropertyTableOrientation::AlignPropertiesInColumns);
|
|
|
|
|
HistoryPropertyTable->SetShowRowHeader(true);
|
|
|
|
|
HistoryPropertyTable->SetShowObjectName(false);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// we want to customize some columns
|
|
|
|
|
TArray< TSharedRef<class IPropertyTableCustomColumn>> CustomColumns;
|
|
|
|
|
SourceColumn->AddSupportedProperty(SourceProperty);
|
|
|
|
|
TranslationColumn->AddSupportedProperty(TranslationProperty);
|
2014-11-18 03:20:09 -05:00
|
|
|
CustomColumns.Add(SourceColumn);
|
|
|
|
|
CustomColumns.Add(TranslationColumn);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
if (DataManager->GetAllTranslationsArray().Num() > 0)
|
|
|
|
|
{
|
|
|
|
|
TArray<UObject*> Objects;
|
|
|
|
|
Objects.Add(DataManager->GetAllTranslationsArray()[0]);
|
|
|
|
|
HistoryPropertyTable->SetObjects(Objects);
|
|
|
|
|
}
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
// Build the Path to the data we want to show
|
2014-04-23 18:47:10 -04:00
|
|
|
TSharedRef<FPropertyPath> Path = FPropertyPath::CreateEmpty();
|
2014-11-18 03:20:09 -05:00
|
|
|
UArrayProperty* ContextsProp = FindField<UArrayProperty>(UTranslationUnit::StaticClass(), "Contexts");
|
2014-03-14 14:13:41 -04:00
|
|
|
Path = Path->ExtendPath(FPropertyPath::Create(ContextsProp));
|
|
|
|
|
FPropertyInfo ContextsPropInfo;
|
|
|
|
|
ContextsPropInfo.Property = ContextsProp->Inner;
|
|
|
|
|
ContextsPropInfo.ArrayIndex = 0;
|
|
|
|
|
Path = Path->ExtendPath(ContextsPropInfo);
|
|
|
|
|
|
2014-11-18 03:20:09 -05:00
|
|
|
UProperty* ChangesProp = FindField<UProperty>(FTranslationContextInfo::StaticStruct(), "Changes");
|
2014-03-14 14:13:41 -04:00
|
|
|
FPropertyInfo ChangesPropInfo;
|
|
|
|
|
ChangesPropInfo.Property = ChangesProp;
|
|
|
|
|
ChangesPropInfo.ArrayIndex = INDEX_NONE;
|
|
|
|
|
Path = Path->ExtendPath(ChangesPropInfo);
|
|
|
|
|
HistoryPropertyTable->SetRootPath(Path);
|
|
|
|
|
|
|
|
|
|
// Add the columns we want to display
|
2014-11-18 03:20:09 -05:00
|
|
|
HistoryPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(FTranslationChange::StaticStruct(), "Version"));
|
|
|
|
|
HistoryPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(FTranslationChange::StaticStruct(), "DateAndTime"));
|
2014-03-14 14:13:41 -04:00
|
|
|
HistoryPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)SourceProperty);
|
|
|
|
|
HistoryPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)TranslationProperty);
|
|
|
|
|
|
|
|
|
|
// Freeze columns, don't want user to remove them
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = HistoryPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-18 03:20:09 -05:00
|
|
|
HistoryPropertyTableWidgetHandle = PropertyEditorModule.CreatePropertyTableWidgetHandle(HistoryPropertyTable.ToSharedRef(), CustomColumns);
|
2014-03-14 14:13:41 -04:00
|
|
|
TSharedRef<SWidget> PropertyTableWidget = HistoryPropertyTableWidgetHandle->GetWidget();
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> NewDockTab = SNew(SDockTab)
|
2015-03-18 06:03:00 -04:00
|
|
|
//.Icon(FEditorStyle::GetBrush("TranslationEditor.Tabs.Properties"))
|
2014-11-18 03:20:09 -05:00
|
|
|
.Label(LOCTEXT("HistoryTabTitle", "History"))
|
|
|
|
|
.TabColorScale(GetTabColorScale())
|
2014-03-14 14:13:41 -04:00
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
2014-11-18 03:20:09 -05:00
|
|
|
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
2014-03-14 14:13:41 -04:00
|
|
|
.Padding(0.0f)
|
|
|
|
|
[
|
2014-11-18 03:20:09 -05:00
|
|
|
SNew(SVerticalBox)
|
|
|
|
|
+ SVerticalBox::Slot()
|
|
|
|
|
.HAlign(HAlign_Left)
|
|
|
|
|
.VAlign(VAlign_Center)
|
|
|
|
|
.AutoHeight()
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
|
|
|
.Padding(5.0f)
|
|
|
|
|
[
|
|
|
|
|
SNew(SButton)
|
|
|
|
|
.HAlign(HAlign_Center)
|
|
|
|
|
.VAlign(VAlign_Center)
|
|
|
|
|
.OnClicked(FOnClicked::CreateSP(this, &FTranslationEditor::OnGetHistoryButtonClicked))
|
|
|
|
|
[
|
|
|
|
|
SNew(STextBlock)
|
|
|
|
|
.Text((LOCTEXT("GetHistoryButton", "Get History...")))
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
+ SVerticalBox::Slot()
|
|
|
|
|
.HAlign(HAlign_Fill)
|
|
|
|
|
.VAlign(VAlign_Fill)
|
|
|
|
|
[
|
|
|
|
|
PropertyTableWidget
|
|
|
|
|
]
|
2014-03-14 14:13:41 -04:00
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return NewDockTab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::MapActions()
|
|
|
|
|
{
|
|
|
|
|
FTranslationEditorCommands::Register();
|
|
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction( FTranslationEditorCommands::Get().ChangeSourceFont,
|
|
|
|
|
FExecuteAction::CreateSP(this, &FTranslationEditor::ChangeSourceFont),
|
|
|
|
|
FCanExecuteAction());
|
|
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction( FTranslationEditorCommands::Get().ChangeTranslationTargetFont,
|
|
|
|
|
FExecuteAction::CreateSP(this, &FTranslationEditor::ChangeTranslationTargetFont),
|
|
|
|
|
FCanExecuteAction());
|
|
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction( FTranslationEditorCommands::Get().SaveTranslations,
|
|
|
|
|
FExecuteAction::CreateSP(this, &FTranslationEditor::SaveAsset_Execute),
|
|
|
|
|
FCanExecuteAction());
|
2014-04-23 17:49:26 -04:00
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction(FTranslationEditorCommands::Get().PreviewAllTranslationsInEditor,
|
|
|
|
|
FExecuteAction::CreateSP(this, &FTranslationEditor::PreviewAllTranslationsInEditor_Execute),
|
|
|
|
|
FCanExecuteAction());
|
2014-04-23 18:20:15 -04:00
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction(FTranslationEditorCommands::Get().ExportToPortableObjectFormat,
|
|
|
|
|
FExecuteAction::CreateSP(this, &FTranslationEditor::ExportToPortableObjectFormat_Execute),
|
|
|
|
|
FCanExecuteAction());
|
2014-04-23 18:48:34 -04:00
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
ToolkitCommands->MapAction(FTranslationEditorCommands::Get().ImportFromPortableObjectFormat,
|
|
|
|
|
FExecuteAction::CreateSP(this, &FTranslationEditor::ImportFromPortableObjectFormat_Execute),
|
|
|
|
|
FCanExecuteAction());
|
|
|
|
|
|
2014-04-23 18:48:34 -04:00
|
|
|
ToolkitCommands->MapAction(FTranslationEditorCommands::Get().OpenSearchTab,
|
|
|
|
|
FExecuteAction::CreateSP(this, &FTranslationEditor::OpenSearchTab_Execute),
|
|
|
|
|
FCanExecuteAction());
|
2015-02-19 20:53:05 -05:00
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction(FTranslationEditorCommands::Get().OpenTranslationPicker,
|
|
|
|
|
FExecuteAction::CreateStatic(&ITranslationEditor::OpenTranslationPicker),
|
|
|
|
|
FCanExecuteAction());
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::ChangeSourceFont()
|
|
|
|
|
{
|
|
|
|
|
// Use path from current font
|
Initial support for composite fonts for Slate, UMG, and Canvas
Slate now has the concept of composite fonts and font families (via FCompositeFont and FTypeface). A composite font is a font that contains a default font family, as well as any number of sub-font families which should be used for a given set of character ranges. This change will greatly improve the localization support for fonts.
UFont assets can now use two forms of caching "offline" (which is the way they have always worked historically), and "runtime" (which utilizes the Slate font cache to cache glyphs on demand). These runtime cached UFont assets are now the only way to specify which font to use for a UMG widget, and address the previous issues about ensuring that the required font files were staged for your game.
The Slate font cache now works on FFontData instances, rather than filenames. This allows the UFont asset to embed a blob of TTF or OTF font data inside it, rather than require the fonts be loaded from files on disk.
The Canvas text renderer has been updated to support runtime cached UFont assets. This gives our legacy Canvas based tools the same improved font localization support as the rest of the Slate-based editor UI.
UFont asset creation has been changed to use runtime caching by default, and additionally, you can now import a TTF or OTF file via the Content Browser and it will automatically create a UFont asset. If you still want an offline cached UFont asset, you can just change the cache type in the font editor, and the usual font picker dialog will appear and allow you to generate a font texture atlas.
[CL 2342203 by Jamie Dale in Main branch]
2014-10-28 09:02:03 -04:00
|
|
|
FString DefaultFile = TranslationEditorUtils::GetFontFilename(SourceFont);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
FString NewFontFilename;
|
|
|
|
|
bool bOpened = OpenFontPicker(DefaultFile, NewFontFilename);
|
|
|
|
|
|
|
|
|
|
if ( bOpened && NewFontFilename != "")
|
|
|
|
|
{
|
|
|
|
|
SourceFont = FSlateFontInfo(NewFontFilename, SourceFont.Size);
|
|
|
|
|
RefreshUI();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::ChangeTranslationTargetFont()
|
|
|
|
|
{
|
|
|
|
|
// Use path from current font
|
Initial support for composite fonts for Slate, UMG, and Canvas
Slate now has the concept of composite fonts and font families (via FCompositeFont and FTypeface). A composite font is a font that contains a default font family, as well as any number of sub-font families which should be used for a given set of character ranges. This change will greatly improve the localization support for fonts.
UFont assets can now use two forms of caching "offline" (which is the way they have always worked historically), and "runtime" (which utilizes the Slate font cache to cache glyphs on demand). These runtime cached UFont assets are now the only way to specify which font to use for a UMG widget, and address the previous issues about ensuring that the required font files were staged for your game.
The Slate font cache now works on FFontData instances, rather than filenames. This allows the UFont asset to embed a blob of TTF or OTF font data inside it, rather than require the fonts be loaded from files on disk.
The Canvas text renderer has been updated to support runtime cached UFont assets. This gives our legacy Canvas based tools the same improved font localization support as the rest of the Slate-based editor UI.
UFont asset creation has been changed to use runtime caching by default, and additionally, you can now import a TTF or OTF file via the Content Browser and it will automatically create a UFont asset. If you still want an offline cached UFont asset, you can just change the cache type in the font editor, and the usual font picker dialog will appear and allow you to generate a font texture atlas.
[CL 2342203 by Jamie Dale in Main branch]
2014-10-28 09:02:03 -04:00
|
|
|
FString DefaultFile = TranslationEditorUtils::GetFontFilename(TranslationTargetFont);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
FString NewFontFilename;
|
|
|
|
|
bool bOpened = OpenFontPicker(DefaultFile, NewFontFilename);
|
|
|
|
|
|
|
|
|
|
if ( bOpened && NewFontFilename != "")
|
|
|
|
|
{
|
|
|
|
|
TranslationTargetFont = FSlateFontInfo(NewFontFilename, TranslationTargetFont.Size);
|
|
|
|
|
RefreshUI();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::RefreshUI()
|
|
|
|
|
{
|
|
|
|
|
// Set the fonts in our custom font columns and text block
|
|
|
|
|
SourceColumn->SetFont(SourceFont);
|
|
|
|
|
TranslationColumn->SetFont(TranslationTargetFont);
|
|
|
|
|
PreviewTextBlock->SetFont(TranslationTargetFont);
|
|
|
|
|
|
|
|
|
|
// Refresh our widget displays
|
2014-04-23 17:47:40 -04:00
|
|
|
if (UntranslatedPropertyTableWidgetHandle.IsValid())
|
|
|
|
|
{
|
|
|
|
|
UntranslatedPropertyTableWidgetHandle->RequestRefresh();
|
|
|
|
|
}
|
|
|
|
|
if (ReviewPropertyTableWidgetHandle.IsValid())
|
|
|
|
|
{
|
|
|
|
|
ReviewPropertyTableWidgetHandle->RequestRefresh();
|
|
|
|
|
}
|
|
|
|
|
if (CompletedPropertyTableWidgetHandle.IsValid())
|
|
|
|
|
{
|
|
|
|
|
CompletedPropertyTableWidgetHandle->RequestRefresh();
|
|
|
|
|
}
|
|
|
|
|
if (ContextPropertyTableWidgetHandle.IsValid())
|
|
|
|
|
{
|
|
|
|
|
ContextPropertyTableWidgetHandle->RequestRefresh();
|
|
|
|
|
}
|
|
|
|
|
if (HistoryPropertyTableWidgetHandle.IsValid())
|
|
|
|
|
{
|
|
|
|
|
HistoryPropertyTableWidgetHandle->RequestRefresh();
|
|
|
|
|
}
|
2014-04-23 18:48:34 -04:00
|
|
|
if (SearchPropertyTableWidgetHandle.IsValid())
|
|
|
|
|
{
|
|
|
|
|
SearchPropertyTableWidgetHandle->RequestRefresh();
|
|
|
|
|
}
|
2014-04-23 19:14:07 -04:00
|
|
|
if (ChangedOnImportPropertyTableWidgetHandle.IsValid())
|
|
|
|
|
{
|
|
|
|
|
ChangedOnImportPropertyTableWidgetHandle->RequestRefresh();
|
|
|
|
|
}
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FTranslationEditor::OpenFontPicker( const FString DefaultFile, FString& OutFile )
|
|
|
|
|
{
|
|
|
|
|
const FString FontFileDescription = LOCTEXT( "FontFileDescription", "Font File" ).ToString();
|
2014-04-02 18:09:23 -04:00
|
|
|
const FString FontFileExtension = TEXT("*.ttf;*.otf");
|
2014-03-14 14:13:41 -04:00
|
|
|
const FString FileTypes = FString::Printf( TEXT("%s (%s)|%s"), *FontFileDescription, *FontFileExtension, *FontFileExtension );
|
|
|
|
|
|
|
|
|
|
// Prompt the user for the filenames
|
|
|
|
|
TArray<FString> OpenFilenames;
|
|
|
|
|
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
|
|
|
|
|
bool bOpened = false;
|
|
|
|
|
if ( DesktopPlatform )
|
|
|
|
|
{
|
|
|
|
|
void* ParentWindowWindowHandle = NULL;
|
|
|
|
|
|
2014-04-02 18:09:23 -04:00
|
|
|
const TSharedPtr<SWindow>& ParentWindow = FSlateApplication::Get().FindWidgetWindow(PreviewTextBlock);
|
|
|
|
|
if ( ParentWindow.IsValid() && ParentWindow->GetNativeWindow().IsValid() )
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-02 18:09:23 -04:00
|
|
|
ParentWindowWindowHandle = ParentWindow->GetNativeWindow()->GetOSWindowHandle();
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bOpened = DesktopPlatform->OpenFileDialog(
|
|
|
|
|
ParentWindowWindowHandle,
|
|
|
|
|
LOCTEXT("ChooseFontWindowTitle", "Choose Font").ToString(),
|
|
|
|
|
FPaths::GetPath(DefaultFile),
|
|
|
|
|
TEXT(""),
|
|
|
|
|
FileTypes,
|
|
|
|
|
EFileDialogFlags::None,
|
|
|
|
|
OpenFilenames
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( bOpened && OpenFilenames.Num() > 0 )
|
|
|
|
|
{
|
|
|
|
|
OutFile = OpenFilenames[0];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
OutFile = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bOpened;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 18:54:03 -04:00
|
|
|
void FTranslationEditor::UpdateUntranslatedSelection()
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-23 17:47:40 -04:00
|
|
|
TSharedPtr<SDockTab> UntranslatedTabSharedPtr = UntranslatedTab.Pin();
|
|
|
|
|
if (UntranslatedTabSharedPtr.IsValid() && UntranslatedTabSharedPtr->IsForeground() && UntranslatedPropertyTable.IsValid())
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-23 18:54:03 -04:00
|
|
|
TSet<TSharedRef<IPropertyTableRow>> SelectedRows = UntranslatedPropertyTable->GetSelectedRows();
|
|
|
|
|
UpdateTranslationUnitSelection(SelectedRows);
|
2014-04-23 18:48:34 -04:00
|
|
|
}
|
2014-04-23 18:54:03 -04:00
|
|
|
}
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-04-23 18:54:03 -04:00
|
|
|
void FTranslationEditor::UpdateNeedsReviewSelection()
|
|
|
|
|
{
|
|
|
|
|
TSharedPtr<SDockTab> ReviewTabSharedPtr = ReviewTab.Pin();
|
|
|
|
|
if (ReviewTabSharedPtr.IsValid() && ReviewTabSharedPtr->IsForeground() && ReviewPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
TSet<TSharedRef<IPropertyTableRow>> SelectedRows = ReviewPropertyTable->GetSelectedRows();
|
|
|
|
|
UpdateTranslationUnitSelection(SelectedRows);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::UpdateCompletedSelection()
|
|
|
|
|
{
|
|
|
|
|
TSharedPtr<SDockTab> CompletedTabSharedPtr = CompletedTab.Pin();
|
|
|
|
|
if (CompletedTabSharedPtr.IsValid() && CompletedTabSharedPtr->IsForeground() && CompletedPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
TSet<TSharedRef<IPropertyTableRow>> SelectedRows = CompletedPropertyTable->GetSelectedRows();
|
|
|
|
|
UpdateTranslationUnitSelection(SelectedRows);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::UpdateSearchSelection()
|
|
|
|
|
{
|
|
|
|
|
TSharedPtr<SDockTab> SearchTabSharedPtr = SearchTab.Pin();
|
|
|
|
|
if (SearchTabSharedPtr.IsValid() && SearchTabSharedPtr->IsForeground() && SearchPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
TSet<TSharedRef<IPropertyTableRow>> SelectedRows = SearchPropertyTable->GetSelectedRows();
|
|
|
|
|
UpdateTranslationUnitSelection(SelectedRows);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
void FTranslationEditor::UpdateChangedOnImportSelection()
|
|
|
|
|
{
|
|
|
|
|
TSharedPtr<SDockTab> ChangedOnImportTabSharedPtr = SearchTab.Pin();
|
|
|
|
|
if (ChangedOnImportTabSharedPtr.IsValid() && ChangedOnImportTabSharedPtr->IsForeground() && ChangedOnImportPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
TSet<TSharedRef<IPropertyTableRow>> SelectedRows = ChangedOnImportPropertyTable->GetSelectedRows();
|
|
|
|
|
UpdateTranslationUnitSelection(SelectedRows);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 18:54:03 -04:00
|
|
|
void FTranslationEditor::UpdateTranslationUnitSelection(TSet<TSharedRef<IPropertyTableRow>>& SelectedRows)
|
|
|
|
|
{
|
2014-03-14 14:13:41 -04:00
|
|
|
// Can only really handle single selection
|
|
|
|
|
if (SelectedRows.Num() == 1)
|
|
|
|
|
{
|
|
|
|
|
TSharedRef<IPropertyTableRow> SelectedRow = *(SelectedRows.CreateConstIterator());
|
|
|
|
|
TSharedRef<FPropertyPath> PartialPath = SelectedRow->GetPartialPath();
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
TWeakObjectPtr<UObject> UObjectWeakPtr = SelectedRow->GetDataSource()->AsUObject();
|
|
|
|
|
if (UObjectWeakPtr.IsValid())
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-23 18:47:10 -04:00
|
|
|
UObject* UObjectPtr = UObjectWeakPtr.Get();
|
|
|
|
|
if (UObjectPtr != NULL)
|
2014-04-23 17:47:40 -04:00
|
|
|
{
|
2014-04-23 18:47:10 -04:00
|
|
|
UTranslationUnit* SelectedTranslationUnit = (UTranslationUnit*)UObjectPtr;
|
|
|
|
|
if (SelectedTranslationUnit != NULL)
|
|
|
|
|
{
|
|
|
|
|
PreviewTextBlock->SetText(SelectedTranslationUnit->Translation);
|
|
|
|
|
NamespaceTextBlock->SetText(FText::Format(LOCTEXT("TranslationNamespace", "Namespace: {0}"), FText::FromString(SelectedTranslationUnit->Namespace)));
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
// Add the ContextPropertyTable-specific path
|
|
|
|
|
UArrayProperty* ContextArrayProp = FindField<UArrayProperty>(UTranslationUnit::StaticClass(), "Contexts");
|
|
|
|
|
FPropertyInfo ContextArrayPropInfo;
|
|
|
|
|
ContextArrayPropInfo.Property = ContextArrayProp;
|
|
|
|
|
ContextArrayPropInfo.ArrayIndex = INDEX_NONE;
|
|
|
|
|
TSharedRef<FPropertyPath> ContextPath = FPropertyPath::CreateEmpty();
|
|
|
|
|
ContextPath = ContextPath->ExtendPath(PartialPath);
|
|
|
|
|
ContextPath = ContextPath->ExtendPath(ContextArrayPropInfo);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
if (ContextPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
TArray<UObject*> ObjectArray;
|
|
|
|
|
ObjectArray.Add(SelectedTranslationUnit);
|
|
|
|
|
ContextPropertyTable->SetObjects(ObjectArray);
|
|
|
|
|
ContextPropertyTable->SetRootPath(ContextPath);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
// Need to re-add the columns we want to display
|
|
|
|
|
ContextPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(FTranslationContextInfo::StaticStruct(), "Key"));
|
|
|
|
|
ContextPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(FTranslationContextInfo::StaticStruct(), "Context"));
|
2014-04-23 17:47:40 -04:00
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = ContextPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedPtr<IPropertyTableCell> ContextToSelectPtr = ContextPropertyTable->GetFirstCellInTable();
|
|
|
|
|
|
|
|
|
|
if (ContextToSelectPtr.IsValid())
|
|
|
|
|
{
|
|
|
|
|
TSet<TSharedRef<IPropertyTableCell>> CellsToSelect;
|
|
|
|
|
CellsToSelect.Add(ContextToSelectPtr.ToSharedRef());
|
|
|
|
|
ContextPropertyTable->SetSelectedCells(CellsToSelect);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-23 17:47:40 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::SaveAsset_Execute()
|
|
|
|
|
{
|
|
|
|
|
// Doesn't call parent SaveAsset_Execute, only need to tell data manager to write data
|
|
|
|
|
DataManager->WriteTranslationData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::UpdateContextSelection()
|
|
|
|
|
{
|
2014-04-23 17:47:40 -04:00
|
|
|
if (ContextPropertyTable.IsValid())
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-23 17:47:40 -04:00
|
|
|
TSet<TSharedRef<IPropertyTableRow>> SelectedRows = ContextPropertyTable->GetSelectedRows();
|
|
|
|
|
TSharedRef<FPropertyPath> InitialPath = ContextPropertyTable->GetRootPath();
|
|
|
|
|
UProperty* PropertyToFind = InitialPath->GetRootProperty().Property.Get();
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-04-23 17:47:40 -04:00
|
|
|
// Can only really handle single selection
|
|
|
|
|
if (SelectedRows.Num() == 1)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-23 17:47:40 -04:00
|
|
|
TSharedRef<IPropertyTableRow> SelectedRow = *(SelectedRows.CreateConstIterator());
|
|
|
|
|
TSharedRef<FPropertyPath> PartialPath = SelectedRow->GetPartialPath();
|
|
|
|
|
|
2014-04-23 18:47:10 -04:00
|
|
|
TWeakObjectPtr<UObject> UObjectWeakPtr = SelectedRow->GetDataSource()->AsUObject();
|
|
|
|
|
if (UObjectWeakPtr.IsValid())
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-23 18:47:10 -04:00
|
|
|
UObject* UObjectPtr = UObjectWeakPtr.Get();
|
|
|
|
|
if (UObjectPtr != NULL)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-23 18:47:10 -04:00
|
|
|
UTranslationUnit* SelectedTranslationUnit = (UTranslationUnit*)UObjectPtr;
|
|
|
|
|
if (SelectedTranslationUnit != NULL)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-04-23 18:47:10 -04:00
|
|
|
// Index of the leaf most property is the context info index we need
|
|
|
|
|
FTranslationContextInfo& SelectedContextInfo = SelectedTranslationUnit->Contexts[PartialPath->GetLeafMostProperty().ArrayIndex];
|
|
|
|
|
|
|
|
|
|
// If this is a translation unit from the review tab and they select a context, possibly update the selected translation with one from that context
|
|
|
|
|
// Only change the suggested translation if they haven't yet reviewed it
|
|
|
|
|
if (SelectedTranslationUnit->HasBeenReviewed == false)
|
2014-04-23 17:47:40 -04:00
|
|
|
{
|
2014-04-23 18:47:10 -04:00
|
|
|
for (int32 ChangeIndex = 0; ChangeIndex < SelectedContextInfo.Changes.Num(); ++ChangeIndex)
|
2014-04-23 17:47:40 -04:00
|
|
|
{
|
2014-04-23 18:47:10 -04:00
|
|
|
// Find most recent, non-empty translation
|
|
|
|
|
if (!SelectedContextInfo.Changes[ChangeIndex].Translation.IsEmpty() && SelectedTranslationUnit->Translation != SelectedContextInfo.Changes[ChangeIndex].Translation)
|
|
|
|
|
{
|
|
|
|
|
SelectedTranslationUnit->Modify();
|
|
|
|
|
SelectedTranslationUnit->Translation = SelectedContextInfo.Changes[ChangeIndex].Translation;
|
|
|
|
|
SelectedTranslationUnit->PostEditChange();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add the HistoryPropertyTable-specific path
|
|
|
|
|
TSharedRef<FPropertyPath> HistoryPath = ContextPropertyTable->GetRootPath();
|
|
|
|
|
UArrayProperty* ContextArrayProp = FindField<UArrayProperty>(UTranslationUnit::StaticClass(), "Contexts");
|
|
|
|
|
FPropertyInfo ContextPropInfo;
|
|
|
|
|
ContextPropInfo.Property = ContextArrayProp->Inner;
|
|
|
|
|
ContextPropInfo.ArrayIndex = PartialPath->GetLeafMostProperty().ArrayIndex;
|
|
|
|
|
HistoryPath = HistoryPath->ExtendPath(ContextPropInfo);
|
|
|
|
|
UArrayProperty* ChangesProp = FindField<UArrayProperty>(FTranslationContextInfo::StaticStruct(), "Changes");
|
|
|
|
|
FPropertyInfo ChangesPropInfo;
|
|
|
|
|
ChangesPropInfo.Property = ChangesProp;
|
|
|
|
|
ChangesPropInfo.ArrayIndex = INDEX_NONE;
|
|
|
|
|
HistoryPath = HistoryPath->ExtendPath(ChangesPropInfo);
|
|
|
|
|
if (HistoryPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
TArray<UObject*> ObjectArray;
|
|
|
|
|
ObjectArray.Add(SelectedTranslationUnit);
|
|
|
|
|
HistoryPropertyTable->SetObjects(ObjectArray);
|
|
|
|
|
HistoryPropertyTable->SetRootPath(HistoryPath);
|
|
|
|
|
|
|
|
|
|
// Need to re-add the columns we want to display
|
|
|
|
|
HistoryPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(FTranslationChange::StaticStruct(), "Version"));
|
|
|
|
|
HistoryPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(FTranslationChange::StaticStruct(), "DateAndTime"));
|
|
|
|
|
HistoryPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(FTranslationChange::StaticStruct(), "Source"));
|
|
|
|
|
HistoryPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(FTranslationChange::StaticStruct(), "Translation"));
|
|
|
|
|
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = HistoryPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
2014-04-23 17:47:40 -04:00
|
|
|
}
|
|
|
|
|
}
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 17:49:26 -04:00
|
|
|
void FTranslationEditor::PreviewAllTranslationsInEditor_Execute()
|
|
|
|
|
{
|
|
|
|
|
DataManager->PreviewAllTranslationsInEditor();
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 18:20:15 -04:00
|
|
|
void FTranslationEditor::ExportToPortableObjectFormat_Execute()
|
|
|
|
|
{
|
2014-04-23 19:06:27 -04:00
|
|
|
const FString PortableObjectFileDescription = LOCTEXT("PortableObjectFileDescription", "Portable Object File").ToString();
|
|
|
|
|
const FString PortableObjectFileExtension = TEXT("*.po");
|
|
|
|
|
const FString FileTypes = FString::Printf(TEXT("%s (%s)|%s"), *PortableObjectFileDescription, *PortableObjectFileExtension, *PortableObjectFileExtension);
|
|
|
|
|
const FString DefaultFilename = FPaths::GetBaseFilename(ManifestFilePath) + "-" + FPaths::GetBaseFilename(FPaths::GetPath(ArchiveFilePath)) + ".po";
|
2014-04-23 19:14:07 -04:00
|
|
|
FString DefaultPath = FPaths::GameSavedDir();
|
|
|
|
|
if (LastExportFilePath != "")
|
|
|
|
|
{
|
|
|
|
|
DefaultPath = LastExportFilePath;
|
|
|
|
|
}
|
2014-04-23 19:06:27 -04:00
|
|
|
TArray<FString> SaveFilenames;
|
|
|
|
|
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
|
2014-04-23 18:20:15 -04:00
|
|
|
bool bSelected = false;
|
2014-04-23 19:14:07 -04:00
|
|
|
bool bHadError = false;
|
2014-04-23 18:20:15 -04:00
|
|
|
|
2014-04-23 19:06:27 -04:00
|
|
|
// Prompt the user for the filename
|
|
|
|
|
if (DesktopPlatform)
|
2014-04-23 18:20:15 -04:00
|
|
|
{
|
2014-04-23 19:06:27 -04:00
|
|
|
void* ParentWindowWindowHandle = NULL;
|
|
|
|
|
|
|
|
|
|
const TSharedPtr<SWindow>& ParentWindow = FSlateApplication::Get().FindWidgetWindow(PreviewTextBlock);
|
|
|
|
|
if (ParentWindow.IsValid() && ParentWindow->GetNativeWindow().IsValid())
|
|
|
|
|
{
|
|
|
|
|
ParentWindowWindowHandle = ParentWindow->GetNativeWindow()->GetOSWindowHandle();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bSelected = DesktopPlatform->SaveFileDialog(
|
|
|
|
|
ParentWindowWindowHandle,
|
|
|
|
|
LOCTEXT("ChooseExportLocationWindowTitle", "Choose Export Location").ToString(),
|
2014-04-23 19:14:07 -04:00
|
|
|
LastExportFilePath,
|
2014-04-23 19:06:27 -04:00
|
|
|
DefaultFilename,
|
|
|
|
|
FileTypes,
|
|
|
|
|
EFileDialogFlags::None,
|
|
|
|
|
SaveFilenames
|
|
|
|
|
);
|
2014-04-23 18:20:15 -04:00
|
|
|
}
|
|
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
if (bSelected)
|
2014-04-23 19:06:27 -04:00
|
|
|
{
|
2014-04-23 19:14:07 -04:00
|
|
|
GWarn->BeginSlowTask(LOCTEXT("ExportingInternationalization", "Exporting Internationalization Data..."), true);
|
2014-04-23 19:06:27 -04:00
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
// Write translation data first to ensure all changes are exported
|
|
|
|
|
DataManager->WriteTranslationData();
|
2014-04-23 19:06:27 -04:00
|
|
|
|
2014-09-04 09:39:37 -04:00
|
|
|
// Source path needs to be relative to Engine or Game directory
|
|
|
|
|
FString ManifestFullPath = FPaths::ConvertRelativePathToFull(ManifestFilePath);
|
|
|
|
|
FString EngineFullPath = FPaths::ConvertRelativePathToFull(FPaths::EngineContentDir());
|
|
|
|
|
FString FolderRelativeManifestPath = ManifestFilePath;
|
|
|
|
|
bool IsEngineManifest = false;
|
|
|
|
|
if (ManifestFullPath.StartsWith(EngineFullPath))
|
|
|
|
|
{
|
|
|
|
|
IsEngineManifest = true;
|
|
|
|
|
}
|
|
|
|
|
if (IsEngineManifest)
|
|
|
|
|
{
|
|
|
|
|
FPaths::MakePathRelativeTo(FolderRelativeManifestPath, *FPaths::EngineDir());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
FPaths::MakePathRelativeTo(FolderRelativeManifestPath, *FPaths::GameDir());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Paths like "Content/Localization/Editor/" are not considered relative for some reason, so add "./" if neccessary
|
|
|
|
|
if (!FPaths::IsRelative(FolderRelativeManifestPath))
|
|
|
|
|
{
|
|
|
|
|
FolderRelativeManifestPath = FString(TEXT("./")) + FolderRelativeManifestPath;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
UInternationalizationExportSettings* ExportSettings = NewObject<UInternationalizationExportSettings>();
|
|
|
|
|
ExportSettings->CulturesToGenerate.Empty();
|
|
|
|
|
ExportSettings->CulturesToGenerate.Add(FPaths::GetBaseFilename(FPaths::GetPath(ArchiveFilePath)));
|
|
|
|
|
ExportSettings->CommandletClass = "InternationalizationExport";
|
2014-09-04 09:39:37 -04:00
|
|
|
ExportSettings->SourcePath = FPaths::GetPath(FolderRelativeManifestPath);
|
2014-04-23 19:14:07 -04:00
|
|
|
ExportSettings->ManifestName = FPaths::GetBaseFilename(ManifestFilePath) + ".manifest";
|
|
|
|
|
ExportSettings->ArchiveName = FPaths::GetBaseFilename(ManifestFilePath) + ".archive";
|
|
|
|
|
ExportSettings->bExportLoc = true;
|
|
|
|
|
ExportSettings->bImportLoc = false;
|
2014-09-17 11:51:38 -04:00
|
|
|
ExportSettings->bUseCultureDirectory = false;
|
2014-04-23 18:20:15 -04:00
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
ExportSettings->DestinationPath = DefaultPath / DefaultFilename;
|
2014-04-23 18:20:15 -04:00
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
if (SaveFilenames.Num() > 0)
|
2014-04-23 18:20:15 -04:00
|
|
|
{
|
2014-05-01 00:16:11 -04:00
|
|
|
ExportSettings->DestinationPath = FPaths::GetPath(SaveFilenames[0]);
|
|
|
|
|
ExportSettings->PortableObjectName = FPaths::GetCleanFilename(SaveFilenames[0]);
|
2014-04-23 19:14:07 -04:00
|
|
|
LastExportFilePath = FPaths::GetPath(SaveFilenames[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write these settings to a temporary config file that the Internationalization Export Commandlet will read
|
|
|
|
|
FString TempConfigFilepath = FPaths::GameSavedDir() / "Config" / "InternationalizationExport.ini";
|
|
|
|
|
ExportSettings->SaveConfig(CPF_Config, *TempConfigFilepath);
|
|
|
|
|
|
|
|
|
|
// Using .ini config saving means these settings will be saved in the GetClass()->GetPathName() section
|
|
|
|
|
TArray<FString> ConfigSections;
|
|
|
|
|
ConfigSections.Add(ExportSettings->GetClass()->GetPathName());
|
|
|
|
|
FMessageLog TranslationEditorMessageLog("TranslationEditor");
|
|
|
|
|
|
|
|
|
|
for (FString& ConfigSection : ConfigSections)
|
|
|
|
|
{
|
|
|
|
|
// Spawn the LocalizationExport commandlet, and run its log output back into ours
|
|
|
|
|
FString AppURL = FPlatformProcess::ExecutableName(true);
|
|
|
|
|
FString Parameters = FString("-run=InternationalizationExport -config=") + TempConfigFilepath + " -section=" + ConfigSection;
|
|
|
|
|
|
|
|
|
|
void* WritePipe;
|
|
|
|
|
void* ReadPipe;
|
|
|
|
|
FPlatformProcess::CreatePipe(ReadPipe, WritePipe);
|
|
|
|
|
FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*AppURL, *Parameters, false, false, false, NULL, 0, NULL, WritePipe);
|
|
|
|
|
|
|
|
|
|
while (FPlatformProcess::IsProcRunning(ProcessHandle))
|
|
|
|
|
{
|
|
|
|
|
FString NewLine = FPlatformProcess::ReadPipe(ReadPipe);
|
|
|
|
|
if (NewLine.Len() > 0)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LocalizationExport, Log, TEXT("%s"), *NewLine);
|
|
|
|
|
FFormatNamedArguments Arguments;
|
|
|
|
|
Arguments.Add(TEXT("LogMessage"), FText::FromString(NewLine));
|
|
|
|
|
TranslationEditorMessageLog.Info(FText::Format(LOCTEXT("LocalizationExportLog", "Localization Export Log: {LogMessage}"), Arguments));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FPlatformProcess::Sleep(0.25);
|
|
|
|
|
}
|
2014-04-23 18:20:15 -04:00
|
|
|
FString NewLine = FPlatformProcess::ReadPipe(ReadPipe);
|
|
|
|
|
if (NewLine.Len() > 0)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LocalizationExport, Log, TEXT("%s"), *NewLine);
|
2014-04-23 19:14:07 -04:00
|
|
|
FFormatNamedArguments Arguments;
|
|
|
|
|
Arguments.Add(TEXT("LogMessage"), FText::FromString(NewLine));
|
|
|
|
|
TranslationEditorMessageLog.Info(FText::Format(LOCTEXT("LocalizationExportLog", "Localization Export Log: {LogMessage}"), Arguments));
|
2014-04-23 18:20:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FPlatformProcess::Sleep(0.25);
|
2014-04-23 19:14:07 -04:00
|
|
|
FPlatformProcess::ClosePipe(ReadPipe, WritePipe);
|
|
|
|
|
|
|
|
|
|
int32 ReturnCode;
|
|
|
|
|
if (!FPlatformProcess::GetProcReturnCode(ProcessHandle, &ReturnCode))
|
|
|
|
|
{
|
|
|
|
|
bHadError = true;
|
|
|
|
|
}
|
|
|
|
|
else if (ReturnCode != 0)
|
|
|
|
|
{
|
|
|
|
|
bHadError = true;
|
|
|
|
|
}
|
2014-04-23 18:20:15 -04:00
|
|
|
}
|
|
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
GWarn->EndSlowTask();
|
2014-04-23 18:20:15 -04:00
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
if (bHadError)
|
2014-04-23 18:20:15 -04:00
|
|
|
{
|
2014-04-23 19:14:07 -04:00
|
|
|
TranslationEditorMessageLog.Error(LOCTEXT("FailedToExportLocalization", "Failed to export localization!"));
|
|
|
|
|
TranslationEditorMessageLog.Notify(LOCTEXT("FailedToExportLocalization", "Failed to export localization!"));
|
|
|
|
|
TranslationEditorMessageLog.Open(EMessageSeverity::Error);
|
2014-04-23 18:20:15 -04:00
|
|
|
}
|
|
|
|
|
}
|
2014-04-23 19:14:07 -04:00
|
|
|
}
|
2014-04-23 18:20:15 -04:00
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
void FTranslationEditor::ImportFromPortableObjectFormat_Execute()
|
|
|
|
|
{
|
|
|
|
|
const FString PortableObjectFileDescription = LOCTEXT("PortableObjectFileDescription", "Portable Object File").ToString();
|
|
|
|
|
const FString PortableObjectFileExtension = TEXT("*.po");
|
|
|
|
|
const FString FileTypes = FString::Printf(TEXT("%s (%s)|%s"), *PortableObjectFileDescription, *PortableObjectFileExtension, *PortableObjectFileExtension);
|
|
|
|
|
FString DefaultPath = FPaths::GameSavedDir();
|
|
|
|
|
if (LastImportFilePath != "")
|
|
|
|
|
{
|
|
|
|
|
DefaultPath = LastImportFilePath;
|
|
|
|
|
}
|
|
|
|
|
TArray<FString> OpenFilenames;
|
|
|
|
|
bool bHadError = false;
|
|
|
|
|
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
|
|
|
|
|
|
|
|
|
|
bool bOpened = false;
|
|
|
|
|
if (DesktopPlatform)
|
|
|
|
|
{
|
|
|
|
|
void* ParentWindowWindowHandle = NULL;
|
|
|
|
|
|
|
|
|
|
const TSharedPtr<SWindow>& ParentWindow = FSlateApplication::Get().FindWidgetWindow(PreviewTextBlock);
|
|
|
|
|
if (ParentWindow.IsValid() && ParentWindow->GetNativeWindow().IsValid())
|
|
|
|
|
{
|
|
|
|
|
ParentWindowWindowHandle = ParentWindow->GetNativeWindow()->GetOSWindowHandle();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bOpened = DesktopPlatform->OpenFileDialog(
|
|
|
|
|
ParentWindowWindowHandle,
|
|
|
|
|
LOCTEXT("ChooseImportLocationWindowTitle", "Choose File to Import").ToString(),
|
|
|
|
|
DefaultPath,
|
|
|
|
|
TEXT(""),
|
|
|
|
|
FileTypes,
|
|
|
|
|
EFileDialogFlags::None,
|
|
|
|
|
OpenFilenames
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bOpened)
|
|
|
|
|
{
|
2014-09-11 16:10:24 -04:00
|
|
|
// Source path needs to be relative to Engine or Game directory
|
|
|
|
|
FString ManifestFullPath = FPaths::ConvertRelativePathToFull(ManifestFilePath);
|
|
|
|
|
FString EngineFullPath = FPaths::ConvertRelativePathToFull(FPaths::EngineContentDir());
|
|
|
|
|
FString FolderRelativeManifestPath = ManifestFilePath;
|
|
|
|
|
bool IsEngineManifest = false;
|
|
|
|
|
if (ManifestFullPath.StartsWith(EngineFullPath))
|
|
|
|
|
{
|
|
|
|
|
IsEngineManifest = true;
|
|
|
|
|
}
|
|
|
|
|
if (IsEngineManifest)
|
|
|
|
|
{
|
|
|
|
|
FPaths::MakePathRelativeTo(FolderRelativeManifestPath, *FPaths::EngineDir());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
FPaths::MakePathRelativeTo(FolderRelativeManifestPath, *FPaths::GameDir());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Paths like "Content/Localization/Editor/" are not considered relative for some reason, so add "./" if neccessary
|
|
|
|
|
if (!FPaths::IsRelative(FolderRelativeManifestPath))
|
|
|
|
|
{
|
|
|
|
|
FolderRelativeManifestPath = FString(TEXT("./")) + FolderRelativeManifestPath;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 19:14:07 -04:00
|
|
|
UInternationalizationExportSettings* ImportSettings = NewObject<UInternationalizationExportSettings>();
|
|
|
|
|
ImportSettings->CulturesToGenerate.Empty();
|
|
|
|
|
ImportSettings->CulturesToGenerate.Add(FPaths::GetBaseFilename(FPaths::GetPath(ArchiveFilePath)));
|
|
|
|
|
ImportSettings->CommandletClass = "InternationalizationExport";
|
2014-09-11 16:10:24 -04:00
|
|
|
ImportSettings->DestinationPath = FPaths::GetPath(FolderRelativeManifestPath);
|
2014-04-23 19:14:07 -04:00
|
|
|
ImportSettings->ManifestName = FPaths::GetBaseFilename(ManifestFilePath) + ".manifest";
|
|
|
|
|
ImportSettings->ArchiveName = FPaths::GetBaseFilename(ManifestFilePath) + ".archive";
|
|
|
|
|
ImportSettings->bExportLoc = false;
|
|
|
|
|
ImportSettings->bImportLoc = true;
|
2014-09-17 11:51:38 -04:00
|
|
|
ImportSettings->bUseCultureDirectory = false;
|
2014-04-23 19:14:07 -04:00
|
|
|
|
|
|
|
|
ImportSettings->SourcePath = DefaultPath / FPaths::GetBaseFilename(ManifestFilePath);
|
|
|
|
|
|
|
|
|
|
if (OpenFilenames.Num() > 0)
|
|
|
|
|
{
|
2014-05-01 00:16:11 -04:00
|
|
|
ImportSettings->SourcePath = FPaths::GetPath(OpenFilenames[0]);
|
|
|
|
|
ImportSettings->PortableObjectName = FPaths::GetCleanFilename(OpenFilenames[0]);
|
2014-04-23 19:14:07 -04:00
|
|
|
LastImportFilePath = FPaths::GetPath(OpenFilenames[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write translation data first to ensure all changes are exported
|
|
|
|
|
bHadError = !(DataManager->WriteTranslationData(true));
|
|
|
|
|
|
|
|
|
|
if (!bHadError)
|
|
|
|
|
{
|
|
|
|
|
GWarn->BeginSlowTask(LOCTEXT("ImportingInternationalization", "Importing Internationalization Data..."), true);
|
|
|
|
|
|
|
|
|
|
// Write these settings to a temporary config file that the Internationalization Export Commandlet will read
|
|
|
|
|
FString TempConfigFilepath = FPaths::GameSavedDir() / "Config" / "InternationalizationExport.ini";
|
|
|
|
|
ImportSettings->SaveConfig(CPF_Config, *TempConfigFilepath);
|
|
|
|
|
|
|
|
|
|
// Using .ini config saving means these settings will be saved in the GetClass()->GetPathName() section
|
|
|
|
|
TArray<FString> ConfigSections;
|
|
|
|
|
ConfigSections.Add(ImportSettings->GetClass()->GetPathName());
|
|
|
|
|
FMessageLog TranslationEditorMessageLog("TranslationEditor");
|
|
|
|
|
|
|
|
|
|
for (FString& ConfigSection : ConfigSections)
|
|
|
|
|
{
|
|
|
|
|
// Spawn the LocalizationExport commandlet, and run its log output back into ours
|
|
|
|
|
FString AppURL = FPlatformProcess::ExecutableName(true);
|
|
|
|
|
FString Parameters = FString("-run=InternationalizationExport -config=") + TempConfigFilepath + " -section=" + ConfigSection;
|
|
|
|
|
|
|
|
|
|
void* WritePipe;
|
|
|
|
|
void* ReadPipe;
|
|
|
|
|
FPlatformProcess::CreatePipe(ReadPipe, WritePipe);
|
|
|
|
|
FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*AppURL, *Parameters, false, false, false, NULL, 0, NULL, WritePipe);
|
|
|
|
|
|
|
|
|
|
while (FPlatformProcess::IsProcRunning(ProcessHandle))
|
|
|
|
|
{
|
|
|
|
|
FString NewLine = FPlatformProcess::ReadPipe(ReadPipe);
|
|
|
|
|
if (NewLine.Len() > 0)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LocalizationExport, Log, TEXT("%s"), *NewLine);
|
|
|
|
|
FFormatNamedArguments Arguments;
|
|
|
|
|
Arguments.Add(TEXT("LogMessage"), FText::FromString(NewLine));
|
|
|
|
|
TranslationEditorMessageLog.Info(FText::Format(LOCTEXT("LocalizationImportLog", "Localization Import Log: {LogMessage}"), Arguments));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FPlatformProcess::Sleep(0.25);
|
|
|
|
|
}
|
|
|
|
|
FString NewLine = FPlatformProcess::ReadPipe(ReadPipe);
|
|
|
|
|
if (NewLine.Len() > 0)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LocalizationExport, Log, TEXT("%s"), *NewLine);
|
|
|
|
|
FFormatNamedArguments Arguments;
|
|
|
|
|
Arguments.Add(TEXT("LogMessage"), FText::FromString(NewLine));
|
|
|
|
|
TranslationEditorMessageLog.Info(FText::Format(LOCTEXT("LocalizationImportLog", "Localization Import Log: {LogMessage}"), Arguments));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FPlatformProcess::Sleep(0.25);
|
|
|
|
|
FPlatformProcess::ClosePipe(ReadPipe, WritePipe);
|
|
|
|
|
|
|
|
|
|
int32 ReturnCode;
|
|
|
|
|
if (!FPlatformProcess::GetProcReturnCode(ProcessHandle, &ReturnCode))
|
|
|
|
|
{
|
|
|
|
|
bHadError = true;
|
|
|
|
|
}
|
|
|
|
|
else if (ReturnCode != 0)
|
|
|
|
|
{
|
|
|
|
|
bHadError = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GWarn->EndSlowTask();
|
|
|
|
|
|
|
|
|
|
if (bHadError)
|
|
|
|
|
{
|
|
|
|
|
TranslationEditorMessageLog.Error(LOCTEXT("FailedToExportLocalization", "Failed to export localization!"));
|
|
|
|
|
TranslationEditorMessageLog.Notify(LOCTEXT("FailedToExportLocalization", "Failed to export localization!"), EMessageSeverity::Info, true);
|
|
|
|
|
TranslationEditorMessageLog.Open(EMessageSeverity::Error);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DataManager->LoadFromArchive(DataManager->GetAllTranslationsArray(), true, true);
|
|
|
|
|
|
|
|
|
|
TabManager->InvokeTab(ChangedOnImportTabId);
|
|
|
|
|
ChangedOnImportPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetChangedOnImportArray());
|
|
|
|
|
// Need to re-add the columns we want to display
|
|
|
|
|
ChangedOnImportPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Source"));
|
|
|
|
|
ChangedOnImportPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "TranslationBeforeImport"));
|
|
|
|
|
ChangedOnImportPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Translation"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-23 18:20:15 -04:00
|
|
|
}
|
|
|
|
|
|
2014-04-23 18:48:34 -04:00
|
|
|
void FTranslationEditor::OnFilterTextChanged(const FText& InFilterText)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::OnFilterTextCommitted(const FText& InFilterText, ETextCommit::Type CommitInfo)
|
|
|
|
|
{
|
|
|
|
|
const FString InFilterString = InFilterText.ToString();
|
|
|
|
|
|
|
|
|
|
if (CommitInfo == ETextCommit::OnEnter)
|
|
|
|
|
{
|
|
|
|
|
if (InFilterString != CurrentSearchFilter)
|
|
|
|
|
{
|
|
|
|
|
CurrentSearchFilter = InFilterString;
|
|
|
|
|
|
|
|
|
|
DataManager->PopulateSearchResultsUsingFilter(InFilterString);
|
|
|
|
|
|
|
|
|
|
if (SearchPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
SearchPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetSearchResultsArray());
|
|
|
|
|
|
|
|
|
|
// Need to re-add the columns we want to display
|
|
|
|
|
SearchPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Source"));
|
|
|
|
|
SearchPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Translation"));
|
|
|
|
|
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = SearchPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FTranslationEditor::OpenSearchTab_Execute()
|
|
|
|
|
{
|
|
|
|
|
TabManager->InvokeTab(SearchTabId);
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-18 03:20:09 -05:00
|
|
|
FReply FTranslationEditor::OnGetHistoryButtonClicked()
|
|
|
|
|
{
|
|
|
|
|
// Load the actual history data
|
|
|
|
|
DataManager->GetHistoryForTranslationUnits();
|
|
|
|
|
|
|
|
|
|
// Items might have moved from Untranslated to review, so refresh the view of both tables
|
|
|
|
|
if (UntranslatedPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
UntranslatedPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetUntranslatedArray());
|
|
|
|
|
|
|
|
|
|
// Need to re-add the columns we want to display
|
|
|
|
|
UntranslatedPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Source"));
|
|
|
|
|
UntranslatedPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Translation"));
|
|
|
|
|
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = UntranslatedPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ReviewPropertyTable.IsValid())
|
|
|
|
|
{
|
|
|
|
|
ReviewPropertyTable->SetObjects((TArray<UObject*>&)DataManager->GetReviewArray());
|
|
|
|
|
|
|
|
|
|
// Need to re-add the columns we want to display
|
|
|
|
|
ReviewPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Source"));
|
|
|
|
|
ReviewPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "Translation"));
|
|
|
|
|
ReviewPropertyTable->AddColumn((TWeakObjectPtr<UProperty>)FindField<UProperty>(UTranslationUnit::StaticClass(), "HasBeenReviewed"));
|
|
|
|
|
|
|
|
|
|
TArray<TSharedRef<IPropertyTableColumn>> Columns = ReviewPropertyTable->GetColumns();
|
|
|
|
|
for (TSharedRef<IPropertyTableColumn> Column : Columns)
|
|
|
|
|
{
|
|
|
|
|
FString ColumnId = Column->GetId().ToString();
|
|
|
|
|
if (ColumnId == "HasBeenReviewed")
|
|
|
|
|
{
|
|
|
|
|
Column->SetWidth(120);
|
|
|
|
|
Column->SetSizeMode(EPropertyTableColumnSizeMode::Fixed);
|
|
|
|
|
}
|
|
|
|
|
// Freeze columns, don't want user to remove them
|
|
|
|
|
Column->SetFrozen(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure all UI is refreshed
|
|
|
|
|
RefreshUI();
|
|
|
|
|
|
|
|
|
|
// Make sure current selection is reflected
|
|
|
|
|
UpdateUntranslatedSelection();
|
|
|
|
|
UpdateNeedsReviewSelection();
|
|
|
|
|
UpdateCompletedSelection();
|
|
|
|
|
UpdateSearchSelection();
|
|
|
|
|
|
|
|
|
|
return FReply::Handled();
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-14 14:13:41 -04:00
|
|
|
#undef LOCTEXT_NAMESPACE
|