2014-03-14 14:13:41 -04:00
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
# include "LevelsPrivatePCH.h"
2014-05-22 06:52:28 -04:00
# include "Matinee/MatineeActor.h"
2014-03-14 14:13:41 -04:00
# include "EditorLevelUtils.h"
# include "LevelUtils.h"
# include "Editor/PropertyEditor/Public/PropertyEditorModule.h"
# include "Editor/MainFrame/Public/MainFrame.h"
# include "DesktopPlatformModule.h"
# include "LevelEditor.h"
# include "AssetToolsModule.h"
# include "ISourceControlModule.h"
# include "ISourceControlRevision.h"
# include "SourceControlWindows.h"
# define LOCTEXT_NAMESPACE "LevelsView"
FLevelCollectionViewModel : : FLevelCollectionViewModel ( const TWeakObjectPtr < UEditorEngine > & InEditor )
: bIsRefreshing ( false )
, bPendingUpdateActorsCount ( false )
, Filters ( MakeShareable ( new LevelFilterCollection ) )
, CommandList ( MakeShareable ( new FUICommandList ) )
, Editor ( InEditor )
, CurrentWorld ( NULL )
, AddedLevelStreamingClass ( ULevelStreamingKismet : : StaticClass ( ) )
2014-06-23 06:42:01 -04:00
, bSelectionHasChanged ( true )
2014-03-14 14:13:41 -04:00
{
OnResetLevels ( ) ;
}
FLevelCollectionViewModel : : ~ FLevelCollectionViewModel ( )
{
Filters - > OnChanged ( ) . RemoveAll ( this ) ;
Editor - > UnregisterForUndo ( this ) ;
if ( CurrentWorld . IsValid ( ) )
{
RemoveLevelChangeHandlers ( CurrentWorld . Get ( ) ) ;
}
if ( GEngine )
{
GEngine - > OnWorldAdded ( ) . RemoveAll ( this ) ;
GEngine - > OnWorldDestroyed ( ) . RemoveAll ( this ) ;
GEngine - > OnLevelActorAdded ( ) . RemoveAll ( this ) ;
GEngine - > OnLevelActorDeleted ( ) . RemoveAll ( this ) ;
}
}
void FLevelCollectionViewModel : : Initialize ( )
{
BindCommands ( ) ;
Filters - > OnChanged ( ) . AddSP ( this , & FLevelCollectionViewModel : : OnFilterChanged ) ;
Editor - > RegisterForUndo ( this ) ;
// Add world added/destroyed handlers
if ( GEngine )
{
GEngine - > OnWorldAdded ( ) . AddSP ( this , & FLevelCollectionViewModel : : WorldAdded ) ;
GEngine - > OnWorldDestroyed ( ) . AddSP ( this , & FLevelCollectionViewModel : : WorldDestroyed ) ;
GEngine - > OnLevelActorAdded ( ) . AddSP ( this , & FLevelCollectionViewModel : : OnLevelActorAdded ) ;
GEngine - > OnLevelActorDeleted ( ) . AddSP ( this , & FLevelCollectionViewModel : : OnLevelActorDeleted ) ;
// We need a world to browse levels. Get the first one in the list
if ( GEditor )
{
SetCurrentWorld ( GEditor - > GetEditorWorldContext ( ) . World ( ) ) ;
}
}
2014-06-23 06:42:01 -04:00
USelection : : SelectionChangedEvent . AddSP ( this , & FLevelCollectionViewModel : : OnActorSelectionChanged ) ;
SelectionChanged . AddSP ( this , & FLevelCollectionViewModel : : OnActorOrLevelSelectionChanged ) ;
2014-03-14 14:13:41 -04:00
}
void FLevelCollectionViewModel : : Tick ( float DeltaTime )
{
if ( bPendingUpdateActorsCount )
{
UpdateLevelActorsCount ( ) ;
}
}
TStatId FLevelCollectionViewModel : : GetStatId ( ) const
{
RETURN_QUICK_DECLARE_CYCLE_STAT ( FLevelCollectionViewModel , STATGROUP_Tickables ) ;
}
void FLevelCollectionViewModel : : BindCommands ( )
{
const FLevelsViewCommands & Commands = FLevelsViewCommands : : Get ( ) ;
FUICommandList & ActionList = * CommandList ;
//selected level
ActionList . MapAction ( Commands . MakeLevelCurrent ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : MakeLevelCurrent_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : IsSelectedLevelUnlocked ) ) ;
ActionList . MapAction ( Commands . MoveActorsToSelected ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : MoveActorsToSelected_Executed ) ,
2014-06-23 06:42:01 -04:00
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : IsValidMoveActorsToLevel ) ) ;
2014-03-14 14:13:41 -04:00
//invalid selected levels
ActionList . MapAction ( Commands . FixUpInvalidReference ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : FixupInvalidReference_Executed ) ) ;
ActionList . MapAction ( Commands . RemoveInvalidReference ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : RemoveInvalidSelectedLevels_Executed ) ) ;
//levels
ActionList . MapAction ( Commands . EditProperties ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : EditProperties_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : CanEditProperties ) ) ;
ActionList . MapAction ( Commands . SaveSelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SaveSelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlocked ) ) ;
ActionList . MapAction ( Commands . SCCCheckOut ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnSCCCheckOut ) ) ;
ActionList . MapAction ( Commands . SCCCheckIn ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnSCCCheckIn ) ) ;
ActionList . MapAction ( Commands . SCCOpenForAdd ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnSCCOpenForAdd ) ) ;
ActionList . MapAction ( Commands . SCCHistory ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnSCCHistory ) ) ;
ActionList . MapAction ( Commands . SCCRefresh ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnSCCRefresh ) ) ;
ActionList . MapAction ( Commands . SCCDiffAgainstDepot ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnSCCDiffAgainstDepot ) ) ;
ActionList . MapAction ( Commands . SCCConnect ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnSCCConnect ) ) ;
ActionList . MapAction ( Commands . MigrateSelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : MigrateSelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlocked ) ) ;
ActionList . MapAction ( Commands . DisplayActorCount ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnToggleDisplayActorCount ) ,
FCanExecuteAction ( ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : GetDisplayActorCountState ) ) ;
ActionList . MapAction ( Commands . DisplayLightmassSize ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnToggleLightmassSize ) ,
FCanExecuteAction ( ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : GetDisplayLightmassSizeState ) ) ;
ActionList . MapAction ( Commands . DisplayFileSize ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnToggleFileSize ) ,
FCanExecuteAction ( ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : GetDisplayFileSizeState ) ) ;
ActionList . MapAction ( Commands . DisplayPaths ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnToggleDisplayPaths ) ,
FCanExecuteAction ( ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : GetDisplayPathsState ) ) ;
ActionList . MapAction ( Commands . DisplayEditorOffset ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : OnToggleEditorOffset ) ,
FCanExecuteAction ( ) ,
FIsActionChecked : : CreateSP ( this , & FLevelCollectionViewModel : : GetDisplayEditorOffsetState ) ) ;
ActionList . MapAction ( Commands . CreateEmptyLevel ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : CreateEmptyLevel_Executed ) ) ;
ActionList . MapAction ( Commands . AddExistingLevel ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AddExistingLevel_Executed ) ) ;
ActionList . MapAction ( Commands . AddSelectedActorsToNewLevel ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AddSelectedActorsToNewLevel_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreActorsSelected ) ) ;
ActionList . MapAction ( Commands . RemoveSelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : RemoveSelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlockedAndNotPersistent ) ) ;
ActionList . MapAction ( Commands . MergeSelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : MergeSelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlocked ) ) ;
// new level streaming method
ActionList . MapAction ( Commands . SetAddStreamingMethod_Blueprint ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SetAddedLevelStreamingClass_Executed , ULevelStreamingKismet : : StaticClass ( ) ) ,
FCanExecuteAction ( ) ,
FIsActionChecked : : CreateSP ( this , & FLevelCollectionViewModel : : IsNewStreamingMethodChecked , ULevelStreamingKismet : : StaticClass ( ) ) ) ;
ActionList . MapAction ( Commands . SetAddStreamingMethod_AlwaysLoaded ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SetAddedLevelStreamingClass_Executed , ULevelStreamingAlwaysLoaded : : StaticClass ( ) ) ,
FCanExecuteAction ( ) ,
FIsActionChecked : : CreateSP ( this , & FLevelCollectionViewModel : : IsNewStreamingMethodChecked , ULevelStreamingAlwaysLoaded : : StaticClass ( ) ) ) ;
// change streaming method
ActionList . MapAction ( Commands . SetStreamingMethod_Blueprint ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SetStreamingLevelsClass_Executed , ULevelStreamingKismet : : StaticClass ( ) ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlockedAndNotPersistent ) ,
FIsActionChecked : : CreateSP ( this , & FLevelCollectionViewModel : : IsStreamingMethodChecked , ULevelStreamingKismet : : StaticClass ( ) ) ) ;
ActionList . MapAction ( Commands . SetStreamingMethod_AlwaysLoaded ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SetStreamingLevelsClass_Executed , ULevelStreamingAlwaysLoaded : : StaticClass ( ) ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlockedAndNotPersistent ) ,
FIsActionChecked : : CreateSP ( this , & FLevelCollectionViewModel : : IsStreamingMethodChecked , ULevelStreamingAlwaysLoaded : : StaticClass ( ) ) ) ;
//level selection
ActionList . MapAction ( Commands . SelectAllLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SelectAllLevels_Executed ) ) ;
ActionList . MapAction ( Commands . DeselectAllLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : DeselectAllLevels_Executed ) ) ;
ActionList . MapAction ( Commands . InvertLevelSelection ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : InvertSelection_Executed ) ) ;
//actors
ActionList . MapAction ( Commands . SelectLevelActors ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SelectActors_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlocked ) ) ;
ActionList . MapAction ( Commands . DeselectLevelActors ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : DeselectActors_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlocked ) ) ;
//streaming volumes
ActionList . MapAction ( Commands . AddStreamingLevelVolumes ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AddStreamingLevelVolumes_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : CanAddOrSelectStreamingVolumes ) ) ;
ActionList . MapAction ( Commands . SetStreamingLevelVolumes ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SetStreamingLevelVolumes_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : CanAddOrSelectStreamingVolumes ) ) ;
ActionList . MapAction ( Commands . SelectStreamingVolumes ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : SelectStreamingVolumes_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlocked ) ) ;
ActionList . MapAction ( Commands . ClearStreamingVolumes ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : ClearStreamingVolumes_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsUnlocked ) ) ;
//visibility
ActionList . MapAction ( Commands . ShowSelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : ShowSelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreLevelsSelected ) ) ;
ActionList . MapAction ( Commands . HideSelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : HideSelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreLevelsSelected ) ) ;
ActionList . MapAction ( Commands . ShowOnlySelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : ShowOnlySelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreLevelsSelected ) ) ;
ActionList . MapAction ( Commands . ShowAllLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : ShowAllLevels_Executed ) ) ;
ActionList . MapAction ( Commands . HideAllLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : HideAllLevels_Executed ) ) ;
//lock
ActionList . MapAction ( Commands . LockSelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : LockSelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsNotPersistent ) ) ;
ActionList . MapAction ( Commands . UnockSelectedLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : UnockSelectedLevels_Executed ) ,
FCanExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : AreSelectedLevelsNotPersistent ) ) ;
ActionList . MapAction ( Commands . LockAllLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : LockAllLevels_Executed ) ) ;
ActionList . MapAction ( Commands . UnockAllLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : UnockAllLevels_Executed ) ) ;
ActionList . MapAction ( Commands . LockReadOnlyLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : ToggleReadOnlyLevels_Executed ) ) ;
ActionList . MapAction ( Commands . UnlockReadOnlyLevels ,
FExecuteAction : : CreateSP ( this , & FLevelCollectionViewModel : : ToggleReadOnlyLevels_Executed ) ) ;
}
void FLevelCollectionViewModel : : ToggleReadOnlyLevels_Executed ( )
{
GEngine - > bLockReadOnlyLevels = ! GEngine - > bLockReadOnlyLevels ;
}
void FLevelCollectionViewModel : : OnToggleDisplayActorCount ( )
{
2014-05-21 11:16:12 -04:00
ULevelBrowserSettings * Settings = GetMutableDefault < ULevelBrowserSettings > ( ) ;
Settings - > bDisplayActorCount = ! Settings - > bDisplayActorCount ;
Settings - > PostEditChange ( ) ;
2014-03-14 14:13:41 -04:00
2014-05-21 11:16:12 -04:00
DisplayActorCountChanged . Broadcast ( Settings - > bDisplayActorCount ) ;
2014-03-14 14:13:41 -04:00
}
bool FLevelCollectionViewModel : : GetDisplayActorCountState ( ) const
{
2014-05-21 11:16:12 -04:00
return ( GetDefault < ULevelBrowserSettings > ( ) - > bDisplayActorCount ) ;
2014-03-14 14:13:41 -04:00
}
void FLevelCollectionViewModel : : OnToggleLightmassSize ( )
{
2014-05-21 11:16:12 -04:00
ULevelBrowserSettings * Settings = GetMutableDefault < ULevelBrowserSettings > ( ) ;
Settings - > bDisplayLightmassSize = ! GetDisplayLightmassSizeState ( ) ;
Settings - > PostEditChange ( ) ;
2014-03-14 14:13:41 -04:00
2014-05-21 11:16:12 -04:00
DisplayLightmassSizeChanged . Broadcast ( Settings - > bDisplayLightmassSize ) ;
2014-03-14 14:13:41 -04:00
}
bool FLevelCollectionViewModel : : GetDisplayLightmassSizeState ( ) const
{
2014-05-21 11:16:12 -04:00
return GetDefault < ULevelBrowserSettings > ( ) - > bDisplayLightmassSize ;
2014-03-14 14:13:41 -04:00
}
void FLevelCollectionViewModel : : OnToggleFileSize ( )
{
2014-05-21 11:16:12 -04:00
ULevelBrowserSettings * Settings = GetMutableDefault < ULevelBrowserSettings > ( ) ;
Settings - > bDisplayFileSize = ! GetDisplayFileSizeState ( ) ;
Settings - > PostEditChange ( ) ;
2014-03-14 14:13:41 -04:00
2014-05-21 11:16:12 -04:00
DisplayFileSizeChanged . Broadcast ( Settings - > bDisplayFileSize ) ;
2014-03-14 14:13:41 -04:00
}
bool FLevelCollectionViewModel : : GetDisplayFileSizeState ( ) const
{
2014-05-21 11:16:12 -04:00
return GetDefault < ULevelBrowserSettings > ( ) - > bDisplayFileSize ;
2014-03-14 14:13:41 -04:00
}
void FLevelCollectionViewModel : : OnToggleEditorOffset ( )
{
2014-05-21 11:16:12 -04:00
ULevelBrowserSettings * Settings = GetMutableDefault < ULevelBrowserSettings > ( ) ;
Settings - > bDisplayEditorOffset = ! Settings - > bDisplayEditorOffset ;
Settings - > PostEditChange ( ) ;
2014-03-14 14:13:41 -04:00
2014-05-21 11:16:12 -04:00
DisplayEditorOffsetChanged . Broadcast ( Settings - > bDisplayEditorOffset ) ;
2014-03-14 14:13:41 -04:00
}
bool FLevelCollectionViewModel : : GetDisplayEditorOffsetState ( ) const
{
2014-05-21 11:16:12 -04:00
return GetDefault < ULevelBrowserSettings > ( ) - > bDisplayEditorOffset ;
2014-03-14 14:13:41 -04:00
}
void FLevelCollectionViewModel : : OnToggleDisplayPaths ( )
{
2014-05-21 11:16:12 -04:00
ULevelBrowserSettings * Settings = GetMutableDefault < ULevelBrowserSettings > ( ) ;
Settings - > bDisplayPaths = ! GetDisplayPathsState ( ) ;
Settings - > PostEditChange ( ) ;
2014-03-14 14:13:41 -04:00
}
bool FLevelCollectionViewModel : : GetDisplayPathsState ( ) const
{
2014-05-21 11:16:12 -04:00
return ( GetDefault < ULevelBrowserSettings > ( ) - > bDisplayPaths ) ;
2014-03-14 14:13:41 -04:00
}
bool FLevelCollectionViewModel : : CanShiftSelection ( )
{
if ( ! IsOneLevelSelected ( ) )
{
return false ;
}
for ( int32 i = 0 ; i < SelectedLevels . Num ( ) ; + + i )
{
if ( ! SelectedLevels [ i ] . IsValid ( ) | | SelectedLevels [ i ] - > IsLocked ( ) | |
SelectedLevels [ i ] - > IsPersistent ( ) | | ! SelectedLevels [ i ] - > IsLevel ( ) )
{
return false ;
}
}
return true ;
}
void FLevelCollectionViewModel : : ShiftSelection ( bool bUp )
{
if ( ! CanShiftSelection ( ) )
{
return ;
}
if ( ! IsSelectedLevelUnlocked ( ) )
{
FMessageDialog : : Open ( EAppMsgType : : Ok , LOCTEXT ( " ShiftLevelLocked " , " Shift Level: The requested operation could not be completed because the level is locked. " ) ) ;
return ;
}
const ULevel * InLevel = SelectedLevels [ 0 ] - > GetLevel ( ) . Get ( ) ;
UWorld * OwningWorld = InLevel - > OwningWorld ;
check ( OwningWorld ) ;
int32 PrevFoundLevelIndex = - 1 ;
int32 FoundLevelIndex = - 1 ;
int32 PostFoundLevelIndex = - 1 ;
for ( int32 LevelIndex = 0 ; LevelIndex < OwningWorld - > StreamingLevels . Num ( ) ; + + LevelIndex )
{
ULevelStreaming * StreamingLevel = OwningWorld - > StreamingLevels [ LevelIndex ] ;
if ( StreamingLevel ! = NULL )
{
ULevel * Level = StreamingLevel - > GetLoadedLevel ( ) ;
if ( Level ! = NULL & & Level - > OwningWorld ! = NULL )
{
if ( FoundLevelIndex > - 1 )
{
// Mark the first valid index after the found level and stop searching.
PostFoundLevelIndex = LevelIndex ;
break ;
}
else
{
if ( Level = = InLevel )
{
// We've found the level.
FoundLevelIndex = LevelIndex ;
}
else
{
// Mark this level as being the index before the found level.
PrevFoundLevelIndex = LevelIndex ;
}
}
}
}
}
// If we found the level . . .
if ( FoundLevelIndex > - 1 )
{
// Check if we found a destination index to swap it to.
const int32 DestIndex = bUp ? PrevFoundLevelIndex : PostFoundLevelIndex ;
const bool bFoundPrePost = DestIndex > - 1 ;
if ( bFoundPrePost )
{
// Swap the level into position.
const FScopedTransaction Transaction ( NSLOCTEXT ( " UnrealEd " , " ShiftLevelInLevelBrowser " , " Shift level in Level Browser " ) ) ;
OwningWorld - > Modify ( ) ;
OwningWorld - > StreamingLevels . Swap ( FoundLevelIndex , DestIndex ) ;
OwningWorld - > MarkPackageDirty ( ) ;
}
}
RefreshSortIndexes ( ) ;
}
void FLevelCollectionViewModel : : AddFilter ( const TSharedRef < LevelFilter > & InFilter )
{
Filters - > Add ( InFilter ) ;
OnFilterChanged ( ) ;
}
void FLevelCollectionViewModel : : RemoveFilter ( const TSharedRef < LevelFilter > & InFilter )
{
Filters - > Remove ( InFilter ) ;
OnFilterChanged ( ) ;
}
TArray < TSharedPtr < FLevelViewModel > > & FLevelCollectionViewModel : : GetLevels ( )
{
return FilteredLevelViewModels ;
}
const TArray < TSharedPtr < FLevelViewModel > > & FLevelCollectionViewModel : : GetSelectedLevels ( ) const
{
return SelectedLevels ;
}
const TArray < TSharedPtr < FLevelViewModel > > & FLevelCollectionViewModel : : GetInvalidSelectedLevels ( ) const
{
return InvalidSelectedLevels ;
}
void FLevelCollectionViewModel : : GetSelectedLevelNames ( OUT TArray < FName > & OutSelectedLevelNames ) const
{
AppendSelectLevelNames ( OutSelectedLevelNames ) ;
}
void FLevelCollectionViewModel : : SetSelectedLevels ( const TArray < TSharedPtr < FLevelViewModel > > & InSelectedLevels )
{
InvalidSelectedLevels . Empty ( ) ;
TArray < class ULevel * > Levels ;
TArray < UPackage * > PackagesToUpdate ;
for ( auto LevelIter = InSelectedLevels . CreateConstIterator ( ) ; LevelIter ; + + LevelIter )
{
const auto LevelViewModel = * LevelIter ;
// Only add the level if its valid.
if ( LevelViewModel - > IsLevel ( ) )
{
ULevel * Level = LevelViewModel - > GetLevel ( ) . Get ( ) ;
if ( Level ! = NULL )
{
Levels . Add ( Level ) ;
if ( Level - > GetOutermost ( ) ! = NULL )
{
PackagesToUpdate . Add ( Level - > GetOutermost ( ) ) ;
}
}
}
else if ( LevelViewModel - > IsLevelStreaming ( ) )
{
InvalidSelectedLevels . AddUnique ( LevelViewModel ) ;
}
}
ISourceControlModule : : Get ( ) . QueueStatusUpdate ( PackagesToUpdate ) ;
// Pass this list to our own function
SetSelectedLevelsInWorld ( Levels ) ;
}
void FLevelCollectionViewModel : : SetSelectedLevels ( const TArray < FName > & LevelNames )
{
TArray < class ULevel * > Levels ;
TArray < UPackage * > PackagesToUpdate ;
for ( auto LevelIter = FilteredLevelViewModels . CreateConstIterator ( ) ; LevelIter ; + + LevelIter )
{
const auto LevelViewModel = * LevelIter ;
if ( LevelNames . Contains ( LevelViewModel - > GetFName ( ) ) )
{
// Only add the level if its valid and not a volume level.
if ( LevelViewModel - > IsLevel ( ) )
{
ULevel * Level = LevelViewModel - > GetLevel ( ) . Get ( ) ;
if ( Level ! = NULL )
{
Levels . Add ( Level ) ;
if ( Level - > GetOutermost ( ) ! = NULL )
{
PackagesToUpdate . Add ( Level - > GetOutermost ( ) ) ;
}
}
}
}
}
ISourceControlModule : : Get ( ) . QueueStatusUpdate ( PackagesToUpdate ) ;
// Pass this list to our own function
SetSelectedLevelsInWorld ( Levels ) ;
}
void FLevelCollectionViewModel : : SetSelectedLevelsInWorld ( const TArray < ULevel * > & Levels )
{
// Pass the list we just created to the world to set the selection
if ( CurrentWorld . IsValid ( ) )
{
CurrentWorld - > SetSelectedLevels ( Levels ) ;
}
}
void FLevelCollectionViewModel : : SetSelectedLevel ( const FName & LevelName )
{
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
TArray < class ULevel * > Levels ;
for ( auto LevelIter = FilteredLevelViewModels . CreateConstIterator ( ) ; LevelIter ; + + LevelIter )
{
const auto LevelViewModel = * LevelIter ;
if ( LevelName = = LevelViewModel - > GetFName ( ) )
{
// Only add the level if its valid and not a volume level.
if ( LevelViewModel - > IsLevel ( ) )
{
ULevel * Level = LevelViewModel - > GetLevel ( ) . Get ( ) ;
if ( Level ! = NULL )
{
Levels . AddUnique ( Level ) ;
if ( Level - > GetOutermost ( ) ! = NULL )
{
ISourceControlModule : : Get ( ) . QueueStatusUpdate ( Level - > GetOutermost ( ) ) ;
}
}
break ;
}
}
}
// Pass this list to our own function
SetSelectedLevelsInWorld ( Levels ) ;
}
const TSharedRef < FUICommandList > FLevelCollectionViewModel : : GetCommandList ( ) const
{
return CommandList ;
}
void FLevelCollectionViewModel : : BroadcastUpdateIfNotInRefresh ( )
{
if ( bIsRefreshing = = false )
{
LevelsChanged . Broadcast ( ELevelsAction : : Reset , NULL , NAME_None ) ;
}
}
void FLevelCollectionViewModel : : OnFilterChanged ( )
{
RefreshFilteredLevels ( ) ;
BroadcastUpdateIfNotInRefresh ( ) ;
}
void FLevelCollectionViewModel : : Refresh ( )
{
OnLevelsChanged ( ELevelsAction : : Reset , NULL , NAME_None ) ;
}
void FLevelCollectionViewModel : : RefreshSelected ( )
{
check ( ! bIsRefreshing ) ;
bIsRefreshing = true ;
SelectedLevels . Reset ( ) ;
if ( CurrentWorld . IsValid ( ) )
{
for ( auto LevelIter = FilteredLevelViewModels . CreateConstIterator ( ) ; LevelIter ; + + LevelIter )
{
const auto LevelViewModel = * LevelIter ;
// Only add the level if its valid.
if ( LevelViewModel - > IsLevel ( ) )
{
if ( CurrentWorld - > IsLevelSelected ( LevelViewModel - > GetLevel ( ) . Get ( ) ) = = true )
{
SelectedLevels . Add ( LevelViewModel ) ;
}
}
}
}
// Broadcast that we have changed our selection
SelectionChanged . Broadcast ( ) ;
BroadcastUpdateIfNotInRefresh ( ) ;
bIsRefreshing = false ;
}
void FLevelCollectionViewModel : : OnLevelsChanged ( const ELevelsAction : : Type Action , const TWeakObjectPtr < ULevel > & ChangedLevel , const FName & ChangedProperty )
{
check ( ! bIsRefreshing ) ;
bIsRefreshing = true ;
switch ( Action )
{
case ELevelsAction : : Add :
OnLevelAdded ( ChangedLevel ) ;
break ;
case ELevelsAction : : Rename :
//We purposely ignore re-filtering in this case
SortFilteredLevels ( ) ;
break ;
case ELevelsAction : : Modify :
RefreshFilteredLevels ( ) ;
break ;
case ELevelsAction : : Delete :
OnLevelDelete ( ) ;
break ;
case ELevelsAction : : Reset :
default :
OnResetLevels ( ) ;
break ;
}
LevelsChanged . Broadcast ( Action , ChangedLevel , ChangedProperty ) ;
bIsRefreshing = false ;
}
void FLevelCollectionViewModel : : CreateLocalArrays ( )
{
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
if ( CurrentWorld . IsValid ( ) )
{
TArray < ULevel * > Levels ;
for ( int32 iLevel = 0 ; iLevel < CurrentWorld - > GetNumLevels ( ) ; iLevel + + )
{
ULevel * Level = CurrentWorld - > GetLevel ( iLevel ) ;
if ( Level ! = NULL )
{
Levels . AddUnique ( Level ) ;
if ( Level - > GetOutermost ( ) ! = NULL )
{
ISourceControlModule : : Get ( ) . QueueStatusUpdate ( Level - > GetOutermost ( ) ) ;
}
}
}
TArray < ULevelStreaming * > LevelsStreaming ;
for ( int32 iLevel = 0 ; iLevel < CurrentWorld - > StreamingLevels . Num ( ) ; iLevel + + )
{
ULevelStreaming * StreamingLevel = CurrentWorld - > StreamingLevels [ iLevel ] ;
if ( StreamingLevel ! = NULL )
{
ULevel * Level = StreamingLevel - > GetLoadedLevel ( ) ;
if ( ! Levels . Contains ( Level ) )
{
LevelsStreaming . AddUnique ( StreamingLevel ) ;
}
}
}
CreateViewModels ( Levels , LevelsStreaming ) ;
}
}
void FLevelCollectionViewModel : : PopulateLevelsList ( )
{
DestructivelyPurgeInvalidViewModels ( ) ;
CreateLocalArrays ( ) ;
RefreshSortIndexes ( ) ;
SortFilteredLevels ( ) ;
UpdateLevelActorsCount ( ) ;
}
void FLevelCollectionViewModel : : RefreshSortIndexes ( )
{
for ( auto LevelIt = AllLevelViewModels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
// Only refresh the level if its valid.
if ( ( * LevelIt ) - > IsValid ( ) )
{
( * LevelIt ) - > RefreshStreamingLevelIndex ( ) ;
}
}
OnFilterChanged ( ) ;
}
void FLevelCollectionViewModel : : OnLevelAdded ( const TWeakObjectPtr < ULevel > & AddedLevel )
{
// Force a rebuild of the cached data
PopulateLevelsList ( ) ;
// Tell anyone that wants to know of changes
BroadcastUpdateIfNotInRefresh ( ) ;
}
void FLevelCollectionViewModel : : OnLevelDelete ( )
{
// Force a rebuild of the cached data
PopulateLevelsList ( ) ;
// Tell anyone that wants to know of changes
BroadcastUpdateIfNotInRefresh ( ) ;
}
void FLevelCollectionViewModel : : OnResetLevels ( )
{
// Force a rebuild of the cached data
PopulateLevelsList ( ) ;
// Tell anyone that wants to know of changes
BroadcastUpdateIfNotInRefresh ( ) ;
}
void FLevelCollectionViewModel : : DestructivelyPurgeInvalidViewModels ( )
{
for ( int LevelIndex = AllLevelViewModels . Num ( ) - 1 ; LevelIndex > = 0 ; - - LevelIndex )
{
const auto LevelViewModel = AllLevelViewModels [ LevelIndex ] ;
AllLevelViewModels . RemoveAt ( LevelIndex ) ;
FilteredLevelViewModels . Remove ( LevelViewModel ) ;
SelectedLevels . Remove ( LevelViewModel ) ;
}
}
void FLevelCollectionViewModel : : CreateViewModels ( const TArray < ULevel * > & InLevels , const TArray < ULevelStreaming * > & InLevelStreaming )
{
//InLevels
for ( auto LevelIt = InLevels . CreateConstIterator ( ) ; LevelIt ; + + LevelIt )
{
if ( * LevelIt )
{
const TSharedRef < FLevelViewModel > NewLevelViewModel = FLevelViewModel : : Create ( * LevelIt , NULL , Editor ) ;
AllLevelViewModels . Add ( NewLevelViewModel ) ;
if ( Filters - > PassesAllFilters ( NewLevelViewModel ) )
{
FilteredLevelViewModels . Add ( NewLevelViewModel ) ;
}
}
}
//InStreamedLevels
for ( auto LevelStreamingIt = InLevelStreaming . CreateConstIterator ( ) ; LevelStreamingIt ; + + LevelStreamingIt )
{
ULevelStreaming * LevelStreaming = * LevelStreamingIt ;
if ( LevelStreaming ! = NULL )
{
const TSharedRef < FLevelViewModel > NewLevelViewModel = FLevelViewModel : : Create ( LevelStreaming - > GetLoadedLevel ( ) , LevelStreaming , Editor ) ;
AllLevelViewModels . Add ( NewLevelViewModel ) ;
if ( Filters - > PassesAllFilters ( NewLevelViewModel ) )
{
FilteredLevelViewModels . Add ( NewLevelViewModel ) ;
}
}
}
}
void FLevelCollectionViewModel : : ClearStreamingLevelVolumes ( )
{
for ( auto LevelIt = SelectedLevels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
// Only process the level if its valid.
if ( ( * LevelIt ) - > IsValid ( ) )
{
ULevelStreaming * StreamingLevel = FLevelUtils : : FindStreamingLevel ( ( * LevelIt ) - > GetLevel ( ) . Get ( ) ) ;
if ( StreamingLevel )
{
StreamingLevel - > Modify ( ) ;
// Disassociate the level from the volume.
for ( int32 i = 0 ; i < StreamingLevel - > EditorStreamingVolumes . Num ( ) ; + + i )
{
ALevelStreamingVolume * LevelStreamingVolume = StreamingLevel - > EditorStreamingVolumes [ i ] ;
if ( LevelStreamingVolume )
{
LevelStreamingVolume - > Modify ( ) ;
2014-08-25 11:05:29 -04:00
LevelStreamingVolume - > StreamingLevelNames . Remove ( StreamingLevel - > GetWorldAssetPackageFName ( ) ) ;
2014-03-14 14:13:41 -04:00
}
}
// Disassociate the volumes from the level.
StreamingLevel - > EditorStreamingVolumes . Empty ( ) ;
}
}
}
}
void FLevelCollectionViewModel : : RefreshFilteredLevels ( )
{
FilteredLevelViewModels . Empty ( ) ;
for ( auto LevelIt = AllLevelViewModels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
const auto LevelViewModel = * LevelIt ;
// Only add valid levels.
if ( LevelViewModel - > IsValid ( ) )
{
if ( Filters - > PassesAllFilters ( LevelViewModel ) )
{
FilteredLevelViewModels . Add ( LevelViewModel ) ;
}
}
}
SortFilteredLevels ( ) ;
}
void FLevelCollectionViewModel : : SortFilteredLevels ( )
{
struct FCompareLevels
{
FORCEINLINE bool operator ( ) ( const TSharedPtr < FLevelViewModel > & Lhs , const TSharedPtr < FLevelViewModel > & Rhs ) const
{
//First, sort the ViewModels into tiers:
//Persistent Level
//Streaming Levels
int LeftTier = 0 ;
int RightTier = 0 ;
if ( Lhs - > IsLevel ( ) )
{
LeftTier = ( Lhs - > IsPersistent ( ) ) ? 1 : 2 ;
}
if ( Rhs - > IsLevel ( ) )
{
RightTier = ( Rhs - > IsPersistent ( ) ) ? 1 : 2 ;
}
if ( LeftTier ! = RightTier )
{
//Sort the tiers
return ( LeftTier < RightTier ) ;
}
else
{
//Within the Streaming Levels tier, sort by a user-defined order.
return ( Lhs - > GetStreamingLevelIndex ( ) < Rhs - > GetStreamingLevelIndex ( ) ) ;
}
return false ;
}
} ;
FilteredLevelViewModels . Sort ( FCompareLevels ( ) ) ;
}
void FLevelCollectionViewModel : : AppendSelectLevelNames ( TArray < FName > & OutLevelNames ) const
{
for ( auto LevelsIt = SelectedLevels . CreateConstIterator ( ) ; LevelsIt ; + + LevelsIt )
{
const TSharedPtr < FLevelViewModel > & Level = * LevelsIt ;
OutLevelNames . Add ( Level - > GetFName ( ) ) ;
}
}
void FLevelCollectionViewModel : : GetSelectedLevelPackages ( TArray < UPackage * > * OutSelectedPackages , TArray < FString > * OutSelectedPackagesNames )
{
for ( auto SelectedLevelIt = SelectedLevels . CreateIterator ( ) ; SelectedLevelIt ; + + SelectedLevelIt )
{
if ( ( * SelectedLevelIt ) - > GetLevel ( ) . IsValid ( ) )
{
ULevel * CurrentLevel = ( * SelectedLevelIt ) - > GetLevel ( ) . Get ( ) ;
if ( OutSelectedPackages )
{
( * OutSelectedPackages ) . Add ( CurrentLevel - > GetOutermost ( ) ) ;
}
if ( OutSelectedPackagesNames )
{
( * OutSelectedPackagesNames ) . Add ( CurrentLevel - > GetOutermost ( ) - > GetName ( ) ) ;
}
}
}
}
//delegates
bool FLevelCollectionViewModel : : IsOneLevelSelected ( ) const
{
return ( SelectedLevels . Num ( ) = = 1 ) ;
}
bool FLevelCollectionViewModel : : IsSelectedLevelUnlocked ( ) const
{
if ( ! IsOneLevelSelected ( ) )
{
return false ;
}
return ( SelectedLevels [ 0 ] . IsValid ( ) & & ! SelectedLevels [ 0 ] - > IsLocked ( ) ) ;
}
bool FLevelCollectionViewModel : : AreLevelsSelected ( ) const
{
return ( SelectedLevels . Num ( ) > 0 ) ;
}
bool FLevelCollectionViewModel : : AreSelectedLevelsUnlocked ( ) const
{
if ( ! AreLevelsSelected ( ) )
{
return false ;
}
for ( int32 i = 0 ; i < SelectedLevels . Num ( ) ; + + i )
{
if ( ! SelectedLevels [ i ] . IsValid ( ) | | SelectedLevels [ i ] - > IsLocked ( ) )
{
return false ;
}
}
return true ;
}
bool FLevelCollectionViewModel : : AreSelectedLevelsNotPersistent ( ) const
{
if ( ! AreLevelsSelected ( ) )
{
return false ;
}
for ( int32 i = 0 ; i < SelectedLevels . Num ( ) ; + + i )
{
if ( ! SelectedLevels [ i ] . IsValid ( ) | | SelectedLevels [ i ] - > IsPersistent ( ) )
{
return false ;
}
}
return true ;
}
bool FLevelCollectionViewModel : : AreSelectedLevelsUnlockedAndNotPersistent ( ) const
{
if ( ! AreLevelsSelected ( ) )
{
return false ;
}
for ( int32 i = 0 ; i < SelectedLevels . Num ( ) ; + + i )
{
if ( ! SelectedLevels [ i ] . IsValid ( ) | | SelectedLevels [ i ] - > IsLocked ( ) | | SelectedLevels [ i ] - > IsPersistent ( ) )
{
return false ;
}
}
return true ;
}
2014-06-23 06:42:01 -04:00
bool FLevelCollectionViewModel : : AreAllSelectedLevelsUnlockedAndVisible ( ) const
{
for ( const auto & Level : SelectedLevels )
{
if ( Level - > IsLocked ( ) = = true | |
Level - > IsVisible ( ) = = false )
{
return false ;
}
}
return SelectedLevels . Num ( ) > 0 ;
}
2014-03-14 14:13:41 -04:00
bool FLevelCollectionViewModel : : AreActorsSelected ( ) const
{
return Editor - > GetSelectedActorCount ( ) > 0 ;
}
bool FLevelCollectionViewModel : : CanEditProperties ( ) const
{
if ( ! AreLevelsSelected ( ) )
{
return false ;
}
for ( int32 i = 0 ; i < SelectedLevels . Num ( ) ; + + i )
{
if ( ! SelectedLevels [ i ] . IsValid ( ) | | SelectedLevels [ i ] - > IsLocked ( ) | | SelectedLevels [ i ] - > IsPersistent ( ) )
{
return false ;
}
}
return true ;
}
bool FLevelCollectionViewModel : : CanAddOrSelectStreamingVolumes ( ) const
{
bool bStreamingLevelVolumeSelected = false ;
for ( FSelectionIterator It ( GEditor - > GetSelectedActorIterator ( ) ) ; It ; + + It )
{
const ALevelStreamingVolume * StreamingVolume = Cast < ALevelStreamingVolume > ( * It ) ;
if ( StreamingVolume & & StreamingVolume - > GetLevel ( ) = = GWorld - > PersistentLevel )
{
bStreamingLevelVolumeSelected = true ;
break ;
}
}
return ! bStreamingLevelVolumeSelected ? false : AreSelectedLevelsUnlocked ( ) ;
}
//selected level
void FLevelCollectionViewModel : : MakeLevelCurrent_Executed ( )
{
check ( SelectedLevels . Num ( ) = = 1 ) ;
SelectedLevels [ 0 ] - > MakeLevelCurrent ( ) ;
}
void FLevelCollectionViewModel : : EditProperties_Executed ( )
{
//Remove any selected actor info from the Inspector and the Property views.
GEditor - > SelectNone ( true , true ) ;
TArray < UObject * > SelectedObjects ;
for ( auto SelectedLevelIt = SelectedLevels . CreateIterator ( ) ; SelectedLevelIt ; + + SelectedLevelIt )
{
if ( ( * SelectedLevelIt ) - > IsLevelStreaming ( ) )
{
ULevelStreaming * LevelStreaming = ( * SelectedLevelIt ) - > GetLevelStreaming ( ) . Get ( ) ;
SelectedObjects . Add ( LevelStreaming ) ;
}
}
if ( SelectedObjects . Num ( ) > 0 )
{
IMainFrameModule & MainFrameModule = FModuleManager : : LoadModuleChecked < IMainFrameModule > ( TEXT ( " MainFrame " ) ) ;
FPropertyEditorModule & PropertyEditorModule = FModuleManager : : LoadModuleChecked < FPropertyEditorModule > ( TEXT ( " PropertyEditor " ) ) ;
// If the slate main frame is shown, summon a new property viewer in the Level editor module
if ( MainFrameModule . IsWindowInitialized ( ) )
{
FLevelEditorModule & LevelEditorModule = FModuleManager : : GetModuleChecked < FLevelEditorModule > ( TEXT ( " LevelEditor " ) ) ;
LevelEditorModule . SummonSelectionDetails ( ) ;
}
else // create a floating property window if the slate main frame is not initialized
{
PropertyEditorModule . CreateFloatingDetailsView ( SelectedObjects , true ) ;
}
GUnrealEd - > UpdateFloatingPropertyWindowsFromActorList ( SelectedObjects ) ;
}
}
void FLevelCollectionViewModel : : MoveActorsToSelected_Executed ( )
{
// We shouldn't be able to get here if we have more than 1 level selected. But just in case lets check.
2014-07-21 04:58:19 -04:00
if ( SelectedLevels . Num ( ) = = 1 )
{
// If matinee is open, and if an actor being moved belongs to it, message the user
if ( GLevelEditorModeTools ( ) . IsModeActive ( FBuiltinEditorModes : : EM_InterpEdit ) )
{
const FEdModeInterpEdit * InterpEditMode = ( const FEdModeInterpEdit * ) GLevelEditorModeTools ( ) . GetActiveMode ( FBuiltinEditorModes : : EM_InterpEdit ) ;
if ( InterpEditMode & & InterpEditMode - > MatineeActor )
{
TArray < AActor * > ControlledActors ;
InterpEditMode - > MatineeActor - > GetControlledActors ( ControlledActors ) ;
2014-07-31 06:08:14 -04:00
// are any of the selected actors in the matinee
USelection * SelectedActors = GEditor - > GetSelectedActors ( ) ;
for ( FSelectionIterator Iter ( * SelectedActors ) ; Iter ; + + Iter )
2014-07-21 04:58:19 -04:00
{
2014-07-31 06:08:14 -04:00
AActor * Actor = CastChecked < AActor > ( * Iter ) ;
if ( Actor ! = nullptr & & ( Actor = = InterpEditMode - > MatineeActor | | ControlledActors . Contains ( Actor ) ) )
2014-07-21 04:58:19 -04:00
{
2014-07-31 06:08:14 -04:00
const bool ExitInterp = EAppReturnType : : Yes = = FMessageDialog : : Open ( EAppMsgType : : YesNo , NSLOCTEXT ( " UnrealEd " , " MatineeUnableToMove " , " You must close Matinee before moving actors. \n Do you wish to do this now and continue? " ) ) ;
if ( ! ExitInterp )
2014-07-21 04:58:19 -04:00
{
2014-07-31 06:08:14 -04:00
return ;
2014-07-21 04:58:19 -04:00
}
2014-07-31 06:08:14 -04:00
GLevelEditorModeTools ( ) . DeactivateMode ( FBuiltinEditorModes : : EM_InterpEdit ) ;
break ;
2014-07-21 04:58:19 -04:00
}
}
}
}
2014-03-14 14:13:41 -04:00
GEditor - > MoveSelectedActorsToLevel ( SelectedLevels [ 0 ] - > GetLevel ( ) . Get ( ) ) ;
}
}
//levels
void FLevelCollectionViewModel : : SaveSelectedLevels_Executed ( )
{
// NOTE: We'll build a list of levels to save here. We don't want to use the SelectedLevels member
// since that list will be reset when Serialize is called
TArray < ULevel * > LevelsToSave ;
for ( auto SelectedLevelIt = SelectedLevels . CreateIterator ( ) ; SelectedLevelIt ; + + SelectedLevelIt )
{
if ( ( * SelectedLevelIt ) - > GetLevel ( ) . IsValid ( ) )
{
LevelsToSave . Add ( ( * SelectedLevelIt ) - > GetLevel ( ) . Get ( ) ) ;
}
}
TArray < UPackage * > PackagesNotNeedingCheckout ;
// Prompt the user to check out the levels from source control before saving
if ( FEditorFileUtils : : PromptToCheckoutLevels ( false , LevelsToSave , & PackagesNotNeedingCheckout ) )
{
for ( auto LevelToSaveIt = LevelsToSave . CreateIterator ( ) ; LevelToSaveIt ; + + LevelToSaveIt )
{
FEditorFileUtils : : SaveLevel ( * LevelToSaveIt ) ;
}
}
else if ( PackagesNotNeedingCheckout . Num ( ) > 0 )
{
// The user canceled the checkout dialog but some packages didnt need to be checked out in order to save
// For each selected level if the package its in didnt need to be saved, save the level!
for ( auto LevelToSaveIt = LevelsToSave . CreateIterator ( ) ; LevelToSaveIt ; + + LevelToSaveIt )
{
ULevel * Level = * LevelToSaveIt ;
if ( PackagesNotNeedingCheckout . Contains ( Level - > GetOutermost ( ) ) )
{
FEditorFileUtils : : SaveLevel ( Level ) ;
}
else
{
//remove it from the list, so that only successfully saved levels are highlighted when saving is complete
LevelsToSave . Remove ( Level ) ;
}
}
}
// Select the levels that were saved successfully
SetSelectedLevelsInWorld ( LevelsToSave ) ;
}
void FLevelCollectionViewModel : : OnSCCCheckOut ( )
{
TArray < UPackage * > PackagesToCheckOut ;
GetSelectedLevelPackages ( & PackagesToCheckOut , NULL ) ;
// Update the source control status of all potentially relevant packages
ISourceControlModule : : Get ( ) . GetProvider ( ) . Execute ( ISourceControlOperation : : Create < FUpdateStatus > ( ) , PackagesToCheckOut ) ;
// Now check them out
FEditorFileUtils : : CheckoutPackages ( PackagesToCheckOut ) ;
}
void FLevelCollectionViewModel : : OnSCCCheckIn ( )
{
TArray < UPackage * > Packages ;
TArray < FString > PackageNames ;
GetSelectedLevelPackages ( & Packages , & PackageNames ) ;
// Prompt the user to ask if they would like to first save any dirty packages they are trying to check-in
const FEditorFileUtils : : EPromptReturnCode UserResponse = FEditorFileUtils : : PromptForCheckoutAndSave ( Packages , true , true ) ;
// If the user elected to save dirty packages, but one or more of the packages failed to save properly OR if the user
// canceled out of the prompt, don't follow through on the check-in process
const bool bShouldProceed = ( UserResponse = = FEditorFileUtils : : EPromptReturnCode : : PR_Success | | UserResponse = = FEditorFileUtils : : EPromptReturnCode : : PR_Declined ) ;
if ( bShouldProceed )
{
FSourceControlWindows : : PromptForCheckin ( PackageNames ) ;
}
else
{
// If a failure occurred, alert the user that the check-in was aborted. This warning shouldn't be necessary if the user cancelled
// from the dialog, because they obviously intended to cancel the whole operation.
if ( UserResponse = = FEditorFileUtils : : EPromptReturnCode : : PR_Failure )
{
FMessageDialog : : Open ( EAppMsgType : : Ok , NSLOCTEXT ( " UnrealEd " , " SCC_Checkin_Aborted " , " Check-in aborted as a result of save failure. " ) ) ;
}
}
}
void FLevelCollectionViewModel : : OnSCCOpenForAdd ( )
{
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
TArray < FString > PackageNames ;
GetSelectedLevelPackages ( NULL , & PackageNames ) ;
TArray < FString > PackagesToAdd ;
TArray < UPackage * > PackagesToSave ;
for ( auto PackageIt = PackageNames . CreateConstIterator ( ) ; PackageIt ; + + PackageIt )
{
const FSourceControlStatePtr SourceControlState = SourceControlProvider . GetState ( SourceControlHelpers : : PackageFilename ( * PackageIt ) , EStateCacheUsage : : Use ) ;
if ( SourceControlState . IsValid ( ) & & ! SourceControlState - > IsSourceControlled ( ) )
{
PackagesToAdd . Add ( * PackageIt ) ;
// Make sure the file actually exists on disk before adding it
FString Filename ;
if ( ! FPackageName : : DoesPackageExist ( * PackageIt , NULL , & Filename ) )
{
UPackage * Package = FindPackage ( NULL , * * PackageIt ) ;
if ( Package )
{
PackagesToSave . Add ( Package ) ;
}
}
}
}
if ( PackagesToAdd . Num ( ) > 0 )
{
// If any of the packages are new, save them now
if ( PackagesToSave . Num ( ) > 0 )
{
const bool bCheckDirty = false ;
const bool bPromptToSave = false ;
const FEditorFileUtils : : EPromptReturnCode Return = FEditorFileUtils : : PromptForCheckoutAndSave ( PackagesToSave , bCheckDirty , bPromptToSave ) ;
}
SourceControlProvider . Execute ( ISourceControlOperation : : Create < FMarkForAdd > ( ) , SourceControlHelpers : : PackageFilenames ( PackagesToAdd ) ) ;
}
}
void FLevelCollectionViewModel : : OnSCCHistory ( )
{
TArray < FString > PackageNames ;
for ( auto SelectedLevelIt = SelectedLevels . CreateIterator ( ) ; SelectedLevelIt ; + + SelectedLevelIt )
{
if ( ( * SelectedLevelIt ) - > GetLevel ( ) . IsValid ( ) )
{
PackageNames . Add ( ( * SelectedLevelIt ) - > GetLevel ( ) . Get ( ) - > GetOutermost ( ) - > GetName ( ) ) ;
}
}
FSourceControlWindows : : DisplayRevisionHistory ( SourceControlHelpers : : PackageFilenames ( PackageNames ) ) ;
}
void FLevelCollectionViewModel : : OnSCCRefresh ( )
{
if ( ISourceControlModule : : Get ( ) . IsEnabled ( ) )
{
TArray < UPackage * > Packages ;
for ( auto SelectedLevelIt = SelectedLevels . CreateIterator ( ) ; SelectedLevelIt ; + + SelectedLevelIt )
{
if ( ( * SelectedLevelIt ) - > GetLevel ( ) . IsValid ( ) )
{
Packages . Add ( ( * SelectedLevelIt ) - > GetLevel ( ) . Get ( ) - > GetOutermost ( ) ) ;
}
}
ISourceControlModule : : Get ( ) . QueueStatusUpdate ( Packages ) ;
}
}
void FLevelCollectionViewModel : : OnSCCDiffAgainstDepot ( )
{
// Load the asset registry module
FAssetToolsModule & AssetToolsModule = FModuleManager : : GetModuleChecked < FAssetToolsModule > ( " AssetTools " ) ;
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
// Iterate over each selected asset
for ( auto SelectedLevelIt = SelectedLevels . CreateIterator ( ) ; SelectedLevelIt ; + + SelectedLevelIt )
{
UPackage * OriginalPackage = ( * SelectedLevelIt ) - > GetLevel ( ) . Get ( ) - > GetOutermost ( ) ;
FString PackageName = OriginalPackage - > GetName ( ) ;
// Make sure our history is up to date
TSharedRef < FUpdateStatus , ESPMode : : ThreadSafe > UpdateStatusOperation = ISourceControlOperation : : Create < FUpdateStatus > ( ) ;
UpdateStatusOperation - > SetUpdateHistory ( true ) ;
SourceControlProvider . Execute ( UpdateStatusOperation , OriginalPackage ) ;
// Get the SCC state
FSourceControlStatePtr SourceControlState = SourceControlProvider . GetState ( OriginalPackage , EStateCacheUsage : : Use ) ;
// If the level is in SCC.
if ( SourceControlState . IsValid ( ) & & SourceControlState - > IsSourceControlled ( ) )
{
// Get the file name of package
FString RelativeFileName ;
if ( FPackageName : : DoesPackageExist ( PackageName , NULL , & RelativeFileName ) )
{
if ( SourceControlState - > GetHistorySize ( ) > 0 )
{
TSharedPtr < ISourceControlRevision , ESPMode : : ThreadSafe > Revision = SourceControlState - > GetHistoryItem ( 0 ) ;
check ( Revision . IsValid ( ) ) ;
// Get the head revision of this package from source control
FString AbsoluteFileName = FPaths : : ConvertRelativePathToFull ( RelativeFileName ) ;
FString TempFileName ;
if ( Revision - > Get ( TempFileName ) )
{
// 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 that package
FText NotMapReason ;
UPackage * OldPackage = LoadPackage ( NULL , * TempFileName , LOAD_None ) ;
if ( OldPackage ! = NULL & & GEditor - > PackageIsAMapFile ( * TempFileName , NotMapReason ) )
{
/* Set the revision information*/
UPackage * Package = OriginalPackage ;
FRevisionInfo OldRevision ;
OldRevision . Changelist = Revision - > GetCheckInIdentifier ( ) ;
OldRevision . Date = Revision - > GetDate ( ) ;
OldRevision . Revision = Revision - > GetRevisionNumber ( ) ;
FRevisionInfo NewRevision ;
NewRevision . Revision = - 1 ;
// Dump assets to temp text files
FString OldTextFilename = AssetToolsModule . Get ( ) . DumpAssetToTempFile ( OldPackage ) ;
FString NewTextFilename = AssetToolsModule . Get ( ) . DumpAssetToTempFile ( OriginalPackage ) ;
FString DiffCommand = GetDefault < UEditorLoadingSavingSettings > ( ) - > TextDiffToolPath . FilePath ;
2014-05-01 08:53:08 -04:00
AssetToolsModule . Get ( ) . CreateDiffProcess ( DiffCommand , OldTextFilename , NewTextFilename ) ;
2014-03-14 14:13:41 -04:00
AssetToolsModule . Get ( ) . DiffAssets ( OldPackage , OriginalPackage , OldRevision , NewRevision ) ;
}
}
}
}
}
}
}
void FLevelCollectionViewModel : : OnSCCConnect ( ) const
{
ISourceControlModule : : Get ( ) . ShowLoginDialog ( FSourceControlLoginClosed ( ) , ELoginWindowMode : : Modeless ) ;
}
void FLevelCollectionViewModel : : MigrateSelectedLevels_Executed ( )
{
// Gather the package names for the levels
TArray < FName > PackageNames ;
for ( auto SelectedLevelIt = SelectedLevels . CreateIterator ( ) ; SelectedLevelIt ; + + SelectedLevelIt )
{
if ( UObject * Level = ( * SelectedLevelIt ) - > GetLevel ( ) . Get ( ) )
{
PackageNames . Add ( Level - > GetOutermost ( ) - > GetFName ( ) ) ;
}
}
FAssetToolsModule & AssetToolsModule = FModuleManager : : Get ( ) . LoadModuleChecked < FAssetToolsModule > ( " AssetTools " ) ;
AssetToolsModule . Get ( ) . MigratePackages ( PackageNames ) ;
}
void FLevelCollectionViewModel : : CreateEmptyLevel_Executed ( )
{
EditorLevelUtils : : CreateNewLevel ( CurrentWorld . Get ( ) , false , AddedLevelStreamingClass ) ;
}
void FLevelCollectionViewModel : : AddExistingLevel_Executed ( )
{
AddExistingLevel ( ) ;
}
2014-06-30 19:03:07 -04:00
void FLevelCollectionViewModel : : AddExistingLevel ( bool bRemoveInvalidSelectedLevelsAfter )
2014-03-14 14:13:41 -04:00
{
2014-08-13 15:24:26 -04:00
if ( UEditorEngine : : IsUsingWorldAssets ( ) )
2014-03-14 14:13:41 -04:00
{
2014-06-30 19:03:07 -04:00
FEditorFileUtils : : FOnLevelsChosen LevelsChosenDelegate = FEditorFileUtils : : FOnLevelsChosen : : CreateSP ( this , & FLevelCollectionViewModel : : HandleAddExistingLevelSelected , bRemoveInvalidSelectedLevelsAfter ) ;
const bool bAllowMultipleSelection = true ;
FEditorFileUtils : : OpenLevelPickingDialog ( LevelsChosenDelegate , bAllowMultipleSelection ) ;
}
else
{
TArray < FString > OpenFilenames ;
IDesktopPlatform * DesktopPlatform = FDesktopPlatformModule : : Get ( ) ;
bool bOpened = false ;
if ( DesktopPlatform )
2014-03-14 14:13:41 -04:00
{
2014-06-30 19:03:07 -04:00
void * ParentWindowWindowHandle = NULL ;
IMainFrameModule & MainFrameModule = FModuleManager : : LoadModuleChecked < IMainFrameModule > ( TEXT ( " MainFrame " ) ) ;
const TSharedPtr < SWindow > & MainFrameParentWindow = MainFrameModule . GetParentWindow ( ) ;
if ( MainFrameParentWindow . IsValid ( ) & & MainFrameParentWindow - > GetNativeWindow ( ) . IsValid ( ) )
{
ParentWindowWindowHandle = MainFrameParentWindow - > GetNativeWindow ( ) - > GetOSWindowHandle ( ) ;
}
bOpened = DesktopPlatform - > OpenFileDialog (
ParentWindowWindowHandle ,
NSLOCTEXT ( " UnrealEd " , " Open " , " Open " ) . ToString ( ) ,
* FEditorDirectories : : Get ( ) . GetLastDirectory ( ELastDirectory : : UNR ) ,
TEXT ( " " ) ,
* FEditorFileUtils : : GetFilterString ( FI_Load ) ,
EFileDialogFlags : : Multiple ,
OpenFilenames
) ;
2014-03-14 14:13:41 -04:00
}
2014-06-30 19:03:07 -04:00
if ( bOpened )
{
// Save the path as default for next time
FEditorDirectories : : Get ( ) . SetLastDirectory ( ELastDirectory : : UNR , FPaths : : GetPath ( OpenFilenames [ 0 ] ) ) ;
TArray < FString > Filenames ;
for ( int32 FileIndex = 0 ; FileIndex < OpenFilenames . Num ( ) ; + + FileIndex )
{
// Strip paths from to get the level package names.
const FString FilePath ( OpenFilenames [ FileIndex ] ) ;
// make sure the level is in our package cache, because the async loading code will use this to find it
if ( ! FPaths : : FileExists ( FilePath ) )
{
FMessageDialog : : Open ( EAppMsgType : : Ok , NSLOCTEXT ( " UnrealEd " , " Error_LevelImportFromExternal " , " Importing external sublevels is not allowed. Move the level files into the standard content directory and try again. \n After moving the level(s), restart the editor. " ) ) ;
return ;
}
FText ErrorMessage ;
bool bFilenameIsValid = FEditorFileUtils : : IsValidMapFilename ( OpenFilenames [ FileIndex ] , ErrorMessage ) ;
if ( ! bFilenameIsValid )
{
// Start the loop over, prompting for save again
const FText DisplayFilename = FText : : FromString ( IFileManager : : Get ( ) . ConvertToAbsolutePathForExternalAppForRead ( * OpenFilenames [ FileIndex ] ) ) ;
FFormatNamedArguments Arguments ;
Arguments . Add ( TEXT ( " Filename " ) , DisplayFilename ) ;
Arguments . Add ( TEXT ( " LineTerminators " ) , FText : : FromString ( LINE_TERMINATOR LINE_TERMINATOR ) ) ;
Arguments . Add ( TEXT ( " ErrorMessage " ) , ErrorMessage ) ;
const FText DisplayMessage = FText : : Format ( NSLOCTEXT ( " UnrealEd " , " Error_InvalidLevelToAdd " , " Unable to add streaming level {Filename}{LineTerminators}{ErrorMessage} " ) , Arguments ) ;
FMessageDialog : : Open ( EAppMsgType : : Ok , DisplayMessage ) ;
return ;
}
Filenames . Add ( FilePath ) ;
}
TArray < FString > PackageNames ;
for ( const auto & Filename : Filenames )
{
const FString & PackageName = FPackageName : : FilenameToLongPackageName ( Filename ) ;
PackageNames . Add ( PackageName ) ;
}
EditorLevelUtils : : AddLevelsToWorld ( CurrentWorld . Get ( ) , PackageNames , AddedLevelStreamingClass ) ;
if ( bRemoveInvalidSelectedLevelsAfter )
{
RemoveInvalidSelectedLevels_Executed ( ) ;
}
}
}
}
void FLevelCollectionViewModel : : HandleAddExistingLevelSelected ( const TArray < FAssetData > & SelectedAssets , bool bRemoveInvalidSelectedLevelsAfter )
{
TArray < FString > PackageNames ;
for ( const auto & AssetData : SelectedAssets )
{
PackageNames . Add ( AssetData . PackageName . ToString ( ) ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-30 19:03:07 -04:00
EditorLevelUtils : : AddLevelsToWorld ( CurrentWorld . Get ( ) , PackageNames , AddedLevelStreamingClass ) ;
if ( bRemoveInvalidSelectedLevelsAfter )
2014-03-14 14:13:41 -04:00
{
2014-06-30 19:03:07 -04:00
RemoveInvalidSelectedLevels_Executed ( ) ;
2014-03-14 14:13:41 -04:00
}
}
void FLevelCollectionViewModel : : AddSelectedActorsToNewLevel_Executed ( )
{
EditorLevelUtils : : CreateNewLevel ( CurrentWorld . Get ( ) , true , AddedLevelStreamingClass ) ;
}
void FLevelCollectionViewModel : : FixupInvalidReference_Executed ( )
{
// Browsing is essentially the same as adding an existing level
2014-06-30 19:03:07 -04:00
const bool bRemoveInvalidSelectedLevelsAfter = true ;
AddExistingLevel ( bRemoveInvalidSelectedLevelsAfter ) ;
2014-03-14 14:13:41 -04:00
}
void FLevelCollectionViewModel : : RemoveInvalidSelectedLevels_Executed ( )
{
for ( auto InvalidLevelIt = InvalidSelectedLevels . CreateIterator ( ) ; InvalidLevelIt ; + + InvalidLevelIt )
{
ULevelStreaming * LevelStreaming = ( * InvalidLevelIt ) - > GetLevelStreaming ( ) . Get ( ) ;
EditorLevelUtils : : RemoveInvalidLevelFromWorld ( LevelStreaming ) ;
}
// Force a rebuild of the cached data
PopulateLevelsList ( ) ;
}
void FLevelCollectionViewModel : : RemoveSelectedLevels_Executed ( )
{
// If we have dirty levels that can be removed from the world
bool bHaveDirtyLevels = false ;
// Gather levels to remove
TArray < ULevel * > LevelsToRemove ;
for ( auto LevelIt = SelectedLevels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
ULevel * CurLevel = ( * LevelIt ) - > GetLevel ( ) . Get ( ) ;
if ( CurLevel ! = NULL )
{
if ( CurLevel - > GetOutermost ( ) - > IsDirty ( ) & & ! FLevelUtils : : IsLevelLocked ( CurLevel ) )
{
// this level is dirty and can be removed from the world
bHaveDirtyLevels = true ;
}
LevelsToRemove . Add ( CurLevel ) ;
}
}
// Depending on the state of the level, create a warning message
FText LevelWarning = LOCTEXT ( " RemoveLevel_Undo " , " Removing levels cannot be undone. Proceed? " ) ;
if ( bHaveDirtyLevels )
{
LevelWarning = LOCTEXT ( " RemoveLevel_Dirty " , " Removing levels cannot be undone. Any changes to these levels will be lost. Proceed? " ) ;
}
// Ask the user if they really wish to remove the level(s)
FSuppressableWarningDialog : : FSetupInfo Info ( LevelWarning , LOCTEXT ( " RemoveLevel_Message " , " Remove Level " ) , " RemoveLevelWarning " ) ;
Info . ConfirmText = LOCTEXT ( " RemoveLevel_Yes " , " Yes " ) ;
Info . CancelText = LOCTEXT ( " RemoveLevel_No " , " No " ) ;
FSuppressableWarningDialog RemoveLevelWarning ( Info ) ;
if ( RemoveLevelWarning . ShowModal ( ) = = FSuppressableWarningDialog : : Cancel )
{
return ;
}
// If matinee is opened, and if it belongs to the level being removed, close it
2014-06-18 10:16:16 -04:00
if ( GLevelEditorModeTools ( ) . IsModeActive ( FBuiltinEditorModes : : EM_InterpEdit ) )
2014-03-14 14:13:41 -04:00
{
2014-06-18 10:16:16 -04:00
const FEdModeInterpEdit * InterpEditMode = ( const FEdModeInterpEdit * ) GLevelEditorModeTools ( ) . GetActiveMode ( FBuiltinEditorModes : : EM_InterpEdit ) ;
2014-03-14 14:13:41 -04:00
if ( InterpEditMode & & InterpEditMode - > MatineeActor & & LevelsToRemove . Contains ( InterpEditMode - > MatineeActor - > GetLevel ( ) ) )
{
2014-06-18 10:16:16 -04:00
GLevelEditorModeTools ( ) . ActivateDefaultMode ( ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-06-18 10:16:16 -04:00
else if ( GLevelEditorModeTools ( ) . IsModeActive ( FBuiltinEditorModes : : EM_Landscape ) )
2014-03-14 14:13:41 -04:00
{
2014-06-18 10:16:16 -04:00
GLevelEditorModeTools ( ) . ActivateDefaultMode ( ) ;
2014-03-14 14:13:41 -04:00
}
// Disassociate selected levels from streaming volumes since the levels will be removed
ClearStreamingLevelVolumes ( ) ;
// Remove each level!
for ( auto LevelIt = LevelsToRemove . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
ULevel * CurLevel = ( * LevelIt ) ;
if ( ! FLevelUtils : : IsLevelLocked ( CurLevel ) )
{
// If the level isn't locked (which means it can be removed) unselect all actors before removing the level
// This avoids crashing in areas that rely on getting a selected actors level. The level will be invalid after its removed.
for ( int32 ActorIdx = 0 ; ActorIdx < CurLevel - > Actors . Num ( ) ; + + ActorIdx )
{
GEditor - > SelectActor ( CurLevel - > Actors [ ActorIdx ] , /*bInSelected=*/ false , /*bSelectEvenIfHidden=*/ false ) ;
}
}
EditorLevelUtils : : RemoveLevelFromWorld ( CurLevel ) ;
}
2014-06-19 06:56:28 -04:00
2014-03-14 14:13:41 -04:00
// Collect garbage to clear out the destroyed level
CollectGarbage ( GARBAGE_COLLECTION_KEEPFLAGS ) ;
}
void FLevelCollectionViewModel : : MergeSelectedLevels_Executed ( )
{
// Stash off a copy of the original array, so the selection can be restored
TArray < TSharedPtr < FLevelViewModel > > SelectedLevelsCopy ;
SelectedLevelsCopy . Append ( SelectedLevels ) ;
//make sure the selected levels are made visible (and thus fully loaded) before merging
ShowSelectedLevels_Executed ( ) ;
//restore the original selection and select all actors in the selected levels
SetSelectedLevels ( SelectedLevelsCopy ) ;
SelectActors_Executed ( ) ;
//Create a new level with the selected actors
ULevel * NewLevel = EditorLevelUtils : : CreateNewLevel ( CurrentWorld . Get ( ) , true , AddedLevelStreamingClass ) ;
//If the new level was successfully created (ie the user did not cancel)
if ( ( NewLevel ! = NULL ) & & ( CurrentWorld . IsValid ( ) ) )
{
if ( CurrentWorld - > SetCurrentLevel ( NewLevel ) )
{
FEditorDelegates : : NewCurrentLevel . Broadcast ( ) ;
}
GEditor - > NoteSelectionChange ( ) ;
//restore the original selection and remove the levels that were merged
SetSelectedLevels ( SelectedLevelsCopy ) ;
RemoveSelectedLevels_Executed ( ) ;
//select the resulting merged level for feedback
SetSelectedLevel ( NewLevel - > GetFName ( ) ) ;
}
}
void FLevelCollectionViewModel : : SetAddedLevelStreamingClass_Executed ( UClass * InClass )
{
AddedLevelStreamingClass = InClass ;
}
bool FLevelCollectionViewModel : : IsNewStreamingMethodChecked ( UClass * InClass ) const
{
return AddedLevelStreamingClass = = InClass ;
}
bool FLevelCollectionViewModel : : IsStreamingMethodChecked ( UClass * InClass ) const
{
for ( auto LevelIt = SelectedLevels . CreateConstIterator ( ) ; LevelIt ; + + LevelIt )
{
const TSharedPtr < FLevelViewModel > Level = * LevelIt ;
const TWeakObjectPtr < ULevelStreaming > LevelStreaming = Level - > GetLevelStreaming ( ) ;
if ( LevelStreaming . IsValid ( ) & & LevelStreaming - > GetClass ( ) = = InClass )
{
return true ;
}
}
return false ;
}
void FLevelCollectionViewModel : : SetStreamingLevelsClass_Executed ( UClass * InClass )
{
// First prompt to save the selected levels, as changing the streaming method will unload/reload them
SaveSelectedLevels_Executed ( ) ;
// Stash off a copy of the original array, as changing the streaming method can destroy the selection
TArray < TSharedPtr < FLevelViewModel > > SelectedLevelsCopy ;
SelectedLevelsCopy . Append ( SelectedLevels ) ;
// Apply the new streaming method to the selected levels
for ( auto LevelsToChangeIt = SelectedLevelsCopy . CreateIterator ( ) ; LevelsToChangeIt ; + + LevelsToChangeIt )
{
( * LevelsToChangeIt ) - > SetStreamingClass ( InClass ) ;
}
SetSelectedLevels ( SelectedLevelsCopy ) ;
}
//level selection
void FLevelCollectionViewModel : : SelectAllLevels_Executed ( )
{
SetSelectedLevels ( FilteredLevelViewModels ) ;
}
void FLevelCollectionViewModel : : DeselectAllLevels_Executed ( )
{
TArray < TSharedPtr < FLevelViewModel > > NoLevels ;
SetSelectedLevels ( NoLevels ) ;
}
void FLevelCollectionViewModel : : InvertSelection_Executed ( )
{
TArray < TSharedPtr < FLevelViewModel > > InvertedLevels ;
for ( auto LevelIt = FilteredLevelViewModels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
// Only add the level if its valid
if ( ( * LevelIt ) - > IsValid ( ) )
{
if ( ! SelectedLevels . Contains ( * LevelIt ) )
{
InvertedLevels . Add ( * LevelIt ) ;
}
}
}
SetSelectedLevels ( InvertedLevels ) ;
}
//actors
void FLevelCollectionViewModel : : SelectActors_Executed ( )
{
//first clear any existing actor selection
const FScopedTransaction Transaction ( LOCTEXT ( " SelectActors " , " Select Actors in Level " ) ) ;
GEditor - > GetSelectedActors ( ) - > Modify ( ) ;
GEditor - > SelectNone ( false , true ) ;
for ( auto LevelIt = SelectedLevels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
if ( ( * LevelIt ) - > IsLevel ( ) )
{
( * LevelIt ) - > SelectActors ( /*bSelect*/ true , /*bNotify*/ true , /*bSelectEvenIfHidden*/ true ) ;
}
}
}
void FLevelCollectionViewModel : : DeselectActors_Executed ( )
{
const FScopedTransaction Transaction ( LOCTEXT ( " DeselectActors " , " Deselect Actors in Level " ) ) ;
for ( auto LevelIt = SelectedLevels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
if ( ( * LevelIt ) - > IsLevel ( ) )
{
( * LevelIt ) - > SelectActors ( /*bSelect*/ false , /*bNotify*/ true , /*bSelectEvenIfHidden*/ true ) ;
}
}
}
//streaming volumes
void FLevelCollectionViewModel : : SelectStreamingVolumes_Executed ( )
{
// Iterate over selected levels and make a list of volumes to select.
TArray < ALevelStreamingVolume * > LevelStreamingVolumesToSelect ;
for ( auto LevelIt = SelectedLevels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
// Only process the level if its valid.
if ( ( * LevelIt ) - > IsValid ( ) )
{
ULevelStreaming * StreamingLevel = FLevelUtils : : FindStreamingLevel ( ( * LevelIt ) - > GetLevel ( ) . Get ( ) ) ;
if ( StreamingLevel )
{
for ( int32 i = 0 ; i < StreamingLevel - > EditorStreamingVolumes . Num ( ) ; + + i )
{
ALevelStreamingVolume * LevelStreamingVolume = StreamingLevel - > EditorStreamingVolumes [ i ] ;
if ( LevelStreamingVolume )
{
LevelStreamingVolumesToSelect . Add ( LevelStreamingVolume ) ;
}
}
}
}
}
// Select the volumes.
const FScopedTransaction Transaction ( LOCTEXT ( " SelectAssociatedStreamingVolumes " , " Select Associated Streaming Volumes " ) ) ;
GEditor - > GetSelectedActors ( ) - > Modify ( ) ;
GEditor - > SelectNone ( false , true ) ;
for ( int32 i = 0 ; i < LevelStreamingVolumesToSelect . Num ( ) ; + + i )
{
ALevelStreamingVolume * LevelStreamingVolume = LevelStreamingVolumesToSelect [ i ] ;
GEditor - > SelectActor ( LevelStreamingVolume , /*bInSelected=*/ true , false , true ) ;
}
GEditor - > NoteSelectionChange ( ) ;
}
void FLevelCollectionViewModel : : AssembleSelectedLevelStreamingVolumes ( TArray < ALevelStreamingVolume * > & OutLevelStreamingVolumes )
{
OutLevelStreamingVolumes . Empty ( ) ;
for ( FSelectionIterator It ( GEditor - > GetSelectedActorIterator ( ) ) ; It ; + + It )
{
ALevelStreamingVolume * StreamingVolume = Cast < ALevelStreamingVolume > ( * It ) ;
if ( StreamingVolume & & StreamingVolume - > GetLevel ( ) = = GWorld - > PersistentLevel )
{
OutLevelStreamingVolumes . Add ( StreamingVolume ) ;
}
}
}
void FLevelCollectionViewModel : : SetStreamingLevelVolumes_Executed ( )
{
ClearStreamingLevelVolumes ( ) ;
AddStreamingLevelVolumes ( ) ;
}
void FLevelCollectionViewModel : : AddStreamingLevelVolumes ( )
{
TArray < ALevelStreamingVolume * > LevelStreamingVolumes ;
AssembleSelectedLevelStreamingVolumes ( LevelStreamingVolumes ) ;
if ( LevelStreamingVolumes . Num ( ) = = 0 )
{
return ;
}
const FScopedTransaction Transaction ( NSLOCTEXT ( " UnrealEd " , " AddStreamingVolumes " , " Add Streaming Volumes " ) ) ;
for ( auto LevelIt = SelectedLevels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
if ( ( * LevelIt ) - > IsLevel ( ) )
{
ULevelStreaming * StreamingLevel = FLevelUtils : : FindStreamingLevel ( ( * LevelIt ) - > GetLevel ( ) . Get ( ) ) ;
if ( StreamingLevel )
{
StreamingLevel - > Modify ( ) ;
for ( int32 i = 0 ; i < LevelStreamingVolumes . Num ( ) ; + + i )
{
ALevelStreamingVolume * LevelStreamingVolume = LevelStreamingVolumes [ i ] ;
// Associate the level to the volume.
LevelStreamingVolume - > Modify ( ) ;
2014-08-25 11:05:29 -04:00
LevelStreamingVolume - > StreamingLevelNames . AddUnique ( StreamingLevel - > GetWorldAssetPackageFName ( ) ) ;
2014-03-14 14:13:41 -04:00
// Associate the volume to the level.
StreamingLevel - > EditorStreamingVolumes . AddUnique ( LevelStreamingVolume ) ;
}
}
}
}
}
void FLevelCollectionViewModel : : AddStreamingLevelVolumes_Executed ( )
{
AddStreamingLevelVolumes ( ) ;
}
void FLevelCollectionViewModel : : ClearStreamingVolumes_Executed ( )
{
int32 Result = FMessageDialog : : Open ( EAppMsgType : : YesNo , LOCTEXT ( " ClearStreamingVolumesPrompt " , " Are you sure you want to clear streaming volumes? " ) ) ;
// If the user wants to continue with the restart set the pending project to swtich to and close the editor
if ( Result = = EAppReturnType : : Yes )
{
ClearStreamingLevelVolumes ( ) ;
}
}
//visibility
void FLevelCollectionViewModel : : SetVisible ( TArray < TSharedPtr < FLevelViewModel > > & LevelViewModels , bool bVisible )
{
2014-04-02 18:09:23 -04:00
TArray < TSharedPtr < FLevelViewModel > > CachedLevelViewModels = LevelViewModels ;
for ( const TSharedPtr < FLevelViewModel > & Level : CachedLevelViewModels )
2014-03-14 14:13:41 -04:00
{
// Only set visibility if the level its valid.
2014-04-02 18:09:23 -04:00
if ( Level - > IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
2014-04-02 18:09:23 -04:00
Level - > SetVisible ( bVisible ) ;
2014-03-14 14:13:41 -04:00
}
}
}
void FLevelCollectionViewModel : : ShowSelectedLevels_Executed ( )
{
//stash off a copy of the original array, as setting visibility can destroy the selection
TArray < TSharedPtr < FLevelViewModel > > SelectedLevelsCopy ;
SelectedLevelsCopy . Append ( SelectedLevels ) ;
SetVisible ( SelectedLevelsCopy , true ) ;
//restore the selection
SetSelectedLevels ( SelectedLevelsCopy ) ;
}
void FLevelCollectionViewModel : : HideSelectedLevels_Executed ( )
{
//stash off a copy of the original array, as setting visibility can destroy the selection
TArray < TSharedPtr < FLevelViewModel > > SelectedLevelsCopy ;
SelectedLevelsCopy . Append ( SelectedLevels ) ;
SetVisible ( SelectedLevelsCopy , false ) ;
}
void FLevelCollectionViewModel : : ShowOnlySelectedLevels_Executed ( )
{
//stash off a copy of the original array, as setting visibility can destroy the selection
TArray < TSharedPtr < FLevelViewModel > > SelectedLevelsCopy ;
SelectedLevelsCopy . Append ( SelectedLevels ) ;
InvertSelection_Executed ( ) ;
HideSelectedLevels_Executed ( ) ;
SetSelectedLevels ( SelectedLevelsCopy ) ;
ShowSelectedLevels_Executed ( ) ;
//restore the selection
SetSelectedLevels ( SelectedLevelsCopy ) ;
}
void FLevelCollectionViewModel : : ShowAllLevels_Executed ( )
{
SetVisible ( AllLevelViewModels , true ) ;
}
void FLevelCollectionViewModel : : HideAllLevels_Executed ( )
{
SetVisible ( AllLevelViewModels , false ) ;
}
//lock
void FLevelCollectionViewModel : : LockSelectedLevels_Executed ( )
{
const FText UndoTransactionText = ( SelectedLevels . Num ( ) = = 1 ) ?
LOCTEXT ( " LockLevel " , " Lock Level " ) :
LOCTEXT ( " LockMultipleLevels " , " Lock Multiple Levels " ) ;
const FScopedTransaction Transaction ( UndoTransactionText ) ;
for ( auto LevelIt = SelectedLevels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
// Only lock the level if its valid.
if ( ( * LevelIt ) - > IsValid ( ) )
{
( * LevelIt ) - > SetLocked ( true ) ;
}
}
}
void FLevelCollectionViewModel : : UnockSelectedLevels_Executed ( )
{
const FText UndoTransactionText = ( SelectedLevels . Num ( ) = = 1 ) ?
LOCTEXT ( " UnlockLevel " , " Unlock Level " ) :
LOCTEXT ( " UnlockMultipleLevels " , " Unlock Multiple Levels " ) ;
const FScopedTransaction Transaction ( UndoTransactionText ) ;
for ( auto LevelIt = SelectedLevels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
// Only unlock the level if its valid.
if ( ( * LevelIt ) - > IsValid ( ) )
{
( * LevelIt ) - > SetLocked ( false ) ;
}
}
}
void FLevelCollectionViewModel : : LockAllLevels_Executed ( )
{
const FScopedTransaction Transaction ( LOCTEXT ( " LockAllLevels " , " Lock All Levels " ) ) ;
for ( auto LevelIt = FilteredLevelViewModels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
// Only lock the level if its valid.
if ( ( * LevelIt ) - > IsValid ( ) )
{
( * LevelIt ) - > SetLocked ( true ) ;
}
}
}
void FLevelCollectionViewModel : : UnockAllLevels_Executed ( )
{
const FScopedTransaction Transaction ( LOCTEXT ( " UnlockAllLevels " , " Unlock All Levels " ) ) ;
for ( auto LevelIt = FilteredLevelViewModels . CreateIterator ( ) ; LevelIt ; + + LevelIt )
{
// Only unlock the level if its valid.
if ( ( * LevelIt ) - > IsValid ( ) )
{
( * LevelIt ) - > SetLocked ( false ) ;
}
}
}
void FLevelCollectionViewModel : : WorldAdded ( UWorld * World )
{
if ( World )
{
// If the current world is not valid set this world to be the current one
if ( ! CurrentWorld . IsValid ( ) )
{
SetCurrentWorld ( World ) ;
}
}
}
void FLevelCollectionViewModel : : WorldDestroyed ( UWorld * InWorld )
{
if ( InWorld )
{
// Remove the level change handlers
RemoveLevelChangeHandlers ( InWorld ) ;
// If this world is the one we are showing levels for remove the reference
if ( InWorld = = CurrentWorld . Get ( ) )
{
CurrentWorld = NULL ;
if ( InWorld ! = GEditor - > GetEditorWorldContext ( ) . World ( ) )
{
SetCurrentWorld ( GEditor - > GetEditorWorldContext ( ) . World ( ) ) ;
}
}
}
}
void FLevelCollectionViewModel : : UpdateLevelActorsCount ( )
{
for ( auto It = AllLevelViewModels . CreateIterator ( ) ; It ; + + It )
{
( * It ) - > UpdateLevelActorsCount ( ) ;
}
bPendingUpdateActorsCount = false ;
}
void FLevelCollectionViewModel : : OnLevelActorAdded ( AActor * InActor )
{
if ( InActor & &
InActor - > GetWorld ( ) = = CurrentWorld . Get ( ) ) // we care about our world only
{
bPendingUpdateActorsCount = true ;
}
}
void FLevelCollectionViewModel : : OnLevelActorDeleted ( AActor * InActor )
{
bPendingUpdateActorsCount = true ;
}
void FLevelCollectionViewModel : : AddLevelChangeHandlers ( UWorld * InWorld )
{
if ( ensure ( InWorld ) )
{
InWorld - > OnLevelsChanged ( ) . AddSP ( this , & FLevelCollectionViewModel : : Refresh ) ;
InWorld - > OnSelectedLevelsChanged ( ) . AddSP ( this , & FLevelCollectionViewModel : : RefreshSelected ) ;
}
}
void FLevelCollectionViewModel : : RemoveLevelChangeHandlers ( UWorld * InWorld )
{
if ( ensure ( InWorld ) )
{
InWorld - > OnLevelsChanged ( ) . RemoveAll ( this ) ;
InWorld - > OnSelectedLevelsChanged ( ) . RemoveAll ( this ) ;
}
}
void FLevelCollectionViewModel : : SetCurrentWorld ( UWorld * InWorld )
{
if ( InWorld = = CurrentWorld . Get ( ) )
{
return ;
}
if ( CurrentWorld . IsValid ( ) )
{
RemoveLevelChangeHandlers ( CurrentWorld . Get ( ) ) ;
}
CurrentWorld = InWorld ;
AddLevelChangeHandlers ( InWorld ) ;
Refresh ( ) ;
}
void FLevelCollectionViewModel : : CacheCanExecuteSourceControlVars ( )
{
bCanExecuteSCCCheckOut = false ;
bCanExecuteSCCOpenForAdd = false ;
bCanExecuteSCCCheckIn = false ;
bCanExecuteSCC = false ;
ISourceControlProvider & SourceControlProvider = ISourceControlModule : : Get ( ) . GetProvider ( ) ;
for ( auto SelectedLevelIt = SelectedLevels . CreateIterator ( ) ; SelectedLevelIt ; + + SelectedLevelIt )
{
if ( ISourceControlModule : : Get ( ) . IsEnabled ( ) & & SourceControlProvider . IsAvailable ( ) )
{
bCanExecuteSCC = true ;
// Check the SCC state for each package in the selected paths
FSourceControlStatePtr SourceControlState = SourceControlProvider . GetState ( ( * SelectedLevelIt ) - > GetLevel ( ) . Get ( ) - > GetOutermost ( ) , EStateCacheUsage : : Use ) ;
if ( SourceControlState . IsValid ( ) )
{
if ( SourceControlState - > CanCheckout ( ) )
{
bCanExecuteSCCCheckOut = true ;
}
else if ( ! SourceControlState - > IsSourceControlled ( ) )
{
bCanExecuteSCCOpenForAdd = true ;
}
else if ( SourceControlState - > IsCheckedOut ( ) | | SourceControlState - > IsAdded ( ) )
{
bCanExecuteSCCCheckIn = true ;
}
}
}
if ( bCanExecuteSCCCheckOut
& & bCanExecuteSCCOpenForAdd
& & bCanExecuteSCCCheckIn
)
{
// All options are available, no need to keep iterating
break ;
}
}
}
2014-06-23 06:42:01 -04:00
bool FLevelCollectionViewModel : : IsValidMoveActorsToLevel ( )
{
static bool bCachedIsValidActorMoveResult = false ;
if ( bSelectionHasChanged )
{
bSelectionHasChanged = false ;
2014-08-25 12:51:25 -04:00
bCachedIsValidActorMoveResult = false ;
2014-06-23 06:42:01 -04:00
2014-08-25 12:51:25 -04:00
// We only operate on a single level
if ( SelectedLevels . Num ( ) = = 1 )
2014-06-23 06:42:01 -04:00
{
2014-08-25 12:51:25 -04:00
ULevel * Level = SelectedLevels [ 0 ] - > GetLevel ( ) . Get ( ) ;
if ( Level )
2014-06-23 06:42:01 -04:00
{
2014-08-25 12:51:25 -04:00
// Allow the move if at least one actor is in another level
USelection * SelectedActors = GEditor - > GetSelectedActors ( ) ;
for ( FSelectionIterator Iter ( * SelectedActors ) ; Iter ; + + Iter )
2014-06-23 06:42:01 -04:00
{
2014-08-25 12:51:25 -04:00
AActor * Actor = CastChecked < AActor > ( * Iter ) ;
if ( Actor ! = nullptr )
2014-06-23 06:42:01 -04:00
{
2014-08-25 12:51:25 -04:00
if ( Actor - > GetLevel ( ) ! = Level )
{
bCachedIsValidActorMoveResult = true ;
break ;
}
2014-06-23 06:42:01 -04:00
}
}
}
}
}
// if non of the selected actors are in the level, just check the level is unlocked
return bCachedIsValidActorMoveResult & & AreAllSelectedLevelsUnlockedAndVisible ( ) ;
}
void FLevelCollectionViewModel : : OnActorSelectionChanged ( UObject * obj )
{
OnActorOrLevelSelectionChanged ( ) ;
}
void FLevelCollectionViewModel : : OnActorOrLevelSelectionChanged ( )
{
bSelectionHasChanged = true ;
}
2014-03-14 14:13:41 -04:00
# undef LOCTEXT_NAMESPACE