2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-05-21 08:45:24 -04:00
# include "UnrealSync.h"
2014-10-14 22:50:06 -04:00
# include "SlateBasics.h"
2014-05-21 08:45:24 -04:00
# include "StandaloneRenderer.h"
# include "LaunchEngineLoop.h"
2014-06-04 11:01:22 -04:00
# include "P4Env.h"
# include "ProcessHelper.h"
2014-10-14 22:50:06 -04:00
# include "SWidgetSwitcher.h"
# include "SDockTab.h"
# include "SlateFwd.h"
2015-04-14 09:13:30 -04:00
# include "SThrobber.h"
2015-04-17 02:54:15 -04:00
# include "SMultiLineEditableTextBox.h"
# include "BaseTextLayoutMarshaller.h"
/**
* Syncing log .
*/
class SSyncLog : public SCompoundWidget
{
public :
SLATE_BEGIN_ARGS ( SSyncLog ) { }
SLATE_END_ARGS ( )
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void Construct ( const FArguments & InArgs )
{
MessagesTextMarshaller = MakeShareable ( new FMarshaller ( ) ) ;
MessagesTextBox = SNew ( SMultiLineEditableTextBox )
. IsReadOnly ( true )
. AlwaysShowScrollbars ( true )
. Marshaller ( MessagesTextMarshaller ) ;
2015-04-21 05:11:57 -04:00
Clear ( ) ;
2015-04-17 02:54:15 -04:00
ChildSlot
[
MessagesTextBox . ToSharedRef ( )
] ;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
/**
* Adding messages to the log .
*
* @ param Message Message to add .
*/
void AddMessage ( const FString & Message )
{
MessagesTextMarshaller - > AddMessage ( Message ) ;
2015-04-21 05:11:57 -04:00
MessagesTextBox - > ScrollTo ( FTextLocation ( NumberOfLines + + ) ) ;
2015-04-17 02:54:15 -04:00
}
/**
* Clear the log .
*/
void Clear ( )
{
NumberOfLines = 0 ;
2015-04-21 05:11:57 -04:00
MessagesTextBox - > ScrollTo ( FTextLocation ( 0 ) ) ;
2015-04-17 02:54:15 -04:00
MessagesTextMarshaller - > Clear ( ) ;
MessagesTextBox - > Refresh ( ) ;
}
private :
/**
* Messages marshaller .
*/
class FMarshaller : public FBaseTextLayoutMarshaller
{
public :
void AddMessage ( const FString & Message )
{
auto NormalText = FTextBlockStyle ( )
. SetFont ( " Fonts/Roboto-Regular " , 10 )
. SetColorAndOpacity ( FSlateColor : : UseForeground ( ) )
. SetShadowOffset ( FVector2D : : ZeroVector )
. SetShadowColorAndOpacity ( FLinearColor : : Black ) ;
TSharedRef < FString > LineText = MakeShareable ( new FString ( Message ) ) ;
TArray < TSharedRef < IRun > > Runs ;
Runs . Add ( FSlateTextRun : : Create ( FRunInfo ( ) , LineText , NormalText ) ) ;
2015-04-21 05:11:57 -04:00
if ( Layout - > IsEmpty ( ) )
{
Layout - > ClearLines ( ) ;
}
2015-04-17 02:54:15 -04:00
Layout - > AddLine ( LineText , Runs ) ;
}
/**
* Clears messages from the text box .
*/
void Clear ( )
{
MakeDirty ( ) ;
}
private :
// FBaseTextLayoutMarshaller missing virtuals.
virtual void SetText ( const FString & SourceString , FTextLayout & TargetTextLayout )
{
// Get text layout.
Layout = & TargetTextLayout ;
}
virtual void GetText ( FString & TargetString , const FTextLayout & SourceTextLayout )
{
SourceTextLayout . GetAsText ( TargetString ) ;
}
FTextLayout * Layout ;
} ;
/** Converts the array of messages into something the text box understands */
TSharedPtr < FMarshaller > MessagesTextMarshaller ;
/** The editable text showing all log messages */
TSharedPtr < SMultiLineEditableTextBox > MessagesTextBox ;
/** Number of currently logged lines. */
int32 NumberOfLines = 0 ;
} ;
2014-06-04 11:01:22 -04:00
2015-04-14 10:57:29 -04:00
/**
* Performs a dialog when running editor is detected .
*/
class SEditorRunningDlg : public SCompoundWidget
{
public :
enum class EResponse
{
ForceSync ,
Retry ,
Cancel
} ;
SLATE_BEGIN_ARGS ( SEditorRunningDlg ) { }
SLATE_ATTRIBUTE ( TSharedPtr < SWindow > , ParentWindow )
SLATE_ATTRIBUTE ( FText , Message )
SLATE_ATTRIBUTE ( float , WrapMessageAt )
SLATE_END_ARGS ( )
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void Construct ( const FArguments & InArgs )
{
ParentWindow = InArgs . _ParentWindow . Get ( ) ;
ParentWindow - > SetWidgetToFocusOnActivate ( SharedThis ( this ) ) ;
Response = EResponse : : Retry ;
FSlateFontInfo MessageFont ( FCoreStyle : : Get ( ) . GetFontStyle ( " StandardDialog.LargeFont " ) ) ;
this - > ChildSlot
[
SNew ( SBorder )
. BorderImage ( FCoreStyle : : Get ( ) . GetBrush ( " ToolPanel.GroupBorder " ) )
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. HAlign ( HAlign_Fill )
. VAlign ( VAlign_Fill )
. FillHeight ( 1.0f )
. MaxHeight ( 550 )
. Padding ( 12.0f )
[
SNew ( SScrollBox )
+ SScrollBox : : Slot ( )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " UE4EditorInstanceDetectedDialog " , " UE4Editor detected currently running on the system. Please close it before proceeding. " ) )
. Font ( MessageFont )
. WrapTextAt ( InArgs . _WrapMessageAt )
]
]
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
. Padding ( 0.0f )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. HAlign ( HAlign_Right )
. VAlign ( VAlign_Bottom )
. Padding ( 2.f )
[
SNew ( SUniformGridPanel )
. SlotPadding ( FCoreStyle : : Get ( ) . GetMargin ( " StandardDialog.SlotPadding " ) )
. MinDesiredSlotWidth ( FCoreStyle : : Get ( ) . GetFloat ( " StandardDialog.MinDesiredSlotWidth " ) )
. MinDesiredSlotHeight ( FCoreStyle : : Get ( ) . GetFloat ( " StandardDialog.MinDesiredSlotHeight " ) )
+ SUniformGridPanel : : Slot ( 0 , 0 )
[
SNew ( SButton )
. Text ( LOCTEXT ( " CancelSync " , " Cancel sync " ) )
. OnClicked ( this , & SEditorRunningDlg : : HandleButtonClicked , EResponse : : Cancel )
. ContentPadding ( FCoreStyle : : Get ( ) . GetMargin ( " StandardDialog.ContentPadding " ) )
. HAlign ( HAlign_Center )
]
+ SUniformGridPanel : : Slot ( 1 , 0 )
[
SNew ( SButton )
. Text ( LOCTEXT ( " RetryEditorRunning " , " Retry if editor is running " ) )
. OnClicked ( this , & SEditorRunningDlg : : HandleButtonClicked , EResponse : : Retry )
. ContentPadding ( FCoreStyle : : Get ( ) . GetMargin ( " StandardDialog.ContentPadding " ) )
. HAlign ( HAlign_Center )
]
+ SUniformGridPanel : : Slot ( 2 , 0 )
[
SNew ( SButton )
. Text ( LOCTEXT ( " ForceSync " , " Force sync " ) )
. OnClicked ( this , & SEditorRunningDlg : : HandleButtonClicked , EResponse : : ForceSync )
. ContentPadding ( FCoreStyle : : Get ( ) . GetMargin ( " StandardDialog.ContentPadding " ) )
. HAlign ( HAlign_Center )
]
]
]
]
] ;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
/**
* Shows modal dialog window and gets it ' s response .
*/
static EResponse ShowAndGetResponse ( )
{
TSharedPtr < SWindow > OutWindow = SNew ( SWindow )
. Title ( LOCTEXT ( " UE4EditorInstanceDetected " , " UE4Editor instance detected! " ) )
. SizingRule ( ESizingRule : : Autosized )
. AutoCenter ( EAutoCenter : : PreferredWorkArea )
. SupportsMinimize ( false ) . SupportsMaximize ( false ) ;
TSharedPtr < SEditorRunningDlg > OutDialog = SNew ( SEditorRunningDlg )
. ParentWindow ( OutWindow )
. WrapMessageAt ( 512.0f ) ;
OutWindow - > SetContent ( OutDialog . ToSharedRef ( ) ) ;
FSlateApplication : : Get ( ) . AddModalWindow ( OutWindow . ToSharedRef ( ) , FGlobalTabmanager : : Get ( ) - > GetRootWindow ( ) ) ;
return OutDialog - > GetResponse ( ) ;
}
private :
/**
* Gets response from this dialog widget .
*
* @ returns Response .
*/
EResponse GetResponse ( ) const
{
return Response ;
}
/**
* Handles button click on any dialog button .
*/
FReply HandleButtonClicked ( EResponse Response )
{
this - > Response = Response ;
ParentWindow - > RequestDestroyWindow ( ) ;
return FReply : : Handled ( ) ;
}
/** Parent window pointer */
TSharedPtr < SWindow > ParentWindow ;
/** Saved response */
EResponse Response ;
} ;
2014-05-21 08:45:24 -04:00
/**
* Simple text combo box widget .
*/
class SSimpleTextComboBox : public SCompoundWidget
{
/* Delegate for selection changed event. */
DECLARE_DELEGATE_TwoParams ( FOnSelectionChanged , int32 , ESelectInfo : : Type ) ;
SLATE_BEGIN_ARGS ( SSimpleTextComboBox ) { }
SLATE_EVENT ( FOnSelectionChanged , OnSelectionChanged )
SLATE_END_ARGS ( )
public :
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void Construct ( const FArguments & InArgs )
{
OnSelectionChanged = InArgs . _OnSelectionChanged ;
this - > ChildSlot
[
SNew ( SComboBox < TSharedPtr < FString > > )
. OptionsSource ( & OptionsSource )
. OnSelectionChanged ( this , & SSimpleTextComboBox : : ComboBoxSelectionChanged )
. OnGenerateWidget ( this , & SSimpleTextComboBox : : MakeWidgetFromOption )
[
SNew ( STextBlock ) . Text ( this , & SSimpleTextComboBox : : GetCurrentFTextOption )
]
] ;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
/**
* Adds value to the options source .
*
* @ param Value Value to add .
*/
void Add ( const FString & Value )
{
2015-04-21 08:10:22 -04:00
CurrentOption = 0 ;
2014-05-21 08:45:24 -04:00
OptionsSource . Add ( MakeShareable ( new FString ( Value ) ) ) ;
}
/**
* Gets current option value .
*
* @ returns Reference to current option value .
*/
const FString & GetCurrentOption ( ) const
{
return * OptionsSource [ CurrentOption ] ;
}
/**
* Checks if options source is empty .
*
* @ returns True if options source is empty . False otherwise .
*/
bool IsEmpty ( )
{
return OptionsSource . Num ( ) = = 0 ;
}
/**
* Clears the options source .
*/
void Clear ( )
{
2015-04-21 08:10:22 -04:00
CurrentOption = - 1 ;
2014-05-21 08:45:24 -04:00
OptionsSource . Empty ( ) ;
}
private :
/**
* Combo box selection changed event handling .
*
* @ param Value Value of the picked selection .
* @ param SelectInfo Selection info enum .
*/
void ComboBoxSelectionChanged ( TSharedPtr < FString > Value , ESelectInfo : : Type SelectInfo )
{
2014-06-05 12:11:12 -04:00
CurrentOption = - 1 ;
for ( int32 OptionId = 0 ; OptionId < OptionsSource . Num ( ) ; + + OptionId )
{
if ( OptionsSource [ OptionId ] - > Equals ( * Value ) )
{
CurrentOption = OptionId ;
}
}
2014-05-21 08:45:24 -04:00
OnSelectionChanged . ExecuteIfBound ( CurrentOption , SelectInfo ) ;
}
/**
* Coverts given value into widget .
*
* @ param Value Value of the option .
*
* @ return Widget .
*/
TSharedRef < SWidget > MakeWidgetFromOption ( TSharedPtr < FString > Value )
{
return SNew ( STextBlock ) . Text ( FText : : FromString ( * Value ) ) ;
}
/**
* Gets current option converted to FText class .
*
* @ returns Current option converted to FText class .
*/
FText GetCurrentFTextOption ( ) const
{
return FText : : FromString ( OptionsSource . Num ( ) = = 0 ? " " : GetCurrentOption ( ) ) ;
}
/* Currently selected option. */
int32 CurrentOption = 0 ;
/* Array of options. */
TArray < TSharedPtr < FString > > OptionsSource ;
/* Delegate that will be called when selection had changed. */
FOnSelectionChanged OnSelectionChanged ;
} ;
/**
* Widget to store and select enabled widgets by radio buttons .
*/
class SRadioContentSelection : public SCompoundWidget
{
public :
DECLARE_DELEGATE_OneParam ( FOnSelectionChanged , int32 ) ;
/**
* Radio content selection item .
*/
class FItem : public TSharedFromThis < FItem >
{
public :
/**
* Constructor
*
* @ param Parent Parent SRadioContentSelection widget reference .
* @ param Id Id of the item .
* @ param Name Name of the item .
* @ param Content Content widget to store by this item .
*/
2015-04-21 08:10:22 -04:00
FItem ( SRadioContentSelection & Parent , int32 Id , FText Name , TSharedRef < SWidget > Content )
2014-05-21 08:45:24 -04:00
: Parent ( Parent ) , Id ( Id ) , Name ( Name ) , Content ( Content )
{
}
/**
* Item initialization method .
*/
void Init ( )
{
Disable ( ) ;
WholeItemWidget = SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( ) . AutoHeight ( )
[
SNew ( SCheckBox )
2015-04-09 02:24:25 -04:00
. Style ( FCoreStyle : : Get ( ) , " RadioButton " )
2014-05-21 08:45:24 -04:00
. OnCheckStateChanged ( this , & FItem : : OnCheckStateChange )
. IsChecked ( this , & FItem : : IsCheckboxChecked )
[
SNew ( STextBlock )
2015-04-21 08:10:22 -04:00
. Text ( Name )
2014-05-21 08:45:24 -04:00
]
]
2015-04-09 02:24:25 -04:00
+ SVerticalBox : : Slot ( ) . VAlign ( VAlign_Fill ) . Padding ( 19.0f , 2.0f , 2.0f , 2.0f )
2014-05-21 08:45:24 -04:00
[
GetContent ( )
] ;
}
/**
* Gets this item content widget .
*
* @ returns Content widget .
*/
TSharedRef < SWidget > GetContent ( )
{
return Content ;
}
/**
* Gets widget that represents this item .
*
* @ returns Widget that represents this item .
*/
TSharedRef < SWidget > GetWidget ( )
{
return WholeItemWidget . ToSharedRef ( ) ;
}
/**
* Enables this item .
*/
void Enable ( )
{
GetContent ( ) - > SetEnabled ( true ) ;
}
/**
* Disables this item .
*/
void Disable ( )
{
GetContent ( ) - > SetEnabled ( false ) ;
}
/**
* Tells if check box needs to be in checked state .
*
* @ returns State of the check box enum .
*/
2014-12-10 14:24:09 -05:00
ECheckBoxState IsCheckboxChecked ( ) const
2014-05-21 08:45:24 -04:00
{
return Parent . GetChosen ( ) = = Id
2014-12-10 14:24:09 -05:00
? ECheckBoxState : : Checked
: ECheckBoxState : : Unchecked ;
2014-05-21 08:45:24 -04:00
}
private :
/**
* Function that is called when check box state is changed .
*
* @ parent InNewState New state enum .
*/
2014-12-10 14:24:09 -05:00
void OnCheckStateChange ( ECheckBoxState InNewState )
2014-05-21 08:45:24 -04:00
{
Parent . ChooseEnabledItem ( Id ) ;
}
/* Item id. */
int32 Id ;
/* Item name. */
2015-04-21 08:10:22 -04:00
FText Name ;
2014-05-21 08:45:24 -04:00
/* Outer item widget. */
TSharedPtr < SWidget > WholeItemWidget ;
/* Stored widget. */
TSharedRef < SWidget > Content ;
/* Parent reference. */
SRadioContentSelection & Parent ;
} ;
SLATE_BEGIN_ARGS ( SRadioContentSelection ) { }
SLATE_EVENT ( FOnSelectionChanged , OnSelectionChanged )
SLATE_END_ARGS ( )
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void Construct ( const FArguments & InArgs )
{
OnSelectionChanged = InArgs . _OnSelectionChanged ;
MainBox = SNew ( SVerticalBox ) ;
this - > ChildSlot
[
MainBox . ToSharedRef ( )
] ;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
/**
* Adds widget to this selection with given name .
*
* @ param Name Name of the widget in this selection .
* @ param Content The widget itself .
*/
2015-04-21 08:10:22 -04:00
void Add ( FText Name , TSharedRef < SWidget > Content )
2014-05-21 08:45:24 -04:00
{
TSharedRef < FItem > Item = MakeShareable ( new FItem ( * this , Items . Num ( ) , Name , Content ) ) ;
Item - > Init ( ) ;
Items . Add ( Item ) ;
RebuildMainBox ( ) ;
}
/**
* Enables chosen item and disable others .
*
* @ param ItemId Chosen item id .
*/
void ChooseEnabledItem ( int32 ItemId )
{
Chosen = ItemId ;
for ( int32 CurrentItemId = 0 ; CurrentItemId < Items . Num ( ) ; + + CurrentItemId )
{
if ( CurrentItemId = = ItemId )
{
Items [ CurrentItemId ] - > Enable ( ) ;
}
else
{
Items [ CurrentItemId ] - > Disable ( ) ;
}
}
OnSelectionChanged . ExecuteIfBound ( Chosen ) ;
}
/**
* Gets currently chosen item from this widget .
*
* @ returns Chosen item id .
*/
int32 GetChosen ( ) const
{
return Chosen ;
}
/**
* Gets widget based on item id .
*
* @ param ItemId Widget item id .
*
* @ returns Reference to requested widget .
*/
TSharedRef < SWidget > GetContentWidget ( int32 ItemId )
{
return Items [ ItemId ] - > GetContent ( ) ;
}
private :
/**
* Function to rebuild main and fill it with items provided .
*/
void RebuildMainBox ( )
{
MainBox - > ClearChildren ( ) ;
for ( auto Item : Items )
{
MainBox - > AddSlot ( ) . AutoHeight ( ) . Padding ( FMargin ( 0 , 20 , 0 , 0 ) )
[
Item - > GetWidget ( )
] ;
}
if ( Items . Num ( ) > 0 )
{
ChooseEnabledItem ( 0 ) ;
}
}
/* Delegate that will be called when the selection changed. */
FOnSelectionChanged OnSelectionChanged ;
/* Main box ptr. */
TSharedPtr < SVerticalBox > MainBox ;
/* Array of items/widgets. */
TArray < TSharedRef < FItem > > Items ;
/* Chosen widget. */
int32 Chosen ;
} ;
/**
* Sync latest promoted widget .
*/
2014-06-04 11:01:22 -04:00
class SLatestPromoted : public SCompoundWidget , public ILabelNameProvider
2014-05-21 08:45:24 -04:00
{
public :
SLATE_BEGIN_ARGS ( SLatestPromoted ) { }
SLATE_END_ARGS ( )
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void Construct ( const FArguments & InArgs )
{
2014-06-04 11:01:22 -04:00
DataReady = MakeShareable ( FPlatformProcess : : CreateSynchEvent ( true ) ) ;
2014-05-21 08:45:24 -04:00
this - > ChildSlot
[
SNew ( STextBlock ) . Text ( FText : : FromString ( " This option will sync to the latest promoted label for given game. " ) )
] ;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
/**
* Gets command line from current options picked by user .
*
* @ returns UAT UnrealSync command line .
*/
2014-06-13 06:14:46 -04:00
FString GetLabelName ( ) const override
2014-05-21 08:45:24 -04:00
{
2014-06-04 11:01:22 -04:00
DataReady - > Wait ( ) ;
return CurrentLabelName ;
2014-05-21 08:45:24 -04:00
}
/**
2014-06-04 11:01:22 -04:00
* Gets message to display when sync task has started .
2014-05-21 08:45:24 -04:00
*/
2014-06-04 11:01:22 -04:00
virtual FString GetStartedMessage ( ) const
2014-05-21 08:45:24 -04:00
{
2014-06-04 11:01:22 -04:00
return " Sync to latest started. Pending label data. Please wait. " ;
}
/**
* Gets message to display when sync task has finished .
*/
virtual FString GetFinishedMessage ( ) const
{
return " Sync to latest finished. " ;
}
2014-06-13 06:14:46 -04:00
FString GetGameName ( ) const override
2014-06-04 11:01:22 -04:00
{
DataReady - > Wait ( ) ;
return ILabelNameProvider : : GetGameName ( ) ;
}
/**
* Refresh data .
*
* @ param GameName Current game name .
*/
2014-06-13 06:14:46 -04:00
void RefreshData ( const FString & GameName ) override
2014-06-04 11:01:22 -04:00
{
ILabelNameProvider : : RefreshData ( GameName ) ;
auto Labels = FUnrealSync : : GetPromotedLabelsForGame ( GameName ) ;
if ( Labels - > Num ( ) ! = 0 )
{
CurrentLabelName = ( * Labels ) [ 0 ] ;
}
DataReady - > Trigger ( ) ;
}
/**
* Reset data .
*
* @ param GameName Current game name .
*/
2014-06-13 06:14:46 -04:00
void ResetData ( const FString & GameName ) override
2014-06-04 11:01:22 -04:00
{
ILabelNameProvider : : ResetData ( GameName ) ;
DataReady - > Reset ( ) ;
2014-05-21 08:45:24 -04:00
}
/**
* Tells if this particular widget has data ready for sync .
*
* @ returns True if ready . False otherwise .
*/
2014-06-13 06:14:46 -04:00
bool IsReadyForSync ( ) const override
2014-05-21 08:45:24 -04:00
{
return true ;
}
private :
/* Currently picked game name. */
FString CurrentGameName ;
2014-06-04 11:01:22 -04:00
/* Current label name. */
FString CurrentLabelName ;
/* Event that will trigger when data is ready. */
TSharedPtr < FEvent > DataReady ;
2014-05-21 08:45:24 -04:00
} ;
/**
* Base class for pick label widgets .
*/
2014-06-04 11:01:22 -04:00
class SPickLabel : public SCompoundWidget , public ILabelNameProvider
2014-05-21 08:45:24 -04:00
{
public :
SLATE_BEGIN_ARGS ( SPickLabel ) { }
2015-01-28 09:33:56 -05:00
SLATE_ATTRIBUTE ( FText , Title )
2014-05-21 08:45:24 -04:00
SLATE_END_ARGS ( )
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void Construct ( const FArguments & InArgs )
{
LabelsCombo = SNew ( SSimpleTextComboBox ) ;
LabelsCombo - > Add ( " Needs refreshing " ) ;
this - > ChildSlot
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( ) . AutoWidth ( ) . VAlign ( VAlign_Center )
[
SNew ( STextBlock ) . Text ( InArgs . _Title )
]
+ SHorizontalBox : : Slot ( ) . HAlign ( HAlign_Fill )
2015-01-28 09:33:56 -05:00
[
LabelsCombo . ToSharedRef ( )
]
2014-05-21 08:45:24 -04:00
] ;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
/**
* Gets command line from current options picked by user .
*
* @ returns UAT UnrealSync command line .
*/
2014-06-13 06:14:46 -04:00
FString GetLabelName ( ) const override
2014-05-21 08:45:24 -04:00
{
2014-06-05 12:11:12 -04:00
return LabelsCombo - > GetCurrentOption ( ) ;
2014-05-21 08:45:24 -04:00
}
/**
* Tells if this particular widget has data ready for sync .
*
* @ returns True if ready . False otherwise .
*/
2014-06-13 06:14:46 -04:00
bool IsReadyForSync ( ) const override
2014-05-21 08:45:24 -04:00
{
return FUnrealSync : : HasValidData ( ) & & ! LabelsCombo - > IsEmpty ( ) ;
}
2014-06-04 11:01:22 -04:00
/**
* Reset data .
*
* @ param GameName Current game name .
*/
2014-06-13 06:14:46 -04:00
void ResetData ( const FString & GameName ) override
2014-06-04 11:01:22 -04:00
{
ILabelNameProvider : : ResetData ( GameName ) ;
LabelsCombo - > Clear ( ) ;
LabelsCombo - > Add ( " Loading P4 labels data... " ) ;
LabelsCombo - > SetEnabled ( false ) ;
}
2014-05-21 08:45:24 -04:00
protected :
/**
* Reset current labels combo options .
*
* @ param LabelOptions Option to fill labels combo .
*/
void SetLabelOptions ( const TArray < FString > & LabelOptions )
{
LabelsCombo - > Clear ( ) ;
if ( FUnrealSync : : HasValidData ( ) )
{
for ( auto LabelName : LabelOptions )
{
LabelsCombo - > Add ( LabelName ) ;
}
LabelsCombo - > SetEnabled ( true ) ;
}
else
{
2014-06-04 11:01:22 -04:00
LabelsCombo - > Add ( " P4 data loading failed. " ) ;
2014-05-21 08:45:24 -04:00
LabelsCombo - > SetEnabled ( false ) ;
}
}
private :
/* Labels combo widget. */
TSharedPtr < SSimpleTextComboBox > LabelsCombo ;
} ;
/**
* Pick promoted label widget .
*/
class SPickPromoted : public SPickLabel
{
public :
/**
* Refresh widget method .
*
* @ param GameName Game name to refresh for .
*/
2014-06-13 06:14:46 -04:00
void RefreshData ( const FString & GameName ) override
2014-05-21 08:45:24 -04:00
{
SetLabelOptions ( * FUnrealSync : : GetPromotedLabelsForGame ( GameName ) ) ;
2014-06-04 11:01:22 -04:00
SPickLabel : : RefreshData ( GameName ) ;
2014-05-21 08:45:24 -04:00
}
} ;
/**
* Pick promotable label widget .
*/
class SPickPromotable : public SPickLabel
{
public :
/**
* Refresh widget method .
*
* @ param GameName Game name to refresh for .
*/
2014-06-13 06:14:46 -04:00
void RefreshData ( const FString & GameName ) override
2014-05-21 08:45:24 -04:00
{
SetLabelOptions ( * FUnrealSync : : GetPromotableLabelsForGame ( GameName ) ) ;
2014-06-04 11:01:22 -04:00
SPickLabel : : RefreshData ( GameName ) ;
2014-05-21 08:45:24 -04:00
}
} ;
/**
* Pick any label widget .
*/
class SPickAny : public SPickLabel
{
public :
/**
* Refresh widget method .
*
* @ param GameName Game name to refresh for .
*/
2014-06-13 06:14:46 -04:00
void RefreshData ( const FString & GameName ) override
2014-05-21 08:45:24 -04:00
{
SetLabelOptions ( * FUnrealSync : : GetAllLabels ( ) ) ;
2014-06-04 11:01:22 -04:00
SPickLabel : : RefreshData ( GameName ) ;
2014-05-21 08:45:24 -04:00
}
} ;
/**
* Pick game widget .
*/
class SPickGameWidget : public SCompoundWidget
{
public :
/* Delegate for game picked event. */
DECLARE_DELEGATE_OneParam ( FOnGamePicked , const FString & ) ;
SLATE_BEGIN_ARGS ( SPickGameWidget ) { }
SLATE_EVENT ( FOnGamePicked , OnGamePicked )
SLATE_END_ARGS ( )
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void Construct ( const FArguments & InArgs )
{
OnGamePicked = InArgs . _OnGamePicked ;
GamesOptions = SNew ( SSimpleTextComboBox )
. OnSelectionChanged ( this , & SPickGameWidget : : OnComboBoxSelectionChanged ) ;
auto PossibleGameNames = FUnrealSync : : GetPossibleGameNames ( ) ;
2015-04-27 12:35:19 -04:00
if ( PossibleGameNames - > Remove ( FUnrealSync : : GetSharedPromotableP4FolderName ( ) ) )
{
GamesOptions - > Add ( FUnrealSync : : GetSharedPromotableDisplayName ( ) ) ;
}
2014-05-21 08:45:24 -04:00
for ( auto PossibleGameName : * PossibleGameNames )
{
GamesOptions - > Add ( PossibleGameName ) ;
}
this - > ChildSlot
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( ) . AutoWidth ( ) . VAlign ( VAlign_Center )
[
SNew ( STextBlock ) . Text ( FText : : FromString ( " Pick game to sync: " ) )
]
+ SHorizontalBox : : Slot ( ) . HAlign ( HAlign_Fill )
[
GamesOptions . ToSharedRef ( )
]
] ;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
/**
* Gets current game selected .
*
* @ returns Currently selected game .
*/
const FString & GetCurrentGame ( )
{
return GamesOptions - > GetCurrentOption ( ) ;
}
private :
/**
* Function is called when combo box selection is changed .
2014-06-04 11:01:22 -04:00
* It called OnGamePicked event .
2014-05-21 08:45:24 -04:00
*/
void OnComboBoxSelectionChanged ( int32 SelectionId , ESelectInfo : : Type SelectionInfo )
{
OnGamePicked . ExecuteIfBound ( GamesOptions - > GetCurrentOption ( ) ) ;
}
/* Game options widget. */
TSharedPtr < SSimpleTextComboBox > GamesOptions ;
/* Delegate that is going to be called when game was picked by the user. */
FOnGamePicked OnGamePicked ;
} ;
/**
* Main tab widget .
*/
class SMainTabWidget : public SCompoundWidget
{
2015-04-09 03:11:14 -04:00
/**
* External threads requests dispatcher .
*/
class FExternalThreadsDispatcher : public TSharedFromThis < FExternalThreadsDispatcher , ESPMode : : ThreadSafe >
{
public :
/** Delegate that represents rendering thread request. */
DECLARE_DELEGATE ( FRenderingThreadRequest ) ;
/**
* Executes all pending requests .
*
* Some Slate methods are restricted for either game or Slate rendering
* thread . If external thread tries to execute them assert raises , which is
* telling that it ' s unsafe .
*
* This method executes all pending requests on Slate thread , so you can
* use those to execute some restricted methods .
*/
EActiveTimerReturnType ExecuteRequests ( double CurrentTime , float DeltaTime )
{
FScopeLock Lock ( & RequestsMutex ) ;
2015-04-14 02:22:12 -04:00
for ( int32 ReqId = 0 ; ReqId < Requests . Num ( ) ; + + ReqId )
2015-04-09 03:11:14 -04:00
{
2015-04-14 02:22:12 -04:00
Requests [ ReqId ] . Execute ( ) ;
2015-04-09 03:11:14 -04:00
}
2015-04-14 02:22:12 -04:00
Requests . Empty ( 4 ) ;
2015-04-09 03:11:14 -04:00
return EActiveTimerReturnType : : Continue ;
}
/**
* Adds delegate to pending requests list .
*/
void AddRenderingThreadRequest ( FRenderingThreadRequest Request )
{
FScopeLock Lock ( & RequestsMutex ) ;
Requests . Add ( MoveTemp ( Request ) ) ;
}
private :
/** Mutex for pending requests list. */
FCriticalSection RequestsMutex ;
/** Pending requests list. */
TArray < FRenderingThreadRequest > Requests ;
} ;
2014-05-21 08:45:24 -04:00
public :
2015-04-09 03:11:14 -04:00
SMainTabWidget ( )
: ExternalThreadsDispatcher ( MakeShareable ( new FExternalThreadsDispatcher ( ) ) )
{ }
SLATE_BEGIN_ARGS ( SMainTabWidget ) { }
2014-05-21 08:45:24 -04:00
SLATE_END_ARGS ( )
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void Construct ( const FArguments & InArgs )
{
RadioSelection = SNew ( SRadioContentSelection ) ;
2015-04-21 08:10:22 -04:00
AddToRadioSelection ( LOCTEXT ( " SyncToLatestPromoted " , " Sync to the latest promoted " ) , SNew ( SLatestPromoted ) ) ;
AddToRadioSelection ( LOCTEXT ( " SyncToChosenPromoted " , " Sync to chosen promoted label " ) , SNew ( SPickPromoted ) . Title ( LOCTEXT ( " PickPromotedLabel " , " Pick promoted label: " ) ) ) ;
AddToRadioSelection ( LOCTEXT ( " SyncToChosenPromotable " , " Sync to chosen promotable label since last promoted " ) , SNew ( SPickPromotable ) . Title ( LOCTEXT ( " PickPromotableLabel " , " Pick promotable label: " ) ) ) ;
AddToRadioSelection ( LOCTEXT ( " SyncToAnyChosen " , " Sync to any chosen label " ) , SNew ( SPickAny ) . Title ( LOCTEXT ( " PickLabel " , " Pick label: " ) ) ) ;
2014-05-21 08:45:24 -04:00
PickGameWidget = SNew ( SPickGameWidget )
. OnGamePicked ( this , & SMainTabWidget : : OnCurrentGameChanged ) ;
ArtistSyncCheckBox = SNew ( SCheckBox )
[
2015-04-21 08:10:22 -04:00
SNew ( STextBlock ) . Text ( LOCTEXT ( " ArtistSync " , " Artist sync? " ) )
2014-05-21 08:45:24 -04:00
] ;
2015-04-22 10:06:57 -04:00
if ( ! FUnrealSync : : IsDebugParameterSet ( ) )
2015-04-10 10:22:22 -04:00
{
// Checked by default.
ArtistSyncCheckBox - > ToggleCheckedState ( ) ;
}
2014-05-21 08:45:24 -04:00
PreviewSyncCheckBox = SNew ( SCheckBox )
[
2015-04-21 08:10:22 -04:00
SNew ( STextBlock ) . Text ( LOCTEXT ( " PreviewSync " , " Preview sync? " ) )
] ;
AutoClobberSyncCheckBox = SNew ( SCheckBox )
[
SNew ( STextBlock ) . Text ( LOCTEXT ( " AutoClobberSync " , " Auto-clobber sync? " ) )
2014-05-21 08:45:24 -04:00
] ;
2014-05-29 16:59:04 -04:00
GoBackButton = SNew ( SButton )
2014-05-21 08:45:24 -04:00
. IsEnabled ( false )
2014-05-29 16:59:04 -04:00
. OnClicked ( this , & SMainTabWidget : : OnGoBackButtonClick )
2014-05-21 08:45:24 -04:00
[
2015-04-21 08:10:22 -04:00
SNew ( STextBlock ) . Text ( LOCTEXT ( " GoBack " , " Go back " ) )
2014-05-21 08:45:24 -04:00
] ;
2015-04-10 10:22:22 -04:00
TSharedPtr < SVerticalBox > MainBox ;
2014-05-21 08:45:24 -04:00
Switcher = SNew ( SWidgetSwitcher )
+ SWidgetSwitcher : : Slot ( )
[
2015-04-10 10:22:22 -04:00
SAssignNew ( MainBox , SVerticalBox )
2015-04-09 02:24:25 -04:00
+ SVerticalBox : : Slot ( ) . AutoHeight ( ) . Padding ( 5.0f )
2014-05-21 08:45:24 -04:00
[
PickGameWidget . ToSharedRef ( )
]
+ SVerticalBox : : Slot ( ) . VAlign ( VAlign_Fill )
[
RadioSelection . ToSharedRef ( )
]
+ SVerticalBox : : Slot ( ) . AutoHeight ( )
[
SNew ( SHorizontalBox )
2014-05-29 16:59:04 -04:00
+ SHorizontalBox : : Slot ( ) . AutoWidth ( )
[
SNew ( SButton ) . HAlign ( HAlign_Right )
. OnClicked ( this , & SMainTabWidget : : OnReloadLabels )
. IsEnabled ( this , & SMainTabWidget : : IsReloadLabelsReady )
. VAlign ( VAlign_Center )
[
SNew ( STextBlock ) . Text ( FText : : FromString ( " Reload Labels " ) )
]
]
2014-05-21 08:45:24 -04:00
+ SHorizontalBox : : Slot ( ) . HAlign ( HAlign_Fill )
2015-04-21 08:10:22 -04:00
+ SHorizontalBox : : Slot ( ) . AutoWidth ( ) . VAlign ( VAlign_Top ) . Padding ( 0.0f , 0.0f , 10.0f , 0.0f )
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
[
AutoClobberSyncCheckBox . ToSharedRef ( )
]
]
2014-05-21 08:45:24 -04:00
+ SHorizontalBox : : Slot ( ) . AutoWidth ( )
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
[
ArtistSyncCheckBox . ToSharedRef ( )
]
+ SVerticalBox : : Slot ( )
2015-04-21 08:10:22 -04:00
[
PreviewSyncCheckBox . ToSharedRef ( )
]
2014-05-21 08:45:24 -04:00
]
2015-04-14 03:21:31 -04:00
+ SHorizontalBox : : Slot ( ) . AutoWidth ( ) . Padding ( 30 , 0 , 0 , 0 )
2014-05-21 08:45:24 -04:00
[
SNew ( SButton ) . HAlign ( HAlign_Right )
. OnClicked ( this , & SMainTabWidget : : OnSync )
. IsEnabled ( this , & SMainTabWidget : : IsSyncReady )
. VAlign ( VAlign_Center )
[
SNew ( STextBlock ) . Text ( FText : : FromString ( " Sync! " ) )
]
]
2015-04-14 03:21:31 -04:00
+ SHorizontalBox : : Slot ( ) . AutoWidth ( )
[
SNew ( SButton ) . HAlign ( HAlign_Right )
. OnClicked ( this , & SMainTabWidget : : RunUE4 )
. VAlign ( VAlign_Center )
[
SNew ( STextBlock ) . Text ( FText : : FromString ( " Run UE4 " ) )
]
]
2014-05-21 08:45:24 -04:00
]
]
+ SWidgetSwitcher : : Slot ( )
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
[
2015-04-17 02:54:15 -04:00
SAssignNew ( Log , SSyncLog )
2014-05-21 08:45:24 -04:00
]
+ SVerticalBox : : Slot ( ) . AutoHeight ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
2015-04-14 09:13:30 -04:00
[
SAssignNew ( Throbber , SThrobber )
. Animate ( SThrobber : : VerticalAndOpacity ) . NumPieces ( 5 )
]
2014-05-21 08:45:24 -04:00
+ SHorizontalBox : : Slot ( ) . AutoWidth ( )
2015-04-14 02:22:12 -04:00
[
SAssignNew ( CancelButton , SButton )
. OnClicked ( this , & SMainTabWidget : : OnCancelButtonClick )
[
SNew ( STextBlock ) . Text ( FText : : FromString ( " Cancel " ) )
]
]
+ SHorizontalBox : : Slot ( ) . AutoWidth ( )
2014-05-21 08:45:24 -04:00
[
2014-05-29 16:59:04 -04:00
GoBackButton . ToSharedRef ( )
2014-05-21 08:45:24 -04:00
]
]
] ;
this - > ChildSlot
[
Switcher . ToSharedRef ( )
] ;
2015-04-22 10:06:57 -04:00
if ( FUnrealSync : : IsDebugParameterSet ( ) )
2015-04-10 10:22:22 -04:00
{
MainBox - > InsertSlot ( 2 ) . AutoHeight ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
[
SNew ( STextBlock ) . Text ( LOCTEXT ( " OverrideSyncStepSpec " , " Override sync step specification " ) )
]
+ SHorizontalBox : : Slot ( )
[
SNew ( SEditableTextBox ) . OnTextCommitted ( this , & SMainTabWidget : : OnOverrideSyncStepText )
]
] ;
}
2014-06-04 11:01:22 -04:00
FUnrealSync : : RegisterOnDataReset ( FUnrealSync : : FOnDataReset : : CreateRaw ( this , & SMainTabWidget : : DataReset ) ) ;
FUnrealSync : : RegisterOnDataLoaded ( FUnrealSync : : FOnDataLoaded : : CreateRaw ( this , & SMainTabWidget : : DataLoaded ) ) ;
2014-05-21 08:45:24 -04:00
2015-04-09 03:11:14 -04:00
RegisterActiveTimer ( 0.5f , FWidgetActiveTimerDelegate : : CreateThreadSafeSP ( & ExternalThreadsDispatcher . Get ( ) , & FExternalThreadsDispatcher : : ExecuteRequests ) ) ;
2014-05-29 16:59:04 -04:00
OnReloadLabels ( ) ;
2014-05-21 08:45:24 -04:00
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
2014-06-04 11:01:22 -04:00
/**
* Destructor .
*/
virtual ~ SMainTabWidget ( )
{
FUnrealSync : : TerminateLoadingProcess ( ) ;
2015-04-14 02:22:12 -04:00
FUnrealSync : : TerminateSyncingProcess ( ) ;
2014-06-04 11:01:22 -04:00
}
2014-05-21 08:45:24 -04:00
private :
2015-04-09 03:11:14 -04:00
/**
* Queues adding lines to the log for execution on Slate rendering thread .
*/
2015-04-14 02:22:12 -04:00
void ExternalThreadAddLinesToLog ( TSharedPtr < TArray < TSharedPtr < FString > > > Lines )
2015-04-09 03:11:14 -04:00
{
2015-04-17 02:54:15 -04:00
ExternalThreadsDispatcher - > AddRenderingThreadRequest ( FExternalThreadsDispatcher : : FRenderingThreadRequest : : CreateRaw ( this , & SMainTabWidget : : AddLinesToLog , Lines ) ) ;
2015-04-09 03:11:14 -04:00
}
/**
* Adds lines to the log .
*
* @ param Lines Lines to add .
*/
2015-04-14 02:22:12 -04:00
void AddLinesToLog ( TSharedPtr < TArray < TSharedPtr < FString > > > Lines )
2015-04-09 03:11:14 -04:00
{
2015-04-14 02:22:12 -04:00
for ( const auto & Line : * Lines )
2015-04-09 03:11:14 -04:00
{
2015-04-17 02:54:15 -04:00
Log - > AddMessage ( * Line . Get ( ) ) ;
2015-04-09 03:11:14 -04:00
}
}
2014-05-21 08:45:24 -04:00
/**
* Generates list view item from FString .
*
* @ param Value Value to convert .
* @ param OwnerTable List view that will contain this item .
*
* @ returns Converted STableRow object .
*/
TSharedRef < ITableRow > GenerateLogItem ( TSharedPtr < FString > Value , const TSharedRef < STableViewBase > & OwnerTable )
{
return SNew ( STableRow < TSharedPtr < FString > > , OwnerTable )
[
SNew ( STextBlock ) . Text ( FText : : FromString ( * Value ) )
] ;
}
/**
* Gets current sync command line provider .
*
* @ returns Current sync cmd line provider .
*/
2014-06-04 11:01:22 -04:00
ILabelNameProvider & GetCurrentSyncCmdLineProvider ( )
2014-05-21 08:45:24 -04:00
{
return * SyncCommandLineProviders [ RadioSelection - > GetChosen ( ) ] ;
}
/**
* Gets current sync command line provider .
*
* @ returns Current sync cmd line provider .
*/
2014-06-04 11:01:22 -04:00
const ILabelNameProvider & GetCurrentSyncCmdLineProvider ( ) const
2014-05-21 08:45:24 -04:00
{
return * SyncCommandLineProviders [ RadioSelection - > GetChosen ( ) ] ;
}
2015-04-14 02:22:12 -04:00
/**
* Performs a procedure that needs to be done when GoBack button is clicked .
* It tells the app to go back to the beginning .
*/
void GoBack ( )
{
Switcher - > SetActiveWidgetIndex ( 0 ) ;
2015-04-17 02:54:15 -04:00
Log - > Clear ( ) ;
2015-04-14 02:22:12 -04:00
OnReloadLabels ( ) ;
}
2014-05-21 08:45:24 -04:00
/**
2014-05-29 16:59:04 -04:00
* Function that is called on when go back button is clicked .
* It tells the app to go back to the beginning .
2014-05-21 08:45:24 -04:00
*
* @ returns Tells that this event was handled .
*/
2014-05-29 16:59:04 -04:00
FReply OnGoBackButtonClick ( )
2014-05-21 08:45:24 -04:00
{
2015-04-14 02:22:12 -04:00
GoBack ( ) ;
return FReply : : Handled ( ) ;
}
/**
* Function that is called on when cancel button is clicked .
* It tells the app to cancel the sync and go back to the beginning .
*
* @ returns Tells that this event was handled .
*/
FReply OnCancelButtonClick ( )
{
FUnrealSync : : TerminateLoadingProcess ( ) ;
FUnrealSync : : TerminateSyncingProcess ( ) ;
2015-04-21 05:11:57 -04:00
ExternalThreadsDispatcher - > AddRenderingThreadRequest ( FExternalThreadsDispatcher : : FRenderingThreadRequest : : CreateRaw ( this , & SMainTabWidget : : GoBack ) ) ;
2014-05-21 08:45:24 -04:00
return FReply : : Handled ( ) ;
}
/**
* Tells Sync button if it should be enabled . It depends on the combination
* of user choices and if P4 data is currently ready .
*
* @ returns True if Sync button should be enabled . False otherwise .
*/
bool IsSyncReady ( ) const
{
return GetCurrentSyncCmdLineProvider ( ) . IsReadyForSync ( ) ;
}
2014-05-29 16:59:04 -04:00
/**
* Tells reload labels button if it should be enabled .
*
* @ returns True if reload labels button should be enabled . False otherwise .
*/
bool IsReloadLabelsReady ( ) const
{
return ! FUnrealSync : : IsLoadingInProgress ( ) ;
}
/**
* Launches reload labels background process .
*
* @ returns Tells that this event was handled .
*/
FReply OnReloadLabels ( )
{
FUnrealSync : : StartLoadingData ( ) ;
return FReply : : Handled ( ) ;
}
2015-04-14 03:21:31 -04:00
/**
* Executes UE4Editor . exe for current branch .
*/
FReply RunUE4 ( )
{
# if PLATFORM_WINDOWS
auto ProcessPath = FPaths : : Combine ( * FPaths : : GetPath ( FPlatformProcess : : GetApplicationName ( FPlatformProcess : : GetCurrentProcessId ( ) ) ) , TEXT ( " UE4Editor.exe " ) ) ;
# else
// Needs to be implemented on other platforms.
# endif
RunProcess ( ProcessPath ) ;
return FReply : : Handled ( ) ;
}
2014-05-21 08:45:24 -04:00
/**
* Sync button click function . Gets all widget data , constructs command
* line and launches syncing .
*
* @ returns Tells that this event was handled .
*/
FReply OnSync ( )
{
2015-04-14 10:57:29 -04:00
if ( CheckIfEditorIsRunning ( ) )
{
return FReply : : Handled ( ) ;
}
2015-04-10 10:22:22 -04:00
FSyncSettings Settings (
ArtistSyncCheckBox - > IsChecked ( ) ,
PreviewSyncCheckBox - > IsChecked ( ) ,
2015-04-21 08:10:22 -04:00
AutoClobberSyncCheckBox - > IsChecked ( ) ,
2015-04-10 10:22:22 -04:00
OverrideSyncStep ) ;
2014-05-21 08:45:24 -04:00
Switcher - > SetActiveWidgetIndex ( 1 ) ;
2015-04-21 05:11:57 -04:00
FUnrealSync : : LaunchSync ( MoveTemp ( Settings ) , GetCurrentSyncCmdLineProvider ( ) ,
2014-05-21 08:45:24 -04:00
FUnrealSync : : FOnSyncFinished : : CreateRaw ( this , & SMainTabWidget : : SyncingFinished ) ,
FUnrealSync : : FOnSyncProgress : : CreateRaw ( this , & SMainTabWidget : : SyncingProgress ) ) ;
2014-06-04 11:01:22 -04:00
GoBackButton - > SetEnabled ( false ) ;
2015-04-14 02:22:12 -04:00
CancelButton - > SetEnabled ( true ) ;
2015-04-14 09:13:30 -04:00
Throbber - > SetAnimate ( SThrobber : : EAnimation : : VerticalAndOpacity ) ;
2014-06-04 11:01:22 -04:00
2014-05-21 08:45:24 -04:00
return FReply : : Handled ( ) ;
}
/**
* Function that is called whenever monitoring thread will update its log .
*
* @ param Log Log of the operation up to this moment .
*
* @ returns True if process should continue , false otherwise .
*/
bool SyncingProgress ( const FString & Log )
{
if ( Log . IsEmpty ( ) )
{
return true ;
}
static FString Buffer ;
Buffer + = Log . Replace ( TEXT ( " \r " ) , TEXT ( " " ) ) ;
FString Line ;
FString Rest ;
2015-04-14 02:22:12 -04:00
TSharedPtr < TArray < TSharedPtr < FString > > > Lines = MakeShareable ( new TArray < TSharedPtr < FString > > ( ) ) ;
2015-04-09 03:11:14 -04:00
2014-05-21 08:45:24 -04:00
while ( Buffer . Split ( " \n " , & Line , & Rest ) )
{
2015-04-14 02:22:12 -04:00
Lines - > Add ( MakeShareable ( new FString ( Line ) ) ) ;
2014-05-21 08:45:24 -04:00
Buffer = Rest ;
}
2015-04-09 03:11:14 -04:00
ExternalThreadAddLinesToLog ( Lines ) ;
2014-05-21 08:45:24 -04:00
return true ;
}
/**
* Function that is called when P4 syncing is finished .
*
* @ param bSuccess True if syncing finished . Otherwise false .
*/
void SyncingFinished ( bool bSuccess )
{
2015-04-14 09:13:30 -04:00
Throbber - > SetAnimate ( SThrobber : : EAnimation : : None ) ;
2015-04-14 02:22:12 -04:00
CancelButton - > SetEnabled ( false ) ;
2014-05-29 16:59:04 -04:00
GoBackButton - > SetEnabled ( true ) ;
2014-05-21 08:45:24 -04:00
}
/**
* Function to call when current game changed . Is refreshing
* label lists in the widget .
*
2014-06-04 11:01:22 -04:00
* @ param CurrentGameName Game name chosen .
2014-05-21 08:45:24 -04:00
*/
void OnCurrentGameChanged ( const FString & CurrentGameName )
{
2014-06-04 11:01:22 -04:00
if ( ! FUnrealSync : : HasValidData ( ) )
{
return ;
}
2014-05-21 08:45:24 -04:00
for ( auto SyncCommandLineProvider : SyncCommandLineProviders )
{
2014-06-04 11:01:22 -04:00
SyncCommandLineProvider - > RefreshData (
CurrentGameName . Equals ( FUnrealSync : : GetSharedPromotableDisplayName ( ) )
? " "
: CurrentGameName ) ;
2014-05-21 08:45:24 -04:00
}
}
/**
2014-06-04 11:01:22 -04:00
* Function to call when P4 cached data is reset .
2014-05-21 08:45:24 -04:00
*/
2014-06-04 11:01:22 -04:00
void DataReset ( )
{
for ( auto SyncCommandLineProvider : SyncCommandLineProviders )
{
SyncCommandLineProvider - > ResetData (
PickGameWidget - > GetCurrentGame ( ) . Equals ( FUnrealSync : : GetSharedPromotableDisplayName ( ) )
? " "
: PickGameWidget - > GetCurrentGame ( ) ) ;
}
}
/**
* Function to call when P4 cached data is loaded .
*/
void DataLoaded ( )
2014-05-21 08:45:24 -04:00
{
const FString & GameName = PickGameWidget - > GetCurrentGame ( ) ;
2014-06-04 11:01:22 -04:00
for ( auto SyncCommandLineProvider : SyncCommandLineProviders )
{
SyncCommandLineProvider - > RefreshData (
GameName . Equals ( FUnrealSync : : GetSharedPromotableDisplayName ( ) )
? " "
: GameName ) ;
}
2014-05-21 08:45:24 -04:00
}
2015-04-10 10:22:22 -04:00
/**
* Happens when someone edits the override sync step text box .
*/
void OnOverrideSyncStepText ( const FText & CommittedText , ETextCommit : : Type Type ) ;
2014-05-21 08:45:24 -04:00
/**
* Method to add command line provider / widget to correct arrays .
*
* @ param Name Name of the radio selection widget item .
* @ param Widget Widget to add .
*/
template < typename TWidgetType >
2015-04-21 08:10:22 -04:00
void AddToRadioSelection ( FText Name , TSharedRef < TWidgetType > Widget )
2014-05-21 08:45:24 -04:00
{
RadioSelection - > Add ( Name , Widget ) ;
SyncCommandLineProviders . Add ( Widget ) ;
}
2015-04-14 10:57:29 -04:00
/**
* Checks if the editor is currently running on the system and asks user to
* close it .
*
* @ returns False if editor is not opened or user forced to continue .
* Otherwise true .
*/
bool CheckIfEditorIsRunning ( )
{
auto Response = SEditorRunningDlg : : EResponse : : Retry ;
bool bEditorIsRunning = false ;
while ( Response = = SEditorRunningDlg : : EResponse : : Retry & & ( ( bEditorIsRunning = CheckForEditorProcess ( ) ) = = true ) )
{
Response = SEditorRunningDlg : : ShowAndGetResponse ( ) ;
}
return bEditorIsRunning & & Response ! = SEditorRunningDlg : : EResponse : : ForceSync ;
}
/**
* Checks if the editor is currently running on the system .
*
* @ returns False if editor is not opened . Otherwise true .
*/
bool CheckForEditorProcess ( )
{
for ( const auto & PossibleExecutablePath : GetPossibleExecutablePaths ( ) )
{
if ( IsRunningProcess ( PossibleExecutablePath ) )
{
return true ;
}
}
return false ;
}
# if PLATFORM_WINDOWS
/**
* Returns possible colliding UE4Editor executables .
*
* @ returns Array of possible executables .
*/
static TArray < FString > GetPossibleExecutablePaths ( )
{
FString BasePath = FPaths : : GetPath ( FPlatformProcess : : GetApplicationName ( FPlatformProcess : : GetCurrentProcessId ( ) ) ) ;
TArray < FString > Out ;
Out . Add ( FPaths : : Combine ( * BasePath , TEXT ( " UE4Editor.exe " ) ) ) ;
Out . Add ( FPaths : : Combine ( * BasePath , TEXT ( " UE4Editor-Win32-Debug.exe " ) ) ) ;
Out . Add ( FPaths : : Combine ( * BasePath , TEXT ( " UE4Editor-Win64-Debug.exe " ) ) ) ;
return Out ;
}
# endif
2014-05-21 08:45:24 -04:00
/* Main widget switcher. */
TSharedPtr < SWidgetSwitcher > Switcher ;
/* Radio selection used to chose method to sync. */
TSharedPtr < SRadioContentSelection > RadioSelection ;
/* Widget to pick game used to sync. */
TSharedPtr < SPickGameWidget > PickGameWidget ;
/* Check box to tell if this should be an artist sync. */
TSharedPtr < SCheckBox > ArtistSyncCheckBox ;
/* Check box to tell if this should be a preview sync. */
TSharedPtr < SCheckBox > PreviewSyncCheckBox ;
2015-04-21 08:10:22 -04:00
/* Check box to tell if this should be a auto-clobber sync. */
TSharedPtr < SCheckBox > AutoClobberSyncCheckBox ;
2014-05-21 08:45:24 -04:00
2015-04-09 03:11:14 -04:00
/* External thread requests dispatcher. */
TSharedRef < FExternalThreadsDispatcher , ESPMode : : ThreadSafe > ExternalThreadsDispatcher ;
2015-04-17 02:54:15 -04:00
/* Syncing log. */
TSharedPtr < SSyncLog > Log ;
2015-04-09 03:11:14 -04:00
2014-05-29 16:59:04 -04:00
/* Go back button reference. */
TSharedPtr < SButton > GoBackButton ;
2015-04-14 02:22:12 -04:00
/* Cancel button reference. */
TSharedPtr < SButton > CancelButton ;
2015-04-14 09:13:30 -04:00
/* Throbber to indicate work-in-progress. */
TSharedPtr < SThrobber > Throbber ;
2014-05-21 08:45:24 -04:00
/* Array of sync command line providers. */
2014-06-04 11:01:22 -04:00
TArray < TSharedRef < ILabelNameProvider > > SyncCommandLineProviders ;
2015-04-10 10:22:22 -04:00
/* Override sync step value. */
FString OverrideSyncStep ;
2014-05-21 08:45:24 -04:00
} ;
2015-04-10 10:22:22 -04:00
void SMainTabWidget : : OnOverrideSyncStepText ( const FText & CommittedText , ETextCommit : : Type Type )
{
OverrideSyncStep = CommittedText . ToString ( ) ;
}
2014-05-21 08:45:24 -04:00
/**
* Creates and returns main tab .
*
* @ param Args Args used to spawn tab .
*
* @ returns Main UnrealSync tab .
*/
TSharedRef < SDockTab > GetMainTab ( const FSpawnTabArgs & Args )
{
TSharedRef < SDockTab > MainTab =
SNew ( SDockTab )
. TabRole ( ETabRole : : MajorTab )
2015-04-09 04:40:26 -04:00
. Label ( FText : : FromString ( " Syncing " ) )
2014-05-21 08:45:24 -04:00
. ToolTipText ( FText : : FromString ( " Sync Unreal Engine tool. " ) ) ;
MainTab - > SetContent (
SNew ( SMainTabWidget )
) ;
2015-04-09 04:40:26 -04:00
FGlobalTabmanager : : Get ( ) - > SetActiveTab ( MainTab ) ;
2014-05-21 08:45:24 -04:00
return MainTab ;
}
2014-06-04 11:01:22 -04:00
/**
2015-04-09 04:40:26 -04:00
* Creates and returns P4 settings tab .
2014-06-04 11:01:22 -04:00
*
2015-04-09 04:40:26 -04:00
* @ param Args Args used to spawn tab .
*
* @ returns P4 settings UnrealSync tab .
2014-06-04 11:01:22 -04:00
*/
2015-04-09 04:40:26 -04:00
TSharedRef < SDockTab > GetP4EnvTab ( const FSpawnTabArgs & Args )
2014-05-21 08:45:24 -04:00
{
2015-04-09 04:40:26 -04:00
TSharedRef < SDockTab > P4EnvTab =
SNew ( SDockTab )
. TabRole ( ETabRole : : MajorTab )
. Label ( FText : : FromString ( " Perforce Settings " ) )
. ToolTipText ( FText : : FromString ( " Perforce settings. " ) ) ;
2014-05-21 08:45:24 -04:00
2015-04-09 04:40:26 -04:00
P4EnvTab - > SetContent (
SNew ( SP4EnvTabWidget )
) ;
return P4EnvTab ;
}
void InitGUI ( const TCHAR * CommandLine , bool bP4EnvTabOnly )
{
2014-05-21 08:45:24 -04:00
// crank up a normal Slate application using the platform's standalone renderer
FSlateApplication : : InitializeAsStandaloneApplication ( GetStandardStandaloneRenderer ( ) ) ;
// set the application name
FGlobalTabmanager : : Get ( ) - > SetApplicationTitle ( NSLOCTEXT ( " UnrealSync " , " AppTitle " , " Unreal Sync " ) ) ;
2015-04-09 04:40:26 -04:00
auto TabStack = FTabManager : : NewStack ( ) ;
if ( ! bP4EnvTabOnly )
{
TabStack - > AddTab ( " MainTab " , ETabState : : OpenedTab ) ;
FGlobalTabmanager : : Get ( ) - > RegisterTabSpawner ( " MainTab " , FOnSpawnTab : : CreateStatic ( & GetMainTab ) ) ;
TabStack - > SetForegroundTab ( FTabId ( " MainTab " ) ) ;
}
FGlobalTabmanager : : Get ( ) - > RegisterTabSpawner ( " P4EnvTab " , FOnSpawnTab : : CreateStatic ( & GetP4EnvTab ) ) ;
TabStack - > AddTab ( " P4EnvTab " , ETabState : : OpenedTab ) ;
2014-05-21 08:45:24 -04:00
TSharedRef < FTabManager : : FLayout > Layout = FTabManager : : NewLayout ( " UnrealSyncLayout " )
- > AddArea (
FTabManager : : NewArea ( 720 , 370 )
- > SetWindow ( FVector2D ( 420 , 10 ) , false )
2015-04-09 04:40:26 -04:00
- > Split ( TabStack )
2014-05-21 08:45:24 -04:00
) ;
FGlobalTabmanager : : Get ( ) - > RestoreFrom ( Layout , TSharedPtr < SWindow > ( ) ) ;
2015-04-09 04:40:26 -04:00
2014-05-21 08:45:24 -04:00
// loop while the server does the rest
while ( ! GIsRequestingExit )
{
FSlateApplication : : Get ( ) . PumpMessages ( ) ;
FSlateApplication : : Get ( ) . Tick ( ) ;
FPlatformProcess : : Sleep ( 0 ) ;
}
FSlateApplication : : Shutdown ( ) ;
}