void FAssetTypeActions_DataTable::OpenAssetEditor( const TArray<UObject*>& InObjects, TSharedPtr<IToolkitHost> EditWithinLevelEditor ) { TArray<UDataTable*> DataTablesToOpen; TArray<UDataTable*> InvalidDataTables; for (UObject* Obj : InObjects) { UDataTable* Table = Cast<UDataTable>(Obj); if (Table) { if (Table->RowStruct) { DataTablesToOpen.Add(Table); } else { InvalidDataTables.Add(Table); } } } if (InvalidDataTables.Num() > 0) { FTextBuilder DataTablesListText; DataTablesListText.Indent(); for (UDataTable* Table : InvalidDataTables) { const FName ResolvedRowStructName = Table->GetRowStructName(); DataTablesListText.AppendLineFormat(LOCTEXT("DataTable_MissingRowStructListEntry", "* {0} (Row Structure: {1})"), FText::FromString(Table->GetName()), FText::FromName(ResolvedRowStructName)); } const EAppReturnType::Type DlgResult = OpenMsgDlgInt( EAppMsgType::YesNoCancel, FText::Format(LOCTEXT("DataTable_MissingRowStructMsg", "The following Data Tables are missing their row structure and will not be editable.\n\n{0}\n\nDo you want to open these data tables?"), DataTablesListText.ToText()), LOCTEXT("DataTable_MissingRowStructTitle", "Continue?") ); switch(DlgResult) { case EAppReturnType::Yes: DataTablesToOpen.Append(InvalidDataTables); break; case EAppReturnType::Cancel: return; default: break; } } FDataTableEditorModule& DataTableEditorModule = FModuleManager::LoadModuleChecked<FDataTableEditorModule>("DataTableEditor"); for (UDataTable* Table : DataTablesToOpen) { DataTableEditorModule.CreateDataTableEditor(EToolkitMode::Standalone, EditWithinLevelEditor, Table); } }
bool FCollection::CheckinCollection(FText& OutError) { if ( !ensure(SourceFilename.Len()) ) { OutError = LOCTEXT("Error_Internal", "There was an internal error."); return false; } ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider(); if ( !ISourceControlModule::Get().IsEnabled() ) { OutError = LOCTEXT("Error_SCCDisabled", "Source control is not enabled. Enable source control in the preferences menu."); return false; } if ( !SourceControlProvider.IsAvailable() ) { OutError = LOCTEXT("Error_SCCNotAvailable", "Source control is currently not available. Check your connection and try again."); return false; } const FString AbsoluteFilename = FPaths::ConvertRelativePathToFull(SourceFilename); FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(AbsoluteFilename, EStateCacheUsage::ForceUpdate); if (SourceControlState.IsValid() && !SourceControlState->IsSourceControlled()) { // Not yet in the depot. Add it. const bool bWasAdded = (SourceControlProvider.Execute(ISourceControlOperation::Create<FMarkForAdd>(), AbsoluteFilename) == ECommandResult::Succeeded); if (!bWasAdded) { OutError = FText::Format(LOCTEXT("Error_SCCAdd", "Failed to add collection '{0}' to source control."), FText::FromName(CollectionName)); return false; } SourceControlState = SourceControlProvider.GetState(AbsoluteFilename, EStateCacheUsage::ForceUpdate); } if ( SourceControlState.IsValid() && !(SourceControlState->IsCheckedOut() || SourceControlState->IsAdded()) ) { OutError = FText::Format(LOCTEXT("Error_SCCNotCheckedOut", "Collection '{0}' not checked out or open for add."), FText::FromName(CollectionName)); return false; } // Form an appropriate summary for the changelist const FText CollectionNameText = FText::FromName( CollectionName ); FTextBuilder ChangelistDescBuilder; if (SourceControlState.IsValid() && SourceControlState->IsAdded()) { ChangelistDescBuilder.AppendLineFormat(LOCTEXT("CollectionAddedNewDesc", "Added collection '{0}'"), CollectionNameText); } else { if (IsDynamic()) { // @todo collection Change description for dynamic collections } else { // Gather differences from disk TArray<FName> ObjectsAdded; TArray<FName> ObjectsRemoved; GetObjectDifferencesFromDisk(ObjectsAdded, ObjectsRemoved); ObjectsAdded.Sort(); ObjectsRemoved.Sort(); // Report added files FFormatNamedArguments Args; Args.Add(TEXT("FirstObjectAdded"), ObjectsAdded.Num() > 0 ? FText::FromName(ObjectsAdded[0]) : NSLOCTEXT("Core", "None", "None")); Args.Add(TEXT("NumberAdded"), FText::AsNumber(ObjectsAdded.Num())); Args.Add(TEXT("FirstObjectRemoved"), ObjectsRemoved.Num() > 0 ? FText::FromName(ObjectsRemoved[0]) : NSLOCTEXT("Core", "None", "None")); Args.Add(TEXT("NumberRemoved"), FText::AsNumber(ObjectsRemoved.Num())); Args.Add(TEXT("CollectionName"), CollectionNameText); if (ObjectsAdded.Num() == 1) { ChangelistDescBuilder.AppendLineFormat(LOCTEXT("CollectionAddedSingleDesc", "Added '{FirstObjectAdded}' to collection '{CollectionName}'"), Args); } else if (ObjectsAdded.Num() > 1) { ChangelistDescBuilder.AppendLineFormat(LOCTEXT("CollectionAddedMultipleDesc", "Added {NumberAdded} objects to collection '{CollectionName}':"), Args); ChangelistDescBuilder.Indent(); for (const FName& AddedObjectName : ObjectsAdded) { ChangelistDescBuilder.AppendLine(FText::FromName(AddedObjectName)); } ChangelistDescBuilder.Unindent(); } if ( ObjectsRemoved.Num() == 1 ) { ChangelistDescBuilder.AppendLineFormat(LOCTEXT("CollectionRemovedSingleDesc", "Removed '{FirstObjectRemoved}' from collection '{CollectionName}'"), Args); } else if (ObjectsRemoved.Num() > 1) { ChangelistDescBuilder.AppendLineFormat(LOCTEXT("CollectionRemovedMultipleDesc", "Removed {NumberRemoved} objects from collection '{CollectionName}'"), Args); ChangelistDescBuilder.Indent(); for (const FName& RemovedObjectName : ObjectsRemoved) { ChangelistDescBuilder.AppendLine(FText::FromName(RemovedObjectName)); } ChangelistDescBuilder.Unindent(); } } // Parent change? if (DiskSnapshot.ParentCollectionGuid != ParentCollectionGuid) { ChangelistDescBuilder.AppendLineFormat(LOCTEXT("CollectionChangedParentDesc", "Changed the parent of collection '{0}'"), CollectionNameText); } // Version bump? if (FileVersion < ECollectionVersion::CurrentVersion) { ChangelistDescBuilder.AppendLineFormat(LOCTEXT("CollectionUpgradedDesc", "Upgraded collection '{0}' (was version {1}, now version {2})"), CollectionNameText, FText::AsNumber(FileVersion), FText::AsNumber(ECollectionVersion::CurrentVersion)); } } FText ChangelistDesc = ChangelistDescBuilder.ToText(); if (ChangelistDesc.IsEmpty()) { // No changes could be detected ChangelistDesc = FText::Format(LOCTEXT("CollectionNotModifiedDesc", "Collection '{0}' not modified"), CollectionNameText); } // Finally check in the file TSharedRef<FCheckIn, ESPMode::ThreadSafe> CheckInOperation = ISourceControlOperation::Create<FCheckIn>(); CheckInOperation->SetDescription( ChangelistDesc ); if ( SourceControlProvider.Execute( CheckInOperation, AbsoluteFilename ) ) { return true; } else { OutError = FText::Format(LOCTEXT("Error_SCCCheckIn", "Failed to check in collection '{0}'."), FText::FromName(CollectionName)); return false; } }
bool LocalizationCommandletTasks::ReportLoadedAudioAssets(const TArray<ULocalizationTarget*>& Targets, const TOptional<FString>& CultureName) { TSet<FString> LoadedDialogueWaveAssets; TSet<FString> LoadedSoundWaveAssets; for (const ULocalizationTarget* Target : Targets) { const FString RootAssetPath = Target->IsMemberOfEngineTargetSet() ? TEXT("/Engine") : TEXT("/Game"); TArray<FString> CulturesToTest; { if (CultureName.IsSet()) { CulturesToTest.Add(CultureName.GetValue()); } else { CulturesToTest.Reserve(Target->Settings.SupportedCulturesStatistics.Num()); for (const FCultureStatistics& CultureData : Target->Settings.SupportedCulturesStatistics) { CulturesToTest.Add(CultureData.CultureName); } } } TArray<FString> DialogueWavePathsToTest; TArray<FString> SoundWavePathsToTest; { const FString NativeCulture = Target->Settings.SupportedCulturesStatistics.IsValidIndex(Target->Settings.NativeCultureIndex) ? Target->Settings.SupportedCulturesStatistics[Target->Settings.NativeCultureIndex].CultureName : FString(); const bool bImportNativeAsSource = Target->Settings.ImportDialogueSettings.bImportNativeAsSource && !NativeCulture.IsEmpty(); if (bImportNativeAsSource) { DialogueWavePathsToTest.Add(RootAssetPath); SoundWavePathsToTest.Add(RootAssetPath / Target->Settings.ImportDialogueSettings.ImportedDialogueFolder); } for (const FString& Culture : CulturesToTest) { if (bImportNativeAsSource && Culture == NativeCulture) { continue; } DialogueWavePathsToTest.Add(RootAssetPath / TEXT("L10N") / Culture); SoundWavePathsToTest.Add(RootAssetPath / TEXT("L10N") / Culture / Target->Settings.ImportDialogueSettings.ImportedDialogueFolder); } } ForEachObjectOfClass(UDialogueWave::StaticClass(), [&](UObject* InObject) { const FString ObjectPath = InObject->GetPathName(); auto FindAssetPathPredicate = [&](const FString& InAssetPath) -> bool { return ObjectPath.StartsWith(InAssetPath, ESearchCase::IgnoreCase); }; if (DialogueWavePathsToTest.ContainsByPredicate(FindAssetPathPredicate)) { LoadedDialogueWaveAssets.Add(ObjectPath); } }); ForEachObjectOfClass(USoundWave::StaticClass(), [&](UObject* InObject) { const FString ObjectPath = InObject->GetPathName(); auto FindAssetPathPredicate = [&](const FString& InAssetPath) -> bool { return ObjectPath.StartsWith(InAssetPath, ESearchCase::IgnoreCase); }; if (SoundWavePathsToTest.ContainsByPredicate(FindAssetPathPredicate)) { LoadedSoundWaveAssets.Add(ObjectPath); } }); } if (LoadedDialogueWaveAssets.Num() > 0 || LoadedSoundWaveAssets.Num() > 0) { FTextBuilder MsgBuilder; MsgBuilder.AppendLine(LOCTEXT("Warning_LoadedAudioAssetsMsg", "The following audio assets have been loaded by the editor and may cause the dialogue import to fail as their files will be read-only.")); MsgBuilder.AppendLine(FText::GetEmpty()); MsgBuilder.AppendLine(LOCTEXT("Warning_LoadedAudioAssetsMsg_Continue", "Do you want to continue?")); if (LoadedDialogueWaveAssets.Num() > 0) { MsgBuilder.AppendLine(FText::GetEmpty()); MsgBuilder.AppendLine(LOCTEXT("Warning_LoadedAudioAssetsMsg_DialogueWaves", "Dialogue Waves:")); MsgBuilder.Indent(); for (const FString& LoadedDialogueWaveAsset : LoadedDialogueWaveAssets) { MsgBuilder.AppendLine(LoadedDialogueWaveAsset); } MsgBuilder.Unindent(); } if (LoadedSoundWaveAssets.Num() > 0) { MsgBuilder.AppendLine(FText::GetEmpty()); MsgBuilder.AppendLine(LOCTEXT("Warning_LoadedAudioAssetsMsg_SoundWaves", "Sound Waves:")); MsgBuilder.Indent(); for (const FString& LoadedSoundWaveAsset : LoadedSoundWaveAssets) { MsgBuilder.AppendLine(LoadedSoundWaveAsset); } MsgBuilder.Unindent(); } const FText MsgTitle = LOCTEXT("Warning_LoadedAudioAssetsTitle", "Warning - Loaded Audio Assets"); return FMessageDialog::Open(EAppMsgType::YesNo, MsgBuilder.ToText(), &MsgTitle) == EAppReturnType::Yes; } return true; }