You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Skein, the only provider that returns 'true' for 'UsesSnapshots()' requires the user to be at head when doing a check-in operation, or the check-in will fail. This is enforced within the plugin, not the CLI, by performing an FSync prior to doing an FCheckIn. It's not easy to do the sync within the CLI as part of the check-in as the editor doesn't release its file locks when doing an FCheckIn, causing syncs to fail. For this, a code path was introduced in SourceControlMenuHelpers that triggers a sync before triggering the check-in, when clicking the 'Check In Changes' button visible in the bottom right of the editor within UEFN. However, this approach fails if other code paths in the editor call ChoosePackagesToCheckIn directly. This is known to happen for the MainFrame's "Submit Content" action, which was therefore disabled for Skein in #26272334, but the issue could be more widespread. To provide a definitive fix for this issue, the sync is moved to within ChoosePackagesToCheckIn, triggered only when 'UsesSnapshots()' is true, which effectively means Skein only. #rnx [CL 27582511 by wouter burgers in ue5-main branch]
622 lines
20 KiB
C++
622 lines
20 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SourceControlWindows.h"
|
|
#include "SSourceControlSubmit.h"
|
|
#include "AssetViewUtils.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 "SourceControlSettings.h"
|
|
#include "Bookmarks/BookmarkScoped.h"
|
|
|
|
#if SOURCE_CONTROL_WITH_SLATE
|
|
|
|
#define LOCTEXT_NAMESPACE "SourceControlWindows"
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
// FCheckinResultInfo
|
|
|
|
FCheckinResultInfo::FCheckinResultInfo()
|
|
: Result(ECommandResult::Failed)
|
|
, bAutoCheckedOut(false)
|
|
{
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
// Helper function(s)
|
|
|
|
static bool SaveDirtyPackages(bool bUseDialog)
|
|
{
|
|
const bool bPromptUserToSave = bUseDialog;
|
|
const bool bSaveMapPackages = true;
|
|
const bool bSaveContentPackages = true;
|
|
const bool bFastSave = false;
|
|
const bool bNotifyNoPackagesSaved = false;
|
|
const bool bCanBeDeclined = true; // If the user clicks "don't save" this will continue and lose their changes
|
|
|
|
bool bSaved = FEditorFileUtils::SaveDirtyPackages(bPromptUserToSave, bSaveMapPackages, bSaveContentPackages, bFastSave, bNotifyNoPackagesSaved, bCanBeDeclined);
|
|
|
|
// bSaved can be true if the user selects to not save an asset by unchecking it and clicking "save"
|
|
if (bSaved)
|
|
{
|
|
TArray<UPackage*> DirtyPackages;
|
|
FEditorFileUtils::GetDirtyWorldPackages(DirtyPackages);
|
|
FEditorFileUtils::GetDirtyContentPackages(DirtyPackages);
|
|
|
|
bSaved = DirtyPackages.Num() == 0;
|
|
}
|
|
|
|
return bSaved;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
// FSourceControlWindows
|
|
|
|
TWeakPtr<SNotificationItem> FSourceControlWindows::ChoosePackagesToCheckInNotification;
|
|
|
|
bool FSourceControlWindows::ChoosePackagesToCheckIn(const FSourceControlWindowsOnCheckInComplete& OnCompleteDelegate)
|
|
{
|
|
if (!ISourceControlModule::Get().IsEnabled())
|
|
{
|
|
FCheckinResultInfo ResultInfo;
|
|
ResultInfo.Description = LOCTEXT("SourceControlDisabled", "Revision control is not enabled.");
|
|
OnCompleteDelegate.ExecuteIfBound(ResultInfo);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (!ISourceControlModule::Get().GetProvider().IsAvailable())
|
|
{
|
|
FCheckinResultInfo ResultInfo;
|
|
ResultInfo.Description = LOCTEXT("NoSCCConnection", "No connection to revision control available!");
|
|
|
|
FMessageLog EditorErrors("EditorErrors");
|
|
EditorErrors.Warning(ResultInfo.Description)->AddToken(
|
|
FDocumentationToken::Create(TEXT("Engine/UI/SourceControl")));
|
|
EditorErrors.Notify();
|
|
|
|
OnCompleteDelegate.ExecuteIfBound(ResultInfo);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (ISourceControlModule::Get().GetProvider().UsesSnapshots())
|
|
{
|
|
bool bSyncNeeded = FSourceControlWindows::CanSyncLatest();
|
|
if (bSyncNeeded)
|
|
{
|
|
FBookmarkScoped BookmarkScoped; // Preserve viewport camera orientation.
|
|
|
|
if (!FSourceControlWindows::SyncLatest())
|
|
{
|
|
FCheckinResultInfo ResultInfo;
|
|
ResultInfo.Description = LOCTEXT("SourceControlSyncFailed", "Revision control failed to sync to the latest revision.");
|
|
OnCompleteDelegate.ExecuteIfBound(ResultInfo);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// SyncLatest saves packages so do that explicitly if sync is not needed.
|
|
SaveDirtyPackages(/*bUseDialog=*/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 = SourceControlHelpers::GetSourceControlLocations();
|
|
|
|
// make sure the SourceControlProvider state cache is populated as well
|
|
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();
|
|
|
|
if (ISourceControlModule::Get().IsEnabled() &&
|
|
ISourceControlModule::Get().GetProvider().IsAvailable() &&
|
|
!ChoosePackagesToCheckInNotification.IsValid())
|
|
{
|
|
if (SourceControlModule.GetProvider().GetNumLocalChanges().IsSet())
|
|
{
|
|
return SourceControlModule.GetProvider().GetNumLocalChanges().GetValue() > 0;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool FSourceControlWindows::ShouldChoosePackagesToCheckBeVisible()
|
|
{
|
|
return GetDefault<USourceControlSettings>()->bEnableSubmitContentMenuAction;
|
|
}
|
|
|
|
bool FSourceControlWindows::SyncLatest()
|
|
{
|
|
bool bSaved = SaveDirtyPackages(/*bUseDialog=*/true);
|
|
|
|
// if not properly saved, ask for confirmation from the user before continuing.
|
|
if (!bSaved)
|
|
{
|
|
FText DialogText = NSLOCTEXT("SourceControlCommands", "UnsavedWarningText", "Warning: There are modified assets which are not being saved. If you sync to latest you may lose your unsaved changes. Do you want to continue?");
|
|
FText DialogTitle = NSLOCTEXT("SourceControlCommands", "UnsavedWarningTitle", "Unsaved changes");
|
|
|
|
EAppReturnType::Type DialogResult = FMessageDialog::Open(EAppMsgType::YesNo, DialogText, DialogTitle);
|
|
|
|
bSaved = (DialogResult == EAppReturnType::Yes);
|
|
}
|
|
|
|
// if properly saved or confirmation given, find all packages and use source control to update them.
|
|
if (bSaved)
|
|
{
|
|
bool bSuccess = AssetViewUtils::SyncLatestFromSourceControl();
|
|
if (!bSuccess)
|
|
{
|
|
FText Message(LOCTEXT("SCC_Sync_Failed", "Failed to sync files!"));
|
|
FMessageLog("SourceControl").Notify(Message);
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool FSourceControlWindows::CanSyncLatest()
|
|
{
|
|
ISourceControlModule& SourceControlModule = ISourceControlModule::Get();
|
|
|
|
if (SourceControlModule.IsEnabled() &&
|
|
SourceControlModule.GetProvider().IsAvailable())
|
|
{
|
|
if (SourceControlModule.GetProvider().IsAtLatestRevision().IsSet())
|
|
{
|
|
return !SourceControlModule.GetProvider().IsAtLatestRevision().GetValue();
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
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)
|
|
.AllowUncheckFiles_Lambda([&]()
|
|
{
|
|
if (SourceControlProvider.IsAvailable())
|
|
{
|
|
return !SourceControlProvider.UsesSnapshots();
|
|
}
|
|
return true;
|
|
})
|
|
.AllowDiffAgainstDepot(SourceControlProvider.AllowsDiffAgainstDepot());
|
|
|
|
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);
|
|
|
|
if (!ISourceControlModule::Get().UsesCustomProjectDir())
|
|
{
|
|
// 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);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// For project-based source control, we want to go through with a check in attempt even when
|
|
// files are not checked out by the current user, and generate a warning dialog
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// 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);
|
|
CheckInOperation->SetKeepCheckedOut(SourceControlWidget->WantToKeepCheckedOut());
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
bool bUseSourceControlStateCache = true;
|
|
TArray<FString> PendingDeletePaths = SourceControlHelpers::GetSourceControlLocations();
|
|
|
|
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 revision 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;
|
|
|
|
for (TMap<FString, FSourceControlStatePtr>::TConstIterator PackageIter(PackageStates); PackageIter; ++PackageIter)
|
|
{
|
|
const FString PackageName = *PackageIter.Key();
|
|
|
|
UPackage* Package = FindPackage(nullptr, *PackageName);
|
|
if (Package != nullptr)
|
|
{
|
|
LoadedPackages.Add(Package);
|
|
}
|
|
|
|
PackageNames.Add(PackageName);
|
|
}
|
|
|
|
// Get a list of all the checked out project files
|
|
TMap<FString, FSourceControlStatePtr> ProjectFileStates;
|
|
FEditorFileUtils::FindAllSubmittableProjectFiles(ProjectFileStates);
|
|
for (TMap<FString, FSourceControlStatePtr>::TConstIterator It(ProjectFileStates); It; ++It)
|
|
{
|
|
ConfigFilesToSubmit.Add(It.Key());
|
|
}
|
|
|
|
// 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
|
|
|