2020-05-20 12:48:17 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
2020-05-20 13:04:13 -04:00
# include "SourceControlMenuHelpers.h"
2020-05-20 12:48:17 -04:00
# include "ISourceControlOperation.h"
# include "SourceControlOperations.h"
# include "ISourceControlProvider.h"
# include "ISourceControlModule.h"
2021-01-11 15:31:58 -04:00
# include "ISourceControlWindowsModule.h"
2020-05-20 12:48:17 -04:00
# include "SourceControlMenuHelpers.h"
# include "SourceControlWindows.h"
2022-10-03 20:38:09 -04:00
# include "UnsavedAssetsTrackerModule.h"
2020-05-20 12:48:17 -04:00
# include "FileHelpers.h"
2022-10-26 12:57:32 -04:00
# include "Logging/MessageLog.h"
2020-05-20 12:48:17 -04:00
# include "ToolMenuContext.h"
# include "ToolMenus.h"
2022-05-09 13:12:28 -04:00
# include "Styling/AppStyle.h"
2020-05-20 13:04:13 -04:00
# include "Widgets/Input/SComboButton.h"
2022-09-26 16:32:49 -04:00
# include "Widgets/Input/SButton.h"
2020-05-20 13:04:13 -04:00
# include "Widgets/Images/SImage.h"
2022-12-11 23:09:22 -05:00
# include "Widgets/Layout/SSeparator.h"
2022-12-09 14:18:01 -05:00
# include "Widgets/Images/SLayeredImage.h"
2021-10-20 14:15:53 -04:00
# include "LevelEditorActions.h"
2022-09-26 16:32:49 -04:00
# include "PackageTools.h"
# include "Misc/ConfigCacheIni.h"
2022-10-26 15:30:49 -04:00
# include "Misc/MessageDialog.h"
2022-12-09 14:18:01 -05:00
# include "RevisionControlStyle/RevisionControlStyle.h"
2023-01-26 10:15:04 -05:00
# include "Bookmarks/BookmarkScoped.h"
2023-02-16 12:43:53 -05:00
# include "Styling/StyleColors.h"
2020-05-20 12:48:17 -04:00
# define LOCTEXT_NAMESPACE "SourceControlCommands"
TSharedRef < FUICommandList > FSourceControlCommands : : ActionList ( new FUICommandList ( ) ) ;
FSourceControlCommands : : FSourceControlCommands ( )
: TCommands < FSourceControlCommands >
(
" SourceControl " ,
2022-11-23 11:57:50 -05:00
NSLOCTEXT ( " Contexts " , " SourceControl " , " Revision Control " ) ,
2020-05-20 12:48:17 -04:00
" LevelEditor " ,
2022-05-09 13:12:28 -04:00
FAppStyle : : GetAppStyleSetName ( )
2020-05-20 12:48:17 -04:00
)
{ }
/**
* Initialize commands
*/
void FSourceControlCommands : : RegisterCommands ( )
{
2022-11-23 11:57:50 -05:00
UI_COMMAND ( ConnectToSourceControl , " Connect to Revision Control... " , " Connect to a revision control system for tracking changes to your content and levels. " , EUserInterfaceActionType : : Button , FInputChord ( ) ) ;
UI_COMMAND ( ChangeSourceControlSettings , " Change Revision Control Settings... " , " Opens a dialog to change revision control settings. " , EUserInterfaceActionType : : Button , FInputChord ( ) ) ;
2023-02-01 19:44:37 -05:00
UI_COMMAND ( ViewChangelists , " View Changes " , " Opens a dialog displaying current changes. " , EUserInterfaceActionType : : Button , FInputChord ( ) ) ;
2021-10-20 14:15:53 -04:00
UI_COMMAND ( SubmitContent , " Submit Content " , " Opens a dialog with check in options for content and levels. " , EUserInterfaceActionType : : Button , FInputChord ( ) ) ;
UI_COMMAND ( CheckOutModifiedFiles , " Check Out Modified Files " , " Opens a dialog to check out any assets which have been modified. " , EUserInterfaceActionType : : Button , FInputChord ( ) ) ;
2022-12-11 23:09:22 -05:00
UI_COMMAND ( RevertAll , " Revert All Files " , " Opens a dialog to revert any assets which have been modified. " , EUserInterfaceActionType : : Button , FInputChord ( ) ) ;
2020-05-20 12:48:17 -04:00
ActionList - > MapAction (
ConnectToSourceControl ,
2021-01-11 15:31:58 -04:00
FExecuteAction : : CreateStatic ( & FSourceControlCommands : : ConnectToSourceControl_Clicked )
2020-05-20 12:48:17 -04:00
) ;
ActionList - > MapAction (
ChangeSourceControlSettings ,
FExecuteAction : : CreateStatic ( & FSourceControlCommands : : ConnectToSourceControl_Clicked )
) ;
2021-01-11 15:31:58 -04:00
ActionList - > MapAction (
ViewChangelists ,
FExecuteAction : : CreateStatic ( & FSourceControlCommands : : ViewChangelists_Clicked ) ,
2022-09-26 16:32:49 -04:00
FCanExecuteAction : : CreateStatic ( & FSourceControlCommands : : ViewChangelists_CanExecute ) ,
FIsActionChecked : : CreateLambda ( [ ] ( ) { return false ; } ) ,
FIsActionButtonVisible : : CreateStatic ( & FSourceControlCommands : : ViewChangelists_IsVisible )
2021-01-11 15:31:58 -04:00
) ;
2021-10-20 14:15:53 -04:00
ActionList - > MapAction (
SubmitContent ,
FExecuteAction : : CreateLambda ( [ ] ( ) { FSourceControlWindows : : ChoosePackagesToCheckIn ( ) ; } ) ,
2022-09-30 16:16:47 -04:00
FCanExecuteAction : : CreateStatic ( & FSourceControlWindows : : CanChoosePackagesToCheckIn ) ,
FIsActionChecked : : CreateLambda ( [ ] ( ) { return false ; } ) ,
FIsActionButtonVisible : : CreateStatic ( & FSourceControlCommands : : SubmitContent_IsVisible )
2021-10-20 14:15:53 -04:00
) ;
2020-05-20 12:48:17 -04:00
ActionList - > MapAction (
CheckOutModifiedFiles ,
FExecuteAction : : CreateStatic ( & FSourceControlCommands : : CheckOutModifiedFiles_Clicked ) ,
FCanExecuteAction : : CreateStatic ( & FSourceControlCommands : : CheckOutModifiedFiles_CanExecute )
) ;
2022-12-11 23:09:22 -05:00
ActionList - > MapAction (
RevertAll ,
FExecuteAction : : CreateStatic ( & FSourceControlCommands : : RevertAllModifiedFiles_Clicked ) ,
2023-02-17 11:00:54 -05:00
FCanExecuteAction : : CreateStatic ( & FSourceControlCommands : : RevertAllModifiedFiles_CanExecute )
2022-12-11 23:09:22 -05:00
) ;
2020-05-20 12:48:17 -04:00
}
void FSourceControlCommands : : ConnectToSourceControl_Clicked ( )
{
// Show login window regardless of current status - its useful as a shortcut to change settings.
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
SourceControlModule . ShowLoginDialog ( FSourceControlLoginClosed ( ) , ELoginWindowMode : : Modeless , EOnLoginWindowStartup : : PreserveProvider ) ;
}
2021-01-11 15:31:58 -04:00
bool FSourceControlCommands : : ViewChangelists_CanExecute ( )
{
2021-03-17 13:43:31 -04:00
return ISourceControlWindowsModule : : Get ( ) . CanShowChangelistsTab ( ) ;
2021-01-11 15:31:58 -04:00
}
2022-09-26 16:32:49 -04:00
bool FSourceControlCommands : : ViewChangelists_IsVisible ( )
{
return ISourceControlModule : : Get ( ) . GetProvider ( ) . UsesChangelists ( ) ;
}
2022-09-30 16:16:47 -04:00
bool FSourceControlCommands : : SubmitContent_IsVisible ( )
{
if ( FSourceControlMenuHelpers : : GetSourceControlCheckInStatusVisibility ( ) = = EVisibility : : Visible )
{
return false ;
}
2022-10-15 02:16:54 -04:00
if ( ! FSourceControlWindows : : ShouldChoosePackagesToCheckBeVisible ( ) )
{
return false ;
}
2022-09-30 16:16:47 -04:00
return true ;
}
2021-01-11 15:31:58 -04:00
void FSourceControlCommands : : ViewChangelists_Clicked ( )
{
ISourceControlWindowsModule : : Get ( ) . ShowChangelistsTab ( ) ;
}
2020-05-20 12:48:17 -04:00
bool FSourceControlCommands : : CheckOutModifiedFiles_CanExecute ( )
{
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
if ( ISourceControlModule : : Get ( ) . IsEnabled ( ) & &
ISourceControlModule : : Get ( ) . GetProvider ( ) . IsAvailable ( ) )
{
TArray < UPackage * > PackagesToSave ;
FEditorFileUtils : : GetDirtyWorldPackages ( PackagesToSave ) ;
FEditorFileUtils : : GetDirtyContentPackages ( PackagesToSave ) ;
return PackagesToSave . Num ( ) > 0 ;
}
return false ;
}
void FSourceControlCommands : : CheckOutModifiedFiles_Clicked ( )
{
TArray < UPackage * > PackagesToSave ;
FEditorFileUtils : : GetDirtyWorldPackages ( PackagesToSave ) ;
FEditorFileUtils : : GetDirtyContentPackages ( PackagesToSave ) ;
const bool bCheckDirty = true ;
const bool bPromptUserToSave = false ;
FEditorFileUtils : : PromptForCheckoutAndSave ( PackagesToSave , bCheckDirty , bPromptUserToSave ) ;
}
2023-02-17 11:00:54 -05:00
bool FSourceControlCommands : : RevertAllModifiedFiles_CanExecute ( )
{
// If CHECK-IN CHANGES button is active, the REVERT ALL option should be active.
if ( FUnsavedAssetsTrackerModule : : Get ( ) . GetUnsavedAssetNum ( ) > 0 )
{
return true ;
}
if ( FSourceControlWindows : : CanChoosePackagesToCheckIn ( ) )
{
return true ;
}
return false ;
}
2022-12-11 23:09:22 -05:00
void FSourceControlCommands : : RevertAllModifiedFiles_Clicked ( )
{
FText Message = LOCTEXT ( " RevertAllModifiedFiles " , " Are you sure you want to revert all local changes? By proceeding, your local changes will be discarded, and the state of your last synced snapshot will be restored. " ) ;
FText Title = LOCTEXT ( " RevertAllModifiedFiles_Title " , " Revert all local changes " ) ;
2023-01-20 15:27:17 -05:00
if ( FMessageDialog : : Open ( EAppMsgType : : YesNo , EAppReturnType : : No , Message , & Title ) = = EAppReturnType : : Yes )
2022-12-11 23:09:22 -05:00
{
2023-02-28 12:13:31 -05:00
FSourceControlMenuHelpers : : SaveUnsavedFiles ( ) ;
2023-01-26 10:15:04 -05:00
FBookmarkScoped BookmarkScoped ;
2023-01-20 15:31:16 -05:00
FSourceControlWindows : : RevertAllChangesAndReloadWorld ( ) ;
2022-12-11 23:09:22 -05:00
}
}
2022-09-26 16:32:49 -04:00
FSourceControlMenuHelpers & FSourceControlMenuHelpers : : Get ( )
{
// Singleton instance
static FSourceControlMenuHelpers SourceControlMenuHelpers ;
return SourceControlMenuHelpers ;
}
2020-05-20 12:48:17 -04:00
FSourceControlMenuHelpers : : EQueryState FSourceControlMenuHelpers : : QueryState = FSourceControlMenuHelpers : : EQueryState : : NotQueried ;
void FSourceControlMenuHelpers : : CheckSourceControlStatus ( )
{
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
if ( SourceControlModule . IsEnabled ( ) )
{
SourceControlModule . GetProvider ( ) . Execute ( ISourceControlOperation : : Create < FConnect > ( ) ,
EConcurrency : : Asynchronous ,
FSourceControlOperationComplete : : CreateStatic ( & FSourceControlMenuHelpers : : OnSourceControlOperationComplete ) ) ;
QueryState = EQueryState : : Querying ;
}
}
void FSourceControlMenuHelpers : : OnSourceControlOperationComplete ( const FSourceControlOperationRef & InOperation , ECommandResult : : Type InResult )
{
QueryState = EQueryState : : Queried ;
}
TSharedRef < SWidget > FSourceControlMenuHelpers : : GenerateSourceControlMenuContent ( )
{
UToolMenu * SourceControlMenu = UToolMenus : : Get ( ) - > RegisterMenu ( " StatusBar.ToolBar.SourceControl " , NAME_None , EMultiBoxType : : Menu , false ) ;
FToolMenuSection & Section = SourceControlMenu - > AddSection ( " SourceControlActions " , LOCTEXT ( " SourceControlMenuHeadingActions " , " Actions " ) ) ;
2021-01-11 15:31:58 -04:00
Section . AddMenuEntry (
FSourceControlCommands : : Get ( ) . ViewChangelists ,
TAttribute < FText > ( ) ,
TAttribute < FText > ( ) ,
2022-12-09 14:18:01 -05:00
FSlateIcon ( FRevisionControlStyleManager : : GetStyleSetName ( ) , " RevisionControl.ChangelistsTab " )
2021-01-11 15:31:58 -04:00
) ;
2021-10-20 14:15:53 -04:00
Section . AddMenuEntry (
FSourceControlCommands : : Get ( ) . SubmitContent ,
TAttribute < FText > ( ) ,
TAttribute < FText > ( ) ,
2022-12-09 14:18:01 -05:00
FSlateIcon ( FRevisionControlStyleManager : : GetStyleSetName ( ) , " RevisionControl.Actions.Submit " )
2021-10-20 14:15:53 -04:00
) ;
2020-05-20 12:48:17 -04:00
Section . AddMenuEntry (
FSourceControlCommands : : Get ( ) . CheckOutModifiedFiles ,
TAttribute < FText > ( ) ,
TAttribute < FText > ( ) ,
2022-12-09 14:18:01 -05:00
FSlateIcon ( FRevisionControlStyleManager : : GetStyleSetName ( ) , " RevisionControl.Actions.CheckOut " )
2020-05-20 12:48:17 -04:00
) ;
2021-10-20 14:15:53 -04:00
Section . AddDynamicEntry ( " ConnectToSourceControl " , FNewToolMenuSectionDelegate : : CreateLambda ( [ ] ( FToolMenuSection & InSection )
{
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
if ( ISourceControlModule : : Get ( ) . IsEnabled ( ) & & ISourceControlModule : : Get ( ) . GetProvider ( ) . IsAvailable ( ) )
{
InSection . AddMenuEntry (
FSourceControlCommands : : Get ( ) . ChangeSourceControlSettings ,
TAttribute < FText > ( ) ,
TAttribute < FText > ( ) ,
2022-12-09 14:18:01 -05:00
FSlateIcon ( FRevisionControlStyleManager : : GetStyleSetName ( ) , " RevisionControl.Actions.ChangeSettings " )
2021-10-20 14:15:53 -04:00
) ;
}
else
{
InSection . AddMenuEntry (
FSourceControlCommands : : Get ( ) . ConnectToSourceControl ,
TAttribute < FText > ( ) ,
TAttribute < FText > ( ) ,
2022-12-09 14:18:01 -05:00
FSlateIcon ( FRevisionControlStyleManager : : GetStyleSetName ( ) , " RevisionControl.Icon " )
2021-10-20 14:15:53 -04:00
) ;
}
} ) ) ;
2020-05-20 12:48:17 -04:00
return UToolMenus : : Get ( ) - > GenerateWidget ( " StatusBar.ToolBar.SourceControl " , FToolMenuContext ( FSourceControlCommands : : ActionList ) ) ;
}
2022-12-11 23:09:22 -05:00
TSharedRef < SWidget > FSourceControlMenuHelpers : : GenerateCheckInComboButtonContent ( )
{
UToolMenu * SourceControlMenu = UToolMenus : : Get ( ) - > RegisterMenu ( " StatusBar.ToolBar.SourceControl.CheckInCombo " , NAME_None , EMultiBoxType : : Menu , false ) ;
FToolMenuSection & Section = SourceControlMenu - > AddSection ( " SourceControlComboActions " , LOCTEXT ( " SourceControlComboMenuHeadingActions " , " Actions " ) ) ;
Section . AddMenuEntry (
FSourceControlCommands : : Get ( ) . RevertAll ,
TAttribute < FText > ( ) ,
TAttribute < FText > ( ) ,
FSlateIcon ( FAppStyle : : GetAppStyleSetName ( ) , " SourceControl.Actions.Revert " )
) ;
Section . AddMenuEntry (
FSourceControlCommands : : Get ( ) . ViewChangelists ,
TAttribute < FText > ( ) ,
TAttribute < FText > ( ) ,
FSlateIcon ( FAppStyle : : GetAppStyleSetName ( ) , " SourceControl.ChangelistsTab " )
) ;
return UToolMenus : : Get ( ) - > GenerateWidget ( " StatusBar.ToolBar.SourceControl.CheckInCombo " , FToolMenuContext ( FSourceControlCommands : : ActionList ) ) ;
}
2020-05-20 12:48:17 -04:00
FText FSourceControlMenuHelpers : : GetSourceControlStatusText ( )
{
if ( QueryState = = EQueryState : : Querying )
{
return LOCTEXT ( " SourceControlStatus_Querying " , " Contacting Server.... " ) ;
}
else
{
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
if ( SourceControlModule . IsEnabled ( ) )
{
if ( ! SourceControlModule . GetProvider ( ) . IsAvailable ( ) )
{
2022-03-04 16:10:23 -05:00
return LOCTEXT ( " SourceControlStatus_Error_ServerUnavailable " , " Server Unavailable " ) ;
2020-05-20 12:48:17 -04:00
}
else
{
2022-11-23 11:57:50 -05:00
return LOCTEXT ( " SourceControlStatus_Available " , " Revision Control " ) ;
2020-05-20 12:48:17 -04:00
}
}
else
{
2022-11-23 11:57:50 -05:00
return LOCTEXT ( " SourceControlStatus_Error_Off " , " Revision Control " ) ; // Relies on the icon on the status bar widget to know if the source control is on or off.
2020-05-20 12:48:17 -04:00
}
}
}
FText FSourceControlMenuHelpers : : GetSourceControlTooltip ( )
{
if ( QueryState = = EQueryState : : Querying )
{
2022-11-23 11:57:50 -05:00
return LOCTEXT ( " SourceControlUnknown " , " Revision control status is unknown " ) ;
2020-05-20 12:48:17 -04:00
}
else
{
return ISourceControlModule : : Get ( ) . GetProvider ( ) . GetStatusText ( ) ;
}
}
2022-12-09 14:18:01 -05:00
const FSlateBrush * FSourceControlMenuHelpers : : GetSourceControlIconBadge ( )
2020-05-20 12:48:17 -04:00
{
if ( QueryState = = EQueryState : : Querying )
{
2022-12-09 14:18:01 -05:00
return nullptr ;
2020-05-20 12:48:17 -04:00
}
else
{
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
if ( SourceControlModule . IsEnabled ( ) )
{
if ( ! SourceControlModule . GetProvider ( ) . IsAvailable ( ) )
{
2022-12-09 14:18:01 -05:00
static const FSlateBrush * ErrorBrush = FRevisionControlStyleManager : : Get ( ) . GetBrush ( " RevisionControl.Icon.WarningBadge " ) ;
2020-05-20 12:48:17 -04:00
return ErrorBrush ;
}
else
{
2022-12-09 14:18:01 -05:00
static const FSlateBrush * OnBrush = FRevisionControlStyleManager : : Get ( ) . GetBrush ( " RevisionControl.Icon.ConnectedBadge " ) ;
2020-05-20 12:48:17 -04:00
return OnBrush ;
}
}
else
{
2022-12-09 14:18:01 -05:00
static const FSlateBrush * OffBrush = nullptr ;
2020-05-20 12:48:17 -04:00
return OffBrush ;
}
}
}
2022-09-26 16:32:49 -04:00
/** Sync Status */
bool FSourceControlMenuHelpers : : IsAtLatestRevision ( )
{
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
2023-03-03 11:21:12 -05:00
return SourceControlModule . IsEnabled ( ) & &
SourceControlModule . GetProvider ( ) . IsAvailable ( ) & &
SourceControlModule . GetProvider ( ) . IsAtLatestRevision ( ) . IsSet ( ) & &
SourceControlModule . GetProvider ( ) . IsAtLatestRevision ( ) . GetValue ( ) ;
}
bool FSourceControlMenuHelpers : : CanSourceControlSync ( )
{
return ! IsAtLatestRevision ( ) ;
2022-09-26 16:32:49 -04:00
}
EVisibility FSourceControlMenuHelpers : : GetSourceControlSyncStatusVisibility ( )
{
bool bDisplaySourceControlSyncStatus = false ;
GConfig - > GetBool ( TEXT ( " SourceControlSettings " ) , TEXT ( " DisplaySourceControlSyncStatus " ) , bDisplaySourceControlSyncStatus , GEditorIni ) ;
2023-03-03 11:21:12 -05:00
if ( bDisplaySourceControlSyncStatus )
2022-09-26 16:32:49 -04:00
{
2023-03-03 11:21:12 -05:00
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
if ( SourceControlModule . IsEnabled ( ) & &
SourceControlModule . GetProvider ( ) . IsAvailable ( ) & &
SourceControlModule . GetProvider ( ) . IsAtLatestRevision ( ) . IsSet ( ) ) // Only providers that implement IsAtLatestRevision are supported.
{
return EVisibility : : Visible ;
}
2022-09-26 16:32:49 -04:00
}
return EVisibility : : Collapsed ;
}
FText FSourceControlMenuHelpers : : GetSourceControlSyncStatusText ( )
{
2023-03-03 11:21:12 -05:00
if ( CanSourceControlSync ( ) )
2022-09-26 16:32:49 -04:00
{
2023-03-03 11:21:12 -05:00
return LOCTEXT ( " SyncLatestButtonNotAtHeadText " , " Sync Latest " ) ;
2022-09-26 16:32:49 -04:00
}
2023-03-03 11:21:12 -05:00
return LOCTEXT ( " SyncLatestButtonAtHeadText " , " At Latest " ) ;
2022-09-26 16:32:49 -04:00
}
FText FSourceControlMenuHelpers : : GetSourceControlSyncStatusTooltipText ( )
{
2023-03-03 11:21:12 -05:00
if ( CanSourceControlSync ( ) )
2022-09-26 16:32:49 -04:00
{
2023-03-03 11:21:12 -05:00
return LOCTEXT ( " SyncLatestButtonNotAtHeadTooltipText " , " Sync to the latest Snapshot for this project " ) ;
2022-09-26 16:32:49 -04:00
}
2023-03-03 11:21:12 -05:00
return LOCTEXT ( " SyncLatestButtonAtHeadTooltipText " , " Currently at the latest Snapshot for this project " ) ;
2022-09-26 16:32:49 -04:00
}
const FSlateBrush * FSourceControlMenuHelpers : : GetSourceControlSyncStatusIcon ( )
{
2022-12-09 14:18:01 -05:00
static const FSlateBrush * AtHeadBrush = FRevisionControlStyleManager : : Get ( ) . GetBrush ( " RevisionControl.StatusBar.AtLatestRevision " ) ;
static const FSlateBrush * NotAtHeadBrush = FRevisionControlStyleManager : : Get ( ) . GetBrush ( " RevisionControl.StatusBar.NotAtLatestRevision " ) ;
2022-09-26 16:32:49 -04:00
2023-03-03 11:21:12 -05:00
if ( CanSourceControlSync ( ) )
2022-09-26 16:32:49 -04:00
{
2023-03-03 11:21:12 -05:00
return NotAtHeadBrush ;
2022-09-26 16:32:49 -04:00
}
2023-03-03 11:21:12 -05:00
return AtHeadBrush ;
2022-09-26 16:32:49 -04:00
}
FReply FSourceControlMenuHelpers : : OnSourceControlSyncClicked ( )
{
2023-01-20 15:31:16 -05:00
if ( FSourceControlWindows : : CanSyncLatest ( ) )
2022-11-14 18:26:11 -05:00
{
2023-01-26 10:15:04 -05:00
FBookmarkScoped BookmarkScoped ;
2023-01-20 15:31:16 -05:00
FSourceControlWindows : : SyncLatest ( ) ;
2022-11-14 18:26:11 -05:00
}
2022-09-26 16:32:49 -04:00
return FReply : : Handled ( ) ;
}
/** Check-in Status */
int FSourceControlMenuHelpers : : GetNumLocalChanges ( )
{
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
2023-03-03 11:21:12 -05:00
if ( SourceControlModule . IsEnabled ( ) & &
SourceControlModule . GetProvider ( ) . IsAvailable ( ) & &
SourceControlModule . GetProvider ( ) . GetNumLocalChanges ( ) . IsSet ( ) )
2022-09-26 16:32:49 -04:00
{
return SourceControlModule . GetProvider ( ) . GetNumLocalChanges ( ) . GetValue ( ) ;
}
return 0 ;
}
2023-02-28 12:13:31 -05:00
void FSourceControlMenuHelpers : : SaveUnsavedFiles ( )
{
// Get a list of all the unsaved packages
TArray < FString > UnsavedFileNames = FUnsavedAssetsTrackerModule : : Get ( ) . GetUnsavedAssets ( ) ;
2023-03-03 11:21:12 -05:00
if ( UnsavedFileNames . Num ( ) > 0 )
2023-02-28 12:13:31 -05:00
{
2023-03-03 11:21:12 -05:00
TArray < UPackage * > UnsavedPackages ;
UnsavedPackages . Reserve ( UnsavedFileNames . Num ( ) ) ;
2023-02-28 12:13:31 -05:00
2023-03-03 11:21:12 -05:00
for ( FString & FileName : UnsavedFileNames )
{
FString PackageName = UPackageTools : : FilenameToPackageName ( FileName ) ;
UPackage * Package = FindPackage ( nullptr , * PackageName ) ;
if ( Package ! = nullptr )
{
UnsavedPackages . Add ( Package ) ;
}
}
UEditorLoadingAndSavingUtils : : SavePackages ( UnsavedPackages , /*bOnlyDirty=*/ true ) ;
}
}
bool FSourceControlMenuHelpers : : CanSourceControlCheckIn ( )
{
return ( GetNumLocalChanges ( ) > 0 ) ;
2023-02-28 12:13:31 -05:00
}
2022-09-26 16:32:49 -04:00
EVisibility FSourceControlMenuHelpers : : GetSourceControlCheckInStatusVisibility ( )
{
bool bDisplaySourceControlCheckInStatus = false ;
GConfig - > GetBool ( TEXT ( " SourceControlSettings " ) , TEXT ( " DisplaySourceControlCheckInStatus " ) , bDisplaySourceControlCheckInStatus , GEditorIni ) ;
2023-03-03 11:21:12 -05:00
if ( bDisplaySourceControlCheckInStatus )
2022-09-26 16:32:49 -04:00
{
2023-03-03 11:21:12 -05:00
ISourceControlModule & SourceControlModule = ISourceControlModule : : Get ( ) ;
if ( SourceControlModule . IsEnabled ( ) & &
SourceControlModule . GetProvider ( ) . IsAvailable ( ) & &
SourceControlModule . GetProvider ( ) . GetNumLocalChanges ( ) . IsSet ( ) ) // Only providers that implement GetNumLocalChanges are supported.
{
return EVisibility : : Visible ;
}
2022-09-26 16:32:49 -04:00
}
return EVisibility : : Collapsed ;
}
FText FSourceControlMenuHelpers : : GetSourceControlCheckInStatusText ( )
{
2023-03-03 11:21:12 -05:00
if ( CanSourceControlCheckIn ( ) )
2022-09-26 16:32:49 -04:00
{
return LOCTEXT ( " CheckInButtonChangesText " , " Check-in Changes " ) ;
}
return LOCTEXT ( " CheckInButtonNoChangesText " , " No Changes " ) ;
}
FText FSourceControlMenuHelpers : : GetSourceControlCheckInStatusTooltipText ( )
{
2023-03-03 11:21:12 -05:00
if ( CanSourceControlCheckIn ( ) )
2022-09-26 16:32:49 -04:00
{
2023-03-03 11:21:12 -05:00
return FText : : Format ( LOCTEXT ( " CheckInButtonChangesTooltipText " , " Check-in {0} change(s) to this project " ) , GetNumLocalChanges ( ) ) ;
2022-09-26 16:32:49 -04:00
}
return LOCTEXT ( " CheckInButtonNoChangesTooltipText " , " No Changes to check in for this project " ) ;
}
const FSlateBrush * FSourceControlMenuHelpers : : GetSourceControlCheckInStatusIcon ( )
{
2022-12-09 14:18:01 -05:00
static const FSlateBrush * NoLocalChangesBrush = FRevisionControlStyleManager : : Get ( ) . GetBrush ( " RevisionControl.StatusBar.NoLocalChanges " ) ;
static const FSlateBrush * HasLocalChangesBrush = FRevisionControlStyleManager : : Get ( ) . GetBrush ( " RevisionControl.StatusBar.HasLocalChanges " ) ;
2022-09-26 16:32:49 -04:00
2023-03-03 11:21:12 -05:00
if ( CanSourceControlCheckIn ( ) )
2022-09-26 16:32:49 -04:00
{
return HasLocalChangesBrush ;
}
return NoLocalChangesBrush ;
}
FReply FSourceControlMenuHelpers : : OnSourceControlCheckInChangesClicked ( )
{
2023-03-03 11:21:12 -05:00
if ( CanSourceControlCheckIn ( ) )
2022-09-26 16:32:49 -04:00
{
2023-02-28 12:13:31 -05:00
FSourceControlMenuHelpers : : SaveUnsavedFiles ( ) ;
2022-09-26 16:32:49 -04:00
FSourceControlWindows : : ChoosePackagesToCheckIn ( ) ;
}
return FReply : : Handled ( ) ;
}
2020-05-20 12:48:17 -04:00
TSharedRef < SWidget > FSourceControlMenuHelpers : : MakeSourceControlStatusWidget ( )
{
2022-12-09 14:18:01 -05:00
TSharedRef < SLayeredImage > SourceControlIcon =
SNew ( SLayeredImage )
2023-02-16 12:43:53 -05:00
. ColorAndOpacity ( FSlateColor : : UseForeground ( ) )
2022-12-09 14:18:01 -05:00
. Image ( FRevisionControlStyleManager : : Get ( ) . GetBrush ( " RevisionControl.Icon " ) ) ;
SourceControlIcon - > AddLayer ( TAttribute < const FSlateBrush * > : : CreateStatic ( & FSourceControlMenuHelpers : : GetSourceControlIconBadge ) ) ;
2020-05-20 12:48:17 -04:00
return
2022-09-26 16:32:49 -04:00
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
2020-05-20 12:48:17 -04:00
[
2022-10-03 20:38:09 -04:00
// NOTE: The unsaved can have its own menu extension in the status bar to decouple it from source control, but putting all the buttons in the right order
// on the status bar is not deterministic, you need to know the name of the menu that is before or after and the menu is dynamic. Having it here
// ensure its position with respect to the source control button.
FUnsavedAssetsTrackerModule : : Get ( ) . MakeUnsavedAssetsStatusBarWidget ( )
]
2023-02-20 17:59:49 -05:00
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. Padding ( 4.0f , - 5.0f ) // Intentional negative padding to make the separator cover the whole status bar vertically
[
SNew ( SSeparator )
. Thickness ( 2.0f )
. Orientation ( EOrientation : : Orient_Vertical )
]
2022-11-01 07:01:53 -04:00
+ SHorizontalBox : : Slot ( ) // Check In Changes Button
2022-09-26 16:32:49 -04:00
. VAlign ( VAlign_Center )
2023-02-20 17:59:49 -05:00
. Padding ( FMargin ( 0.0f , 0.0f , 4.0f , 0.0f ) )
2022-09-26 16:32:49 -04:00
. AutoWidth ( )
[
SNew ( SButton )
. ButtonStyle ( & FAppStyle : : Get ( ) . GetWidgetStyle < FButtonStyle > ( " StatusBar.StatusBarButton " ) )
. ToolTipText_Static ( & FSourceControlMenuHelpers : : GetSourceControlCheckInStatusTooltipText )
. Visibility_Static ( & FSourceControlMenuHelpers : : GetSourceControlCheckInStatusVisibility )
2023-03-03 11:21:12 -05:00
. IsEnabled_Lambda ( [ ] ( ) { return CanSourceControlCheckIn ( ) ; } )
2022-09-26 16:32:49 -04:00
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. HAlign ( HAlign_Center )
[
SNew ( SImage )
. Image_Static ( & FSourceControlMenuHelpers : : GetSourceControlCheckInStatusIcon )
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. Padding ( FMargin ( 5 , 0 , 0 , 0 ) )
[
SNew ( STextBlock )
. TextStyle ( & FAppStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " NormalText " ) )
. Text_Static ( & FSourceControlMenuHelpers : : GetSourceControlCheckInStatusText )
]
]
. OnClicked_Static ( & FSourceControlMenuHelpers : : OnSourceControlCheckInChangesClicked )
]
2022-12-11 23:09:22 -05:00
+ SHorizontalBox : : Slot ( ) // Check In Kebab Combo button
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SComboButton )
. ContentPadding ( FMargin ( 7.f , 0.f ) )
. ComboButtonStyle ( & FAppStyle : : Get ( ) . GetWidgetStyle < FComboButtonStyle > ( " StatusBar.StatusBarEllipsisComboButton " ) )
. MenuPlacement ( MenuPlacement_AboveAnchor )
. Visibility_Static ( & FSourceControlMenuHelpers : : GetSourceControlCheckInStatusVisibility )
. OnGetMenuContent ( FOnGetContent : : CreateStatic ( & FSourceControlMenuHelpers : : GenerateCheckInComboButtonContent ) )
]
2023-02-20 21:07:58 -05:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SSeparator )
. Visibility_Static ( & FSourceControlMenuHelpers : : GetSourceControlCheckInStatusVisibility )
. Thickness ( 1.0 )
. Orientation ( EOrientation : : Orient_Vertical )
]
2022-11-01 07:01:53 -04:00
+ SHorizontalBox : : Slot ( ) // Sync Latest Button
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SButton )
. ButtonStyle ( & FAppStyle : : Get ( ) . GetWidgetStyle < FButtonStyle > ( " StatusBar.StatusBarButton " ) )
. ToolTipText_Static ( & FSourceControlMenuHelpers : : GetSourceControlSyncStatusTooltipText )
. Visibility_Static ( & FSourceControlMenuHelpers : : GetSourceControlSyncStatusVisibility )
2023-03-03 11:21:12 -05:00
. IsEnabled_Lambda ( [ ] ( ) { return CanSourceControlSync ( ) ; } )
2022-11-01 07:01:53 -04:00
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. HAlign ( HAlign_Center )
[
SNew ( SImage )
. Image_Static ( & FSourceControlMenuHelpers : : GetSourceControlSyncStatusIcon )
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. Padding ( FMargin ( 5 , 0 , 0 , 0 ) )
[
SNew ( STextBlock )
. TextStyle ( & FAppStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " NormalText " ) )
. Text_Static ( & FSourceControlMenuHelpers : : GetSourceControlSyncStatusText )
]
]
. OnClicked_Static ( & FSourceControlMenuHelpers : : OnSourceControlSyncClicked )
]
2023-02-20 21:07:58 -05:00
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SSeparator )
. Visibility_Static ( & FSourceControlMenuHelpers : : GetSourceControlCheckInStatusVisibility )
. Thickness ( 1.0 )
. Orientation ( EOrientation : : Orient_Vertical )
]
2022-11-01 07:01:53 -04:00
+ SHorizontalBox : : Slot ( ) // Source Control Menu
2022-09-26 16:32:49 -04:00
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( SComboButton )
. ContentPadding ( FMargin ( 6.0f , 0.0f ) )
. ToolTipText_Static ( & FSourceControlMenuHelpers : : GetSourceControlTooltip )
. MenuPlacement ( MenuPlacement_AboveAnchor )
. ComboButtonStyle ( & FAppStyle : : Get ( ) . GetWidgetStyle < FComboButtonStyle > ( " StatusBar.StatusBarComboButton " ) )
. ButtonContent ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. HAlign ( HAlign_Center )
[
2022-12-09 14:18:01 -05:00
SourceControlIcon
2022-09-26 16:32:49 -04:00
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. Padding ( FMargin ( 5 , 0 , 0 , 0 ) )
[
SNew ( STextBlock )
. TextStyle ( & FAppStyle : : Get ( ) . GetWidgetStyle < FTextBlockStyle > ( " NormalText " ) )
. Text_Static ( & FSourceControlMenuHelpers : : GetSourceControlStatusText )
]
]
. OnGetMenuContent ( FOnGetContent : : CreateStatic ( & FSourceControlMenuHelpers : : GenerateSourceControlMenuContent ) )
] ;
2020-05-20 12:48:17 -04:00
}
# undef LOCTEXT_NAMESPACE