2022-09-07 17:15:39 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "SSourceControlChangelistRows.h"
2023-08-09 18:41:28 -04:00
# include "ComponentReregisterContext.h"
# include "FileHelpers.h"
2022-09-07 17:15:39 -04:00
# include "ISourceControlModule.h"
2023-01-31 01:26:50 -05:00
# include "PackageTools.h"
2023-08-09 18:41:28 -04:00
# include "PackageSourceControlHelper.h"
2023-01-31 01:26:50 -05:00
# include "SourceControlHelpers.h"
2022-09-07 17:15:39 -04:00
# include "UncontrolledChangelistsModule.h"
# include "SourceControlOperations.h"
2023-01-31 01:26:50 -05:00
# include "UnsavedAssetsTrackerModule.h"
2022-09-12 18:11:36 -04:00
# include "Styling/AppStyle.h"
2022-09-07 17:15:55 -04:00
# include "Widgets/Images/SImage.h"
2023-01-31 01:26:50 -05:00
# include "Widgets/Input/SButton.h"
2022-09-07 17:15:55 -04:00
# include "Widgets/Text/STextBlock.h"
# include "Algo/Transform.h"
2024-02-23 07:58:22 -05:00
# include "Containers/Ticker.h"
2023-01-31 01:26:50 -05:00
# include "RevisionControlStyle/RevisionControlStyle.h"
# include "Styling/SlateStyleRegistry.h"
# include "Styling/StarshipCoreStyle.h"
2023-02-14 20:25:02 -05:00
# include "Misc/MessageDialog.h"
2023-01-31 01:26:50 -05:00
# include "Widgets/Images/SThrobber.h"
# include "Widgets/Layout/SWidgetSwitcher.h"
2022-09-07 17:15:39 -04:00
# define LOCTEXT_NAMESPACE "SourceControlChangelistRow"
2023-08-09 18:41:28 -04:00
namespace
{
bool CheckoutAndSavePackages ( const TArray < FString > & Files )
{
FPackageSourceControlHelper PackageHelper ;
TArray < FString > PackageNames ;
PackageNames . Reserve ( Files . Num ( ) ) ;
for ( const FString & Filename : Files )
{
PackageNames . Add ( UPackageTools : : FilenameToPackageName ( Filename ) ) ;
}
if ( PackageHelper . Checkout ( PackageNames ) )
{
TArray < UPackage * > Packages ;
Packages . Reserve ( PackageNames . Num ( ) ) ;
{
FGlobalComponentReregisterContext ReregisterContext ;
for ( const FString & PackageName : PackageNames )
{
Packages . Add ( UPackageTools : : LoadPackage ( PackageName ) ) ;
}
}
constexpr bool bOnlyDirty = false ;
return UEditorLoadingAndSavingUtils : : SavePackages ( Packages , bOnlyDirty ) ;
}
return false ;
}
}
2022-09-15 18:45:09 -04:00
FName SourceControlFileViewColumn : : Icon : : Id ( ) { return TEXT ( " Icon " ) ; }
2022-11-23 11:57:50 -05:00
FText SourceControlFileViewColumn : : Icon : : GetDisplayText ( ) { return LOCTEXT ( " Name_Icon " , " Revision Control Status " ) ; }
2022-09-15 18:45:09 -04:00
FText SourceControlFileViewColumn : : Icon : : GetToolTipText ( ) { return LOCTEXT ( " Icon_Column_Tooltip " , " Displays the asset/file status " ) ; }
2022-09-07 17:15:39 -04:00
2022-09-15 18:45:09 -04:00
FName SourceControlFileViewColumn : : Name : : Id ( ) { return TEXT ( " Name " ) ; }
FText SourceControlFileViewColumn : : Name : : GetDisplayText ( ) { return LOCTEXT ( " Name_Column " , " Name " ) ; }
FText SourceControlFileViewColumn : : Name : : GetToolTipText ( ) { return LOCTEXT ( " Name_Column_Tooltip " , " Displays the asset/file name " ) ; }
FName SourceControlFileViewColumn : : Path : : Id ( ) { return TEXT ( " Path " ) ; }
FText SourceControlFileViewColumn : : Path : : GetDisplayText ( ) { return LOCTEXT ( " Path_Column " , " Path " ) ; }
FText SourceControlFileViewColumn : : Path : : GetToolTipText ( ) { return LOCTEXT ( " Path_Column_Tooltip " , " Displays the asset/file path " ) ; }
FName SourceControlFileViewColumn : : Type : : Id ( ) { return TEXT ( " Type " ) ; }
FText SourceControlFileViewColumn : : Type : : GetDisplayText ( ) { return LOCTEXT ( " Type_Column " , " Type " ) ; }
FText SourceControlFileViewColumn : : Type : : GetToolTipText ( ) { return LOCTEXT ( " Type_Column_Tooltip " , " Displays the asset type " ) ; }
FName SourceControlFileViewColumn : : LastModifiedTimestamp : : Id ( ) { return TEXT ( " LastModifiedTimestamp " ) ; }
FText SourceControlFileViewColumn : : LastModifiedTimestamp : : GetDisplayText ( ) { return LOCTEXT ( " LastModifiedTimestamp_Column " , " Last Saved " ) ; }
FText SourceControlFileViewColumn : : LastModifiedTimestamp : : GetToolTipText ( ) { return LOCTEXT ( " LastMofiedTimestamp_Column_Tooltip " , " Displays the last time the file/asset was saved on user hard drive " ) ; }
FName SourceControlFileViewColumn : : CheckedOutByUser : : Id ( ) { return TEXT ( " CheckedOutByUser " ) ; }
FText SourceControlFileViewColumn : : CheckedOutByUser : : GetDisplayText ( ) { return LOCTEXT ( " CheckedOutByUser_Column " , " User " ) ; }
FText SourceControlFileViewColumn : : CheckedOutByUser : : GetToolTipText ( ) { return LOCTEXT ( " CheckedOutByUser_Column_Tooltip " , " Displays the other user(s) that checked out the file / asset , if any " ) ; }
2022-09-07 17:15:39 -04:00
2023-01-31 01:26:50 -05:00
FName SourceControlFileViewColumn : : Changelist : : Id ( ) { return TEXT ( " Changelist " ) ; }
FText SourceControlFileViewColumn : : Changelist : : GetDisplayText ( ) { return LOCTEXT ( " Changelist_Column " , " Changelist " ) ; }
FText SourceControlFileViewColumn : : Changelist : : GetToolTipText ( ) { return LOCTEXT ( " Changelist_Column_Tooltip " , " Displays the changelist the asset/file belongs to, if any " ) ; }
FName SourceControlFileViewColumn : : Dirty : : Id ( ) { return TEXT ( " Dirty " ) ; }
FText SourceControlFileViewColumn : : Dirty : : GetDisplayText ( ) { return LOCTEXT ( " Dirty_Column " , " Unsaved " ) ; }
FText SourceControlFileViewColumn : : Dirty : : GetToolTipText ( ) { return LOCTEXT ( " Dirty_Column_Tooltip " , " Displays whether the asset/file has unsaved changes " ) ; }
FName SourceControlFileViewColumn : : Discard : : Id ( ) { return TEXT ( " Discard " ) ; }
FText SourceControlFileViewColumn : : Discard : : GetDisplayText ( ) { return LOCTEXT ( " Discard_Column " , " Discard Unsaved Changes " ) ; }
FText SourceControlFileViewColumn : : Discard : : GetToolTipText ( ) { return LOCTEXT ( " Discard_Column_Tooltip " , " Provides option to discard unsaved changes to an asset/file " ) ; }
2022-11-01 16:30:00 -04:00
FText FormatChangelistFileCountText ( int32 DisplayedCount , int32 TotalCount )
{
return DisplayedCount = = TotalCount ?
FText : : Format ( INVTEXT ( " ({0}) " ) , TotalCount ) :
FText : : Format ( LOCTEXT ( " FilterNum " , " ({0} out of {1}) " ) , DisplayedCount , TotalCount ) ;
}
2022-09-07 17:15:39 -04:00
void SChangelistTableRow : : Construct ( const FArguments & InArgs , const TSharedRef < STableViewBase > & InOwner )
{
TreeItem = static_cast < FChangelistTreeItem * > ( InArgs . _TreeItemToVisualize . Get ( ) ) ;
OnPostDrop = InArgs . _OnPostDrop ;
SetToolTipText ( GetChangelistDescriptionText ( ) ) ;
STableRow < FChangelistTreeItemPtr > : : Construct (
STableRow < FChangelistTreeItemPtr > : : FArguments ( )
. Style ( FAppStyle : : Get ( ) , " TableView.Row " )
. Content ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( ) // Icon
. AutoWidth ( )
[
SNew ( SImage )
2023-02-01 17:54:20 -05:00
. Image_Lambda ( [ this ] ( )
{
return ( TreeItem ! = nullptr ) ? FAppStyle : : GetBrush ( TreeItem - > ChangelistState - > GetSmallIconName ( ) ) : FAppStyle : : GetBrush ( " SourceControl.Changelist " ) ;
} )
2022-09-07 17:15:39 -04:00
]
+ SHorizontalBox : : Slot ( ) // Changelist number.
. Padding ( 2 , 0 , 0 , 0 )
. AutoWidth ( )
[
SNew ( STextBlock )
. Text ( this , & SChangelistTableRow : : GetChangelistText )
2022-09-12 18:11:36 -04:00
. HighlightText ( InArgs . _HighlightText )
2022-09-07 17:15:39 -04:00
]
+ SHorizontalBox : : Slot ( ) // Files count.
. Padding ( 4 , 0 , 4 , 0 )
. AutoWidth ( )
[
SNew ( STextBlock )
2022-11-01 16:30:00 -04:00
. Text_Lambda ( [ this ] ( )
{
// Check if the 'Shelved Files' node is currently linked to the tree view. (not filtered out).
return FormatChangelistFileCountText ( TreeItem - > ShelvedChangelistItem - > GetParent ( ) ? TreeItem - > GetChildren ( ) . Num ( ) - 1 : TreeItem - > GetChildren ( ) . Num ( ) , TreeItem - > GetFileCount ( ) ) ;
} )
2022-09-07 17:15:39 -04:00
]
2022-09-12 18:11:36 -04:00
+ SHorizontalBox : : Slot ( ) // Description.
2022-09-07 17:15:39 -04:00
. Padding ( 2 , 0 , 0 , 0 )
. AutoWidth ( )
[
SNew ( STextBlock )
2022-12-05 13:19:35 -05:00
. Text ( this , & SChangelistTableRow : : GetChangelistDescriptionSingleLineText )
2022-09-12 18:11:36 -04:00
. HighlightText ( InArgs . _HighlightText )
2022-09-07 17:15:39 -04:00
]
] , InOwner ) ;
}
2022-09-12 18:11:36 -04:00
void SChangelistTableRow : : PopulateSearchString ( const FChangelistTreeItem & Item , TArray < FString > & OutStrings )
{
OutStrings . Emplace ( Item . GetDisplayText ( ) . ToString ( ) ) ; // The changelist number
2022-12-05 13:19:35 -05:00
OutStrings . Emplace ( Item . GetDescriptionText ( ) . ToString ( ) ) ; // The changelist description.
2022-09-12 18:11:36 -04:00
}
2022-09-07 17:15:39 -04:00
FText SChangelistTableRow : : GetChangelistText ( ) const
{
return TreeItem - > GetDisplayText ( ) ;
}
FText SChangelistTableRow : : GetChangelistDescriptionText ( ) const
{
2022-12-05 13:19:35 -05:00
return TreeItem - > GetDescriptionText ( ) ;
2022-09-12 18:11:36 -04:00
}
2022-12-05 13:19:35 -05:00
FText SChangelistTableRow : : GetChangelistDescriptionSingleLineText ( ) const
2022-09-12 18:11:36 -04:00
{
2023-12-12 17:18:07 -05:00
using namespace SSourceControlCommon ;
return GetSingleLineChangelistDescription ( TreeItem - > GetDescriptionText ( ) , ESingleLineFlags : : NewlineConvertToSpace ) ;
2022-09-07 17:15:39 -04:00
}
FReply SChangelistTableRow : : OnDrop ( const FGeometry & InGeometry , const FDragDropEvent & InDragDropEvent )
{
TSharedPtr < FSCCFileDragDropOp > DropOperation = InDragDropEvent . GetOperationAs < FSCCFileDragDropOp > ( ) ;
if ( DropOperation . IsValid ( ) )
{
FSourceControlChangelistPtr DestChangelist = TreeItem - > ChangelistState - > GetChangelist ( ) ;
check ( DestChangelist . IsValid ( ) ) ;
// NOTE: The UI don't show 'source controlled files' and 'uncontrolled files' at the same time. User cannot select and drag/drop both file types at the same time.
if ( ! DropOperation - > Files . IsEmpty ( ) )
{
TArray < FString > Files ;
Algo : : Transform ( DropOperation - > Files , Files , [ ] ( const FSourceControlStateRef & State ) { return State - > GetFilename ( ) ; } ) ;
SSourceControlCommon : : ExecuteChangelistOperationWithSlowTaskWrapper ( LOCTEXT ( " Dropping_Files_On_Changelist " , " Moving file(s) to the selected changelist... " ) , [ & ] ( )
{
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
SourceControlProvider . Execute ( ISourceControlOperation : : Create < FMoveToChangelist > ( ) , DestChangelist , Files , EConcurrency : : Synchronous , FSourceControlOperationComplete : : CreateLambda (
[ ] ( const TSharedRef < ISourceControlOperation > & Operation , ECommandResult : : Type InResult )
{
if ( InResult = = ECommandResult : : Succeeded )
{
SSourceControlCommon : : DisplaySourceControlOperationNotification ( LOCTEXT ( " Drop_Files_On_Changelist_Succeeded " , " File(s) successfully moved to the selected changelist. " ) , SNotificationItem : : CS_Success ) ;
}
else if ( InResult = = ECommandResult : : Failed )
{
SSourceControlCommon : : DisplaySourceControlOperationNotification ( LOCTEXT ( " Drop_Files_On_Changelist_Failed " , " Failed to move the file(s) to the selected changelist. " ) , SNotificationItem : : CS_Fail ) ;
}
} ) ) ;
} ) ;
}
else if ( ! DropOperation - > UncontrolledFiles . IsEmpty ( ) )
{
// NOTE: This function does several operations that can fails but we don't get feedback.
SSourceControlCommon : : ExecuteUncontrolledChangelistOperationWithSlowTaskWrapper ( LOCTEXT ( " Dropping_Uncontrolled_Files_On_Changelist " , " Moving uncontrolled file(s) to the selected changelist... " ) ,
[ & DropOperation , & DestChangelist ] ( )
{
FUncontrolledChangelistsModule : : Get ( ) . MoveFilesToControlledChangelist ( DropOperation - > UncontrolledFiles , DestChangelist , SSourceControlCommon : : OpenConflictDialog ) ;
// TODO: Fix MoveFilesToControlledChangelist() to report the possible errors and display a notification.
} ) ;
OnPostDrop . ExecuteIfBound ( ) ;
}
2023-08-09 18:41:28 -04:00
else if ( ! DropOperation - > OfflineFiles . IsEmpty ( ) )
{
const TArray < FString > & Files = DropOperation - > OfflineFiles ;
SSourceControlCommon : : ExecuteChangelistOperationWithSlowTaskWrapper ( LOCTEXT ( " Dropping_Files_On_Changelist " , " Moving file(s) to the selected changelist... " ) , [ & ] ( )
{
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
if ( ! CheckoutAndSavePackages ( Files ) )
{
return ;
}
SourceControlProvider . Execute ( ISourceControlOperation : : Create < FMoveToChangelist > ( ) , DestChangelist , Files , EConcurrency : : Synchronous , FSourceControlOperationComplete : : CreateLambda (
[ ] ( const TSharedRef < ISourceControlOperation > & Operation , ECommandResult : : Type InResult )
{
if ( InResult = = ECommandResult : : Succeeded )
{
SSourceControlCommon : : DisplaySourceControlOperationNotification ( LOCTEXT ( " Drop_Files_On_Changelist_Succeeded " , " File(s) successfully moved to the selected changelist. " ) , SNotificationItem : : CS_Success ) ;
}
else if ( InResult = = ECommandResult : : Failed )
{
SSourceControlCommon : : DisplaySourceControlOperationNotification ( LOCTEXT ( " Drop_Files_On_Changelist_Failed " , " Failed to move the file(s) to the selected changelist. " ) , SNotificationItem : : CS_Fail ) ;
}
} ) ) ;
} ) ;
}
2022-09-07 17:15:39 -04:00
}
return FReply : : Handled ( ) ;
}
void SUncontrolledChangelistTableRow : : Construct ( const FArguments & InArgs , const TSharedRef < STableViewBase > & InOwner )
{
TreeItem = static_cast < FUncontrolledChangelistTreeItem * > ( InArgs . _TreeItemToVisualize . Get ( ) ) ;
OnPostDrop = InArgs . _OnPostDrop ;
const FSlateBrush * IconBrush = ( TreeItem ! = nullptr ) ?
FAppStyle : : GetBrush ( TreeItem - > UncontrolledChangelistState - > GetSmallIconName ( ) ) :
FAppStyle : : GetBrush ( " SourceControl.Changelist " ) ;
2022-09-12 18:11:36 -04:00
SetToolTipText ( GetChangelistText ( ) ) ;
2022-09-07 17:15:39 -04:00
STableRow < FChangelistTreeItemPtr > : : Construct (
STableRow < FChangelistTreeItemPtr > : : FArguments ( )
. Style ( FAppStyle : : Get ( ) , " TableView.Row " )
. Content ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
[
SNew ( SImage )
. Image ( IconBrush )
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. Padding ( 2.0f , 0.0f )
. VAlign ( VAlign_Center )
[
SNew ( STextBlock )
. Text ( this , & SUncontrolledChangelistTableRow : : GetChangelistText )
2022-09-12 18:11:36 -04:00
. HighlightText ( InArgs . _HighlightText )
2022-09-07 17:15:39 -04:00
]
+ SHorizontalBox : : Slot ( ) // Files/Offline file count.
. Padding ( 4 , 0 , 4 , 0 )
. AutoWidth ( )
[
SNew ( STextBlock )
2022-11-01 16:30:00 -04:00
. Text_Lambda ( [ this ] ( )
{
return FormatChangelistFileCountText ( TreeItem - > GetChildren ( ) . Num ( ) , TreeItem - > GetFileCount ( ) ) ;
} )
2022-09-07 17:15:39 -04:00
]
] , InOwner ) ;
}
2022-09-12 18:11:36 -04:00
void SUncontrolledChangelistTableRow : : PopulateSearchString ( const FUncontrolledChangelistTreeItem & Item , TArray < FString > & OutStrings )
{
OutStrings . Emplace ( Item . GetDisplayText ( ) . ToString ( ) ) ;
}
2022-09-07 17:15:39 -04:00
FText SUncontrolledChangelistTableRow : : GetChangelistText ( ) const
{
return TreeItem - > GetDisplayText ( ) ;
}
FReply SUncontrolledChangelistTableRow : : OnDrop ( const FGeometry & InGeometry , const FDragDropEvent & InDragDropEvent )
{
TSharedPtr < FSCCFileDragDropOp > Operation = InDragDropEvent . GetOperationAs < FSCCFileDragDropOp > ( ) ;
if ( Operation . IsValid ( ) )
{
2023-08-09 18:41:28 -04:00
if ( Operation - > OfflineFiles . IsEmpty ( ) )
2022-09-07 17:15:39 -04:00
{
2023-08-09 18:41:28 -04:00
SSourceControlCommon : : ExecuteUncontrolledChangelistOperationWithSlowTaskWrapper ( LOCTEXT ( " Drag_File_To_Uncontrolled_Changelist " , " Moving file(s) to the selected uncontrolled changelists... " ) ,
[ this , & Operation ] ( )
{
FUncontrolledChangelistsModule : : Get ( ) . MoveFilesToUncontrolledChangelist ( Operation - > Files , Operation - > UncontrolledFiles , TreeItem - > UncontrolledChangelistState - > Changelist ) ;
} ) ;
}
// Drop unsaved assets (offline files)
else
{
const TArray < FString > & Files = Operation - > OfflineFiles ;
if ( ! CheckoutAndSavePackages ( Files ) )
{
return FReply : : Unhandled ( ) ;
}
SSourceControlCommon : : ExecuteUncontrolledChangelistOperationWithSlowTaskWrapper ( LOCTEXT ( " Drag_File_To_Uncontrolled_Changelist " , " Moving file(s) to the selected uncontrolled changelists... " ) ,
[ this , & Files ] ( )
{
FUncontrolledChangelistsModule : : Get ( ) . MoveFilesToUncontrolledChangelist ( Files , TreeItem - > UncontrolledChangelistState - > Changelist ) ;
} ) ;
}
2022-09-07 17:15:39 -04:00
OnPostDrop . ExecuteIfBound ( ) ;
}
return FReply : : Handled ( ) ;
}
2023-01-31 01:26:50 -05:00
void SUnsavedAssetsTableRow : : Construct ( const FArguments & InArgs , const TSharedRef < STableViewBase > & InOwner )
{
STableRow < FChangelistTreeItemPtr > : : Construct (
STableRow < FChangelistTreeItemPtr > : : FArguments ( )
. Style ( FAppStyle : : Get ( ) , " TableView.Row " )
. Content ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
[
SNew ( SImage )
. Image ( FAppStyle : : GetBrush ( " Assets.Unsaved " ) )
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. Padding ( 2.0f , 0.0f )
. VAlign ( VAlign_Center )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " SourceControl_Unsaved " , " Unsaved " ) )
]
+ SHorizontalBox : : Slot ( ) // Files/Offline file count.
. Padding ( 4 , 0 , 4 , 0 )
. AutoWidth ( )
[
SNew ( STextBlock )
. Text_Lambda ( [ ] { return FText : : Format ( FText : : FromString ( " ({0}) " ) , FUnsavedAssetsTrackerModule : : Get ( ) . GetUnsavedAssetNum ( ) ) ; } )
]
] , InOwner ) ;
}
2022-09-07 17:15:39 -04:00
void SFileTableRow : : Construct ( const FArguments & InArgs , const TSharedRef < STableViewBase > & InOwner )
{
TreeItem = static_cast < FFileTreeItem * > ( InArgs . _TreeItemToVisualize . Get ( ) ) ;
2022-09-12 18:11:36 -04:00
HighlightText = InArgs . _HighlightText ;
2022-09-07 17:15:39 -04:00
FSuperRowType : : FArguments Args = FSuperRowType : : FArguments ( )
. OnDragDetected ( InArgs . _OnDragDetected )
. ShowSelection ( true ) ;
FSuperRowType : : Construct ( Args , InOwner ) ;
}
TSharedRef < SWidget > SFileTableRow : : GenerateWidgetForColumn ( const FName & ColumnId )
{
2022-09-15 18:45:09 -04:00
if ( ColumnId = = SourceControlFileViewColumn : : Icon : : Id ( ) )
2022-09-07 17:15:39 -04:00
{
return SNew ( SBox )
. WidthOverride ( 16 ) // Small Icons are usually 16x16
. HAlign ( HAlign_Center )
[
SSourceControlCommon : : GetSCCFileWidget ( TreeItem - > FileState , TreeItem - > IsShelved ( ) )
] ;
}
2022-09-15 18:45:09 -04:00
else if ( ColumnId = = SourceControlFileViewColumn : : Name : : Id ( ) )
2022-09-07 17:15:39 -04:00
{
return SNew ( STextBlock )
2022-09-12 18:11:36 -04:00
. Text ( this , & SFileTableRow : : GetDisplayName )
2022-09-15 18:45:09 -04:00
. ToolTipText ( this , & SFileTableRow : : GetDisplayName )
2022-09-12 18:11:36 -04:00
. HighlightText ( HighlightText ) ;
2022-09-07 17:15:39 -04:00
}
2022-09-15 18:45:09 -04:00
else if ( ColumnId = = SourceControlFileViewColumn : : Path : : Id ( ) )
2022-09-07 17:15:39 -04:00
{
return SNew ( STextBlock )
. Text ( this , & SFileTableRow : : GetDisplayPath )
2022-09-12 18:11:36 -04:00
. ToolTipText ( this , & SFileTableRow : : GetFilename )
. HighlightText ( HighlightText ) ;
2022-09-07 17:15:39 -04:00
}
2022-09-15 18:45:09 -04:00
else if ( ColumnId = = SourceControlFileViewColumn : : Type : : Id ( ) )
2022-09-07 17:15:39 -04:00
{
return SNew ( STextBlock )
. Text ( this , & SFileTableRow : : GetDisplayType )
2022-09-15 18:45:09 -04:00
. ToolTipText ( this , & SFileTableRow : : GetDisplayType )
2022-09-12 18:11:36 -04:00
. ColorAndOpacity ( this , & SFileTableRow : : GetDisplayColor )
. HighlightText ( HighlightText ) ;
2022-09-07 17:15:39 -04:00
}
2022-09-15 18:45:09 -04:00
else if ( ColumnId = = SourceControlFileViewColumn : : LastModifiedTimestamp : : Id ( ) )
{
return SNew ( STextBlock )
. ToolTipText ( this , & SFileTableRow : : GetLastModifiedTimestamp )
. Text ( this , & SFileTableRow : : GetLastModifiedTimestamp ) ;
}
else if ( ColumnId = = SourceControlFileViewColumn : : CheckedOutByUser : : Id ( ) )
{
return SNew ( STextBlock )
. ToolTipText ( this , & SFileTableRow : : GetCheckedOutByUser )
. Text ( this , & SFileTableRow : : GetCheckedOutByUser ) ;
}
2022-09-07 17:15:39 -04:00
else
{
return SNullWidget : : NullWidget ;
}
}
2022-09-12 18:11:36 -04:00
void SFileTableRow : : PopulateSearchString ( const FFileTreeItem & Item , TArray < FString > & OutStrings )
{
OutStrings . Emplace ( Item . GetAssetName ( ) . ToString ( ) ) ; // Name
OutStrings . Emplace ( Item . GetAssetPath ( ) . ToString ( ) ) ; // Path
OutStrings . Emplace ( Item . GetAssetType ( ) . ToString ( ) ) ; // Type
2022-09-15 18:45:09 -04:00
OutStrings . Emplace ( Item . GetLastModifiedTimestamp ( ) . ToString ( ) ) ;
OutStrings . Emplace ( Item . GetCheckedOutByUser ( ) . ToString ( ) ) ;
2022-09-12 18:11:36 -04:00
}
2022-09-07 17:15:39 -04:00
FText SFileTableRow : : GetDisplayName ( ) const
{
return TreeItem - > GetAssetName ( ) ;
}
FText SFileTableRow : : GetFilename ( ) const
{
return TreeItem - > GetFileName ( ) ;
}
FText SFileTableRow : : GetDisplayPath ( ) const
{
return TreeItem - > GetAssetPath ( ) ;
}
FText SFileTableRow : : GetDisplayType ( ) const
{
return TreeItem - > GetAssetType ( ) ;
}
FSlateColor SFileTableRow : : GetDisplayColor ( ) const
{
return TreeItem - > GetAssetTypeColor ( ) ;
}
2022-09-15 18:45:09 -04:00
FText SFileTableRow : : GetLastModifiedTimestamp ( ) const
{
return TreeItem - > GetLastModifiedTimestamp ( ) ;
}
FText SFileTableRow : : GetCheckedOutByUser ( ) const
{
return TreeItem - > GetCheckedOutByUser ( ) ;
}
2022-09-07 17:15:39 -04:00
void SFileTableRow : : OnDragEnter ( FGeometry const & InGeometry , FDragDropEvent const & InDragDropEvent )
{
TSharedPtr < FDragDropOperation > DragOperation = InDragDropEvent . GetOperation ( ) ;
DragOperation - > SetCursorOverride ( EMouseCursor : : SlashedCircle ) ;
}
void SFileTableRow : : OnDragLeave ( FDragDropEvent const & InDragDropEvent )
{
TSharedPtr < FDragDropOperation > DragOperation = InDragDropEvent . GetOperation ( ) ;
DragOperation - > SetCursorOverride ( EMouseCursor : : None ) ;
}
void SShelvedFilesTableRow : : Construct ( const FArguments & InArgs , const TSharedRef < STableViewBase > & InOwnerTableView )
{
2022-09-12 18:11:36 -04:00
TreeItem = static_cast < FShelvedChangelistTreeItem * > ( InArgs . _TreeItemToVisualize . Get ( ) ) ;
2022-09-07 17:15:39 -04:00
STableRow < FChangelistTreeItemPtr > : : Construct (
STableRow < FChangelistTreeItemPtr > : : FArguments ( )
. Content ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. Padding ( 5 , 0 , 0 , 0 )
[
SNew ( SImage )
2022-09-12 18:11:36 -04:00
. Image ( FAppStyle : : GetBrush ( " SourceControl.ShelvedChangelist " ) )
2022-09-07 17:15:39 -04:00
]
+ SHorizontalBox : : Slot ( )
. Padding ( 2.0f , 1.0f )
. VAlign ( VAlign_Center )
2022-11-01 16:30:00 -04:00
. AutoWidth ( )
2022-09-07 17:15:39 -04:00
[
SNew ( STextBlock )
2022-11-01 16:30:00 -04:00
. Text_Lambda ( [ this ] ( ) { return TreeItem - > GetDisplayText ( ) ; } )
2022-09-12 18:11:36 -04:00
. HighlightText ( InArgs . _HighlightText )
2022-09-07 17:15:39 -04:00
]
2022-11-01 16:30:00 -04:00
+ SHorizontalBox : : Slot ( ) // Shelved file count.
. Padding ( 4 , 0 , 4 , 0 )
. AutoWidth ( )
[
SNew ( STextBlock )
. Text_Lambda ( [ this ] ( )
{
return FormatChangelistFileCountText ( TreeItem - > GetChildren ( ) . Num ( ) , static_cast < const FChangelistTreeItem * > ( TreeItem - > GetParent ( ) . Get ( ) ) - > GetShelvedFileCount ( ) ) ;
} )
]
2022-09-07 17:15:39 -04:00
] ,
InOwnerTableView ) ;
}
2022-09-12 18:11:36 -04:00
void SShelvedFilesTableRow : : PopulateSearchString ( const FShelvedChangelistTreeItem & Item , TArray < FString > & OutStrings )
{
OutStrings . Emplace ( Item . GetDisplayText ( ) . ToString ( ) ) ;
}
2022-09-07 17:15:39 -04:00
void SOfflineFileTableRow : : Construct ( const FArguments & InArgs , const TSharedRef < STableViewBase > & InOwner )
{
TreeItem = static_cast < FOfflineFileTreeItem * > ( InArgs . _TreeItemToVisualize . Get ( ) ) ;
2022-09-12 18:11:36 -04:00
HighlightText = InArgs . _HighlightText ;
2022-09-07 17:15:39 -04:00
2023-08-09 18:41:28 -04:00
FSuperRowType : : FArguments Args = FSuperRowType : : FArguments ( )
. OnDragDetected ( InArgs . _OnDragDetected )
. ShowSelection ( true ) ;
2022-09-07 17:15:39 -04:00
FSuperRowType : : Construct ( Args , InOwner ) ;
}
TSharedRef < SWidget > SOfflineFileTableRow : : GenerateWidgetForColumn ( const FName & ColumnId )
{
2022-09-15 18:45:09 -04:00
if ( ColumnId = = SourceControlFileViewColumn : : Icon : : Id ( ) )
2022-09-07 17:15:39 -04:00
{
return SNew ( SBox )
. WidthOverride ( 16 ) // Small Icons are usually 16x16
. HAlign ( HAlign_Center )
[
SNew ( SImage )
. Image ( FAppStyle : : GetBrush ( FName ( " SourceControl.OfflineFile_Small " ) ) )
] ;
}
2022-09-15 18:45:09 -04:00
else if ( ColumnId = = SourceControlFileViewColumn : : Name : : Id ( ) )
2022-09-07 17:15:39 -04:00
{
return SNew ( STextBlock )
2022-09-15 18:45:09 -04:00
. ToolTipText ( this , & SOfflineFileTableRow : : GetDisplayName )
2022-09-12 18:11:36 -04:00
. Text ( this , & SOfflineFileTableRow : : GetDisplayName )
. HighlightText ( HighlightText ) ;
2022-09-07 17:15:39 -04:00
}
2022-09-15 18:45:09 -04:00
else if ( ColumnId = = SourceControlFileViewColumn : : Path : : Id ( ) )
2022-09-07 17:15:39 -04:00
{
return SNew ( STextBlock )
. Text ( this , & SOfflineFileTableRow : : GetDisplayPath )
2022-09-12 18:11:36 -04:00
. ToolTipText ( this , & SOfflineFileTableRow : : GetFilename )
. HighlightText ( HighlightText ) ;
2022-09-07 17:15:39 -04:00
}
2022-09-15 18:45:09 -04:00
else if ( ColumnId = = SourceControlFileViewColumn : : Type : : Id ( ) )
2022-09-07 17:15:39 -04:00
{
return SNew ( STextBlock )
. Text ( this , & SOfflineFileTableRow : : GetDisplayType )
2022-09-15 18:45:09 -04:00
. ToolTipText ( this , & SOfflineFileTableRow : : GetDisplayType )
2022-09-12 18:11:36 -04:00
. ColorAndOpacity ( this , & SOfflineFileTableRow : : GetDisplayColor )
. HighlightText ( HighlightText ) ;
2022-09-07 17:15:39 -04:00
}
2022-09-15 18:45:09 -04:00
else if ( ColumnId = = SourceControlFileViewColumn : : LastModifiedTimestamp : : Id ( ) )
{
return SNew ( STextBlock )
. ToolTipText ( this , & SOfflineFileTableRow : : GetLastModifiedTimestamp )
. Text ( this , & SOfflineFileTableRow : : GetLastModifiedTimestamp ) ;
}
else if ( ColumnId = = SourceControlFileViewColumn : : CheckedOutByUser : : Id ( ) )
{
return SNew ( STextBlock )
. Text ( FText : : GetEmpty ( ) ) ;
}
2023-01-31 01:26:50 -05:00
else if ( ColumnId = = SourceControlFileViewColumn : : Dirty : : Id ( ) )
{
if ( FUnsavedAssetsTrackerModule : : Get ( ) . IsAssetUnsaved ( GetFilename ( ) . ToString ( ) ) )
{
return SNew ( SBox )
. WidthOverride ( 16 ) // Small Icons are usually 16x16
. HAlign ( HAlign_Center )
[
SNew ( SImage )
. Image ( FAppStyle : : GetBrush ( FName ( " SourceControl.OfflineFile_Small " ) ) )
] ;
}
return SNew ( SBox )
. WidthOverride ( 16 ) ; // Small Icons are usually 16x16
}
else if ( ColumnId = = SourceControlFileViewColumn : : Discard : : Id ( ) )
{
FString Filename = TreeItem - > GetFullPathname ( ) ;
if ( ! FUnsavedAssetsTrackerModule : : Get ( ) . IsAssetUnsaved ( Filename ) )
{
return SNew ( SBox )
. WidthOverride ( 16 ) ; // Small Icons are usually 16x16
}
TSharedRef < SWidgetSwitcher > DiscardSwitcher = SNew ( SWidgetSwitcher ) ;
TSharedRef < SImage > DiscardButton = SNew ( SImage )
. DesiredSizeOverride ( FVector2D { 16.0f } )
. Image ( FAppStyle : : Get ( ) . GetBrush ( " Icons.XCircle " ) )
. ColorAndOpacity ( FSlateColor : : UseSubduedForeground ( ) )
. OnMouseButtonDown_Lambda ( [ this , DiscardSwitcher ] ( const FGeometry & , const FPointerEvent & ) - > FReply
{
2023-02-14 20:25:02 -05:00
// Normalize packagenames and filenames
FString PackageName ;
{
FString TreeName = TreeItem - > GetPackageName ( ) . ToString ( ) ;
if ( ! FPackageName : : TryConvertFilenameToLongPackageName ( TreeName , PackageName ) )
{
PackageName = MoveTemp ( TreeName ) ;
}
}
// Validate we have a saved map
2023-04-24 18:44:23 -04:00
if ( UPackage * Package = FindPackage ( nullptr , * PackageName ) )
2023-02-14 20:25:02 -05:00
{
2023-04-24 18:44:23 -04:00
UPackage * LevelPackage = Package - > GetOutermost ( ) ;
if ( LevelPackage = = GetTransientPackage ( )
| | LevelPackage - > HasAnyFlags ( RF_Transient )
| | ! FPackageName : : IsValidLongPackageName ( LevelPackage - > GetName ( ) ) )
{
FMessageDialog : : Open ( EAppMsgType : : Ok , LOCTEXT ( " DiscardUnsavedChangesSaveMap " , " You need to save the level before discarding unsaved changes. " ) ) ;
return FReply : : Handled ( ) ;
}
2023-02-14 20:25:02 -05:00
}
2023-01-31 01:26:50 -05:00
DiscardSwitcher - > SetActiveWidgetIndex ( 1 ) ;
2024-02-23 07:58:22 -05:00
ExecuteOnGameThread ( UE_SOURCE_LOCATION ,
2023-01-31 01:26:50 -05:00
[ this ]
{
TArray < FString > PackageToReload { TreeItem - > GetPackageName ( ) . ToString ( ) } ;
const bool bAllowReloadWorld = true ;
const bool bInteractive = false ;
USourceControlHelpers : : ApplyOperationAndReloadPackages (
PackageToReload ,
[ ] ( const TArray < FString > & ) - > bool { return true ; } ,
bAllowReloadWorld ,
bInteractive
) ;
2024-02-23 07:58:22 -05:00
} ) ;
2023-01-31 01:26:50 -05:00
return FReply : : Handled ( ) ;
} ) ;
DiscardSwitcher - > AddSlot ( ) [
DiscardButton
] ;
DiscardSwitcher - > AddSlot ( ) [
SNew ( SCircularThrobber )
. Radius ( 7.5f )
] ;
return
SNew ( SBox )
. WidthOverride ( 16 ) // Small Icons are usually 16x16
. Padding ( FMargin { 1 , 0 } )
. ToolTipText ( LOCTEXT ( " UnsavedAsset_DiscardChanges " , " Discard unsaved changes " ) )
[
DiscardSwitcher
] ;
}
2022-09-07 17:15:39 -04:00
else
{
return SNullWidget : : NullWidget ;
}
}
2022-09-12 18:11:36 -04:00
void SOfflineFileTableRow : : PopulateSearchString ( const FOfflineFileTreeItem & Item , TArray < FString > & OutStrings )
{
OutStrings . Emplace ( Item . GetDisplayName ( ) . ToString ( ) ) ; // Name
OutStrings . Emplace ( Item . GetDisplayPath ( ) . ToString ( ) ) ; // Path
OutStrings . Emplace ( Item . GetDisplayType ( ) . ToString ( ) ) ; // Type
2022-09-15 18:45:09 -04:00
OutStrings . Emplace ( Item . GetLastModifiedTimestamp ( ) . ToString ( ) ) ;
2022-09-12 18:11:36 -04:00
}
2022-09-07 17:15:39 -04:00
FText SOfflineFileTableRow : : GetDisplayName ( ) const
{
return TreeItem - > GetDisplayName ( ) ;
}
FText SOfflineFileTableRow : : GetFilename ( ) const
{
return TreeItem - > GetPackageName ( ) ;
}
FText SOfflineFileTableRow : : GetDisplayPath ( ) const
{
return TreeItem - > GetDisplayPath ( ) ;
}
FText SOfflineFileTableRow : : GetDisplayType ( ) const
{
return TreeItem - > GetDisplayType ( ) ;
}
FSlateColor SOfflineFileTableRow : : GetDisplayColor ( ) const
{
return TreeItem - > GetDisplayColor ( ) ;
}
2022-09-15 18:45:09 -04:00
FText SOfflineFileTableRow : : GetLastModifiedTimestamp ( ) const
{
return TreeItem - > GetLastModifiedTimestamp ( ) ;
}
2023-08-09 18:41:28 -04:00
void SOfflineFileTableRow : : OnDragEnter ( FGeometry const & InGeometry , FDragDropEvent const & InDragDropEvent )
{
TSharedPtr < FDragDropOperation > DragOperation = InDragDropEvent . GetOperation ( ) ;
DragOperation - > SetCursorOverride ( EMouseCursor : : SlashedCircle ) ;
}
void SOfflineFileTableRow : : OnDragLeave ( FDragDropEvent const & InDragDropEvent )
{
TSharedPtr < FDragDropOperation > DragOperation = InDragDropEvent . GetOperation ( ) ;
DragOperation - > SetCursorOverride ( EMouseCursor : : None ) ;
}
2022-09-15 18:45:09 -04:00
2022-09-07 17:15:39 -04:00
# undef LOCTEXT_NAMESPACE