2021-02-04 17:41:41 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "SSourceControlCommon.h"
2021-10-29 09:53:59 -04:00
# include "Algo/Count.h"
# include "Algo/Find.h"
2022-05-02 18:06:48 -04:00
# include "AssetRegistry/AssetData.h"
2022-01-07 10:01:19 -05:00
# include "ActorFolder.h"
# include "ActorFolderDesc.h"
2021-02-04 17:41:41 -04:00
# include "AssetToolsModule.h"
2022-05-09 13:12:28 -04:00
# include "Styling/AppStyle.h"
2021-08-31 15:14:29 -04:00
# include "ISourceControlModule.h"
# include "SourceControlAssetDataCache.h"
2021-02-04 17:41:41 -04:00
# include "SourceControlHelpers.h"
2022-09-07 17:15:39 -04:00
# include "SSourceControlFileDialog.h"
2021-02-04 17:41:41 -04:00
# include "Widgets/SOverlay.h"
# include "Widgets/Images/SImage.h"
# include "Widgets/Images/SLayeredImage.h"
# include "Widgets/Layout/SBox.h"
2022-09-07 17:15:55 -04:00
# include "Framework/Docking/TabManager.h"
# include "Framework/Notifications/NotificationManager.h"
2022-09-07 17:15:39 -04:00
# include "Misc/ScopedSlowTask.h"
2022-09-07 17:15:55 -04:00
# include "Editor.h"
2021-02-04 17:41:41 -04:00
# define LOCTEXT_NAMESPACE "SourceControlChangelist"
//////////////////////////////////////////////////////////////////////////
Refactored the Changelist Window UI to work better with large changelists along with bug fixes.
This submit should not regress any existing functionalites of the previous widget.
Along with the user interface changes, notable bug fixes were included
- If a changelist is not specified for P4 operations 'Mark for Add', 'Mark for Delete and 'Checkout', defaulted to the 'default' P4 changlist. Without a valid changelist, the cache wasn't properly updated.
- Fixed updating the cache for P4 'Mark for delete' operation not correctly updating the file changelist cached in the file state.
Other changes:
- P4 changelists are now always returned sorted by changelist number, ascending.
- Some of the safe operations were running synchronous are not running asynchrnous (create new changelist, delete empty changelist, delete shelved files).
This submit addresses the following Jiras:
#jira UE-155207 - Refactor the changelist window layout to have the left/right panel.
#jira UE-155209 - Add the context menu on right click on a file or a changelist.
#jira UE-155218 - Support creating new empty changelist from the changelist view.
#jira UE-155220 - Support moving files from the selected changelist (right view) to another changelist (left view)
#jira UE-155211 - Add visual feedback for any operation taking more than 0.5s.
#jira UE-155212 - Display a list of uncontrolled files in the left panel of the changelist window
#jira UE-155499 - Changelist windows buttons should be disabled if SCC is disabled
#jira UE-155229 - Add an option to automatically refresh the changelist window when new assets are imported|created (as uncontrolled), marked for add, checked out, marked for delete
#jira UE-107577 - Source Control's Changelists dialog does not refresh to reflect changes made while open
#rb Patrick.Enfedaque
#preflight 62ff946ef7404b55a326297b
[CL 21499885 by patrick laflamme in ue5-main branch]
2022-08-22 21:20:05 -04:00
2021-02-04 17:41:41 -04:00
FChangelistTreeItemPtr IChangelistTreeItem : : GetParent ( ) const
{
return Parent ;
}
const TArray < FChangelistTreeItemPtr > & IChangelistTreeItem : : GetChildren ( ) const
{
return Children ;
}
Refactored the Changelist Window UI to work better with large changelists along with bug fixes.
This submit should not regress any existing functionalites of the previous widget.
Along with the user interface changes, notable bug fixes were included
- If a changelist is not specified for P4 operations 'Mark for Add', 'Mark for Delete and 'Checkout', defaulted to the 'default' P4 changlist. Without a valid changelist, the cache wasn't properly updated.
- Fixed updating the cache for P4 'Mark for delete' operation not correctly updating the file changelist cached in the file state.
Other changes:
- P4 changelists are now always returned sorted by changelist number, ascending.
- Some of the safe operations were running synchronous are not running asynchrnous (create new changelist, delete empty changelist, delete shelved files).
This submit addresses the following Jiras:
#jira UE-155207 - Refactor the changelist window layout to have the left/right panel.
#jira UE-155209 - Add the context menu on right click on a file or a changelist.
#jira UE-155218 - Support creating new empty changelist from the changelist view.
#jira UE-155220 - Support moving files from the selected changelist (right view) to another changelist (left view)
#jira UE-155211 - Add visual feedback for any operation taking more than 0.5s.
#jira UE-155212 - Display a list of uncontrolled files in the left panel of the changelist window
#jira UE-155499 - Changelist windows buttons should be disabled if SCC is disabled
#jira UE-155229 - Add an option to automatically refresh the changelist window when new assets are imported|created (as uncontrolled), marked for add, checked out, marked for delete
#jira UE-107577 - Source Control's Changelists dialog does not refresh to reflect changes made while open
#rb Patrick.Enfedaque
#preflight 62ff946ef7404b55a326297b
[CL 21499885 by patrick laflamme in ue5-main branch]
2022-08-22 21:20:05 -04:00
void IChangelistTreeItem : : AddChild ( TSharedRef < IChangelistTreeItem > Child )
2021-02-04 17:41:41 -04:00
{
Child - > Parent = AsShared ( ) ;
Children . Add ( MoveTemp ( Child ) ) ;
}
Refactored the Changelist Window UI to work better with large changelists along with bug fixes.
This submit should not regress any existing functionalites of the previous widget.
Along with the user interface changes, notable bug fixes were included
- If a changelist is not specified for P4 operations 'Mark for Add', 'Mark for Delete and 'Checkout', defaulted to the 'default' P4 changlist. Without a valid changelist, the cache wasn't properly updated.
- Fixed updating the cache for P4 'Mark for delete' operation not correctly updating the file changelist cached in the file state.
Other changes:
- P4 changelists are now always returned sorted by changelist number, ascending.
- Some of the safe operations were running synchronous are not running asynchrnous (create new changelist, delete empty changelist, delete shelved files).
This submit addresses the following Jiras:
#jira UE-155207 - Refactor the changelist window layout to have the left/right panel.
#jira UE-155209 - Add the context menu on right click on a file or a changelist.
#jira UE-155218 - Support creating new empty changelist from the changelist view.
#jira UE-155220 - Support moving files from the selected changelist (right view) to another changelist (left view)
#jira UE-155211 - Add visual feedback for any operation taking more than 0.5s.
#jira UE-155212 - Display a list of uncontrolled files in the left panel of the changelist window
#jira UE-155499 - Changelist windows buttons should be disabled if SCC is disabled
#jira UE-155229 - Add an option to automatically refresh the changelist window when new assets are imported|created (as uncontrolled), marked for add, checked out, marked for delete
#jira UE-107577 - Source Control's Changelists dialog does not refresh to reflect changes made while open
#rb Patrick.Enfedaque
#preflight 62ff946ef7404b55a326297b
[CL 21499885 by patrick laflamme in ue5-main branch]
2022-08-22 21:20:05 -04:00
void IChangelistTreeItem : : RemoveChild ( const TSharedRef < IChangelistTreeItem > & Child )
2021-02-04 17:41:41 -04:00
{
if ( Children . Remove ( Child ) )
{
Child - > Parent = nullptr ;
}
}
//////////////////////////////////////////////////////////////////////////
2021-03-24 08:29:57 -04:00
FFileTreeItem : : FFileTreeItem ( FSourceControlStateRef InFileState , bool bBeautifyPaths , bool bIsShelvedFile )
Refactored the Changelist Window UI to work better with large changelists along with bug fixes.
This submit should not regress any existing functionalites of the previous widget.
Along with the user interface changes, notable bug fixes were included
- If a changelist is not specified for P4 operations 'Mark for Add', 'Mark for Delete and 'Checkout', defaulted to the 'default' P4 changlist. Without a valid changelist, the cache wasn't properly updated.
- Fixed updating the cache for P4 'Mark for delete' operation not correctly updating the file changelist cached in the file state.
Other changes:
- P4 changelists are now always returned sorted by changelist number, ascending.
- Some of the safe operations were running synchronous are not running asynchrnous (create new changelist, delete empty changelist, delete shelved files).
This submit addresses the following Jiras:
#jira UE-155207 - Refactor the changelist window layout to have the left/right panel.
#jira UE-155209 - Add the context menu on right click on a file or a changelist.
#jira UE-155218 - Support creating new empty changelist from the changelist view.
#jira UE-155220 - Support moving files from the selected changelist (right view) to another changelist (left view)
#jira UE-155211 - Add visual feedback for any operation taking more than 0.5s.
#jira UE-155212 - Display a list of uncontrolled files in the left panel of the changelist window
#jira UE-155499 - Changelist windows buttons should be disabled if SCC is disabled
#jira UE-155229 - Add an option to automatically refresh the changelist window when new assets are imported|created (as uncontrolled), marked for add, checked out, marked for delete
#jira UE-107577 - Source Control's Changelists dialog does not refresh to reflect changes made while open
#rb Patrick.Enfedaque
#preflight 62ff946ef7404b55a326297b
[CL 21499885 by patrick laflamme in ue5-main branch]
2022-08-22 21:20:05 -04:00
: IChangelistTreeItem ( bIsShelvedFile ? IChangelistTreeItem : : ShelvedFile : IChangelistTreeItem : : File )
, FileState ( InFileState )
2021-08-31 15:14:29 -04:00
, MinTimeBetweenUpdate ( FTimespan : : FromSeconds ( 5.f ) )
, LastUpdateTime ( )
, bAssetsUpToDate ( false )
2021-02-04 17:41:41 -04:00
{
CheckBoxState = ECheckBoxState : : Checked ;
// Initialize asset data first
2021-08-31 15:14:29 -04:00
if ( bBeautifyPaths )
2021-02-08 09:36:20 -04:00
{
2021-08-31 15:14:29 -04:00
FSourceControlAssetDataCache & AssetDataCache = ISourceControlModule : : Get ( ) . GetAssetDataCache ( ) ;
bAssetsUpToDate = AssetDataCache . GetAssetDataArray ( FileState , Assets ) ;
}
else
{
// We do not need to wait for AssetData from the cache.
bAssetsUpToDate = true ;
2021-02-08 09:36:20 -04:00
}
2021-08-31 15:14:29 -04:00
RefreshAssetInformation ( ) ;
}
2021-02-04 17:41:41 -04:00
2021-08-31 15:14:29 -04:00
void FFileTreeItem : : RefreshAssetInformation ( )
{
2021-02-04 17:41:41 -04:00
// Initialize display-related members
2021-08-31 15:14:29 -04:00
FString Filename = FileState - > GetFilename ( ) ;
2021-06-08 17:12:28 -04:00
FString TempAssetName = SSourceControlCommon : : GetDefaultAssetName ( ) . ToString ( ) ;
2021-02-04 17:41:41 -04:00
FString TempAssetPath = Filename ;
2021-06-08 17:12:28 -04:00
FString TempAssetType = SSourceControlCommon : : GetDefaultAssetType ( ) . ToString ( ) ;
2021-02-08 09:36:20 -04:00
FString TempPackageName = Filename ;
2021-02-04 17:41:41 -04:00
FColor TempAssetColor = FColor ( // Copied from ContentBrowserCLR.cpp
2021-08-31 15:14:29 -04:00
127 + FColor : : Red . R / 2 , // Desaturate the colors a bit (GB colors were too.. much)
127 + FColor : : Red . G / 2 ,
127 + FColor : : Red . B / 2 ,
200 ) ; // Opacity
2021-02-04 17:41:41 -04:00
2021-08-31 15:14:29 -04:00
if ( Assets . IsValid ( ) & & ( Assets - > Num ( ) > 0 ) )
2021-02-04 17:41:41 -04:00
{
2021-10-29 09:53:59 -04:00
auto IsNotRedirector = [ ] ( const FAssetData & InAssetData ) { return ! InAssetData . IsRedirector ( ) ; } ;
int32 NumUserFacingAsset = Algo : : CountIf ( * Assets , IsNotRedirector ) ;
2021-08-31 15:14:29 -04:00
2021-10-29 09:53:59 -04:00
if ( NumUserFacingAsset = = 1 )
2021-02-04 17:41:41 -04:00
{
2021-10-29 09:53:59 -04:00
const FAssetData & AssetData = * Algo : : FindByPredicate ( * Assets , IsNotRedirector ) ;
2021-02-04 17:41:41 -04:00
2021-10-29 09:53:59 -04:00
TempAssetName = RetrieveAssetName ( AssetData ) ;
TempAssetPath = RetrieveAssetPath ( AssetData ) ;
Deprecating ANY_PACKAGE.
This change consists of multiple changes:
Core:
- Deprecation of ANY_PACKAGE macro. Added ANY_PACKAGE_DEPRECATED macro which can still be used for backwards compatibility purposes (only used in CoreUObject)
- Deprecation of StaticFindObjectFast* functions that take bAnyPackage parameter
- Added UStruct::GetStructPathName function that returns FTopLevelAssetPath representing the path name (package + object FName, super quick compared to UObject::GetPathName) + wrapper UClass::GetClassPathName to make it look better when used with UClasses
- Added (Static)FindFirstObject* functions that find a first object given its Name (no Outer). These functions are used in places I consider valid to do global UObject (UClass) lookups like parsing command line parameters / checking for unique object names
- Added static UClass::TryFindType function which serves a similar purpose as FindFirstObject however it's going to throw a warning (with a callstack / maybe ensure in the future?) if short class name is provided. This function is used in places that used to use short class names but now should have been converted to use path names to catch any potential regressions and or edge cases I missed.
- Added static UClass::TryConvertShortNameToPathName utility function
- Added static UClass::TryFixShortClassNameExportPath utility function
- Object text export paths will now also include class path (Texture2D'/Game/Textures/Grass.Grass' -> /Script/Engine.Texture2D'/Game/Textures/Grass.Grass')
- All places that manually generated object export paths for objects will now use FObjectPropertyBase::GetExportPath
- Added a new startup test that checks for short type names in UClass/FProperty MetaData values
AssetRegistry:
- Deprecated any member variables (FAssetData / FARFilter) or functions that use FNames to represent class names and replaced them with FTopLevelAssetPath
- Added new member variables and new function overloads that use FTopLevelAssetPath to represent class names
- This also applies to a few other modules' APIs to match AssetRegistry changes
Everything else:
- Updated code that used ANY_PACKAGE (depending on the use case) to use FindObject(nullptr, PathToObject), UClass::TryFindType (used when path name is expected, warns if it's a short name) or FindFirstObject (usually for finding types based on user input but there's been a few legitimate use cases not related to user input)
- Updated code that used AssetRegistry API to use FTopLevelAssetPaths and USomeClass::StaticClass()->GetClassPathName() instead of GetFName()
- Updated meta data and hardcoded FindObject(ANY_PACKAGE, "EEnumNameOrClassName") calls to use path names
#jira UE-99463
#rb many.people
[FYI] Marcus.Wassmer
#preflight 629248ec2256738f75de9b32
#codereviewnumbers 20320742, 20320791, 20320799, 20320756, 20320809, 20320830, 20320840, 20320846, 20320851, 20320863, 20320780, 20320765, 20320876, 20320786
#ROBOMERGE-OWNER: robert.manuszewski
#ROBOMERGE-AUTHOR: robert.manuszewski
#ROBOMERGE-SOURCE: CL 20430220 via CL 20433854 via CL 20435474 via CL 20435484
#ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v949-20362246)
[CL 20448496 by robert manuszewski in ue5-main branch]
2022-06-01 03:46:59 -04:00
TempAssetType = AssetData . AssetClassPath . ToString ( ) ;
2021-02-04 17:41:41 -04:00
const FAssetToolsModule & AssetToolsModule = FModuleManager : : LoadModuleChecked < FAssetToolsModule > ( TEXT ( " AssetTools " ) ) ;
2021-08-31 15:14:29 -04:00
const TSharedPtr < IAssetTypeActions > AssetTypeActions = AssetToolsModule . Get ( ) . GetAssetTypeActionsForClass ( AssetData . GetClass ( ) ) . Pin ( ) ;
2021-10-29 09:53:59 -04:00
2021-02-04 17:41:41 -04:00
if ( AssetTypeActions . IsValid ( ) )
{
TempAssetColor = AssetTypeActions - > GetTypeColor ( ) ;
}
else
{
TempAssetColor = FColor : : White ;
}
}
else
{
2021-10-29 09:53:59 -04:00
TempAssetName = RetrieveAssetName ( ( * Assets ) [ 0 ] ) ;
TempAssetPath = RetrieveAssetPath ( ( * Assets ) [ 0 ] ) ;
for ( int32 i = 1 ; i < Assets - > Num ( ) ; + + i )
{
TempAssetName + = TEXT ( " ; " ) + RetrieveAssetName ( ( * Assets ) [ i ] ) ;
}
2021-06-08 17:12:28 -04:00
TempAssetType = SSourceControlCommon : : GetDefaultMultipleAsset ( ) . ToString ( ) ;
2021-02-04 17:41:41 -04:00
TempAssetColor = FColor : : White ;
}
// Beautify the package name
TempPackageName = TempAssetPath + " . " + TempAssetName ;
}
else if ( FPackageName : : TryConvertFilenameToLongPackageName ( Filename , TempPackageName ) )
{
// Fake asset name, asset path from the package name
TempAssetPath = TempPackageName ;
int32 LastSlash = - 1 ;
if ( TempPackageName . FindLastChar ( ' / ' , LastSlash ) )
{
TempAssetName = TempPackageName ;
TempAssetName . RightChopInline ( LastSlash + 1 ) ;
}
}
else
{
2021-02-28 23:55:37 -04:00
TempAssetName = FPaths : : GetCleanFilename ( Filename ) ;
2021-02-04 17:41:41 -04:00
TempPackageName = Filename ; // put back original package name if the try failed
2021-06-08 17:12:28 -04:00
TempAssetType = FText : : Format ( SSourceControlCommon : : GetDefaultUnknownAssetType ( ) , FText : : FromString ( FPaths : : GetExtension ( Filename ) . ToUpper ( ) ) ) . ToString ( ) ;
2021-02-04 17:41:41 -04:00
}
// Finally, assign the temp variables to the member variables
AssetName = FText : : FromString ( TempAssetName ) ;
AssetPath = FText : : FromString ( TempAssetPath ) ;
AssetType = FText : : FromString ( TempAssetType ) ;
AssetTypeColor = TempAssetColor ;
PackageName = FText : : FromString ( TempPackageName ) ;
}
2022-09-12 18:11:36 -04:00
FText FFileTreeItem : : GetAssetName ( ) const
{
return AssetName ;
}
2021-08-31 15:14:29 -04:00
FText FFileTreeItem : : GetAssetName ( )
{
const FTimespan CurrentTime = FTimespan : : FromSeconds ( FPlatformTime : : Seconds ( ) ) ;
if ( ( ! bAssetsUpToDate ) & & ( ( CurrentTime - LastUpdateTime ) > MinTimeBetweenUpdate ) )
{
FSourceControlAssetDataCache & AssetDataCache = ISourceControlModule : : Get ( ) . GetAssetDataCache ( ) ;
LastUpdateTime = CurrentTime ;
if ( AssetDataCache . GetAssetDataArray ( FileState , Assets ) )
{
bAssetsUpToDate = true ;
RefreshAssetInformation ( ) ;
}
}
return AssetName ;
}
2021-10-29 09:53:59 -04:00
FString FFileTreeItem : : RetrieveAssetName ( const FAssetData & InAssetData ) const
{
2022-01-07 10:01:19 -05:00
static const FName NAME_ActorLabel ( TEXT ( " ActorLabel " ) ) ;
2021-10-29 09:53:59 -04:00
if ( InAssetData . FindTag ( NAME_ActorLabel ) )
{
FString ResultAssetName = TEXT ( " " ) ;
InAssetData . GetTagValue ( NAME_ActorLabel , ResultAssetName ) ;
return ResultAssetName ;
}
Deprecating ANY_PACKAGE.
This change consists of multiple changes:
Core:
- Deprecation of ANY_PACKAGE macro. Added ANY_PACKAGE_DEPRECATED macro which can still be used for backwards compatibility purposes (only used in CoreUObject)
- Deprecation of StaticFindObjectFast* functions that take bAnyPackage parameter
- Added UStruct::GetStructPathName function that returns FTopLevelAssetPath representing the path name (package + object FName, super quick compared to UObject::GetPathName) + wrapper UClass::GetClassPathName to make it look better when used with UClasses
- Added (Static)FindFirstObject* functions that find a first object given its Name (no Outer). These functions are used in places I consider valid to do global UObject (UClass) lookups like parsing command line parameters / checking for unique object names
- Added static UClass::TryFindType function which serves a similar purpose as FindFirstObject however it's going to throw a warning (with a callstack / maybe ensure in the future?) if short class name is provided. This function is used in places that used to use short class names but now should have been converted to use path names to catch any potential regressions and or edge cases I missed.
- Added static UClass::TryConvertShortNameToPathName utility function
- Added static UClass::TryFixShortClassNameExportPath utility function
- Object text export paths will now also include class path (Texture2D'/Game/Textures/Grass.Grass' -> /Script/Engine.Texture2D'/Game/Textures/Grass.Grass')
- All places that manually generated object export paths for objects will now use FObjectPropertyBase::GetExportPath
- Added a new startup test that checks for short type names in UClass/FProperty MetaData values
AssetRegistry:
- Deprecated any member variables (FAssetData / FARFilter) or functions that use FNames to represent class names and replaced them with FTopLevelAssetPath
- Added new member variables and new function overloads that use FTopLevelAssetPath to represent class names
- This also applies to a few other modules' APIs to match AssetRegistry changes
Everything else:
- Updated code that used ANY_PACKAGE (depending on the use case) to use FindObject(nullptr, PathToObject), UClass::TryFindType (used when path name is expected, warns if it's a short name) or FindFirstObject (usually for finding types based on user input but there's been a few legitimate use cases not related to user input)
- Updated code that used AssetRegistry API to use FTopLevelAssetPaths and USomeClass::StaticClass()->GetClassPathName() instead of GetFName()
- Updated meta data and hardcoded FindObject(ANY_PACKAGE, "EEnumNameOrClassName") calls to use path names
#jira UE-99463
#rb many.people
[FYI] Marcus.Wassmer
#preflight 629248ec2256738f75de9b32
#codereviewnumbers 20320742, 20320791, 20320799, 20320756, 20320809, 20320830, 20320840, 20320846, 20320851, 20320863, 20320780, 20320765, 20320876, 20320786
#ROBOMERGE-OWNER: robert.manuszewski
#ROBOMERGE-AUTHOR: robert.manuszewski
#ROBOMERGE-SOURCE: CL 20430220 via CL 20433854 via CL 20435474 via CL 20435484
#ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v949-20362246)
[CL 20448496 by robert manuszewski in ue5-main branch]
2022-06-01 03:46:59 -04:00
else if ( InAssetData . AssetClassPath = = UActorFolder : : StaticClass ( ) - > GetClassPathName ( ) )
2021-10-29 09:53:59 -04:00
{
2022-01-07 10:01:19 -05:00
FString ActorFolderPath = UActorFolder : : GetAssetRegistryInfoFromPackage ( InAssetData . PackageName ) . GetDisplayName ( ) ;
if ( ! ActorFolderPath . IsEmpty ( ) )
{
return ActorFolderPath ;
}
2021-10-29 09:53:59 -04:00
}
2022-01-07 10:01:19 -05:00
return InAssetData . AssetName . ToString ( ) ;
2021-10-29 09:53:59 -04:00
}
FString FFileTreeItem : : RetrieveAssetPath ( const FAssetData & InAssetData ) const
{
int32 LastDot = - 1 ;
2022-09-08 20:52:53 -04:00
FString Path = InAssetData . GetObjectPathString ( ) ;
2021-10-29 09:53:59 -04:00
// Strip asset name from object path
if ( Path . FindLastChar ( ' . ' , LastDot ) )
{
Path . LeftInline ( LastDot ) ;
}
return Path ;
}
2021-06-08 17:12:28 -04:00
//////////////////////////////////////////////////////////////////////////
Refactored the Changelist Window UI to work better with large changelists along with bug fixes.
This submit should not regress any existing functionalites of the previous widget.
Along with the user interface changes, notable bug fixes were included
- If a changelist is not specified for P4 operations 'Mark for Add', 'Mark for Delete and 'Checkout', defaulted to the 'default' P4 changlist. Without a valid changelist, the cache wasn't properly updated.
- Fixed updating the cache for P4 'Mark for delete' operation not correctly updating the file changelist cached in the file state.
Other changes:
- P4 changelists are now always returned sorted by changelist number, ascending.
- Some of the safe operations were running synchronous are not running asynchrnous (create new changelist, delete empty changelist, delete shelved files).
This submit addresses the following Jiras:
#jira UE-155207 - Refactor the changelist window layout to have the left/right panel.
#jira UE-155209 - Add the context menu on right click on a file or a changelist.
#jira UE-155218 - Support creating new empty changelist from the changelist view.
#jira UE-155220 - Support moving files from the selected changelist (right view) to another changelist (left view)
#jira UE-155211 - Add visual feedback for any operation taking more than 0.5s.
#jira UE-155212 - Display a list of uncontrolled files in the left panel of the changelist window
#jira UE-155499 - Changelist windows buttons should be disabled if SCC is disabled
#jira UE-155229 - Add an option to automatically refresh the changelist window when new assets are imported|created (as uncontrolled), marked for add, checked out, marked for delete
#jira UE-107577 - Source Control's Changelists dialog does not refresh to reflect changes made while open
#rb Patrick.Enfedaque
#preflight 62ff946ef7404b55a326297b
[CL 21499885 by patrick laflamme in ue5-main branch]
2022-08-22 21:20:05 -04:00
FText FShelvedChangelistTreeItem : : GetDisplayText ( ) const
{
return FText : : Format ( LOCTEXT ( " SourceControl_ShelvedFiles " , " Shelved Items ({0}) " ) , Children . Num ( ) ) ;
}
//////////////////////////////////////////////////////////////////////////
2021-06-08 17:12:28 -04:00
FOfflineFileTreeItem : : FOfflineFileTreeItem ( const FString & InFilename )
Refactored the Changelist Window UI to work better with large changelists along with bug fixes.
This submit should not regress any existing functionalites of the previous widget.
Along with the user interface changes, notable bug fixes were included
- If a changelist is not specified for P4 operations 'Mark for Add', 'Mark for Delete and 'Checkout', defaulted to the 'default' P4 changlist. Without a valid changelist, the cache wasn't properly updated.
- Fixed updating the cache for P4 'Mark for delete' operation not correctly updating the file changelist cached in the file state.
Other changes:
- P4 changelists are now always returned sorted by changelist number, ascending.
- Some of the safe operations were running synchronous are not running asynchrnous (create new changelist, delete empty changelist, delete shelved files).
This submit addresses the following Jiras:
#jira UE-155207 - Refactor the changelist window layout to have the left/right panel.
#jira UE-155209 - Add the context menu on right click on a file or a changelist.
#jira UE-155218 - Support creating new empty changelist from the changelist view.
#jira UE-155220 - Support moving files from the selected changelist (right view) to another changelist (left view)
#jira UE-155211 - Add visual feedback for any operation taking more than 0.5s.
#jira UE-155212 - Display a list of uncontrolled files in the left panel of the changelist window
#jira UE-155499 - Changelist windows buttons should be disabled if SCC is disabled
#jira UE-155229 - Add an option to automatically refresh the changelist window when new assets are imported|created (as uncontrolled), marked for add, checked out, marked for delete
#jira UE-107577 - Source Control's Changelists dialog does not refresh to reflect changes made while open
#rb Patrick.Enfedaque
#preflight 62ff946ef7404b55a326297b
[CL 21499885 by patrick laflamme in ue5-main branch]
2022-08-22 21:20:05 -04:00
: IChangelistTreeItem ( IChangelistTreeItem : : OfflineFile )
, Assets ( )
2022-08-26 11:04:20 -04:00
, Filename ( InFilename )
2021-06-08 17:12:28 -04:00
, PackageName ( FText : : FromString ( InFilename ) )
, AssetName ( SSourceControlCommon : : GetDefaultAssetName ( ) )
, AssetPath ( )
, AssetType ( SSourceControlCommon : : GetDefaultAssetType ( ) )
, AssetTypeColor ( )
{
FString TempString ;
USourceControlHelpers : : GetAssetData ( InFilename , Assets ) ;
if ( Assets . Num ( ) > 0 )
{
const FAssetData & AssetData = Assets [ 0 ] ;
2022-09-08 20:52:53 -04:00
AssetPath = FText : : FromString ( AssetData . GetObjectPathString ( ) ) ;
2021-06-08 17:12:28 -04:00
// Find name, asset type & color only if there is exactly one asset
if ( Assets . Num ( ) = = 1 )
{
static FName NAME_ActorLabel ( TEXT ( " ActorLabel " ) ) ;
if ( AssetData . FindTag ( NAME_ActorLabel ) )
{
AssetData . GetTagValue ( NAME_ActorLabel , AssetName ) ;
}
else
{
AssetName = FText : : FromName ( AssetData . AssetName ) ;
}
Deprecating ANY_PACKAGE.
This change consists of multiple changes:
Core:
- Deprecation of ANY_PACKAGE macro. Added ANY_PACKAGE_DEPRECATED macro which can still be used for backwards compatibility purposes (only used in CoreUObject)
- Deprecation of StaticFindObjectFast* functions that take bAnyPackage parameter
- Added UStruct::GetStructPathName function that returns FTopLevelAssetPath representing the path name (package + object FName, super quick compared to UObject::GetPathName) + wrapper UClass::GetClassPathName to make it look better when used with UClasses
- Added (Static)FindFirstObject* functions that find a first object given its Name (no Outer). These functions are used in places I consider valid to do global UObject (UClass) lookups like parsing command line parameters / checking for unique object names
- Added static UClass::TryFindType function which serves a similar purpose as FindFirstObject however it's going to throw a warning (with a callstack / maybe ensure in the future?) if short class name is provided. This function is used in places that used to use short class names but now should have been converted to use path names to catch any potential regressions and or edge cases I missed.
- Added static UClass::TryConvertShortNameToPathName utility function
- Added static UClass::TryFixShortClassNameExportPath utility function
- Object text export paths will now also include class path (Texture2D'/Game/Textures/Grass.Grass' -> /Script/Engine.Texture2D'/Game/Textures/Grass.Grass')
- All places that manually generated object export paths for objects will now use FObjectPropertyBase::GetExportPath
- Added a new startup test that checks for short type names in UClass/FProperty MetaData values
AssetRegistry:
- Deprecated any member variables (FAssetData / FARFilter) or functions that use FNames to represent class names and replaced them with FTopLevelAssetPath
- Added new member variables and new function overloads that use FTopLevelAssetPath to represent class names
- This also applies to a few other modules' APIs to match AssetRegistry changes
Everything else:
- Updated code that used ANY_PACKAGE (depending on the use case) to use FindObject(nullptr, PathToObject), UClass::TryFindType (used when path name is expected, warns if it's a short name) or FindFirstObject (usually for finding types based on user input but there's been a few legitimate use cases not related to user input)
- Updated code that used AssetRegistry API to use FTopLevelAssetPaths and USomeClass::StaticClass()->GetClassPathName() instead of GetFName()
- Updated meta data and hardcoded FindObject(ANY_PACKAGE, "EEnumNameOrClassName") calls to use path names
#jira UE-99463
#rb many.people
[FYI] Marcus.Wassmer
#preflight 629248ec2256738f75de9b32
#codereviewnumbers 20320742, 20320791, 20320799, 20320756, 20320809, 20320830, 20320840, 20320846, 20320851, 20320863, 20320780, 20320765, 20320876, 20320786
#ROBOMERGE-OWNER: robert.manuszewski
#ROBOMERGE-AUTHOR: robert.manuszewski
#ROBOMERGE-SOURCE: CL 20430220 via CL 20433854 via CL 20435474 via CL 20435484
#ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v949-20362246)
[CL 20448496 by robert manuszewski in ue5-main branch]
2022-06-01 03:46:59 -04:00
AssetType = FText : : FromString ( AssetData . AssetClassPath . ToString ( ) ) ;
2021-06-08 17:12:28 -04:00
const FAssetToolsModule & AssetToolsModule = FModuleManager : : LoadModuleChecked < FAssetToolsModule > ( TEXT ( " AssetTools " ) ) ;
const TSharedPtr < IAssetTypeActions > AssetTypeActions = AssetToolsModule . Get ( ) . GetAssetTypeActionsForClass ( AssetData . GetClass ( ) ) . Pin ( ) ;
if ( AssetTypeActions . IsValid ( ) )
{
AssetTypeColor = AssetTypeActions - > GetTypeColor ( ) ;
}
else
{
AssetTypeColor = FColor : : White ;
}
}
else
{
AssetType = SSourceControlCommon : : GetDefaultMultipleAsset ( ) ;
AssetTypeColor = FColor : : White ;
}
// Beautify the package name
PackageName = AssetPath ;
}
else if ( FPackageName : : TryConvertFilenameToLongPackageName ( InFilename , TempString ) )
{
PackageName = FText : : FromString ( TempString ) ;
// Fake asset name, asset path from the package name
AssetPath = PackageName ;
}
else
{
AssetName = FText : : FromString ( FPaths : : GetCleanFilename ( InFilename ) ) ;
AssetType = FText : : Format ( SSourceControlCommon : : GetDefaultUnknownAssetType ( ) , FText : : FromString ( FPaths : : GetExtension ( InFilename ) . ToUpper ( ) ) ) ;
}
}
2021-02-04 17:41:41 -04:00
//////////////////////////////////////////////////////////////////////////
namespace SSourceControlCommon
{
TSharedRef < SWidget > GetSCCFileWidget ( FSourceControlStateRef InFileState , bool bIsShelvedFile )
{
2022-05-09 13:12:28 -04:00
const FSlateBrush * IconBrush = FAppStyle : : GetBrush ( " ContentBrowser.ColumnViewAssetIcon " ) ;
2021-02-04 17:41:41 -04:00
// Make icon overlays (eg, SCC and dirty status) a reasonable size in relation to the icon size (note: it is assumed this icon is square)
const float ICON_SCALING_FACTOR = 0.7f ;
const float IconOverlaySize = IconBrush - > ImageSize . X * ICON_SCALING_FACTOR ;
return SNew ( SOverlay )
// The actual icon
+ SOverlay : : Slot ( )
[
SNew ( SImage )
. Image ( IconBrush )
. ColorAndOpacity_Lambda ( [ bIsShelvedFile ] ( ) - > FSlateColor {
return FSlateColor ( bIsShelvedFile ? FColor : : Yellow : FColor : : White ) ;
} )
]
// Source control state
+ SOverlay : : Slot ( )
. HAlign ( HAlign_Left )
. VAlign ( VAlign_Top )
[
SNew ( SBox )
. WidthOverride ( IconOverlaySize )
. HeightOverride ( IconOverlaySize )
[
SNew ( SLayeredImage , InFileState - > GetIcon ( ) )
2022-09-06 15:43:24 -04:00
. ToolTipText ( InFileState - > GetDisplayTooltip ( ) )
2021-02-04 17:41:41 -04:00
]
] ;
}
2021-06-08 17:12:28 -04:00
FText GetDefaultAssetName ( )
{
return LOCTEXT ( " SourceControl_DefaultAssetName " , " Unavailable " ) ;
}
FText GetDefaultAssetType ( )
{
return LOCTEXT ( " SourceControl_DefaultAssetType " , " Unknown " ) ;
}
FText GetDefaultUnknownAssetType ( )
{
return LOCTEXT ( " SourceControl_FileTypeDefault " , " {0} File " ) ;
}
FText GetDefaultMultipleAsset ( )
{
return LOCTEXT ( " SourceCOntrol_ManyAssetType " , " Multiple Assets " ) ;
}
2022-09-07 17:15:39 -04:00
/** Wraps the execution of a changelist operations with a slow task. */
void ExecuteChangelistOperationWithSlowTaskWrapper ( const FText & Message , const TFunction < void ( ) > & ChangelistTask )
{
// NOTE: This is a ugly workaround for P4 because the generic popup feedback operations in FScopedSourceControlProgress() was supressed for all synchrounous
// operations. For other source control providers, the popup still shows up and showing a slow task and the FScopedSourceControlProgress at the same
// time is a bad user experience. Until we fix source control popup situation in general in the Editor, this hack is in place to avoid the double popup.
// At the time of writing, the other source control provider that supports changelists is Plastic.
if ( ISourceControlModule : : Get ( ) . GetProvider ( ) . GetName ( ) = = " Perforce " )
{
FScopedSlowTask Progress ( 0.f , Message ) ;
Progress . MakeDialog ( ) ;
ChangelistTask ( ) ;
}
else
{
ChangelistTask ( ) ;
}
}
/** Wraps the execution of an uncontrolled changelist operations with a slow task. */
void ExecuteUncontrolledChangelistOperationWithSlowTaskWrapper ( const FText & Message , const TFunction < void ( ) > & UncontrolledChangelistTask )
{
ExecuteChangelistOperationWithSlowTaskWrapper ( Message , UncontrolledChangelistTask ) ;
}
/** Displays toast notification to report the status of task. */
void DisplaySourceControlOperationNotification ( const FText & Message , SNotificationItem : : ECompletionState CompletionState )
{
if ( Message . IsEmpty ( ) )
{
return ;
}
FNotificationInfo NotificationInfo ( Message ) ;
NotificationInfo . ExpireDuration = 6.0f ;
NotificationInfo . Hyperlink = FSimpleDelegate : : CreateLambda ( [ ] ( ) { FGlobalTabmanager : : Get ( ) - > TryInvokeTab ( FName ( " OutputLog " ) ) ; } ) ;
NotificationInfo . HyperlinkText = LOCTEXT ( " ShowOutputLogHyperlink " , " Show Output Log " ) ;
FSlateNotificationManager : : Get ( ) . AddNotification ( NotificationInfo ) - > SetCompletionState ( CompletionState ) ;
}
bool OpenConflictDialog ( const TArray < FSourceControlStateRef > & InFilesConflicts )
{
TSharedPtr < SWindow > Window ;
TSharedPtr < SSourceControlFileDialog > SourceControlFileDialog ;
Window = SNew ( SWindow )
. Title ( LOCTEXT ( " CheckoutPackagesDialogTitle " , " Check Out Assets " ) )
. SizingRule ( ESizingRule : : UserSized )
. ClientSize ( FVector2D ( 1024.0f , 512.0f ) )
. SupportsMaximize ( false )
. SupportsMinimize ( false )
[
SNew ( SBorder )
. Padding ( 4.f )
. BorderImage ( FAppStyle : : GetBrush ( " ToolPanel.GroupBorder " ) )
[
SAssignNew ( SourceControlFileDialog , SSourceControlFileDialog )
. Message ( LOCTEXT ( " CheckoutPackagesDialogMessage " , " Conflict detected in the following assets: " ) )
. Warning ( LOCTEXT ( " CheckoutPackagesWarnMessage " , " Warning: These assets are locked or not at the head revision. You may lose your changes if you continue, as you will be unable to submit them to source control. " ) )
. Files ( InFilesConflicts )
]
] ;
SourceControlFileDialog - > SetWindow ( Window ) ;
Window - > SetWidgetToFocusOnActivate ( SourceControlFileDialog ) ;
GEditor - > EditorAddModalWindow ( Window . ToSharedRef ( ) ) ;
return SourceControlFileDialog - > IsProceedButtonPressed ( ) ;
}
2021-02-04 17:41:41 -04:00
} // end of namespace SSourceControlCommon
Refactored the Changelist Window UI to work better with large changelists along with bug fixes.
This submit should not regress any existing functionalites of the previous widget.
Along with the user interface changes, notable bug fixes were included
- If a changelist is not specified for P4 operations 'Mark for Add', 'Mark for Delete and 'Checkout', defaulted to the 'default' P4 changlist. Without a valid changelist, the cache wasn't properly updated.
- Fixed updating the cache for P4 'Mark for delete' operation not correctly updating the file changelist cached in the file state.
Other changes:
- P4 changelists are now always returned sorted by changelist number, ascending.
- Some of the safe operations were running synchronous are not running asynchrnous (create new changelist, delete empty changelist, delete shelved files).
This submit addresses the following Jiras:
#jira UE-155207 - Refactor the changelist window layout to have the left/right panel.
#jira UE-155209 - Add the context menu on right click on a file or a changelist.
#jira UE-155218 - Support creating new empty changelist from the changelist view.
#jira UE-155220 - Support moving files from the selected changelist (right view) to another changelist (left view)
#jira UE-155211 - Add visual feedback for any operation taking more than 0.5s.
#jira UE-155212 - Display a list of uncontrolled files in the left panel of the changelist window
#jira UE-155499 - Changelist windows buttons should be disabled if SCC is disabled
#jira UE-155229 - Add an option to automatically refresh the changelist window when new assets are imported|created (as uncontrolled), marked for add, checked out, marked for delete
#jira UE-107577 - Source Control's Changelists dialog does not refresh to reflect changes made while open
#rb Patrick.Enfedaque
#preflight 62ff946ef7404b55a326297b
[CL 21499885 by patrick laflamme in ue5-main branch]
2022-08-22 21:20:05 -04:00
# undef LOCTEXT_NAMESPACE