You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#rb trivial #rnx #preflight 62d15f427e1c26dcd715699c - Now that the IVirtualizationSystem interface supports both virtualization and rehydration of package files, it seems pointless to keep a delegate that occurs on pre-submit, rather than just calling the system we really want to call directly. - Deprecating the public methods accessing the delegate from ISourceControlModule should prevent licensees from trying to use it. The delegate was added in 5.0 so even though it is unlikely to have been used by anyone we need to go through the deprecation steps to remove it. -- This leaves the calling code a little more complicated than I'd like, but cannot be avoided. [CL 21109464 by paul chipchase in ue5-main branch]
564 lines
18 KiB
C++
564 lines
18 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"
|
|
#include "Virtualization/VirtualizationSystem.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;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Allow any finalization pre-submit processes to run
|
|
|
|
// TODO: Once this is removed and not deprecated move the following arrays inside of the System.IsEnabled() scope
|
|
TArray<FText> PayloadErrors;
|
|
TArray<FText> DescriptionTags;
|
|
|
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
|
ISourceControlModule::Get().GetOnPreSubmitFinalize().Broadcast(CombinedFileList, DescriptionTags, PayloadErrors);
|
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
|
|
|
UE::Virtualization::IVirtualizationSystem& System = UE::Virtualization::IVirtualizationSystem::Get();
|
|
if (System.IsEnabled())
|
|
{
|
|
if (System.TryVirtualizePackages(CombinedFileList, DescriptionTags, PayloadErrors))
|
|
{
|
|
if (!DescriptionTags.IsEmpty())
|
|
{
|
|
FTextBuilder NewDescription;
|
|
NewDescription.AppendLine(Description.Description);
|
|
|
|
for (const FText& Line : DescriptionTags)
|
|
{
|
|
NewDescription.AppendLine(Line);
|
|
}
|
|
|
|
Description.Description = NewDescription.ToText();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (const FText& Error : PayloadErrors)
|
|
{
|
|
FMessageLog("SourceControl").Error(Error);
|
|
}
|
|
|
|
// TODO: We rely on the calling code to issue a noticeable error message to the user but this is
|
|
// currently handled very inconsistently in the engine and the return values often ignored.
|
|
// So print the error to the log file as well for now but we should try and unify how the errors
|
|
// are reported.
|
|
FText FailureMsg(LOCTEXT("SCC_Virtualization_Failed", "Virtualized payloads failed to submit."));
|
|
FMessageLog("SourceControl").Notify(FailureMsg);
|
|
|
|
OutResultInfo.Result = ECommandResult::Failed;
|
|
OutResultInfo.Description = FailureMsg;
|
|
|
|
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
|
|
|