You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#rb none #jira UE-159596 #rnx #preflight 62d94160110da0f944afdd32 ### Problem - When rolling our virtualization to projects we have run into a number of set up problems which has caused users to fail to submit packages from the editor as when the virtualization failed we prevented the overall submit from going through. - Although we will eventually work through all of these problems and add better fault tolerance for now it is annoying for the content team so we need an easy way for a project to allow package submits to be completed even if the virtualization process part of the submit failed. - Worth noting that the virtualization process failing should never affect the state of the package files, the only downside is that the packages may not be virtualized. ### Fix - The virtualization/rehydration of packages now return an enum instead of a bool although at the moment we are only returning Success and Failed, but it will allow us to expand in the future - Combined the code calling the virtualization process from both the source control window and the source control changelist window into a single utility function. -- Now the two windows only diverge on how they report failure to the user. - This new utility function now checks to see if the virtualization manager suggests if failing the virtualization process should block any package submission to source control or not. - I am not happy with this solution, but I haven't come up with anything that feels right, this solution will at least work. [CL 21199597 by paul chipchase in ue5-main branch]
522 lines
17 KiB
C++
522 lines
17 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SourceControlWindows.h"
|
|
#include "SSourceControlSubmit.h"
|
|
|
|
#include "FileHelpers.h"
|
|
#include "ISourceControlModule.h"
|
|
#include "SourceControlHelpers.h"
|
|
#include "SourceControlOperations.h"
|
|
#include "Framework/Application/SlateApplication.h"
|
|
#include "Framework/Notifications/NotificationManager.h"
|
|
#include "Logging/MessageLog.h"
|
|
#include "Logging/TokenizedMessage.h"
|
|
#include "Misc/MessageDialog.h"
|
|
#include "Widgets/Notifications/SNotificationList.h"
|
|
|
|
|
|
#if SOURCE_CONTROL_WITH_SLATE
|
|
|
|
#define LOCTEXT_NAMESPACE "SourceControlWindows"
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
// FCheckinResultInfo
|
|
|
|
FCheckinResultInfo::FCheckinResultInfo()
|
|
: Result(ECommandResult::Failed)
|
|
, bAutoCheckedOut(false)
|
|
{
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
// FSourceControlWindows
|
|
|
|
TWeakPtr<SNotificationItem> FSourceControlWindows::ChoosePackagesToCheckInNotification;
|
|
|
|
TArray<FString> FSourceControlWindows::GetSourceControlLocations(const bool bContentOnly)
|
|
{
|
|
TArray<FString> SourceControlLocations;
|
|
|
|
{
|
|
TArray<FString> RootPaths;
|
|
FPackageName::QueryRootContentPaths(RootPaths);
|
|
for (const FString& RootPath : RootPaths)
|
|
{
|
|
const FString RootPathOnDisk = FPackageName::LongPackageNameToFilename(RootPath);
|
|
SourceControlLocations.Add(FPaths::ConvertRelativePathToFull(RootPathOnDisk));
|
|
}
|
|
}
|
|
|
|
if (!bContentOnly)
|
|
{
|
|
SourceControlLocations.Add(FPaths::ConvertRelativePathToFull(FPaths::ProjectConfigDir()));
|
|
SourceControlLocations.Add(FPaths::ConvertRelativePathToFull(FPaths::GetProjectFilePath()));
|
|
}
|
|
|
|
return SourceControlLocations;
|
|
}
|
|
|
|
bool FSourceControlWindows::ChoosePackagesToCheckIn(const FSourceControlWindowsOnCheckInComplete& OnCompleteDelegate)
|
|
{
|
|
if (!ISourceControlModule::Get().IsEnabled())
|
|
{
|
|
FCheckinResultInfo ResultInfo;
|
|
ResultInfo.Description = LOCTEXT("SourceControlDisabled", "Source control is not enabled.");
|
|
OnCompleteDelegate.ExecuteIfBound(ResultInfo);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (!ISourceControlModule::Get().GetProvider().IsAvailable())
|
|
{
|
|
FCheckinResultInfo ResultInfo;
|
|
ResultInfo.Description = LOCTEXT("NoSCCConnection", "No connection to source control available!");
|
|
|
|
FMessageLog EditorErrors("EditorErrors");
|
|
EditorErrors.Warning(ResultInfo.Description)->AddToken(
|
|
FDocumentationToken::Create(TEXT("Engine/UI/SourceControl")));
|
|
EditorErrors.Notify();
|
|
|
|
OnCompleteDelegate.ExecuteIfBound(ResultInfo);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Start selection process...
|
|
|
|
// make sure we update the SCC status of all packages (this could take a long time, so we will run it as a background task)
|
|
TArray<FString> Filenames = GetSourceControlLocations();
|
|
|
|
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
|
|
FSourceControlOperationRef Operation = ISourceControlOperation::Create<FUpdateStatus>();
|
|
SourceControlProvider.Execute(
|
|
Operation,
|
|
Filenames,
|
|
EConcurrency::Asynchronous,
|
|
FSourceControlOperationComplete::CreateStatic(&FSourceControlWindows::ChoosePackagesToCheckInCallback, OnCompleteDelegate));
|
|
|
|
if (ChoosePackagesToCheckInNotification.IsValid())
|
|
{
|
|
ChoosePackagesToCheckInNotification.Pin()->ExpireAndFadeout();
|
|
}
|
|
|
|
FNotificationInfo Info(LOCTEXT("ChooseAssetsToCheckInIndicator", "Checking for assets to check in..."));
|
|
Info.bFireAndForget = false;
|
|
Info.ExpireDuration = 0.0f;
|
|
Info.FadeOutDuration = 1.0f;
|
|
|
|
if (SourceControlProvider.CanCancelOperation(Operation))
|
|
{
|
|
Info.ButtonDetails.Add(FNotificationButtonInfo(
|
|
LOCTEXT("ChoosePackagesToCheckIn_CancelButton", "Cancel"),
|
|
LOCTEXT("ChoosePackagesToCheckIn_CancelButtonTooltip", "Cancel the check in operation."),
|
|
FSimpleDelegate::CreateStatic(&FSourceControlWindows::ChoosePackagesToCheckInCancelled, Operation)
|
|
));
|
|
}
|
|
|
|
ChoosePackagesToCheckInNotification = FSlateNotificationManager::Get().AddNotification(Info);
|
|
|
|
if (ChoosePackagesToCheckInNotification.IsValid())
|
|
{
|
|
ChoosePackagesToCheckInNotification.Pin()->SetCompletionState(SNotificationItem::CS_Pending);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool FSourceControlWindows::CanChoosePackagesToCheckIn()
|
|
{
|
|
ISourceControlModule& SourceControlModule = ISourceControlModule::Get();
|
|
|
|
return ISourceControlModule::Get().IsEnabled() &&
|
|
ISourceControlModule::Get().GetProvider().IsAvailable() &&
|
|
!ChoosePackagesToCheckInNotification.IsValid();
|
|
}
|
|
|
|
|
|
bool FSourceControlWindows::PromptForCheckin(FCheckinResultInfo& OutResultInfo, const TArray<FString>& InPackageNames, const TArray<FString>& InPendingDeletePaths, const TArray<FString>& InConfigFiles, bool bUseSourceControlStateCache)
|
|
{
|
|
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Get filenames for packages and config to be checked in
|
|
TArray<FString> AllFiles = SourceControlHelpers::PackageFilenames(InPackageNames);
|
|
AllFiles.Append(InConfigFiles);
|
|
|
|
// Prepare a list of files to have their states updated
|
|
if (!bUseSourceControlStateCache)
|
|
{
|
|
TArray<FString> UpdateRequest;
|
|
UpdateRequest.Append(AllFiles);
|
|
|
|
// If there are pending delete paths to update, add them here.
|
|
UpdateRequest.Append(InPendingDeletePaths);
|
|
|
|
// Force an update on everything that's been requested
|
|
if (UpdateRequest.Num() > 0)
|
|
{
|
|
SourceControlProvider.Execute(ISourceControlOperation::Create<FUpdateStatus>(), UpdateRequest);
|
|
}
|
|
}
|
|
|
|
// Get file status of packages and config
|
|
TArray<FSourceControlStateRef> States;
|
|
SourceControlProvider.GetState(AllFiles, States, EStateCacheUsage::Use);
|
|
|
|
if (InPendingDeletePaths.Num() > 0)
|
|
{
|
|
// Get any files pending delete
|
|
TArray<FSourceControlStateRef> PendingDeleteItems = SourceControlProvider.GetCachedStateByPredicate(
|
|
[&States](const FSourceControlStateRef& State)
|
|
{
|
|
return State->IsDeleted()
|
|
// if the states already contains the pending delete do not bother appending it
|
|
&& !States.Contains(State);
|
|
}
|
|
);
|
|
|
|
// And append them to the list
|
|
States.Append(PendingDeleteItems);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Exit if no assets needing check in
|
|
if (States.Num() == 0)
|
|
{
|
|
OutResultInfo.Result = ECommandResult::Succeeded;
|
|
OutResultInfo.Description = LOCTEXT("NoAssetsToCheckIn", "No assets to check in!");
|
|
|
|
FMessageLog EditorErrors("EditorErrors");
|
|
EditorErrors.Warning(OutResultInfo.Description);
|
|
EditorErrors.Notify();
|
|
|
|
// Consider it a success even if no files were checked in
|
|
return true;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Create a submit files window
|
|
TSharedRef<SWindow> NewWindow = SNew(SWindow)
|
|
.Title(NSLOCTEXT("SourceControl.SubmitWindow", "Title", "Submit Files"))
|
|
.SizingRule(ESizingRule::UserSized)
|
|
.ClientSize(FVector2D(600, 400))
|
|
.SupportsMaximize(true)
|
|
.SupportsMinimize(false);
|
|
|
|
TSharedRef<SSourceControlSubmitWidget> SourceControlWidget =
|
|
SNew(SSourceControlSubmitWidget)
|
|
.ParentWindow(NewWindow)
|
|
.Items(States);
|
|
|
|
NewWindow->SetContent(
|
|
SourceControlWidget
|
|
);
|
|
|
|
FSlateApplication::Get().AddModalWindow(NewWindow, NULL);
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Exit if cancelled by user
|
|
if (SourceControlWidget->GetResult() == ESubmitResults::SUBMIT_CANCELED)
|
|
{
|
|
OutResultInfo.Result = ECommandResult::Cancelled;
|
|
OutResultInfo.Description = LOCTEXT("CheckinCancelled", "File check in cancelled.");
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Get description from the dialog
|
|
FChangeListDescription Description;
|
|
SourceControlWidget->FillChangeListDescription(Description);
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Revert any unchanged files
|
|
if (Description.FilesForSubmit.Num() > 0)
|
|
{
|
|
SourceControlHelpers::RevertUnchangedFiles(SourceControlProvider, Description.FilesForSubmit);
|
|
|
|
// Make sure all files are still checked out
|
|
for (int32 VerifyIndex = Description.FilesForSubmit.Num()-1; VerifyIndex >= 0; --VerifyIndex)
|
|
{
|
|
FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(Description.FilesForSubmit[VerifyIndex], EStateCacheUsage::Use);
|
|
if( SourceControlState.IsValid() && !SourceControlState->IsCheckedOut() && !SourceControlState->IsAdded() && !SourceControlState->IsDeleted() )
|
|
{
|
|
Description.FilesForSubmit.RemoveAt(VerifyIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Mark files for add as needed
|
|
|
|
bool bSuccess = true; // Overall success
|
|
bool bAddSuccess = true;
|
|
bool bCheckinSuccess = true;
|
|
bool bCheckinCancelled = false;
|
|
|
|
TArray<FString> CombinedFileList = Description.FilesForAdd;
|
|
CombinedFileList.Append(Description.FilesForSubmit);
|
|
|
|
if (Description.FilesForAdd.Num() > 0)
|
|
{
|
|
bAddSuccess = SourceControlProvider.Execute(ISourceControlOperation::Create<FMarkForAdd>(), Description.FilesForAdd) == ECommandResult::Succeeded;
|
|
bSuccess &= bAddSuccess;
|
|
|
|
OutResultInfo.FilesAdded = Description.FilesForAdd;
|
|
|
|
if (!bAddSuccess)
|
|
{
|
|
// Note that this message may be overwritten with a checkin error below.
|
|
OutResultInfo.Description = LOCTEXT("SCC_Add_Files_Error", "One or more files were not able to be marked for add to version control!");
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Any files to check in?
|
|
if (CombinedFileList.Num() == 0)
|
|
{
|
|
OutResultInfo.Result = bSuccess ? ECommandResult::Succeeded : ECommandResult::Failed;
|
|
|
|
if (OutResultInfo.Description.IsEmpty())
|
|
{
|
|
OutResultInfo.Description = LOCTEXT("SCC_No_Files", "No files were selected to check in to version control.");
|
|
}
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
FText VirtualizationFailureMsg;
|
|
if (!TryToVirtualizeFilesToSubmit(CombinedFileList, Description.Description, VirtualizationFailureMsg))
|
|
{
|
|
FMessageLog("SourceControl").Notify(VirtualizationFailureMsg);
|
|
|
|
OutResultInfo.Result = ECommandResult::Failed;
|
|
OutResultInfo.Description = VirtualizationFailureMsg;
|
|
|
|
return false;
|
|
}
|
|
|
|
// Check in files
|
|
TSharedRef<FCheckIn, ESPMode::ThreadSafe> CheckInOperation = ISourceControlOperation::Create<FCheckIn>();
|
|
CheckInOperation->SetDescription(Description.Description);
|
|
|
|
ECommandResult::Type CheckInResult = SourceControlProvider.Execute(CheckInOperation, CombinedFileList);
|
|
bCheckinSuccess = CheckInResult == ECommandResult::Succeeded;
|
|
bCheckinCancelled = CheckInResult == ECommandResult::Cancelled;
|
|
|
|
bSuccess &= bCheckinSuccess;
|
|
|
|
if (bCheckinSuccess)
|
|
{
|
|
// report success with a notification
|
|
FNotificationInfo Info(CheckInOperation->GetSuccessMessage());
|
|
Info.ExpireDuration = 8.0f;
|
|
Info.HyperlinkText = LOCTEXT("SCC_Checkin_ShowLog", "Show Message Log");
|
|
Info.Hyperlink = FSimpleDelegate::CreateStatic([](){ FMessageLog("SourceControl").Open(EMessageSeverity::Info, true); });
|
|
FSlateNotificationManager::Get().AddNotification(Info);
|
|
|
|
// also add to the log
|
|
FMessageLog("SourceControl").Info(CheckInOperation->GetSuccessMessage());
|
|
|
|
OutResultInfo.Result = ECommandResult::Succeeded;
|
|
OutResultInfo.Description = CheckInOperation->GetSuccessMessage();
|
|
OutResultInfo.FilesSubmitted = Description.FilesForSubmit;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Abort if cancelled
|
|
if (bCheckinCancelled)
|
|
{
|
|
FText Message(LOCTEXT("CheckinCancelled", "File check in cancelled."));
|
|
|
|
OutResultInfo.Result = ECommandResult::Cancelled;
|
|
OutResultInfo.Description = Message;
|
|
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Exit if errors
|
|
if (!bSuccess)
|
|
{
|
|
FText Message(LOCTEXT("SCC_Checkin_Failed", "Failed to check in files!"));
|
|
FMessageLog("SourceControl").Notify(Message);
|
|
|
|
OutResultInfo.Result = ECommandResult::Failed;
|
|
|
|
if (!bCheckinSuccess || OutResultInfo.Description.IsEmpty())
|
|
{
|
|
OutResultInfo.Description = Message;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Do we want to to re-check out the files we just checked in?
|
|
if (SourceControlWidget->WantToKeepCheckedOut())
|
|
{
|
|
// Re-check out files
|
|
if (SourceControlProvider.Execute(ISourceControlOperation::Create<FCheckOut>(), CombinedFileList) == ECommandResult::Succeeded)
|
|
{
|
|
OutResultInfo.bAutoCheckedOut = true;
|
|
}
|
|
else
|
|
{
|
|
FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("SCC_Checkin_ReCheckOutFailed", "Failed to re-check out files."));
|
|
}
|
|
}
|
|
|
|
SourceControlWidget->ClearChangeListDescription();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool FSourceControlWindows::PromptForCheckin(bool bUseSourceControlStateCache, const TArray<FString>& InPackageNames, const TArray<FString>& InPendingDeletePaths, const TArray<FString>& InConfigFiles)
|
|
{
|
|
FCheckinResultInfo ResultInfo;
|
|
|
|
return PromptForCheckin(ResultInfo, InPackageNames, InPendingDeletePaths, InConfigFiles, bUseSourceControlStateCache);
|
|
}
|
|
|
|
|
|
// Note that:
|
|
// - FSourceControlWindows::DisplayRevisionHistory() is defined in SSourceControlHistory.cpp
|
|
// - FSourceControlWindows::PromptForRevert() is defined in SSourceControlRevert.cpp
|
|
|
|
|
|
void FSourceControlWindows::ChoosePackagesToCheckInCompleted(const TArray<UPackage*>& LoadedPackages, const TArray<FString>& PackageNames, const TArray<FString>& ConfigFiles, FCheckinResultInfo& OutResultInfo)
|
|
{
|
|
if (ChoosePackagesToCheckInNotification.IsValid())
|
|
{
|
|
ChoosePackagesToCheckInNotification.Pin()->ExpireAndFadeout();
|
|
}
|
|
ChoosePackagesToCheckInNotification.Reset();
|
|
|
|
// Prompt the user to ask if they would like to first save any dirty packages they are trying to check-in
|
|
const FEditorFileUtils::EPromptReturnCode UserResponse = FEditorFileUtils::PromptForCheckoutAndSave(LoadedPackages, true, true);
|
|
|
|
// If the user elected to save dirty packages, but one or more of the packages failed to save properly OR if the user
|
|
// canceled out of the prompt, don't follow through on the check-in process
|
|
const bool bShouldProceed = (UserResponse == FEditorFileUtils::EPromptReturnCode::PR_Success || UserResponse == FEditorFileUtils::EPromptReturnCode::PR_Declined);
|
|
if (!bShouldProceed)
|
|
{
|
|
// If a failure occurred, alert the user that the check-in was aborted. This warning shouldn't be necessary if the user cancelled
|
|
// from the dialog, because they obviously intended to cancel the whole operation.
|
|
if (UserResponse == FEditorFileUtils::EPromptReturnCode::PR_Failure)
|
|
{
|
|
OutResultInfo.Description = NSLOCTEXT("UnrealEd", "SCC_Checkin_Aborted", "Check-in aborted as a result of save failure.");
|
|
|
|
FMessageDialog::Open(EAppMsgType::Ok, OutResultInfo.Description);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
TArray<FString> PendingDeletePaths = GetSourceControlLocations();
|
|
|
|
const bool bUseSourceControlStateCache = true;
|
|
PromptForCheckin(OutResultInfo, PackageNames, PendingDeletePaths, ConfigFiles, bUseSourceControlStateCache);
|
|
}
|
|
|
|
void FSourceControlWindows::ChoosePackagesToCheckInCancelled(FSourceControlOperationRef InOperation)
|
|
{
|
|
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
|
|
SourceControlProvider.CancelOperation(InOperation);
|
|
|
|
if (ChoosePackagesToCheckInNotification.IsValid())
|
|
{
|
|
ChoosePackagesToCheckInNotification.Pin()->ExpireAndFadeout();
|
|
}
|
|
ChoosePackagesToCheckInNotification.Reset();
|
|
}
|
|
|
|
void FSourceControlWindows::ChoosePackagesToCheckInCallback(const FSourceControlOperationRef& InOperation, ECommandResult::Type InResult, FSourceControlWindowsOnCheckInComplete OnCompleteDelegate)
|
|
{
|
|
if (ChoosePackagesToCheckInNotification.IsValid())
|
|
{
|
|
ChoosePackagesToCheckInNotification.Pin()->ExpireAndFadeout();
|
|
}
|
|
ChoosePackagesToCheckInNotification.Reset();
|
|
|
|
FCheckinResultInfo ResultInfo;
|
|
|
|
if (InResult != ECommandResult::Succeeded)
|
|
{
|
|
switch (InResult)
|
|
{
|
|
case ECommandResult::Cancelled:
|
|
ResultInfo.Result = ECommandResult::Cancelled;
|
|
ResultInfo.Description = LOCTEXT("CheckInCancelled", "Check in cancelled.");
|
|
break;
|
|
|
|
case ECommandResult::Failed:
|
|
{
|
|
ResultInfo.Description = LOCTEXT("CheckInOperationFailed", "Failed checking source control status!");
|
|
FMessageLog EditorErrors("EditorErrors");
|
|
EditorErrors.Warning(ResultInfo.Description);
|
|
EditorErrors.Notify();
|
|
}
|
|
}
|
|
|
|
OnCompleteDelegate.ExecuteIfBound(ResultInfo);
|
|
|
|
return;
|
|
}
|
|
|
|
// Get a list of all the checked out packages
|
|
TArray<FString> PackageNames;
|
|
TArray<UPackage*> LoadedPackages;
|
|
TMap<FString, FSourceControlStatePtr> PackageStates;
|
|
FEditorFileUtils::FindAllSubmittablePackageFiles(PackageStates, true);
|
|
|
|
TArray<FString> ConfigFilesToSubmit;
|
|
const FString ProjectFilePath = FPaths::GetProjectFilePath();
|
|
|
|
for (TMap<FString, FSourceControlStatePtr>::TConstIterator PackageIter(PackageStates); PackageIter; ++PackageIter)
|
|
{
|
|
const FString PackageName = *PackageIter.Key();
|
|
const FSourceControlStatePtr CurPackageSCCState = PackageIter.Value();
|
|
|
|
if (PackageName == ProjectFilePath)
|
|
{
|
|
ConfigFilesToSubmit.Add(PackageName);
|
|
continue;
|
|
}
|
|
|
|
UPackage* Package = FindPackage(nullptr, *PackageName);
|
|
if (Package != nullptr)
|
|
{
|
|
LoadedPackages.Add(Package);
|
|
}
|
|
|
|
PackageNames.Add(PackageName);
|
|
}
|
|
|
|
// Get a list of all the checked out config files
|
|
TMap<FString, FSourceControlStatePtr> ConfigFileStates;
|
|
FEditorFileUtils::FindAllSubmittableConfigFiles(ConfigFileStates);
|
|
for (TMap<FString, FSourceControlStatePtr>::TConstIterator It(ConfigFileStates); It; ++It)
|
|
{
|
|
ConfigFilesToSubmit.Add(It.Key());
|
|
}
|
|
|
|
ChoosePackagesToCheckInCompleted(LoadedPackages, PackageNames, ConfigFilesToSubmit, ResultInfo);
|
|
OnCompleteDelegate.ExecuteIfBound(ResultInfo);
|
|
}
|
|
|
|
|
|
#undef LOCTEXT_NAMESPACE
|
|
|
|
#endif // SOURCE_CONTROL_WITH_SLATE
|
|
|