2014-03-14 14:13:41 -04:00
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
# include "SourceControlWindowsPCH.h"
# include "AssetToolsModule.h"
# include "ISourceControlRevision.h"
/**
* Wrapper around data from ISourceControlRevision
*/
class FHistoryRevisionListViewItem
{
public :
/** Changelist description */
FString Description ;
/** User name of submitter */
FString UserName ;
/** Clientspec/workspace of submitter */
FString ClientSpec ;
/** File action for this revision (branch, delete, edit, etc.) */
FString Action ;
/** Date of this revision */
FDateTime Date ;
/** Number of this revision */
int32 RevisionNumber ;
/** Changelist number */
int32 ChangelistNumber ;
/** Filesize for this revision (0 in the event of a deletion) */
int32 FileSize ;
/**
* Constructor
*
* @ param InRevision File revision info . to populate this wrapper with
*/
FHistoryRevisionListViewItem ( const TSharedRef < ISourceControlRevision , ESPMode : : ThreadSafe > & InRevision )
{
Description = InRevision - > GetDescription ( ) ;
UserName = InRevision - > GetUserName ( ) ;
ClientSpec = InRevision - > GetClientSpec ( ) ;
Action = InRevision - > GetAction ( ) ;
Date = InRevision - > GetDate ( ) ;
RevisionNumber = InRevision - > GetRevisionNumber ( ) ;
ChangelistNumber = InRevision - > GetCheckInIdentifier ( ) ;
FileSize = InRevision - > GetFileSize ( ) ;
}
} ;
/**
* Managed mirror of FSourceControlFileHistoryInfo . Designed to represent the history of a file in
* a listview .
*/
class FHistoryFileListViewItem
{
public :
/** Depot name of the file */
FString FileName ;
/**
* Constructor
*
* @ param InState Source control state info to populate this managed mirror with
*/
FHistoryFileListViewItem ( const FSourceControlStateRef & InState )
{
FileName = InState - > GetFilename ( ) ;
}
} ;
/**
* A container class to use the tree view to represent a dynamically expandable nested list
*/
struct FHistoryTreeItem
{
// Only one of FileListItem or RevisionListItem should be set
/** Pointer to file info */
TSharedPtr < FHistoryFileListViewItem > FileListItem ;
/** Pointer to revision info */
TSharedPtr < FHistoryRevisionListViewItem > RevisionListItem ;
/** If we are a revision entry, pointer to file entry that owns us */
TWeakPtr < FHistoryTreeItem > Parent ;
/** List of revisions if we are file entry */
TArray < TSharedPtr < FHistoryTreeItem > > Children ;
} ;
/**
* Attempts to get a file list - item that represents the file that specified
* history - tree entry belongs to .
*
* @ param HistoryTreeItemIn The history - tree entry that you want a file item for .
* @ return The file list - item that the specified entry conceptually belongs to ( invalid if HistoryTreeItemIn was invalid ) .
*/
static TSharedPtr < FHistoryFileListViewItem > GetFileListItem ( TSharedPtr < FHistoryTreeItem > HistoryTreeItemIn )
{
TSharedPtr < FHistoryFileListViewItem > FileListItem ;
if ( HistoryTreeItemIn . IsValid ( ) )
{
FileListItem = HistoryTreeItemIn - > FileListItem ;
// if this isn't a file list-item itself
if ( ! FileListItem . IsValid ( ) )
{
// then it should have a parent that is one
TSharedPtr < FHistoryTreeItem > ParentFileItem = HistoryTreeItemIn - > Parent . Pin ( ) ;
check ( ParentFileItem . IsValid ( ) ) ;
check ( ParentFileItem - > FileListItem . IsValid ( ) ) ;
FileListItem = ParentFileItem - > FileListItem ;
}
}
return FileListItem ;
}
/**
* Takes a history - tree entry and attempts to find a corresponding asset object
* for the specified revision . If the specified history item doesn ' t have a valid
* RevisionListItem ( it ' s a file list - item ) , we take that to represent the current
* working version of the asset .
*
* @ param HistoryTreeItemIn The history - tree entry that you want a corresponding object for .
* @ return A UObject that represents the asset at the specified revision ( NULL if we failed to find / create one ) .
*/
static UObject * GetAssetRevisionObject ( TSharedPtr < FHistoryTreeItem > HistoryTreeItemIn )
{
UObject * AssetObject = NULL ;
if ( HistoryTreeItemIn . IsValid ( ) )
{
UPackage * AssetPackage = NULL ; // need a package to find the asset in
TSharedPtr < FHistoryFileListViewItem > FileListItem = GetFileListItem ( HistoryTreeItemIn ) ;
check ( FileListItem . IsValid ( ) ) ;
TSharedPtr < FHistoryRevisionListViewItem > RevisionListItem = HistoryTreeItemIn - > RevisionListItem ;
// if this item is referencing a specific revision (and not the current working version of the asset)
if ( RevisionListItem . IsValid ( ) ) // else,
{
// grab details on this file's state in source control (history, etc.)
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
FSourceControlStatePtr FileSourceControlState = SourceControlProvider . GetState ( FileListItem - > FileName , EStateCacheUsage : : Use ) ;
if ( FileSourceControlState . IsValid ( ) )
{
// lookup the specific revision we want
int32 RevisionNum = RevisionListItem - > RevisionNumber ;
TSharedPtr < ISourceControlRevision , ESPMode : : ThreadSafe > FileRevision = FileSourceControlState - > FindHistoryRevision ( RevisionNum ) ;
FString TempPackageName ;
if ( FileRevision . IsValid ( ) & & FileRevision - > Get ( TempPackageName ) ) // grab the path to a temporary package (where the revision item will be stored)
{
// forcibly disable compile on load in case we are loading old blueprints that might try to update/compile
TGuardValue < bool > DisableCompileOnLoad ( GForceDisableBlueprintCompileOnLoad , true ) ;
// try and load the temporary package
AssetPackage = LoadPackage ( NULL , * TempPackageName , LOAD_None ) ;
}
} // if FileSourceControlState.IsValid()
}
else // if we want the current working version of this asset
{
FString AssetPackageName = FPackageName : : FilenameToLongPackageName ( FileListItem - > FileName ) ;
AssetPackage = FindObject < UPackage > ( NULL , * AssetPackageName ) ;
}
// grab the asset from the package - we assume asset name matches file name
FString AssetName = FPaths : : GetBaseFilename ( FileListItem - > FileName ) ;
AssetObject = FindObject < UObject > ( AssetPackage , * AssetName ) ;
} // if HistoryTreeItemIn.IsValid()
return AssetObject ;
}
/**
* Constructs revision info for the specified history - tree entry .
*
* @ param HistoryTreeItemIn The history - tree entry that you want revision info for .
* @ param RevisionInfoOut The resulting revision info ( out ) .
*/
static void GetRevisionInfo ( TSharedPtr < FHistoryTreeItem > HistoryTreeItemIn , FRevisionInfo & RevisionInfoOut )
{
RevisionInfoOut . Revision = - 1 ; // clear the revision info (-1 is used signify the current working version)
// if this is a specific revision item
if ( HistoryTreeItemIn . IsValid ( ) & & HistoryTreeItemIn - > RevisionListItem . IsValid ( ) )
{
TSharedPtr < FHistoryRevisionListViewItem > RevisionListItem = HistoryTreeItemIn - > RevisionListItem ;
// fill out the revision info
RevisionInfoOut . Revision = RevisionListItem - > RevisionNumber ;
RevisionInfoOut . Changelist = RevisionListItem - > ChangelistNumber ;
RevisionInfoOut . Date = RevisionListItem - > Date ;
}
}
/**
* Takes a array of FHistoryTreeItems and determines if the entries can all be diffed against each other .
*
* @ param SelectedItems A array of FHistoryTreeItems that you want to diff against each other .
* @ param ErrorTextOut Text explaining why the selected items cannot be diffed ( only valid if the return value was false ) .
* @ return True if the selected items could be diffed against each other , false if not .
*/
static bool CanDiffSelectedItems ( TArray < TSharedPtr < FHistoryTreeItem > > const & SelectedItems , FText & ErrorTextOut )
{
bool bCanDiffSelected = false ;
if ( SelectedItems . Num ( ) > 2 )
{
ErrorTextOut = NSLOCTEXT ( " SourceControlHistory " , " TooManyToDiff " , " Cannot diff more than two revisions. " ) ;
}
else if ( SelectedItems . Num ( ) < 2 )
{
ErrorTextOut = NSLOCTEXT ( " SourceControlHistory " , " NotEnoughToDiff " , " Need to select two revisions in order to compare one against the other. " ) ;
}
else
{
TSharedPtr < FHistoryTreeItem > FirstSelection = SelectedItems [ 0 ] ;
TSharedPtr < FHistoryTreeItem > SecondSelection = SelectedItems [ 1 ] ;
if ( ! FirstSelection . IsValid ( ) | | ! SecondSelection . IsValid ( ) )
{
ErrorTextOut = NSLOCTEXT ( " SourceControlHistory " , " InvalidSelection " , " Invalid revisions selected. " ) ;
}
else if ( FirstSelection = = SecondSelection )
{
ErrorTextOut = NSLOCTEXT ( " SourceControlHistory " , " CannotDiffWithSelf " , " You cannot diff a revision against itself. " ) ;
}
else
{
// @TODO make sure the two selections match type (calling GetAssetRevisionObject() to compare class types is too slow)
bCanDiffSelected = true ;
}
}
return bCanDiffSelected ;
} ;
/**
* Takes two FHistoryTreeItems and attempts to diff them against each other ( bringing up the diff window ) .
*
* @ param FirstSelection The first item you want to diff .
* @ param SecondSelection The second item you want to diff .
* @ return True if a diff was performed , false if not .
*/
static bool DiffHistoryItems ( TSharedPtr < FHistoryTreeItem > const FirstSelection , TSharedPtr < FHistoryTreeItem > const SecondSelection )
{
bool bDiffPerformed = false ;
if ( FirstSelection . IsValid ( ) & & SecondSelection . IsValid ( ) )
{
TSharedPtr < FHistoryFileListViewItem > FirstSelectionFileItem = GetFileListItem ( FirstSelection ) ;
TSharedPtr < FHistoryFileListViewItem > SecondSelectionFileItem = GetFileListItem ( SecondSelection ) ;
// we want to make sure the two selections are presented in a sensible order
UObject * LeftDiffAsset = NULL ;
FRevisionInfo LeftVersionInfo ;
UObject * RightDiffAsset = NULL ;
FRevisionInfo RightVersionInfo ;
bool bIsForSingleAsset = ( FirstSelectionFileItem = = SecondSelectionFileItem ) ;
// if we're comparing two revisions for one asset
if ( bIsForSingleAsset )
{
bool bFirstSelectionIsCurrentVersion = FirstSelection - > FileListItem . IsValid ( ) ;
bool bSecondSelectionIsCurrentVersion = SecondSelection - > FileListItem . IsValid ( ) ;
// the second selection is the newer revision iff the first isn't the current working version, and
// it's either the current working version itself, or a newer revision
bool bSecondSelectionIsNewer = ! bFirstSelectionIsCurrentVersion & &
( bSecondSelectionIsCurrentVersion | | ( SecondSelection - > RevisionListItem - > RevisionNumber > FirstSelection - > RevisionListItem - > RevisionNumber ) ) ;
if ( bSecondSelectionIsNewer )
{
RightDiffAsset = GetAssetRevisionObject ( SecondSelection ) ;
GetRevisionInfo ( SecondSelection , RightVersionInfo ) ;
LeftDiffAsset = GetAssetRevisionObject ( FirstSelection ) ;
GetRevisionInfo ( FirstSelection , LeftVersionInfo ) ;
}
else
{
LeftDiffAsset = GetAssetRevisionObject ( SecondSelection ) ;
GetRevisionInfo ( SecondSelection , LeftVersionInfo ) ;
RightDiffAsset = GetAssetRevisionObject ( FirstSelection ) ;
GetRevisionInfo ( FirstSelection , RightVersionInfo ) ;
}
}
else // else, we're comparing revisions from two separate assets
{
// keep them in selection order (left to right)
LeftDiffAsset = GetAssetRevisionObject ( FirstSelection ) ;
GetRevisionInfo ( FirstSelection , LeftVersionInfo ) ;
RightDiffAsset = GetAssetRevisionObject ( SecondSelection ) ;
GetRevisionInfo ( SecondSelection , RightVersionInfo ) ;
}
// if we have an asset object for both selections
if ( ( LeftDiffAsset ! = NULL ) & & ( RightDiffAsset ! = NULL ) )
{
FAssetToolsModule & AssetToolsModule = FModuleManager : : LoadModuleChecked < FAssetToolsModule > ( TEXT ( " AssetTools " ) ) ;
AssetToolsModule . Get ( ) . DiffAssets ( LeftDiffAsset , RightDiffAsset , LeftVersionInfo , RightVersionInfo ) ;
bDiffPerformed = true ;
}
}
return bDiffPerformed ;
}
/**
* A FDragDropOperation that represents dragging a source - control history tree item around .
*/
2014-04-23 17:55:20 -04:00
class FSourceControlHistoryRowDragDropOp : public FDragDropOperation
2014-03-14 14:13:41 -04:00
{
private :
/**
* Stubbed private constructor ( in order to force use of the static New ( ) method ) .
*/
FSourceControlHistoryRowDragDropOp ( )
: PendingDropAction ( EDropAction : : None )
{
}
public :
/**
* Allocates and registers a new FSourceControlHistoryRowDragDropOp for use .
*
* @ return The newly allocated ( and registered ) instance .
*/
static TSharedRef < FSourceControlHistoryRowDragDropOp > New ( )
{
TSharedPtr < FSourceControlHistoryRowDragDropOp > NewOperation = MakeShareable ( new FSourceControlHistoryRowDragDropOp ) ;
NewOperation - > Construct ( ) ;
return NewOperation . ToSharedRef ( ) ;
}
2014-04-02 18:09:23 -04:00
DRAG_DROP_OPERATOR_TYPE ( FSourceControlHistoryRowDragDropOp , FDragDropOperation )
2014-03-14 14:13:41 -04:00
struct EDropAction
{
enum Type
{
None ,
Diff ,
} ;
} ;
/** An enum value detailing what operation is queued to happen (if this item is dropped) */
EDropAction : : Type PendingDropAction ;
/** The items that this operation is conceptually dragging around */
TArray < TSharedPtr < FHistoryTreeItem > > SelectedItems ;
/** Text to display with the widget being dragged around */
FText HoverText ;
/**
* Creates the visual widget that you drag around ( to help visualize the drag / drop operation .
*
* @ return A new slate widget representing the dragged item
*/
virtual TSharedPtr < SWidget > GetDefaultDecorator ( ) const OVERRIDE
{
return SNew ( SBorder )
. BorderImage ( FEditorStyle : : GetBrush ( " Graph.ConnectorFeedback.Border " ) )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. Padding ( 0 , 0 , 3 , 0 )
[
SNew ( SImage )
. Image ( this , & FSourceControlHistoryRowDragDropOp : : GetIcon )
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
[
SNew ( STextBlock )
. Text ( this , & FSourceControlHistoryRowDragDropOp : : GetHoverText )
]
] ;
}
/**
* Easy accessor function for getting at the HoverText variable ( provides a
* default one if HoverText is empty ) .
*
* @ return HoverText if it ' s not empty , otherwise : a default string describing that dropping would result in nothing .
*/
FText GetHoverText ( ) const
{
return ! HoverText . IsEmpty ( )
? HoverText
: NSLOCTEXT ( " SourceControlHistory " , " DropActionToolTip_InvalidDropTarget " , " Cannot drop here. " ) ;
}
/**
* Returns a icon brush corresponding to this operation ' s pending drop action .
*
* @ return An ' error ' icon if there is no pending action , otherwise an ' OK ' icon .
*/
FSlateBrush const * GetIcon ( ) const
{
return PendingDropAction ! = EDropAction : : None
? FEditorStyle : : GetBrush ( TEXT ( " Graph.ConnectorFeedback.OK " ) )
: FEditorStyle : : GetBrush ( TEXT ( " Graph.ConnectorFeedback.Error " ) ) ;
}
} ;
/**
* Class used to construct the ordered row content for revision data
*/
class SHistoryRevisionListRowContent : public SMultiColumnTableRow < TSharedPtr < FHistoryTreeItem > >
{
public :
SLATE_BEGIN_ARGS ( SHistoryRevisionListRowContent )
: _RevisionListItem ( )
{ }
SLATE_EVENT ( FOnDragDetected , OnDragDetected )
SLATE_EVENT ( FOnTableRowDragEnter , OnDragEnter )
SLATE_EVENT ( FOnTableRowDragLeave , OnDragLeave )
SLATE_EVENT ( FOnTableRowDrop , OnDrop )
SLATE_ARGUMENT ( TSharedPtr < FHistoryRevisionListViewItem > , RevisionListItem )
SLATE_END_ARGS ( )
/**
* Construct the widget
*
* @ param InArgs A declaration from which to construct the widget
*/
void Construct ( const FArguments & InArgs , const TSharedRef < STableViewBase > & InOwnerTableView )
{
RevisionListItem = InArgs . _RevisionListItem ;
check ( RevisionListItem . IsValid ( ) ) ;
SMultiColumnTableRow < TSharedPtr < FHistoryTreeItem > > : : Construct (
FSuperRowType : : FArguments ( )
. OnDragDetected ( InArgs . _OnDragDetected )
. OnDragEnter ( InArgs . _OnDragEnter )
. OnDragLeave ( InArgs . _OnDragLeave )
. OnDrop ( InArgs . _OnDrop ) ,
InOwnerTableView
) ;
}
virtual TSharedRef < SWidget > GenerateWidgetForColumn ( const FName & ColumnName ) OVERRIDE
{
check ( RevisionListItem . IsValid ( ) ) ;
if ( ColumnName = = TEXT ( " Revision " ) )
{
FString SCCAction = RevisionListItem - > Action ;
FName ResourceKey ;
if ( SCCAction = = FString ( TEXT ( " add " ) ) )
{
ResourceKey = TEXT ( " SourceControl.Add " ) ;
}
else if ( SCCAction = = FString ( TEXT ( " edit " ) ) )
{
ResourceKey = TEXT ( " SourceControl.Edit " ) ;
}
else if ( SCCAction = = FString ( TEXT ( " delete " ) ) )
{
ResourceKey = TEXT ( " SourceControl.Delete " ) ;
}
else if ( SCCAction = = FString ( TEXT ( " branch " ) ) )
{
ResourceKey = TEXT ( " SourceControl.Branch " ) ;
}
else if ( SCCAction = = FString ( TEXT ( " integrate " ) ) )
{
ResourceKey = TEXT ( " SourceControl.Integrate " ) ;
}
else
{
ResourceKey = TEXT ( " SourceControl.Edit " ) ;
}
// Rows in a tree need to show an SExpanderArrow (it also indents!) to give the appearance of being a tree.
return
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. Padding ( 10 , 0 , 10 , 0 )
. HAlign ( HAlign_Center )
. VAlign ( VAlign_Center )
[
SNew ( SImage )
. Image ( FEditorStyle : : GetBrush ( ResourceKey ) )
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
[
SNew ( STextBlock )
2014-04-23 18:30:01 -04:00
. Text ( FText : : AsNumber ( RevisionListItem - > RevisionNumber , NULL , FInternationalization : : Get ( ) . GetInvariantCulture ( ) ) )
2014-03-14 14:13:41 -04:00
] ;
}
else if ( ColumnName = = TEXT ( " Changelist " ) )
{
return
SNew ( STextBlock )
2014-04-23 18:30:01 -04:00
. Text ( FText : : AsNumber ( RevisionListItem - > ChangelistNumber , NULL , FInternationalization : : Get ( ) . GetInvariantCulture ( ) ) ) ;
2014-03-14 14:13:41 -04:00
}
else if ( ColumnName = = TEXT ( " Date " ) )
{
return
SNew ( STextBlock )
. Text ( FText : : AsDateTime ( RevisionListItem - > Date ) ) ;
}
else if ( ColumnName = = TEXT ( " UserName " ) )
{
return
SNew ( STextBlock )
. Text ( FText : : FromString ( RevisionListItem - > UserName ) ) ;
}
else if ( ColumnName = = TEXT ( " Description " ) )
{
//cut down to single line
FString Description = RevisionListItem - > Description ;
int32 NewLinePos ;
if ( Description . FindChar ( TCHAR ( ' \n ' ) , NewLinePos ) )
{
Description = Description . Left ( NewLinePos ) ;
}
return
SNew ( STextBlock )
. Text ( Description ) ;
}
else
{
return
SNew ( STextBlock )
. Text ( FText : : Format ( NSLOCTEXT ( " SourceControlHistory " , " UnsupportedColumn " , " Unsupported Column: {0} " ) , FText : : FromName ( ColumnName ) ) ) ;
}
}
private :
TSharedPtr < FHistoryRevisionListViewItem > RevisionListItem ;
} ;
/** Panel designed to display the revision history of a package */
class SSourceControlHistoryWidget : public SCompoundWidget
{
public :
SLATE_BEGIN_ARGS ( SSourceControlHistoryWidget )
: _ParentWindow ( )
, _SourceControlStates ( )
{ }
SLATE_ATTRIBUTE ( TSharedPtr < SWindow > , ParentWindow )
SLATE_ATTRIBUTE ( TArray < FSourceControlStateRef > , SourceControlStates )
SLATE_END_ARGS ( )
SSourceControlHistoryWidget ( )
{
}
void Construct ( const FArguments & InArgs )
{
AddHistoryInfo ( InArgs . _SourceControlStates . Get ( ) ) ;
ChildSlot
[
SNew ( SBorder )
. BorderImage ( FEditorStyle : : GetBrush ( " ToolPanel.GroupBorder " ) )
. BorderBackgroundColor ( FLinearColor ( 0.5f , 0.5f , 0.5f , 1.f ) )
[
SNew ( SSplitter )
. Orientation ( Orient_Vertical )
+ SSplitter : : Slot ( )
. Value ( 0.5f )
[
SNew ( SBorder )
[
SNew ( SBox )
. WidthOverride ( 600 )
[
SAssignNew ( MainHistoryListView , SHistoryFileListType )
. TreeItemsSource ( & HistoryCollection )
. ItemHeight ( 25.f )
. SelectionMode ( ESelectionMode : : Multi )
. OnSelectionChanged ( this , & SSourceControlHistoryWidget : : OnRevisionPropertyChanged )
. OnGenerateRow ( this , & SSourceControlHistoryWidget : : OnGenerateRowForHistoryFileList )
. OnGetChildren ( this , & SSourceControlHistoryWidget : : OnGetChildrenForHistoryFileList )
. OnContextMenuOpening ( this , & SSourceControlHistoryWidget : : OnCreateContextMenu )
. HeaderRow
(
SNew ( SHeaderRow )
+ SHeaderRow : : Column ( " Revision " ) . DefaultLabel ( NSLOCTEXT ( " SourceControl.HistoryPanel.Header " , " Revision " , " Revision " ) . ToString ( ) ) . FillWidth ( 100 )
+ SHeaderRow : : Column ( " Changelist " ) . DefaultLabel ( NSLOCTEXT ( " SourceControl.HistoryPanel.Header " , " Changelist " , " ChangeList " ) . ToString ( ) ) . FillWidth ( 150 )
+ SHeaderRow : : Column ( " Date " ) . DefaultLabel ( NSLOCTEXT ( " SourceControl.HistoryPanel.Header " , " Date " , " Date Submitted " ) . ToString ( ) ) . FillWidth ( 250 )
+ SHeaderRow : : Column ( " UserName " ) . DefaultLabel ( NSLOCTEXT ( " SourceControl.HistoryPanel.Header " , " UserName " , " Submitted By " ) . ToString ( ) ) . FillWidth ( 200 )
+ SHeaderRow : : Column ( " Description " ) . DefaultLabel ( NSLOCTEXT ( " SourceControl.HistoryPanel.Header " , " Description " , " Description " ) . ToString ( ) ) . FillWidth ( 300 )
)
]
]
]
+ SSplitter : : Slot ( )
. Value ( 0.5f )
[
SAssignNew ( AdditionalInfoItemsControl , SBorder )
. BorderImage ( FEditorStyle : : GetBrush ( " ToolPanel.GroupBorder " ) )
[
GetAdditionalInfoItemsControlContent ( )
]
]
]
] ;
//expand the top level nodes...
for ( int32 i = 0 ; i < HistoryCollection . Num ( ) ; i + + )
{
MainHistoryListView - > SetItemExpansion ( HistoryCollection [ i ] , true ) ;
}
}
private :
/**
* Constructs the " Additional Info " panel that displays specific revision info
*/
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
TSharedRef < SWidget > GetAdditionalInfoItemsControlContent ( )
{
const float Padding = 2.f ;
return
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. FillWidth ( 0.25f )
[
//Text Column
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControl.HistoryPanel.Info " , " Revision " , " Revision: " ) . ToString ( ) )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControl.HistoryPanel.Info " , " Date " , " Date Submitted: " ) . ToString ( ) )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControl.HistoryPanel.Info " , " SubmittedBy " , " Submitted By: " ) . ToString ( ) )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControl.HistoryPanel.Info " , " Action " , " Action: " ) . ToString ( ) )
]
]
+ SHorizontalBox : : Slot ( )
. FillWidth ( 0.25f )
. Padding ( 20 , 0 )
[
//Data column
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( this , & SSourceControlHistoryWidget : : GetRevisionNumber )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( this , & SSourceControlHistoryWidget : : GetDate )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( this , & SSourceControlHistoryWidget : : GetUserName )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( this , & SSourceControlHistoryWidget : : GetAction )
]
]
+ SHorizontalBox : : Slot ( )
. FillWidth ( 0.25f )
. Padding ( 50 , 0 )
[
//Text Column
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
//empty for spacing
SNullWidget : : NullWidget
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControl.HistoryPanel.Info " , " Changelist " , " Changelist: " ) . ToString ( ) )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControl.HistoryPanel.Info " , " Workspace " , " Workspace: " ) . ToString ( ) )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControl.HistoryPanel.Info " , " FileSize " , " File Size: " ) . ToString ( ) )
]
]
+ SHorizontalBox : : Slot ( )
. FillWidth ( 0.25f )
. Padding ( 20 , 0 )
[
//Data column
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
//empty for spacing
SNullWidget : : NullWidget
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( this , & SSourceControlHistoryWidget : : GetChangelistNumber )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( this , & SSourceControlHistoryWidget : : GetClientSpec )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 0.25f )
. Padding ( Padding )
[
SNew ( STextBlock )
. Text ( this , & SSourceControlHistoryWidget : : GetFileSize )
]
]
]
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
. Padding ( Padding , 10 , Padding , 5 )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControl.HistoryPanel.Info " , " Description " , " Description: " ) . ToString ( ) )
]
+ SVerticalBox : : Slot ( )
. FillHeight ( 1.0f )
[
SNew ( SBorder )
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
. Padding ( 5 )
[
SNew ( STextBlock )
. Text ( this , & SSourceControlHistoryWidget : : GetDescription )
]
]
]
;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
/** Get the last selected revision's revision number */
FString GetRevisionNumber ( ) const
{
if ( LastSelectedRevisionItem . IsValid ( ) )
{
return FString : : Printf ( TEXT ( " %d " ) , LastSelectedRevisionItem . Pin ( ) - > RevisionNumber ) ;
}
return FString ( " " ) ;
}
/** Get the last selected revision's date */
FString GetDate ( ) const
{
if ( LastSelectedRevisionItem . IsValid ( ) )
{
return LastSelectedRevisionItem . Pin ( ) - > Date . ToString ( TEXT ( " %m/%d/%Y %h:%M:%S %A " ) ) ;
}
return FString ( " " ) ;
}
/** Get the last selected revision's username */
FString GetUserName ( ) const
{
if ( LastSelectedRevisionItem . IsValid ( ) )
{
return LastSelectedRevisionItem . Pin ( ) - > UserName ;
}
return FString ( " " ) ;
}
/** Get the last selected revision's revision number */
FString GetAction ( ) const
{
if ( LastSelectedRevisionItem . IsValid ( ) )
{
return LastSelectedRevisionItem . Pin ( ) - > Action ;
}
return FString ( " " ) ;
}
/** Get the last selected revision's changelist number */
FString GetChangelistNumber ( ) const
{
if ( LastSelectedRevisionItem . IsValid ( ) )
{
return FString : : Printf ( TEXT ( " %d " ) , LastSelectedRevisionItem . Pin ( ) - > ChangelistNumber ) ;
}
return FString ( " " ) ;
}
/** Get the last selected revision's client spec */
FString GetClientSpec ( ) const
{
if ( LastSelectedRevisionItem . IsValid ( ) )
{
return LastSelectedRevisionItem . Pin ( ) - > ClientSpec ;
}
return FString ( " " ) ;
}
/** Get the last selected revision's file size */
FString GetFileSize ( ) const
{
if ( LastSelectedRevisionItem . IsValid ( ) )
{
return FString : : Printf ( TEXT ( " %.1f MB " ) , ( ( float ) LastSelectedRevisionItem . Pin ( ) - > FileSize ) / ( 1024.f * 1024.f ) ) ;
}
return FString ( " " ) ;
}
/** Get the last selected revision's description */
FString GetDescription ( ) const
{
if ( LastSelectedRevisionItem . IsValid ( ) )
{
return LastSelectedRevisionItem . Pin ( ) - > Description ;
}
return FString ( " " ) ;
}
/**
* Generates the content of each row , displaying a the File or Revision data for its corresponding type
*/
TSharedRef < ITableRow > OnGenerateRowForHistoryFileList ( TSharedPtr < FHistoryTreeItem > TreeItemPtr , const TSharedRef < STableViewBase > & OwnerTable )
{
TSharedPtr < SWidget > RowContent ;
if ( TreeItemPtr - > FileListItem . IsValid ( ) )
{
TSharedPtr < FHistoryFileListViewItem > FileListItem = TreeItemPtr - > FileListItem ;
return
SNew ( STableRow < TSharedPtr < FName > > , OwnerTable )
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
. Padding ( 5 )
[
SNew ( STextBlock )
. Font ( FEditorStyle : : GetFontStyle ( TEXT ( " BoldFont " ) ) )
. Text ( FileListItem - > FileName )
]
]
. OnDragDetected ( this , & SSourceControlHistoryWidget : : OnRowDragDetected )
. OnDragEnter ( this , & SSourceControlHistoryWidget : : OnRowDragEnter , TreeItemPtr )
. OnDragLeave ( this , & SSourceControlHistoryWidget : : OnRowDragLeave )
. OnDrop ( this , & SSourceControlHistoryWidget : : OnRowDrop , TreeItemPtr ) ;
}
else if ( TreeItemPtr - > RevisionListItem . IsValid ( ) )
{
TSharedPtr < FHistoryRevisionListViewItem > RevisionListItem = TreeItemPtr - > RevisionListItem ;
return
SNew ( SHistoryRevisionListRowContent , OwnerTable )
. RevisionListItem ( RevisionListItem )
. OnDragDetected ( this , & SSourceControlHistoryWidget : : OnRowDragDetected )
. OnDragEnter ( this , & SSourceControlHistoryWidget : : OnRowDragEnter , TreeItemPtr )
. OnDragLeave ( this , & SSourceControlHistoryWidget : : OnRowDragLeave )
. OnDrop ( this , & SSourceControlHistoryWidget : : OnRowDrop , TreeItemPtr ) ;
}
//we should never get here...
return
SNew ( STableRow < TSharedPtr < FName > > , OwnerTable )
[
SNew ( STextBlock )
. Text ( NSLOCTEXT ( " SourceControlHistory " , " ErrorMessage " , " ---ERROR--- " ) )
] ;
}
/**
* Fill out the tree structure with the SSC data
*/
void AddHistoryInfo ( const TArray < FSourceControlStateRef > & InStates )
{
// Construct a new observable collection to serve as the items source for the main list view. It will contain each history file item.
for ( TArray < FSourceControlStateRef > : : TConstIterator Iter ( InStates ) ; Iter ; Iter + + )
{
FSourceControlStateRef SourceControlState = * Iter ;
TSharedPtr < FHistoryTreeItem > FileItem = MakeShareable ( new FHistoryTreeItem ( ) ) ;
FileItem - > FileListItem = MakeShareable ( new FHistoryFileListViewItem ( SourceControlState ) ) ;
// Add each file revision
for ( int HistoryIndex = 0 ; HistoryIndex < SourceControlState - > GetHistorySize ( ) ; HistoryIndex + + )
{
TSharedPtr < ISourceControlRevision , ESPMode : : ThreadSafe > Revision = SourceControlState - > GetHistoryItem ( HistoryIndex ) ;
check ( Revision . IsValid ( ) ) ;
TSharedPtr < FHistoryTreeItem > RevisionItem = MakeShareable ( new FHistoryTreeItem ( ) ) ;
RevisionItem - > RevisionListItem = MakeShareable ( new FHistoryRevisionListViewItem ( Revision . ToSharedRef ( ) ) ) ;
FileItem - > Children . Add ( RevisionItem ) ;
RevisionItem - > Parent = FileItem ;
}
HistoryCollection . Add ( FileItem ) ;
}
}
/**
* Callback returns the revision history ( Children ) nodes for the file ( InItem ) node
*/
void OnGetChildrenForHistoryFileList ( TSharedPtr < FHistoryTreeItem > InItem , TArray < TSharedPtr < FHistoryTreeItem > > & OutChildren )
{
OutChildren = InItem - > Children ;
}
/**
* Called whenever the IsSelected property on a MHistoryRevisionListViewItem changes . Used to specify the last selected revision item .
*
* @ param Owner Object which triggered the event
* @ param Args Event arguments for the property change
*/
void OnRevisionPropertyChanged ( TSharedPtr < FHistoryTreeItem > Item , ESelectInfo : : Type SelectInfo )
{
LastSelectedRevisionItem . Reset ( ) ;
if ( Item . IsValid ( ) )
{
if ( Item - > RevisionListItem . IsValid ( ) )
{
LastSelectedRevisionItem = Item - > RevisionListItem ;
}
else if ( Item - > Children . Num ( ) > 0 & & Item - > Children [ 0 ] - > RevisionListItem . IsValid ( ) )
{
LastSelectedRevisionItem = Item - > Children [ 0 ] - > RevisionListItem ;
}
}
AdditionalInfoItemsControl - > SetContent ( GetAdditionalInfoItemsControlContent ( ) ) ;
}
/** Called to create a context menu when right-clicking on a history item */
TSharedPtr < SWidget > OnCreateContextMenu ( )
{
FMenuBuilder MenuBuilder ( true , NULL ) ;
MenuBuilder . AddMenuEntry (
NSLOCTEXT ( " SourceControl.HistoryWindow.Menu " , " DiffAgainstPrev " , " Diff Against Previous Revision " ) ,
NSLOCTEXT ( " SourceControl.HistoryWindow.Menu " , " DiffAgainstPrevTooltip " , " See changes between this revision and the previous one. " ) ,
FSlateIcon ( ) ,
FUIAction (
FExecuteAction : : CreateSP ( this , & SSourceControlHistoryWidget : : OnDiffAgainstPreviousRev ) ,
FCanExecuteAction : : CreateSP ( this , & SSourceControlHistoryWidget : : CanDiffAgainstPreviousRev )
)
) ;
if ( CanDiffSelected ( ) )
{
MenuBuilder . AddMenuEntry (
NSLOCTEXT ( " SourceControl.HistoryWindow.Menu " , " DiffSelected " , " Diff Selected " ) ,
NSLOCTEXT ( " SourceControl.HistoryWindow.Menu " , " DiffSelectedTooltip " , " Diff the two assets that you have selected. " ) ,
FSlateIcon ( ) ,
FUIAction (
FExecuteAction : : CreateSP ( this , & SSourceControlHistoryWidget : : OnDiffSelected )
)
) ;
}
return MenuBuilder . MakeWidget ( ) ;
}
/** See if we should enabled the 'diff against previous' option */
bool CanDiffAgainstPreviousRev ( ) const
{
// Only allow option if we selected one item and it was a revision, not a file entry
TArray < TSharedPtr < FHistoryTreeItem > > SelectedRevs = MainHistoryListView - > GetSelectedItems ( ) ;
return ( SelectedRevs . Num ( ) = = 1 & & SelectedRevs [ 0 ] . IsValid ( ) ) ;
}
/** Try and perfom a diff between the selected revision and the previous one */
void OnDiffAgainstPreviousRev ( )
{
TArray < TSharedPtr < FHistoryTreeItem > > SelectedRevs = MainHistoryListView - > GetSelectedItems ( ) ;
if ( SelectedRevs . Num ( ) > 0 & & SelectedRevs [ 0 ] . IsValid ( ) )
{
FAssetToolsModule & AssetToolsModule = FModuleManager : : LoadModuleChecked < FAssetToolsModule > ( TEXT ( " AssetTools " ) ) ;
TSharedPtr < FHistoryTreeItem > SelectedItem = SelectedRevs [ 0 ] ;
UObject * SelectedAsset = GetAssetRevisionObject ( SelectedItem ) ;
if ( SelectedItem - > RevisionListItem . IsValid ( ) )
{
TSharedPtr < FHistoryTreeItem > FileItem = SelectedItem - > Parent . Pin ( ) ;
check ( FileItem . IsValid ( ) ) ;
// Now we need to find previous revision
TSharedPtr < FHistoryTreeItem > PreRevisionItem ;
// First, find index of selected revision in its parent file item
// NB. 0 is newest, increasing index means older
int32 RevIndex = FileItem - > Children . Find ( SelectedItem ) ;
check ( RevIndex ! = INDEX_NONE ) ;
if ( RevIndex = = FileItem - > Children . Num ( ) - 1 ) // If oldest revision of this file
{
// .. see if we have an older file
int32 FileIndex = HistoryCollection . Find ( FileItem ) ;
check ( FileIndex ! = INDEX_NONE ) ;
// Do nothing if we selected the newest revision of the newest file...
if ( FileIndex < HistoryCollection . Num ( ) - 1 )
{
// Previous revision is a different file, so get the newest revision of the older file
TSharedPtr < FHistoryTreeItem > PrevFileItem = HistoryCollection [ FileIndex + 1 ] ;
check ( PrevFileItem . IsValid ( ) ) ;
if ( PrevFileItem - > Children . Num ( ) > 0 )
{
PreRevisionItem = PrevFileItem - > Children [ 0 ] ;
}
}
}
else
{
// Not the oldest revision of this file, grab the older entry and get revision number
PreRevisionItem = FileItem - > Children [ RevIndex + 1 ] ;
}
UObject * PreviousAsset = GetAssetRevisionObject ( PreRevisionItem ) ;
if ( ( SelectedAsset ! = NULL ) & & ( PreviousAsset ! = NULL ) )
{
FRevisionInfo OldRevisionInfo ;
GetRevisionInfo ( PreRevisionItem , OldRevisionInfo ) ;
FRevisionInfo NewRevisionInfo ;
GetRevisionInfo ( SelectedItem , NewRevisionInfo ) ;
AssetToolsModule . Get ( ) . DiffAssets ( PreviousAsset , SelectedAsset , OldRevisionInfo , NewRevisionInfo ) ;
}
else
{
FMessageDialog : : Open ( EAppMsgType : : Ok , NSLOCTEXT ( " SourceControl.HistoryWindow " , " UnableToLoadAssets " , " Unable to load assets to diff. Content may no longer be supported? " ) ) ;
}
}
else if ( SelectedAsset ! = NULL )
{
// this should be a file list-item (representing the current working version)
check ( SelectedItem - > FileListItem . IsValid ( ) ) ;
FString const AssetName = SelectedAsset - > GetName ( ) ;
FString const PackageName = FPackageName : : FilenameToLongPackageName ( SelectedItem - > FileListItem - > FileName ) ;
AssetToolsModule . Get ( ) . DiffAgainstDepot ( SelectedAsset , PackageName , AssetName ) ;
}
}
}
/**
* Checks to see if the selected history - tree items can be diff ' d against each other .
*
* @ return True if the selected items can be diff ' d , false if not .
*/
bool CanDiffSelected ( ) const
{
// throw away text so we can utilize a shared utility method
FText ThrowAwayErrorText ;
TArray < TSharedPtr < FHistoryTreeItem > > SelectedRevs = MainHistoryListView - > GetSelectedItems ( ) ;
return CanDiffSelectedItems ( SelectedRevs , ThrowAwayErrorText ) ;
}
/**
* Takes the two selected history items and finds a UObject asset for each ,
* then attempts to open a diff window to compare them .
*/
void OnDiffSelected ( ) const
{
TArray < TSharedPtr < FHistoryTreeItem > > SelectedRevs = MainHistoryListView - > GetSelectedItems ( ) ;
if ( SelectedRevs . Num ( ) > = 2 )
{
if ( ! DiffHistoryItems ( SelectedRevs [ 0 ] , SelectedRevs [ 1 ] ) )
{
FMessageDialog : : Open ( EAppMsgType : : Ok , NSLOCTEXT ( " SourceControl.HistoryWindow " , " UnableToLoadAssets " , " Unable to load assets to diff. Content may no longer be supported? " ) ) ;
}
}
}
/**
* An event handler for mouse drag detection events . Intended to be used as a delegate for
* history tree rows . Creates a FSourceControlHistoryRowDragDropOp ( if the drag was with
* the left mouse - button ) and assumes that all the selected items are the objects being dragged .
*
* @ param MyGeometry The geometry for the dragged widget .
* @ param MouseEvent Describes the mouse drag action ( from when the drag was detected ) .
* @ return A reply detailing how this event was handled ( " Unhandled " if the click was not a left - click ) .
*/
FReply OnRowDragDetected ( FGeometry const & MyGeometry , FPointerEvent const & MouseEvent ) const
{
if ( MouseEvent . IsMouseButtonDown ( EKeys : : LeftMouseButton ) ) //can only drag when editing
{
TSharedRef < FSourceControlHistoryRowDragDropOp > DragOperation = FSourceControlHistoryRowDragDropOp : : New ( ) ;
// assume that what we're dragging is what we have selected
DragOperation - > SelectedItems = MainHistoryListView - > GetSelectedItems ( ) ;
check ( DragOperation - > SelectedItems . Num ( ) > 0 ) ;
return FReply : : Handled ( ) . BeginDragDrop ( DragOperation ) ;
}
else
{
return FReply : : Unhandled ( ) ;
}
}
/**
* An event handler for mouse drag enter events . Intended to be used as a delegate for
* history tree rows . Only handles FSourceControlHistoryRowDragDropOp drag / drop operations .
* Updates the FSourceControlHistoryRowDragDropOp to reflect if a drop action is doable
* ( when over this item ) .
*
* @ param DragDropEvent The drag / drop operation that triggered this handler .
* @ param HoveredItem The history tree item that is conceptually being hovered over .
*/
void OnRowDragEnter ( FDragDropEvent const & DragDropEvent , TSharedPtr < FHistoryTreeItem > const HoveredItem ) const
{
2014-04-23 18:00:50 -04:00
TSharedPtr < FSourceControlHistoryRowDragDropOp > DragRowOp = DragDropEvent . GetOperationAs < FSourceControlHistoryRowDragDropOp > ( ) ;
if ( DragRowOp . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
DragRowOp - > PendingDropAction = FSourceControlHistoryRowDragDropOp : : EDropAction : : None ;
TArray < TSharedPtr < FHistoryTreeItem > > DiffingItems = DragRowOp - > SelectedItems ;
check ( HoveredItem . IsValid ( ) ) ;
DiffingItems . Add ( HoveredItem ) ;
if ( CanDiffSelectedItems ( DiffingItems , DragRowOp - > HoverText ) )
{
DragRowOp - > PendingDropAction = FSourceControlHistoryRowDragDropOp : : EDropAction : : Diff ;
FText const RevisionFormatText = NSLOCTEXT ( " SourceControlHistory " , " Revision " , " Revision {0} " ) ;
FText const CurrentRevisionText = NSLOCTEXT ( " SourceControlHistory " , " CurrentRevsion " , " Current Revision " ) ;
check ( DragRowOp - > SelectedItems . Num ( ) > 0 ) ;
TSharedPtr < FHistoryTreeItem > DraggedItem = DiffingItems [ 0 ] ;
// set text identifying the dragged item's revision (current version vs. revision X)
FText DraggedRevisionText = CurrentRevisionText ;
if ( DraggedItem - > RevisionListItem . IsValid ( ) )
{
DraggedRevisionText = FText : : Format ( RevisionFormatText , FText : : AsNumber ( DraggedItem - > RevisionListItem - > RevisionNumber ) ) ;
}
// set text identifying the hovered item's revision (current version vs. revision X)
FText HoveredRevisionText = CurrentRevisionText ;
if ( HoveredItem - > RevisionListItem . IsValid ( ) )
{
HoveredRevisionText = FText : : Format ( RevisionFormatText , FText : : AsNumber ( HoveredItem - > RevisionListItem - > RevisionNumber ) ) ;
}
TSharedPtr < FHistoryFileListViewItem > const DraggedFileItem = GetFileListItem ( DraggedItem ) ;
// convert DraggedRevisionText from the form "revision X" (or "the current version") to
// "revision X of <filename>"
FString const DraggedFileName = FPaths : : GetBaseFilename ( DraggedFileItem - > FileName ) ;
FText const NamedRevisionTextFormat = NSLOCTEXT ( " SourceControlHistory " , " NamedRevision " , " {0} ({1}) " ) ;
DraggedRevisionText = FText : : Format ( NamedRevisionTextFormat , FText : : FromString ( DraggedFileName ) , DraggedRevisionText ) ;
TSharedPtr < FHistoryFileListViewItem > const HoveredFileItem = GetFileListItem ( HoveredItem ) ;
// if we're diffing two separate files against each other
if ( DraggedFileItem ! = HoveredFileItem )
{
// need to separately identify the hovered over item
FString const HoveredFileName = FPaths : : GetBaseFilename ( HoveredFileItem - > FileName ) ;
HoveredRevisionText = FText : : Format ( NamedRevisionTextFormat , FText : : FromString ( HoveredFileName ) , HoveredRevisionText ) ;
}
FText const DropToDiffTextFormat = NSLOCTEXT ( " SourceControlHistory " , " DropToDiff " , " Drop {0} to diff against: {1}. " ) ;
DragRowOp - > HoverText = FText : : Format ( DropToDiffTextFormat , DraggedRevisionText , HoveredRevisionText ) ;
}
}
}
/**
* An event handler for mouse drag leave events . Intended to be used as a delegate for
* history tree rows . Only handles FSourceControlHistoryRowDragDropOp drag / drop operations .
* Clears any pending drop actions from the FSourceControlHistoryRowDragDropOp .
*
* @ param DragDropEvent The drag / drop operation that triggered this handler .
*/
void OnRowDragLeave ( FDragDropEvent const & DragDropEvent ) const
{
2014-04-23 18:00:50 -04:00
TSharedPtr < FSourceControlHistoryRowDragDropOp > DragRowOp = DragDropEvent . GetOperationAs < FSourceControlHistoryRowDragDropOp > ( ) ;
if ( DragRowOp . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
DragRowOp - > HoverText = FText : : GetEmpty ( ) ;
DragRowOp - > PendingDropAction = FSourceControlHistoryRowDragDropOp : : EDropAction : : None ;
}
}
/**
* An event handler for mouse drop events . Intended to be used as a delegate for
* history tree rows . Only handles FSourceControlHistoryRowDragDropOp drag / drop operations .
* Executes the pending FSourceControlHistoryRowDragDropOp action ( diff , etc . )
*
* @ param DragDropEvent The drag / drop operation that triggered this handler .
* @ param HoveredItem The history tree item that is conceptually being dropped on to .
* @ return A reply detailing how this event was handled ( " Unhandled " if the operation was not a FSourceControlHistoryRowDragDropOp ) .
*/
FReply OnRowDrop ( FDragDropEvent const & DragDropEvent , TSharedPtr < FHistoryTreeItem > const HoveredItem ) const
{
2014-04-23 18:00:50 -04:00
TSharedPtr < FSourceControlHistoryRowDragDropOp > DragRowOp = DragDropEvent . GetOperationAs < FSourceControlHistoryRowDragDropOp > ( ) ;
if ( DragRowOp . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
if ( DragRowOp - > PendingDropAction = = FSourceControlHistoryRowDragDropOp : : EDropAction : : Diff )
{
check ( DragRowOp - > SelectedItems . Num ( ) > 0 ) ;
DiffHistoryItems ( DragRowOp - > SelectedItems [ 0 ] , HoveredItem ) ;
return FReply : : Handled ( ) ;
}
}
return FReply : : Unhandled ( ) ;
}
/** Main list view of the panel, displays each file history item */
typedef STreeView < TSharedPtr < FHistoryTreeItem > > SHistoryFileListType ;
/** ListBox for selecting which object to consolidate */
TSharedPtr < SHistoryFileListType > MainHistoryListView ;
/** Items control for the "additional information" subpanel */
TSharedPtr < SBorder > AdditionalInfoItemsControl ;
/** All file history items the panel should display */
TArray < TSharedPtr < FHistoryTreeItem > > HistoryCollection ;
/** The last selected revision item; Displayed in the "additional information" subpanel */
TWeakPtr < FHistoryRevisionListViewItem > LastSelectedRevisionItem ;
} ;
void FSourceControlWindows : : DisplayRevisionHistory ( const TArray < FString > & InPackageNames )
{
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
// Query for the file history for the provided packages
TArray < FString > PackageFilenames = SourceControlHelpers : : PackageFilenames ( InPackageNames ) ;
TSharedRef < FUpdateStatus , ESPMode : : ThreadSafe > UpdateStatusOperation = ISourceControlOperation : : Create < FUpdateStatus > ( ) ;
UpdateStatusOperation - > SetUpdateHistory ( true ) ;
if ( SourceControlProvider . Execute ( UpdateStatusOperation , PackageFilenames ) )
{
TArray < FSourceControlStateRef > SourceControlStates ;
SourceControlProvider . GetState ( PackageFilenames , SourceControlStates , EStateCacheUsage : : Use ) ;
TSharedRef < SWindow > NewWindow = SNew ( SWindow )
. Title ( NSLOCTEXT ( " SourceControl.HistoryWindow " , " Title " , " File History " ) )
. SizingRule ( ESizingRule : : UserSized )
. AutoCenter ( EAutoCenter : : PreferredWorkArea )
. ClientSize ( FVector2D ( 700 , 400 ) ) ;
TSharedRef < SSourceControlHistoryWidget > SourceControlWidget =
SNew ( SSourceControlHistoryWidget )
. ParentWindow ( NewWindow )
. SourceControlStates ( SourceControlStates ) ;
NewWindow - > SetContent ( SourceControlWidget ) ;
TSharedPtr < SWindow > RootWindow = FGlobalTabmanager : : Get ( ) - > GetRootWindow ( ) ;
if ( RootWindow . IsValid ( ) )
{
FSlateApplication : : Get ( ) . AddWindowAsNativeChild ( NewWindow , RootWindow . ToSharedRef ( ) ) ;
}
else
{
FSlateApplication : : Get ( ) . AddWindow ( NewWindow ) ;
}
}
}