You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3252833 on 2017/01/10 by Ori.Cohen Refactor constraint so that it can be used for external solvers. (Copying //Tasks/UE4/Dev-ImmediateModePhysics to Dev-Framework (//UE4/Dev-Framework)) Change 3256288 on 2017/01/12 by Ori.Cohen Undo constraint refactor as we found a way around it and it made the code much harder to read/debug Change 3373195 on 2017/03/30 by Mike.Beach For nativization, changing it so we key off of the target platform-info struct instead of the platform (in preparation for defining the nativized plugin's platform whitelist). Change 3381178 on 2017/04/05 by Dan.Oconnor Make sure we don't inherit the NATIVE func flag when generating skeleton functions, also make sure all bojects outer'd to the skeleton class are marked transient #jira UE-43616 Change 3381532 on 2017/04/05 by Marc.Audy (4.16) Fix various cases where built lighting on child actors could be lost when loading a level #jira UE-43553 Change 3381586 on 2017/04/05 by Mike.Beach Now generating TArrayCaster conversions for nativized UClass arrays that need it (to handle different TSubclassOf arrays). #jira UE-42676, UE-43257 Change 3381682 on 2017/04/05 by mason.seay Some more changes to test map Change 3381844 on 2017/04/05 by Dan.Oconnor Match existing logic for CPF_ReturnParm/CPF_OutParm. Fixes compilation error in BP_TurbineBlades when using compilation manager Change 3382054 on 2017/04/05 by Zak.Middleton #ue4 - Optimize CharacterMovementComponent::GetPredictionData_Client_Character() and GetPredictionData_Server_Character() to remove virtual calls. #jira UE-30998 Change 3382703 on 2017/04/06 by Lukasz.Furman fixed missing links between navmesh polys when there are more than 4 neighbor connections #jira UE-43524 Change 3383357 on 2017/04/06 by Marc.Audy (4.16) Make SetHiddenInGame propagate consistently with SetVisibility #jira UE-43709 Change 3383359 on 2017/04/06 by Dan.Oconnor Fix last errant SKEL reference when cooking Odin Change 3383591 on 2017/04/06 by Mike.Beach Prevent users from setting object variables as 'config' properties (disallowed by UHT). This prevents some errors that could happen later when users nativize the Blueprint. #jira UE-42085 Change 3384762 on 2017/04/07 by Zak.Middleton #ue4 - Fix SpringArmComponent not restoring relative transform when bUsePawnControlRotation is turned off. Fixes the editor interaction ignoring transform of the component in the viewport after bUsePawnControlRotation is toggled on then off, since by then the world transform had been overwritten (from tick in editor) and nothing would drive transform changes from the editable value. Toggling bUsePawnControlRotation off at runtime now restores the rotation to the initial relative rotation, not stomping it with the current pawn rotation, allowing toggling between the editable/desired base rotation and the control rotation. #jira UE-24850 Change 3384948 on 2017/04/07 by Dan.Oconnor Prevent GForceDisableBlueprintCompileOnLoad from causing all sorts of badness when dependencies are loaded as part of a Diff operation. Instead of setting a global flag we flag the package as LOAD_DisableCompileOnLoad Change 3385267 on 2017/04/07 by Michael.Noland Graph Editing: Pushed some node diffing code down from UAIGraphNode into UEdGraphNode so nodes with details panel properties will diff correctly (e.g., various animation nodes and BP switch nodes) #jira UE-21724 Change 3385473 on 2017/04/07 by Phillip.Kavan #jira UE-43067 - Fix broken pin wires after an Expand Node operation, along with some misc. cleanup. Change summary: - Fixed to use correct string for "Expand Node" transaction name. - Modified FBlueprintEditor::OnExpandNodes() to consolidate some redundant code. - Fixed to generate a unique node GUID for cases where the source graph is not removed after expansion. Change 3385583 on 2017/04/07 by Dan.Oconnor Handle CreatePropertyOnScope nullptr return values (happens for structs missing a struct property) #jira UE-43746 Change 3386581 on 2017/04/10 by Michael.Noland Blueprints: Further hardening FBlueprintActionInfo::GetOwnerClass() #jira UE-43824 Change 3386615 on 2017/04/10 by Marc.Audy Instanced properties can now properly be set on a per-instance basis in blueprint added components. #jira UE-42066 Change 3387000 on 2017/04/10 by Marc.Audy Fix includes for CIS Change 3387229 on 2017/04/10 by mason.seay More changes to TM-Gameplay Added Save Game test (with blueprint) Tick Interval test (with blueprint) BP logic cleanup Level organization Change 3388437 on 2017/04/11 by Mike.Beach Adding support for map/set literals in the backend (so you can use set nodes for structs containing sets/maps, without having to connect a RHS input - resets to struct defaults). #jira UE-42617 Change 3388532 on 2017/04/11 by mason.seay Submitting latest changes for crash repro Change 3389026 on 2017/04/11 by Ben.Zeigler Performance and bug fixes for incremetal cooking with asset registry, duplicate of several changes made on //Fortnite/Main Fix it so AssetRegistry.ScanPathsAndFilesSynchronous won't scan subdirectories inside already scanned directories, this cuts down on the number of cache files Fix 2 second stall when shutting down AssetSourceFilenameCache if it had never been previously created Change 3389163 on 2017/04/11 by Ben.Zeigler #jira UE-42922 Fix it so connecting function input node output pins does not clear default value, we only want to clear the value when connecting an input pin. Properly testing this fix depends on UE-43883 Change 3389205 on 2017/04/11 by Marc.Audy Protect against a handful of GEditor usages that can now be hit in standalone Change 3389220 on 2017/04/11 by Marc.Audy Don't borrow ClassWithin to masquerade as ParentClass during compilation and instead just set the super struct immediately Change 3389222 on 2017/04/11 by Michael.Noland Framework: Adding a cvar (t.TickComponentLatentActionsWithTheComponent) to allow users to revert to the old behavior on when component latent actions tick - Non-zero values behave the same way as actors do, ticking pending latent action when the component ticks, instead of later on in the frame (default behavior in 4.16 and beyond) - Prior to 4.16, components behaved as if the value were 0, which meant their latent actions behaved differently to actors This CVar will be removed in a future version, defaulting to on #jira UE-43661 Change 3389276 on 2017/04/11 by Marc.Audy Spelling fix and NULL to nullptr Change 3389303 on 2017/04/11 by Mieszko.Zielinski Made sure AIController::Posses doesn't get called when compiling Pawn BP #UE4 #jira UE-43873 Change 3390215 on 2017/04/12 by mason.seay Removed some tests, will need further review Change 3390638 on 2017/04/12 by Mike.Beach Generalizing the omission of the CoerceProperty (in EmitTerm) - previously we were only omitting properties for our custom array lib. For wildcards, a coerce property should not be used as its type will not match. NOTE: There is a slight behavior change in UEdGraphSchema_K2::ConvertPropertyToPinType(), as it will return 'wildcard' for params marked as 'ArrayTypeDependentParams' (previously would have returned 'int'). #jira UE-42747 Change 3390774 on 2017/04/12 by Ben.Zeigler #jira UE-43911 Fix several issues with saving a runtime asset registry containing redirectors that caused crashes in cook on the fly. Don't resolve redirectors on incoming links because it will make a circular link, and fix an issue where chained redirectors would break the for loop iteration and return a bad dependency Fix it so the asset registry written out at the beginning of CookOnTheFly uses the registry generator, otherwise it will include all of the stripped editor only tags Change 3390778 on 2017/04/12 by Ben.Zeigler Fix UCookOnTheFlyServer::CollectFilesToCook to check for initial unsolicited packages up front. This is required in iterative mode because it may skip cooking all explicit packages and thus miss a new startup loaded package Change 3390782 on 2017/04/12 by Ben.Zeigler Change RunProjectCommand to not imply -nomcp, and allow reading -clientcmdline to override setting the map parameter to 127.0.0.1 by default Fix RunProjectCommand to remove ios-specific checks to not pass weird platform parameters, and instead never pass them Fix PS4Platform to pass along command line when calling build cook run, args needs to be the last parameter so explicitly set -target= Change 3390859 on 2017/04/12 by Mike.Beach T3D class fields now export with the class's fully qualified path name (to avoid abiguity). Since we can have multiple classes with the same name (Blueprints in different folders), we have to use the class's fully qualified object path. #jira UE-28048 Change 3390914 on 2017/04/12 by Lukasz.Furman fixed missing navlink component's transform in exported navigation data #jira UE-43688 Change 3391122 on 2017/04/12 by Ben.Zeigler Add new PreloadPrimaryAssets call to AssetManager that stream the desired assets without modifying the official load/unload state. This is useful if you want to preload things in case the might be used in the future, and it also supports recursion Fix crash calling GetAssetDataForPath with null path Change 3391494 on 2017/04/12 by Dan.Oconnor Fix bad references in deep object (widget) hierarchies #jira UE-43802 Change 3391529 on 2017/04/12 by Dan.Oconnor Fix log spam, accidently submitted #rnx Change 3391756 on 2017/04/12 by Dan.Oconnor LinkExternalDependencies needs to be performed before we RefreshVariables #jira UE-43843 Change 3392542 on 2017/04/13 by Marc.Audy Ensure that initialized actors get cleaned up when removed from world even if that world hasn't begun play. #jira UE-43879 Change 3392746 on 2017/04/13 by Marc.Audy (4.16) When duplicating a blueprint node, correctly make the new node a sibling of the duplicated node, not a child of it (unless duplicating the root component). Also resets scale of a duplicated root component to 1 to avoid a squaring of the scale for that component. #jira UE-40218 #jira UE-42086 Change 3393253 on 2017/04/13 by Dan.Oconnor Make sure calculated meta data is correctly set on functions generated by the compilation manager (SKEL_ class functions) #jira UE-43883 Change 3393509 on 2017/04/13 by Mike.Beach Removing hack'ish ResetLoaders() call that was causing undesired side-effects (resetting of a loaded package that other objects were relying on). This was originally intended to release file handles so separate editor processes could make updates and save the file (from CL 1712376). Using ResetLoaders() for this is bad though, as it has too many side effects. Instead we have to wait for GC to run. This also makes sure that GC should run as intended as the CookOnTheFly sever is idling. #jira UE-37284 Change 3394350 on 2017/04/14 by Michael.Noland Core: Making FDateTime and FTimespan actually reflected, so they get duplicated properly in CopyPropertiesForUnrelatedObjects, etc... #jira UE-39921 Change 3395985 on 2017/04/17 by Phillip.Kavan #jira UE-38280 - Fix invalid custom type selections on member fields in the User-Defined Structure Editor after a reload. Change summary: - Ensure that the 'SubCategoryObject' member in a UDS variable descriptor has been loaded when converting to an FEdGraphPinType. Change 3396152 on 2017/04/17 by Marc.Audy TickableGameObjects that have IsTickableInEditor false should not tick in the editor #jira UE-40421 Change 3396279 on 2017/04/17 by Phillip.Kavan #jira UE-43968 - Fix failed validation of bitmask enum types when serializing bitmask literal nodes. Change 3396299 on 2017/04/17 by Dan.Oconnor Fix resintancing issues exposed by running TM-Gameplay with -game. We cannot reinstance actors in levels on load because the scene is not created. #jira UE-43859 Change 3396712 on 2017/04/17 by Marc.Audy Call PostLoad on subobjects before copying for unrelated properties to avoid cases where an out of date object patched over in the linker has not been brought up to date #jira UE-38234 Change 3396718 on 2017/04/17 by Mike.Beach Adding a search bar to the components tree for Blueprints. #epicfriday #jira UE-17620 Change 3396999 on 2017/04/17 by Mike.Beach In generated code, call event '_Implementation' functions directly for interface functions being invoked on self (avoids a UHT runtime error). #jira UE-44018 Change 3397700 on 2017/04/18 by Marc.Audy UT struct BlueprintType fixups Change 3397701 on 2017/04/18 by Marc.Audy Odin struct BlueprintType fixups Change 3397703 on 2017/04/18 by Marc.Audy Ocean struct BlueprintType fixups Change 3397704 on 2017/04/18 by Marc.Audy WEX struct BlueprintType fixups Change 3397705 on 2017/04/18 by Marc.Audy Additional UT blueprint type struct fixups Change 3397706 on 2017/04/18 by Marc.Audy Fortnite struct BlueprintType fixups Change 3397708 on 2017/04/18 by Marc.Audy Fixup Engine BlueprintType markup of structs Change 3397709 on 2017/04/18 by Marc.Audy Sample Game struct BlueprintType fixups Change 3397711 on 2017/04/18 by Marc.Audy Mark AnimNodes as BlueprintType and BlueprintInternalUseOnly Change 3397712 on 2017/04/18 by Marc.Audy Paragon struct BlueprintType fixups Change 3397735 on 2017/04/18 by Marc.Audy Definition pieces of BlueprintInternalUseOnly to fix UHT errors with structs already marked to use it Change 3397912 on 2017/04/18 by Mike.Beach Fix for CIS warnings about shadowed variables (fallout from CL 3396718). Change 3398455 on 2017/04/18 by Marc.Audy Make less critical errors log an error rather than immediately throwing allowing multiple errors to be reported in the same compile Change 3398491 on 2017/04/18 by Marc.Audy BPRW/BPRO in a non-BlueprintType is now a UHT error Change 3398539 on 2017/04/18 by Marc.Audy Fixup live link struct markups Change 3399412 on 2017/04/19 by Marc.Audy Fix Match3 blueprint type struct markups Change 3399509 on 2017/04/19 by Phillip.Kavan #jira UE-38574 - Fix AnimBlueprint function graphs marked as 'const' to treat 'self' as read-only when compiling. Change summary: - Modified FKismetCompilerContext::ProcessOneFunctionGraph() to use the function graph schema rather than the compiler context schema for both the function context's schema as well as testing the function for 'const'-ness. For AnimBPs, the compiler context and the function graph context can differ, so we need to make sure we are using the right one when making queries for a specific function context during compilation. - Minor cleanup: changed the function context schema to be 'const' in order to be consistent with the function graph GetSchema() API's result. Added a few 'const' qualifiers where needed to match. - Added a new object version in order to avoid breaking compilation of existing AnimBP function graphs that may already be violating the 'const' rule (this is the same thing that was done when 'const' was first added to "normal" BP function graphs). Just as with normal function graphs in place before the addition, a warning will be generated for existing AnimBP function graphs if they violate 'const' correctness, and an error will be generated for all new ones. Change 3399749 on 2017/04/19 by Mike.Beach Hiding the Nativized Blueprints plugin from the in-editor browser (prevent users from disabling it). Change 3399774 on 2017/04/19 by Marc.Audy ConditionalPostLoad is already called on StaticMesh earlier in the function #rnx Change3400313on 2017/04/19 by Mike.Beach Mirroring CL 3398673 from 4.16 Now, with ICWYU, making sure that the coresponding header gets included first in nativized Blueprint files (else we get a UHT error). Had to fixup some ShooterGame specific files as a result (they had missing includes and forward declarations). #jira UE-44124 Change 3400328 on 2017/04/19 by Mike.Beach Missing file from mirrored change (CL3400313- mirroring CL 3398673 from 4.16) #jira UE-44124 Change 3400415 on 2017/04/19 by Chad.Garyet adding physx switch build to framework Change 3400514 on 2017/04/19 by Mike.Beach Back out changelist3400313/ 3400328 (mirrored from CL 3398673 in 4.16), as it was producing "include PCH first" errors. Likely, CL 3398673 was a fix for a 4.16 specific change, altering the expected include order. We'll have to wait for this one to be integrated back. Change 3400552 on 2017/04/19 by Marc.Audy Undo the calling of post load prior to the CPFUO as dependent objects may not yet be loaded. Instead copy the need load flag to the new CDO subobject, similarly to how the top level CDO object copies its flags over. #jira UE-44150 Change 3400815 on 2017/04/19 by Marc.Audy Spelling fix (part of PR #3490) #rnx Change 3400918 on 2017/04/19 by Marc.Audy Partial pull of PR #3490: Improved remapping game controls support (Contributed by projectgheist) This portion brings in the exposure of the bindings to blueprint #jira UE-44122 Change 3401550 on 2017/04/20 by Marc.Audy fix kitedemo blueprint type markup #rnx Change 3401702 on 2017/04/20 by Mike.Beach Make it so plugins added to a project through the .uproject's 'AdditionalPluginDirectories' list get folded into the generated code project (for visual studio, etc.). Change 3401720 on 2017/04/20 by Mike.Beach Add white and black lists for target type (game, client, server, etc.) to plugin module descriptors. Change 3401725 on 2017/04/20 by Mike.Beach Whitelisting the nativized Blueprint plugin for only the targets it was built for (game, server, or client). Change3401800on 2017/04/20 by Ben.Zeigler Add Algo::BinarySearch, LowerBound, and UpperBound. These are setup to allow binary searching a presorted array, and allow for specifying projection and sort predicates. Convert some engine code to use it Add TSortedMap, which is a map data structure that has the same API as TMap, but is backed by a sorted array. It uses half the memory and performance is faster below n=10 Add FName::CompareIndexes so a SortedMap with FNames can be used without doing very slow string compares, and FNameSortIndexes predicate to sort by it Add code to Algo and Container tests. Split up container tests so the new ones aren't run in smoketest as they are a bit slow Add RemoveCurrent and SetToEnd to ArrayIterator Change 3401849 on 2017/04/20 by Marc.Audy Partial pull of PR #3490: Improved remapping game controls support (Contributed by projectgheist) This portion brings bug fixes and improvements to InputKeySelector UMG widgets. #jira UE-44122 Change 3402088 on 2017/04/20 by Marc.Audy Focus the search box when expanding the map value type #jira UE-44211 Change 3402251 on 2017/04/20 by Ben.Zeigler Fix issue where SortedMap needs to be resorted after serialization, because the sorting may have changed from when it was saved out Change 3402335 on 2017/04/20 by Ben.Zeigler Significant changes to FAssetData serialization and memory, cuts memory significantly but will break code that was using some of the internal API that was not properly hidden before Both Editor and Runtime cache now use the same FAssetRegistryVersion, which is now registered as a custom version Rename FAssetData and FAssetPackage operator<< to SerializeForCache to make it clear that it isn't safe to use for general serialization Remove GroupNames from FAssetData, it has not been useful since the UE4 package structure changed around 4.0 Rename generic-sounding but not actually generic SharedMapView class to AssetDataTagMapSharedView to indicate what it is actually used for Change TagsAndValues to use a new array-backed TSortedMap as the base structure instead of a hash map. Also, it only allocates the map on demand, which saves significant memory at runtime as many packages have no tags Add bFilterAssetDataWithNoTags to [AssetRegistry] ini section, if set it will only save cooked asset data if it has tags, off by default but saves significant memory if your whitelist is set up properly Fix issue where asset registry tags updated by loading assets during cook were not being reflected in the cooked registry Add AssetRegistry::GetAllocatedSize and add to MemReport output Change 3402457 on 2017/04/20 by Ben.Zeigler Enable asset registry iteration and stripping unused asset data in Fortnite. Registry iteration is already on in //Fortnite/Main, stripping is a new feature I want to test Change 3402498 on 2017/04/20 by Ben.Zeigler CIS fix. Why did this compile locally? Change 3402537 on 2017/04/20 by Ben.Zeigler Remove ensure for making AssetData for subobjects, the editor does this for thumbnail creation in some cases Change 3402600 on 2017/04/20 by Ben.Zeigler Add bShouldGuessTypeAndNameInEditor to manager settings, can be set false for games where type cannot be safely implied and content must be resaved Fix up some bool setting code inside asset manager, and fix const correctness and for iterator issues AssetManager can now discover any BlueprintCore type when bHasBlueprintClasses=true Add AssetManager.DumpAssetRegistryInfo to output detailed asset registry usage stats Add Primary Name to asset audit window by default Change 3403556 on 2017/04/21 by Marc.Audy Fix Orion input key selector override class #rnx Change 3404090 on 2017/04/21 by mason.seay Applying Forcefeedback to test map Change 3404093 on 2017/04/21 by mason.seay Changing text in level Change 3404139 on 2017/04/21 by mason.seay Added Force Feedback test and made some tweaks. Change 3404146 on 2017/04/21 by mason.seay Added source reference to Instanced Variable test Change 3404154 on 2017/04/21 by mason.seay More minor tweaks Change 3404155 on 2017/04/21 by Marc.Audy Remove auto #rnx Change 3404188 on 2017/04/21 by Marc.Audy Fixed crash changing variable type when any type other than map #jira UE-44249 #rnx Change 3404463 on 2017/04/21 by Ben.Zeigler Fix asset data code to not ensure when loading an object with invalid exports, and instead print warning with name of package that needs to be resaved Resave a map that had a redirector from a DIFFERENT package saved in it's exports. I do not understand how this happened, but it appears to be related to the lightmap BuiltData transition when old maps are opened Change 3404465 on 2017/04/21 by Ben.Zeigler Fix issue with trying to load editor-only asset classes in a cooked build Fix issues with renaming or changing template Ids of assets from the editor Always print the Duplicate Asset ID error, as if you have more than one the ensuremsg only goes off once Change 3404481 on 2017/04/21 by Dan.Oconnor Remove unneeded walk up hierarchy - prevent stale entries in action database if we compile a BP but don't compile its children Change 3404510 on 2017/04/21 by Phillip.Kavan #jira UE-35727 - Collapsed graphs containing a local variable node will no longer cause a compile error when the parent graph is renamed. Change 3404590 on 2017/04/21 by Michael.Noland Editor: Fixed incorrect filtering of abstract/deprecated UDeveloperSettings and UContentBrowserFrontEndFilterExtension classes caused by a typo (HasAnyCastFlags versus HasAnyClassFlags) Change 3404593 on 2017/04/21 by Marc.Audy Fixed another crash to do with input pin secondary combo box #jira UE-44269 #rnx Change 3404600 on 2017/04/21 by Michael.Noland Core: Allow UE_GC_TRACK_OBJ_AVAILABLE to be set externally #rnx Change 3404602 on 2017/04/21 by Michael.Noland Engine: Switched from an include to a forward declaration of SWidget in UDeveloperSettings to keep it slim #rnx Change 3404608 on 2017/04/21 by Michael.Noland Core: Marked TNumericLimits as constexpr so they can be used in static asserts Change 3404659 on 2017/04/21 by Michael.Noland Engine: Adding includes back to two UDeveloperSettings subclasses Change 3405289 on 2017/04/24 by Marc.Audy Remove auto #rnx Change 3405446 on 2017/04/24 by Marc.Audy Fix Win32 unsigned compile issue Change 3405512 on 2017/04/24 by Mike.Beach Piping through NativizationOptions to filename generation (so we're able to gen different files names per target: client vs. server). Change 3406080 on 2017/04/24 by Ben.Zeigler Deprecate UEngine::OnPostEngineInit and move to FCoreDelegates, clean up comments for the initialization delegates Call OnPostEngineInit from commandlet initialization as well as normal execution. I thought about making a wrapper function, but the commandlet calls EditorInit directly so it wouldn't work Bind delegate to refresh the AssetRegistry native class hierarchy after engine init so it picks up game/plugin classes. Undo ini change that was required to hack around this Change 3406381 on 2017/04/24 by Ben.Zeigler #jira UE-23768 Enable Run Physics With No Controller for montage test pawn. The montage pawn has no controller so wasn't correctly running physics when the root motion stopped. This flag needs to be set to allow it to correctly stop after the montage is over Change 3406438 on 2017/04/24 by Ben.Zeigler Fix deprecation warning Change 3406519 on 2017/04/24 by Phillip.Kavan #jira UE-43612 - Suppress array "Get" node fixup notifications on load when the BP Compilation Manager is enabled. Change summary: - Wrapped BPCM calls to FBlueprintEditorUtils::ReconstructAllNodes() and ReplaceDeprecatedNodes() duirng compile-on-load with bIsRegeneratingOnLoad = true. This matches the BP's state during compile-on-load when the BPCM is not enabled. Change 3406565 on 2017/04/24 by Dan.Oconnor Make sure all interface functions are added to skeleton #jira UE-44152 Change 3407489 on 2017/04/25 by Ben.Zeigler #jira UE-44317 Fix game-only TickableGameObjects to correctly tick in PIE Change 3407558 on 2017/04/25 by Ben.Zeigler Fix Fortnite cook warnings, issue had to do with the CDO being registered as a Primary Asset in conflict with the Class being registered Fix issue with renaming a BP primary asset not finding the old name Change 3407701 on 2017/04/25 by Dan.Oconnor Remove unneeded null check, static analysis doen't like the inconsistency Change 3407995 on 2017/04/25 by Marc.Audy Fixed maps and sets not working correctly with split pin. #jira UE-43857 Change 3408124 on 2017/04/25 by Ben.Zeigler #jira UE-39586 Change it so the blueprint String/Name/Object to Text node creates culture invariant text, and also have them show as an expanded node with a comment explaining this Fix Transform to actually return in the format specified in the comment, and fix comments on many text conversions Change 3408134 on 2017/04/25 by Marc.Audy Graph pin container type now represented by an enumeration (EPinContainerType) rather than 3 "independent" booleans. FEdGraphPinType constructor, UEdGraphNode::CreatePin, and FKismetCompilerContext::SpawnInternalVariable that took 3 booleans deprecated and replaced with a version that takes EPinContainerType. UEdGraphNode::CreatePin parameters reorganized so that PinName is before ContainerType and bIsReference, which default to None and false respectively Change 3408256 on 2017/04/25 by Michael.Noland Core: Changed UClass::ClassFlags to be of type EClassFlags for improved type safety Change 3408282 on 2017/04/25 by Marc.Audy (4.16) Fix incorrect positioning of instance components after duplication #jira UE-44314 Change 3408404 on 2017/04/25 by Mike.Beach Adding and removing the nativized plugin to/from the project when we alter the packaging nativization setting (so it gets picked up by project generation). Change 3408445 on 2017/04/25 by Marc.Audy Fix up missed deprecation cases #rnx Change 3409354 on 2017/04/26 by Marc.Audy Fix Linux CIS failure #rnx Change 3409487 on 2017/04/26 by Marc.Audy When dragging assets in to the SCS create them as siblings, not nested #jira UE-43041 Change 3409776 on 2017/04/26 by Ben.Zeigler #jira UE-44401 Fix issue with cooking a map containing a reparented component. In that case the child component may think it's not editor only, but it's archetype is editor only. This is not allowed in EDL, so now the child is marked as editor only as well Change 3410168 on 2017/04/26 by Dan.Oconnor Avoid calling virtual functions in the middle of compile #jira UE-44243 Change 3410252 on 2017/04/26 by Lukasz.Furman adjusted WITH_GAMEPLAY_DEBUGGER checks after IWYU changes #ue4 Change 3410385 on 2017/04/26 by Marc.Audy ChildActorComponent SetClass no longer fails when setting at runtime. #jira UE-43356 Change 3410466 on 2017/04/26 by Michael.Noland Core: Ensuring EClassFlags is 32 bit in a different way (underlying type of the enum is coming out signed even though all members are unsigned, long term fix is probably to move it to an enum class) #rnx Change 3410476 on 2017/04/26 by Michael.Noland Automation: Deleting some commented out methods #rnx Change 3411070 on 2017/04/27 by Marc.Audy Properly complete deprecation of old attachment API Change 3411338 on 2017/04/27 by mason.seay Map for Latent Action Tick Bug Change 3411637 on 2017/04/27 by Ben.Zeigler Back out CL #3381532 as it was causing crashes when adding new variables to blueprints, as the transaction array was being recursively modified while it was being added to Change 3412052 on 2017/04/27 by mason.seay Updated jump test map and pawn Change 3412231 on 2017/04/27 by Ben.Zeigler Fix issue where running SearchAllAssets multiple times after mounting new paths would throw away the asset registry cache, which slowed down incremental cooking substantially because the cooker mounts the autosave folder Duplicate of CL #3411860 Change 3412233 on 2017/04/27 by Ben.Zeigler Made FStreamableHandle::GetLoadedCount much faster by taking advantage of existing progress counter Duplicate of CL #3411778 Change 3412235 on 2017/04/27 by Ben.Zeigler Add code to FStringAssetReferenceThreadContext and FStringAssetReferenceSerializationScope which allows setting package name and collect options for string asset references serialized via something other than linker load Make RedirectCollector threadsafe to avoid issues with async loading asset references Fix it so ProcessStringAssetReferencePackageList will remove entries from the string asset array like resolve did, and rename function to indicate that Fix it so string asset references created by asset labels do not automatically get cooked, and significantly improve the speed of labels with lots of assets Add code to cooker and asset manager to explicitly mark non-cookable assets as NeverVook, this stops labels from ending up in the build if set that way Added option to not recurse package dependency changes more than one level when hashes change. This ended up not being significantly faster in a realistic case so left disabled Duplicate of CL #3412080 Change 3412352 on 2017/04/27 by Marc.Audy Refix lighting getting wrong position when getting component instance data Change 3412426 on 2017/04/27 by Marc.Audy Take first steps to making ComponentToWorld private and force use of accessor Make bWorldToComponentUpdated private Make ComponentToWorld and bWorldToComponentUpdated mutable Add a SetComponentToWorld function for the (likely ill-advised) places that were setting it directly. Change 3412468 on 2017/04/27 by Marc.Audy Remove last remnants of deprecated (4.11) custom location system Change 3413398 on 2017/04/28 by Marc.Audy Fix up missed deprecated attachment API uses Change 3413403 on 2017/04/28 by Marc.Audy Fix Orion compile error #rnx Change 3413448 on 2017/04/28 by Marc.Audy Fix up kite demo component to world privataization warnings #rnx Change 3413792 on 2017/04/28 by Ben.Zeigler Fix many bugs with blueprint pin default values, and add "Reset to Default Value" option to pin context menu Deprecate and rename SetPinDefaultValue because it actually sets the Autogenerated default. This was being called in bad places and destroying the stored autogenerated defaults #jira UE-40101 Fix expose on spawn pins to correctly update when the spawned object's defaults change #jira UE-21642 Fix struct pin default values to properly update when the struct is changed #jira UE-39418 Fix changed function/macro default values to properly update in already placed call nodes Change 3413839 on 2017/04/28 by samuel.proctor Added some Blueprint focused tests for TM-Gameplay Change 3414030 on 2017/04/28 by Ben.Zeigler Enable use of AssetPtr variables with Config, for native and blueprint This incorporates CL #3302487 but also enables for blueprint usage as that code is new to framework branch Change 3414229 on 2017/04/28 by Marc.Audy Fixup virtuals not calling their Super Remove some autos #rnx Change 3414451 on 2017/04/28 by Lukasz.Furman static analysis fix for gameplay debugger Change 3414482 on 2017/04/28 by Ben.Zeigler Fix crash found where changing pin type on ConvertAsset accessed an array while deleting it Change 3414609 on 2017/04/28 by Ben.Zeigler #jira UE-18146 Refresh graph when disconnecting a resolve asset id node Change 3415852 on 2017/05/01 by Marc.Audy Remove unused code #rnx Change 3415856 on 2017/05/01 by Marc.Audy auto removal #rnx Change 3415858 on 2017/05/01 by Marc.Audy Fix function taking an input as reference when unneeded and causing (still unclear why it suddenly started showing up) error in cooking #rnx Change 3415946 on 2017/05/01 by Marc.Audy Have K2Node_StructOperation skip the K2Node_Variable validation as it doesn't need a property (per CL# 1756451) #rnx Change 3415988 on 2017/05/01 by Lukasz.Furman renamed WorldContext param in AI related static blueprint functions to remove load/cook warnings #jira UE-44544 Change 3416030 on 2017/05/01 by Ben.Zeigler Fix issue with WorldContext pins being broken by my pin value refactor, partial paths like "WorldContext" need to be stored as strings and not as broken object references. Change 3416230 on 2017/05/01 by Marc.Audy Fix spelling error #rnx Change 3416419 on 2017/05/01 by Phillip.Kavan #jira UE-44213 - Nativizing a Blueprint class with a non-nativized Blueprint class subobject dependency will no longer lead to a crash at load time. Change summary: - Modified the FFakeImportTableHelper ctor to inject subobject CDOs into the 'SerializeBeforeCreateCDODependencies' array. This in turn ensures that EDL will serialize those subobject CDOs (if necessary) before we create the subobject's nativized owner's CDO at load time. - Modified FEmitDefaultValueHelper::GenerateCustomDynamicClassInitialization() to emit MiscConvertedSubobject instantiations AFTER we emit the FillUsedAssetsInDynamicClass() call. This is now consistent with the code emitted for other subobjects (all of which assumes that the UsedAssets array has been initialized). - Modified FFindAssetsToInclude::HandleObjectReference() to add UField owner CDOs in addition to the owner class to the asset dependency list. This ensures that owner CDOs will be emitted alongside the class to both the nativized asset dependency table as well as to the fake import table associated with the UDynamicClass linker for the nativized BP asset. Change 3416425 on 2017/05/01 by Phillip.Kavan #jira UE-44219 - Nativizing a Blueprint class with a nativized DOBP class dependency will no longer lead to a compile error at cook/nativization time. - Modified the FGatherConvertedClassDependencies ctor to properly handle DOBPs in exclusive mode that have been explicitly enabled for nativization. Previously, this code wasn't taking that possibility into account, and as a result could lead to a missing header file in a dependent nativized class body's include set. - Modified FGatherConvertedClassDependencies::GetFirstNativeOrConvertedClass() to remove the 'bExcludeBPDataOnly' parameter, as it was primarily just being used for a redundant exclusion check when called from the FGatherConvertedClassDependencies ctor. That call site has now been modified to start searching from the super class instead. Additionally, any DOBPs will already fail the preceding WillClassBeConverted() check if they have not been explicitly enabled for nativization in exclusive mode, and will always fail if nativizing in inclusive mode. The extra check was breaking the explicitly-enabled case, so it was removed to allow explicitly-enabled DOBPs to pass. Notes: - Allowing for explicitly-enabled DOBPs in exclusive mode may be removed in a future change, but since it is currently supported, the changes noted above will at least ensure that the generated code will compile properly for now. Change 3416570 on 2017/05/01 by mason.seay Added UMG test to map. Tweaked force feedback test Change 3416580 on 2017/05/01 by mason.seay Resubmitting sub levels Change 3416597 on 2017/05/01 by Dan.Oconnor Compilation manager iteration, adds machinery for individual blueprint compilation, adds comments, cleans up duplicated code Change 3416636 on 2017/05/01 by Phillip.Kavan #jira UE-44505 - Potential fix for a low-repro crash tied to the Blueprint graph context menu. Change summary: - Switched FBlueprintActionInfo::ActionOwner to be a weak object reference. Change 3416960 on 2017/05/01 by Dan.Oconnor Use compilation manager when clicking the compile button, PIE'ing, etc Change 3417207 on 2017/05/01 by Ben.Zeigler Fix issue with None strings causing default value parsing failures Add SetPinDefaultValueAtConstruction needed by some other changes Change 3417519 on 2017/05/01 by Ben.Zeigler Fix BP compile errors caused by local variables with invalid default values. There's no reason to set autogenerated here because the nodes are transient and invisible in the UI. There is still a problem here, local variables are not getting their default values validated when type is changed, so you end up with an integer that has the default value of a struct. Change 3418659 on 2017/05/02 by Ben.Zeigler #jira UE-44534 Fix it so animation node pins get properly created autogenerated default values that are based on the node struct defaults. This fixes issues when they are reset to other defaults #jira UE-44532 Fix it so connecting an animation asset pin on a node player resets the pin value to the autogenerated default instead of the cached asset. This was causing old unused assets to get unnecessarily cooked Fix it so any animation node with an exposed pin that is an object property will reset that object propery when the pin is exposed. This fixes UE-31015 in a generic way Change the OptionalPinManager to take a Defaults address as well as a current address, to allow setting autogenerated defaults properly Remove Import/ExportKismetDefaultValueToProperty as they were redundant with PropertyValueFromString and were using the wrong pin setting functions, replaced with PropertyValueFromString_Direct and calling the schema pin set functions I need to write some backward compatibility code to fix existing nodes, I'll do that in a later checkin Change 3418700 on 2017/05/02 by Ben.Zeigler Actually fix None object paths for real this time. I did not test sufficiently before Change 3418811 on 2017/05/02 by Ben.Zeigler Fix existing animation blueprint nodes with dead asset references duplicated by pins. This code can be applied independent of the other change to fix specific games Change 3419165 on 2017/05/02 by Dan.Oconnor Add misc. functionality from FKismetEditorUtilities::CompileBlueprint Change 3419202 on 2017/05/02 by Marc.Audy Merging //UE4/Dev-Main to Dev-Framework (//UE4/Dev-Framework) @ 3417825 #rnx Change 3419236 on 2017/05/02 by mason.seay Removed OnPressed event from Widget BP Change 3419314 on 2017/05/02 by Marc.Audy Fix bad auto-resolve #rnx Change 3419524 on 2017/05/02 by Marc.Audy PR #3528: Improved Input BP library node display names (Contributed by projectgheist) #jira UE-44587 #rn Improved Input BP library node display names Change 3419570 on 2017/05/02 by Zak.Middleton #ue4 - Fix typo in TFunctionRef comment/example. Change 3419709 on 2017/05/02 by Dan.Oconnor Fix missing category metadata on SkeletonGeneratedClass when using compilation manager Change 3419756 on 2017/05/02 by Dan.Oconnor Remove unintentional verbosity increase Change 3420875 on 2017/05/03 by Marc.Audy Make IsExecPin static Minor optimization to IsMetaPin #rnx Change 3420981 on 2017/05/03 by Marc.Audy Change tagging temporarily until other changes are done so that we don't have warnings in the meantime #rnx Change 3421367 on 2017/05/03 by Marc.Audy Manually introduce changes from CL# 3398673 in 4.16 that failed to make it to Dev-Framework as a result of the integration submitted as CL# 3401725. #rnx Change 3421685 on 2017/05/03 by Ben.Zeigler #jira UE-23001 Convert literal Asset ID/Class ID pins to store path as string instead of as hard object reference. Old pins are fixed on load, after resaving the hard references will go away Refactor the way that FStringAssetReference and FAssetPtr are serialized, it now does the various fixups in FStringAssetReference::SerializePath, which is called from archivers Change it so the asset registry reads in a list of all scanned redirectors and adds them to GRedirectCollector, this means that saving a string asset reference will automatically fix it up to point to the redirector destination Change the default behavior of FAssetPtr serialize on ArchiveUObject to match what most of it's children want, and remove several special case hacks. It now serializes as asset reference when saving/loading, and as object for other cases Deprecate StringAssetReferenceLoaded/StringAssetReferenceSaving delegates, replace with PreSavePath and PostLoadPath on FStringAssetReference Make AssetLongPathname private on FStringAssetReference, it was deprecated in 4.9 Change 3421728 on 2017/05/03 by Phillip.Kavan Mirror CL 3408285 from //UE4/Release-4.16. #jira UE-44124 #rnx Change 3422370 on 2017/05/03 by Dan.Oconnor Mirror 3422359 Implement UBlueprintGeneratedClass::NeedsLoadForEditorGame to match UBlueprint, also tag a class's CDO as NeedsLoadForEditorGame. This prevents us from failing to load a UBlueprint's GeneratedClass when running the editor with -server. #jira UE-44659 Change 3423192 on 2017/05/04 by Ben.Zeigler CIS Fix Change 3423305 on 2017/05/04 by Ben.Zeigler Fix "Missing opening parenthesis" warnings for Vector and Rotator the same way they were fixed for Transform Change 3423358 on 2017/05/04 by Marc.Audy Merging //UE4/Dev-Main to Dev-Framework (//UE4/Dev-Framework) @ 3422809 #rnx Change 3423766 on 2017/05/04 by Ben.Zeigler #jira UE-44680 Delete some corrupted redirectors that are no longer in use Change 3423804 on 2017/05/04 by Dan.Oconnor Honor SaveIntermediateCompilerResults when using compilation manager Change 3424010 on 2017/05/04 by Marc.Audy Validate that switch string cases are unique Change 3424011 on 2017/05/04 by Marc.Audy Re-fix switch node default pin not appearing as an exec output Remove unused boolean Change 3424071 on 2017/05/04 by Ben.Zeigler Delete FixupRedirects commandlet, replace with -FixupRedirects/FixupRedirectors option on ResavePackages. This new method is much faster than the old commandlet as it uses the asset registry vs loading all packages, fixing up all redirectors in Fortnite only took about an hour vs 12+ hours the old way Removed some hacky bits in Core that only existed to support FixupRedirects Change it so the AssetRegistry listens to DirectoryWatcher callbacks in commandlets now that commandlets use the asset registry properly. This won't do anything unless you tick directory watcher the way that ResavePackages does Change 3424313 on 2017/05/04 by Dan.Oconnor Address missing property flags on SkeletonGeneratedClass when using compilation manager #jira UE-44705 Change 3424325 on 2017/05/04 by Phillip.Kavan #jira UE-44222 - Move nativized UDS implementation details into its own .cpp file in order to avoid circular dependencies. Change summary: - Modified IKismetCompilerInterface::GenerateCppCodeForStruct() to include an output parameter for CPP source and modified FKismet2CompilerModule to match the updated API. - Modified IBlueprintCompilerCppBackend::GenerateCodeFromStruct() to include an output parameter for CPP source and modified FBlueprintCompilerCppBackendBase to match the updated API. - Modified FBlueprintNativeCodeGenUtils::GenerateCppCode() to adjust the call to GenerateCppCodeForStruct() to include CPP source output. - Modified FGatherConvertedClassDependencies::DependenciesForHeader() to switch UDS property dependencies to be forward declarations rather than includes (for default value init code). - Modified FEmitDefaultValueHelper::GenerateGetDefaultValue() to emit implementation details to the 'Body' container, and adjust the header content to be a declaration only. - Modified FIncludeHeaderHelper::EmitInner() to exclude a potentially-redundant line for the module's .h file, for the case when the caller has included the base filename in the 'AlreadyIncluded' set. - Modified FEmitterLocalContext::FindGloballyMappedObject() to limit the 'TryUsedAssetsList' path to UClass conversions only (since that requires a UDynamicClass target to work). - Modified FGatherConvertedClassDependencies::DependenciesForHeader() to only include BPGC fields if they are also being converted. Eliminates an issue with missing header files in generated code. Change 3424359 on 2017/05/04 by Ben.Zeigler Fix issue where StreamableManager would break when requesting an async load that failed the first time. Because our game supports downloading assets during gameplay it's not safe to assume it will never load again. Port of CL #3424159 Change 3424367 on 2017/05/04 by Ben.Zeigler Fix some asset manager warnings to not go off in invalid cases Change 3425270 on 2017/05/05 by Marc.Audy Pack booleans/enums in UEdGraphNode and FOptionalPinFromProperty #rnx Change 3425696 on 2017/05/05 by Ben.Zeigler #jira UE-44672 Fix it so select node option pins get populated with default values properly #jira UE-43927 Fix it so select node opion pin type is correctly maintained accross node recreation, as opposed to deriving from the attached pins #jira UE-44675 Fix it to correctly refresh select node when switching from bool to integer index Change 3425833 on 2017/05/05 by Ben.Zeigler #jira UE-31749 Fix it so Undo works properly when modifying a local variable #jira UE-44736 Fix it so changing the type of a local variable correctly resets the default value Change 3425890 on 2017/05/05 by Marc.Audy Fix Copy/Paste of child actor components losing the template #jira UE-44566 Change 3425947 on 2017/05/05 by Ben.Zeigler This was meant to be part of last checkin Change 3425959 on 2017/05/05 by Ben.Zeigler #jira UE-44692 Fix it so only the sequentially last node can be removed from a Switch On Int, and for Switch On Name stop it from removing an exec pin if it's the only non-default one Change 3425979 on 2017/05/05 by Dan.Oconnor PVS fix Change 3425985 on 2017/05/05 by Phillip.Kavan Fix an uninitialized variable. #rnx Change 3426043 on 2017/05/05 by Ben.Zeigler #jira UE-35583 Correctly refresh array node UI when connecting pins that change it away from wildcard Change 3426174 on 2017/05/05 by Zak.Middleton #ue4 - Avoid call to virtual getSimulationFilterData() to only use it when needed in PreFilter if we actually have items in the IgnoreComponents list (which is rare). The sim filter data 'word2' stores the component ID. Change 3426621 on 2017/05/05 by Phillip.Kavan #jira UE-44708 - Fix an issue that re-introduced component data loss in a non-nativized child Blueprint class with a nativized parent Blueprint class. Change summary: - Removed an unnecessary additional check I had for the presence of "-NativizeAssets" switch on the command line in UBlueprint::BeginCacheForCookedPlatformData(). This check was failing because the usage was recently changed to include an optional value. It was not needed anyway so I just removed it. #rnx Change 3426906 on 2017/05/05 by Ben.Zeigler #jira UE-11189 Fix function/macro input default values to show as a pin customization instead of as a broken text box that doesn't work correctly for most types. This fixes enums and provide validation for other types Types that don't have a customization (most structs) will now show any more, they did not work before either #jira UE-21754 Hide function default values if pass by reference is set Fix it so changing input parameter will also reset default value, to avoid having the wrong type value set and to work the same as local variables Change 3426941 on 2017/05/05 by Dan.Oconnor Fix determinstic cooking of LoadAssetClass nodes in macros Change 3427021 on 2017/05/05 by Dan.Oconnor Build fix, make initialization order in source match artifact #rnx Change 3427135 on 2017/05/05 by Phillip.Kavan #jira UE-44702 - Restore code-based interface classes to Blueprint editor UI. Change summary: - Partially backed out CL# 3348513 to return to previous behavior for 4.16. The UI is no longer filtering on the __is_abstract() type trait for interface classes. - Modified FNativeClassHeaderGenerator::ExportClassFromSourceFileInner() to emit the _getUObject() declaration for native interface types as a default implementation that returns NULL rather than as a pure virtual declaration. #rnx Change 3427144 on 2017/05/06 by Marc.Audy Fix init order #rnx Change 3427146 on 2017/05/06 by Marc.Audy remove stray semicolon #rnx Change 3427242 on 2017/05/06 by Phillip.Kavan #jira UE-44744 - Fix a regression in which a UMG Widget Blueprint property not explicitly marked as a variable would cause Blueprint nativization to fail at package time. Change summary: - Modified FWidgetBlueprintCompiler::CreateClassVariablesFromBlueprint() to only add 'Category' metadata when we set the 'CPF_BlueprintVisible' flag on the UProperty, which in is now tied to whether or not the property has been explcitly marked as a variable. This avoids a UHT warning when compiling the nativized codegen that would cause packaging to fail. #rnx Change 3427720 on 2017/05/08 by Dan.Oconnor Backing out 3419202 #rnx Change 3427725 on 2017/05/08 by Dan.Oconnor SA fix #rnx Change 3427734 on 2017/05/08 by Dan.Oconnor More exhaustive GEditor null checks, to appease SA #rnx Change 3427882 on 2017/05/08 by Marc.Audy Properly order all booleans in intialization #rnx Change 3428049 on 2017/05/08 by Marc.Audy Merging //UE4/Dev-Main to Dev-Framework (//UE4/Dev-Framework) @ 3427804 #rnx Change 3428523 on 2017/05/08 by Ben.Zeigler #jira UE-44781 Refresh function input UI when blueprint graph refreshes, needed as pins may have gone away Change 3428563 on 2017/05/08 by Ben.Zeigler #jira UE-44783 If setting a hard reference pin type from a string, load the referenced object. Change 3428595 on 2017/05/08 by Dan.Oconnor Avoid node reconstruction when we're compiling a blueprint with no linker (e.g., a duplicated blueprint) #jira UE-44777 Change 3428599 on 2017/05/08 by Ben.Zeigler #jira UE-44789 Fix string asset renamer to not mark IsPersistent becuase that crashes in lightmap code, change it so the path fixup doesn't require the persistent flag Change 3428609 on 2017/05/08 by Dan.Oconnor Improved fix for UE-44777 #jira UE-44777 #rnx Change 3429176 on 2017/05/08 by Phillip.Kavan #jira UE-44755 - Fix nativization build errors when packaging a game project that is not IWYU-compliant for a build target that disables PCH files. - Mirrored from //UE4/Release-4.16 (CL# 3429030). #rnx Change 3429198 on 2017/05/08 by Phillip.Kavan CIS fix. #rnx Change 3429583 on 2017/05/08 by Ben.Zeigler Fix SGraphPinClass to work properly after my changes to allow unloaded assets. For Class pins we need to store separate Runtime and Editor asset data objects, as one has _C and refers to the class, and the other doesn't and refers to the blueprint. The content browser wants the editor path, the pin defaults want the runtime path. Change default value widgets to look more like properties widgets by forcing them to act as highlighted and disabling black background Change 3429640 on 2017/05/08 by Marc.Audy Fix issues with select nodes in macros connected to wildcard pins. #jira UE-44799 #rnx Change 3429890 on 2017/05/08 by Ben.Zeigler Fix function/macro defaults to properly propagate when changed using the new edit UI Refactor some code out of the details customization into the k2 schema Disable defaults UI for object/class/interface hard references as it is disabled in KismetCompiler Change3429947on 2017/05/08 by Michael.Noland Core: Backing out CL# 3394352 (marking FDateTime and FTimespan nonexport member Tick with UPROPERTY()), which will re-break UE-39921 but fix UE-44418 There appears to be a more serious underlying issue with how the CDO is instanced which needs to be addressed #jira UE-44418 #reimplementing 3411681 from Release 4.16 Change 3429987 on 2017/05/08 by Ben.Zeigler #jira UE-44798 Do a better job of validating object paths saved as default values, due to an old bug with local variables some object paths are saved as struct exportext At load time clear invalid default value for local variables Add IsValidObjectPath to FPackageName that validates the passed in path would be valid to load with LoadObject Change 3430392 on 2017/05/09 by Marc.Audy Fix SA CIS error #rnx Change 3430747 on 2017/05/09 by Ben.Zeigler #jira UE-44836 Don't reconstruct node during callback for param value changing, this can happen during a reconstruction and recursive reconstruction is unsafe Don't call ModifyUserDefinedPinDefaultValue unless the default value has actually changed Change 3431027 on 2017/05/09 by Marc.Audy Fix BPRW mark up causing Ocean warnings #rnx Change 3431353 on 2017/05/09 by Marc.Audy Fix UHT error due to exposing FJsonObjectWrapper to blueprints #rnx [CL 3431398 by Marc Audy in Main branch]
1465 lines
48 KiB
C++
1465 lines
48 KiB
C++
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Misc/MessageDialog.h"
|
|
#include "Misc/Paths.h"
|
|
#include "ISourceControlOperation.h"
|
|
#include "SourceControlOperations.h"
|
|
#include "ISourceControlRevision.h"
|
|
#include "SourceControlWindows.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "UObject/Object.h"
|
|
#include "UObject/Package.h"
|
|
#include "Misc/PackageName.h"
|
|
#include "InputCoreTypes.h"
|
|
#include "Layout/Visibility.h"
|
|
#include "Layout/Geometry.h"
|
|
#include "Widgets/SNullWidget.h"
|
|
#include "Styling/SlateBrush.h"
|
|
#include "Input/Events.h"
|
|
#include "Input/DragAndDrop.h"
|
|
#include "Input/Reply.h"
|
|
#include "Widgets/DeclarativeSyntaxSupport.h"
|
|
#include "Widgets/SWidget.h"
|
|
#include "Widgets/SCompoundWidget.h"
|
|
#include "Widgets/SBoxPanel.h"
|
|
#include "Widgets/SWindow.h"
|
|
#include "SlateOptMacros.h"
|
|
#include "Framework/Application/SlateApplication.h"
|
|
#include "Textures/SlateIcon.h"
|
|
#include "Framework/Commands/UIAction.h"
|
|
#include "Widgets/Layout/SBorder.h"
|
|
#include "Widgets/Images/SImage.h"
|
|
#include "Widgets/Text/STextBlock.h"
|
|
#include "Widgets/Layout/SBox.h"
|
|
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
|
#include "Widgets/Layout/SSplitter.h"
|
|
#include "Widgets/Views/SExpanderArrow.h"
|
|
#include "Widgets/Views/SHeaderRow.h"
|
|
#include "Widgets/Views/STableViewBase.h"
|
|
#include "Widgets/Views/STableRow.h"
|
|
#include "Widgets/Views/STreeView.h"
|
|
#include "Framework/Docking/TabManager.h"
|
|
#include "EditorStyleSet.h"
|
|
#include "ISourceControlModule.h"
|
|
|
|
#include "IAssetTools.h"
|
|
#include "IAssetTypeActions.h"
|
|
#include "AssetToolsModule.h"
|
|
|
|
/**
|
|
* Wrapper around data from ISourceControlRevision
|
|
*/
|
|
class FHistoryRevisionListViewItem
|
|
{
|
|
public:
|
|
/** Changelist description */
|
|
FString Description;
|
|
|
|
/** User name of submitter */
|
|
FString UserName;
|
|
|
|
/** Clientspec/workspace of submitter */
|
|
FString ClientSpec;
|
|
|
|
/** File action for this revision (branch, delete, edit, etc.) */
|
|
FString Action;
|
|
|
|
/** Source path of branch, if any */
|
|
FString BranchSource;
|
|
|
|
/** Date of this revision */
|
|
FDateTime Date;
|
|
|
|
/** Number of this revision */
|
|
FString Revision;
|
|
|
|
/** Changelist number */
|
|
int32 ChangelistNumber;
|
|
|
|
/** Filesize for this revision (0 in the event of a deletion) */
|
|
int32 FileSize;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param InRevision File revision info. to populate this wrapper with
|
|
*/
|
|
FHistoryRevisionListViewItem( const TSharedRef<ISourceControlRevision, ESPMode::ThreadSafe>& InRevision )
|
|
{
|
|
Description = InRevision->GetDescription();
|
|
UserName = InRevision->GetUserName();
|
|
ClientSpec = InRevision->GetClientSpec();
|
|
Action = InRevision->GetAction();
|
|
BranchSource = InRevision->GetBranchSource().IsValid() ? InRevision->GetBranchSource()->GetFilename() : TEXT("");
|
|
Date = InRevision->GetDate();
|
|
Revision = InRevision->GetRevision();
|
|
ChangelistNumber = InRevision->GetCheckInIdentifier();
|
|
FileSize = InRevision->GetFileSize();
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
* Managed mirror of FSourceControlFileHistoryInfo. Designed to represent the history of a file in
|
|
* a listview.
|
|
*/
|
|
class FHistoryFileListViewItem
|
|
{
|
|
public:
|
|
|
|
/** Depot name of the file */
|
|
FString FileName;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param InFileName File name of the list item
|
|
*/
|
|
FHistoryFileListViewItem( const FString& InFileName )
|
|
: FileName(InFileName)
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* A container class to use the tree view to represent a dynamically expandable nested list
|
|
*/
|
|
struct FHistoryTreeItem
|
|
{
|
|
// Only one of FileListItem or RevisionListItem should be set
|
|
|
|
/** Pointer to file info */
|
|
TSharedPtr<FHistoryFileListViewItem> FileListItem;
|
|
/** Pointer to revision info */
|
|
TSharedPtr<FHistoryRevisionListViewItem> RevisionListItem;
|
|
|
|
/** If we are a revision entry, pointer to file entry that owns us */
|
|
TWeakPtr<FHistoryTreeItem> Parent;
|
|
/** List of revisions if we are file entry */
|
|
TArray< TSharedPtr<FHistoryTreeItem> > Children;
|
|
};
|
|
|
|
/**
|
|
* Attempts to get a file list-item that represents the file that specified
|
|
* history-tree entry belongs to.
|
|
*
|
|
* @param HistoryTreeItemIn The history-tree entry that you want a file item for.
|
|
* @return The file list-item that the specified entry conceptually belongs to (invalid if HistoryTreeItemIn was invalid).
|
|
*/
|
|
static TSharedPtr<FHistoryFileListViewItem> GetFileListItem(TSharedPtr<FHistoryTreeItem> HistoryTreeItemIn)
|
|
{
|
|
TSharedPtr<FHistoryFileListViewItem> FileListItem;
|
|
|
|
if (HistoryTreeItemIn.IsValid())
|
|
{
|
|
FileListItem = HistoryTreeItemIn->FileListItem;
|
|
|
|
// if this isn't a file list-item itself
|
|
if (!FileListItem.IsValid())
|
|
{
|
|
// then it should have a parent that is one
|
|
TSharedPtr<FHistoryTreeItem> ParentFileItem = HistoryTreeItemIn->Parent.Pin();
|
|
check(ParentFileItem.IsValid());
|
|
check(ParentFileItem->FileListItem.IsValid());
|
|
FileListItem = ParentFileItem->FileListItem;
|
|
}
|
|
}
|
|
|
|
return FileListItem;
|
|
}
|
|
|
|
/**
|
|
* Takes a history-tree entry and attempts to find a corresponding asset object
|
|
* for the specified revision. If the specified history item doesn't have a valid
|
|
* RevisionListItem (it's a file list-item), we take that to represent the current
|
|
* working version of the asset.
|
|
*
|
|
* @param HistoryTreeItemIn The history-tree entry that you want a corresponding object for.
|
|
* @return A UObject that represents the asset at the specified revision (NULL if we failed to find/create one).
|
|
*/
|
|
static UObject* GetAssetRevisionObject(TSharedPtr<FHistoryTreeItem> HistoryTreeItemIn)
|
|
{
|
|
UObject* AssetObject = NULL;
|
|
if (HistoryTreeItemIn.IsValid())
|
|
{
|
|
UPackage* AssetPackage = NULL; // need a package to find the asset in
|
|
|
|
TSharedPtr<FHistoryFileListViewItem> FileListItem = GetFileListItem(HistoryTreeItemIn);
|
|
check(FileListItem.IsValid());
|
|
|
|
TSharedPtr<FHistoryRevisionListViewItem> RevisionListItem = HistoryTreeItemIn->RevisionListItem;
|
|
// if this item is referencing a specific revision (and not the current working version of the asset)
|
|
if (RevisionListItem.IsValid()) // else,
|
|
{
|
|
// grab details on this file's state in source control (history, etc.)
|
|
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
|
|
FSourceControlStatePtr FileSourceControlState = SourceControlProvider.GetState(FileListItem->FileName, EStateCacheUsage::Use);
|
|
|
|
if (FileSourceControlState.IsValid())
|
|
{
|
|
// lookup the specific revision we want
|
|
TSharedPtr<ISourceControlRevision, ESPMode::ThreadSafe> FileRevision = FileSourceControlState->FindHistoryRevision(RevisionListItem->Revision);
|
|
|
|
FString TempPackageName;
|
|
if (FileRevision.IsValid() && FileRevision->Get(TempPackageName)) // grab the path to a temporary package (where the revision item will be stored)
|
|
{
|
|
// try and load the temporary package
|
|
AssetPackage = LoadPackage(NULL, *TempPackageName, LOAD_DisableCompileOnLoad);
|
|
}
|
|
} // if FileSourceControlState.IsValid()
|
|
}
|
|
else // if we want the current working version of this asset
|
|
{
|
|
FString AssetPackageName = FPackageName::FilenameToLongPackageName(FileListItem->FileName);
|
|
AssetPackage = FindObject<UPackage>(NULL, *AssetPackageName);
|
|
}
|
|
|
|
// grab the asset from the package - we assume asset name matches file name
|
|
FString AssetName = FPaths::GetBaseFilename(FileListItem->FileName);
|
|
AssetObject = FindObject<UObject>(AssetPackage, *AssetName);
|
|
|
|
} // if HistoryTreeItemIn.IsValid()
|
|
|
|
return AssetObject;
|
|
}
|
|
|
|
|
|
/**
|
|
* Constructs revision info for the specified history-tree entry.
|
|
*
|
|
* @param HistoryTreeItemIn The history-tree entry that you want revision info for.
|
|
* @param RevisionInfoOut The resulting revision info (out).
|
|
*/
|
|
static void GetRevisionInfo(TSharedPtr<FHistoryTreeItem> HistoryTreeItemIn, FRevisionInfo& RevisionInfoOut)
|
|
{
|
|
RevisionInfoOut.Revision = TEXT(""); // clear the revision info (empty string is used signify the current working version)
|
|
|
|
// if this is a specific revision item
|
|
if (HistoryTreeItemIn.IsValid() && HistoryTreeItemIn->RevisionListItem.IsValid())
|
|
{
|
|
TSharedPtr<FHistoryRevisionListViewItem> RevisionListItem = HistoryTreeItemIn->RevisionListItem;
|
|
|
|
// fill out the revision info
|
|
RevisionInfoOut.Revision = RevisionListItem->Revision;
|
|
RevisionInfoOut.Changelist = RevisionListItem->ChangelistNumber;
|
|
RevisionInfoOut.Date = RevisionListItem->Date;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Takes a array of FHistoryTreeItems and determines if the entries can all be diffed against each other.
|
|
*
|
|
* @param SelectedItems A array of FHistoryTreeItems that you want to diff against each other.
|
|
* @param ErrorTextOut Text explaining why the selected items cannot be diffed (only valid if the return value was false).
|
|
* @return True if the selected items could be diffed against each other, false if not.
|
|
*/
|
|
static bool CanDiffSelectedItems(TArray< TSharedPtr<FHistoryTreeItem> > const& SelectedItems, FText& ErrorTextOut)
|
|
{
|
|
bool bCanDiffSelected = false;
|
|
|
|
if (SelectedItems.Num() > 2)
|
|
{
|
|
ErrorTextOut = NSLOCTEXT("SourceControlHistory", "TooManyToDiff", "Cannot diff more than two revisions.");
|
|
}
|
|
else if (SelectedItems.Num() < 2)
|
|
{
|
|
ErrorTextOut = NSLOCTEXT("SourceControlHistory", "NotEnoughToDiff", "Need to select two revisions in order to compare one against the other.");
|
|
}
|
|
else
|
|
{
|
|
TSharedPtr<FHistoryTreeItem> FirstSelection = SelectedItems[0];
|
|
TSharedPtr<FHistoryTreeItem> SecondSelection = SelectedItems[1];
|
|
|
|
if (!FirstSelection.IsValid() || !SecondSelection.IsValid())
|
|
{
|
|
ErrorTextOut = NSLOCTEXT("SourceControlHistory", "InvalidSelection", "Invalid revisions selected.");
|
|
}
|
|
else if (FirstSelection == SecondSelection)
|
|
{
|
|
ErrorTextOut = NSLOCTEXT("SourceControlHistory", "CannotDiffWithSelf", "You cannot diff a revision against itself.");
|
|
}
|
|
else
|
|
{
|
|
// @TODO make sure the two selections match type (calling GetAssetRevisionObject() to compare class types is too slow)
|
|
bCanDiffSelected = true;
|
|
}
|
|
}
|
|
|
|
return bCanDiffSelected;
|
|
};
|
|
|
|
/**
|
|
* Takes two FHistoryTreeItems and attempts to diff them against each other (bringing up the diff window).
|
|
*
|
|
* @param FirstSelection The first item you want to diff.
|
|
* @param SecondSelection The second item you want to diff.
|
|
* @return True if a diff was performed, false if not.
|
|
*/
|
|
static bool DiffHistoryItems(TSharedPtr<FHistoryTreeItem> const FirstSelection, TSharedPtr<FHistoryTreeItem> const SecondSelection)
|
|
{
|
|
bool bDiffPerformed = false;
|
|
|
|
if (FirstSelection.IsValid() && SecondSelection.IsValid())
|
|
{
|
|
TSharedPtr<FHistoryFileListViewItem> FirstSelectionFileItem = GetFileListItem(FirstSelection);
|
|
TSharedPtr<FHistoryFileListViewItem> SecondSelectionFileItem = GetFileListItem(SecondSelection);
|
|
|
|
// we want to make sure the two selections are presented in a sensible order
|
|
UObject* LeftDiffAsset = NULL;
|
|
FRevisionInfo LeftVersionInfo;
|
|
UObject* RightDiffAsset = NULL;
|
|
FRevisionInfo RightVersionInfo;
|
|
|
|
bool bIsForSingleAsset = (FirstSelectionFileItem == SecondSelectionFileItem);
|
|
// if we're comparing two revisions for one asset
|
|
if (bIsForSingleAsset)
|
|
{
|
|
bool bFirstSelectionIsCurrentVersion = FirstSelection->FileListItem.IsValid();
|
|
bool bSecondSelectionIsCurrentVersion = SecondSelection->FileListItem.IsValid();
|
|
|
|
// the second selection is the newer revision iff the first isn't the current working version, and
|
|
// it's either the current working version itself, or a newer revision
|
|
bool bSecondSelectionIsNewer = !bFirstSelectionIsCurrentVersion &&
|
|
(bSecondSelectionIsCurrentVersion ||(SecondSelection->RevisionListItem->Date > FirstSelection->RevisionListItem->Date));
|
|
|
|
if (bSecondSelectionIsNewer)
|
|
{
|
|
RightDiffAsset = GetAssetRevisionObject(SecondSelection);
|
|
GetRevisionInfo(SecondSelection, RightVersionInfo);
|
|
LeftDiffAsset = GetAssetRevisionObject(FirstSelection);
|
|
GetRevisionInfo(FirstSelection, LeftVersionInfo);
|
|
}
|
|
else
|
|
{
|
|
LeftDiffAsset = GetAssetRevisionObject(SecondSelection);
|
|
GetRevisionInfo(SecondSelection, LeftVersionInfo);
|
|
RightDiffAsset = GetAssetRevisionObject(FirstSelection);
|
|
GetRevisionInfo(FirstSelection, RightVersionInfo);
|
|
}
|
|
}
|
|
else // else, we're comparing revisions from two separate assets
|
|
{
|
|
// keep them in selection order (left to right)
|
|
LeftDiffAsset = GetAssetRevisionObject(FirstSelection);
|
|
GetRevisionInfo(FirstSelection, LeftVersionInfo);
|
|
RightDiffAsset = GetAssetRevisionObject(SecondSelection);
|
|
GetRevisionInfo(SecondSelection, RightVersionInfo);
|
|
}
|
|
|
|
// if we have an asset object for both selections
|
|
if ((LeftDiffAsset != NULL) && (RightDiffAsset != NULL))
|
|
{
|
|
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
|
|
AssetToolsModule.Get().DiffAssets(LeftDiffAsset, RightDiffAsset, LeftVersionInfo, RightVersionInfo);
|
|
|
|
bDiffPerformed = true;
|
|
}
|
|
}
|
|
|
|
return bDiffPerformed;
|
|
}
|
|
|
|
/**
|
|
* A FDragDropOperation that represents dragging a source-control history tree item around.
|
|
*/
|
|
class FSourceControlHistoryRowDragDropOp : public FDragDropOperation
|
|
{
|
|
private:
|
|
/**
|
|
* Stubbed private constructor (in order to force use of the static New() method).
|
|
*/
|
|
FSourceControlHistoryRowDragDropOp()
|
|
: PendingDropAction(EDropAction::None)
|
|
{
|
|
}
|
|
|
|
public:
|
|
/**
|
|
* Allocates and registers a new FSourceControlHistoryRowDragDropOp for use.
|
|
*
|
|
* @return The newly allocated (and registered) instance.
|
|
*/
|
|
static TSharedRef<FSourceControlHistoryRowDragDropOp> New()
|
|
{
|
|
TSharedPtr<FSourceControlHistoryRowDragDropOp> NewOperation = MakeShareable(new FSourceControlHistoryRowDragDropOp);
|
|
NewOperation->Construct();
|
|
|
|
return NewOperation.ToSharedRef();
|
|
}
|
|
|
|
DRAG_DROP_OPERATOR_TYPE(FSourceControlHistoryRowDragDropOp, FDragDropOperation)
|
|
|
|
struct EDropAction
|
|
{
|
|
enum Type
|
|
{
|
|
None,
|
|
Diff,
|
|
};
|
|
};
|
|
/** An enum value detailing what operation is queued to happen (if this item is dropped) */
|
|
EDropAction::Type PendingDropAction;
|
|
|
|
/** The items that this operation is conceptually dragging around */
|
|
TArray< TSharedPtr<FHistoryTreeItem> > SelectedItems;
|
|
|
|
/** Text to display with the widget being dragged around */
|
|
FText HoverText;
|
|
|
|
/**
|
|
* Creates the visual widget that you drag around (to help visualize the drag/drop operation.
|
|
*
|
|
* @return A new slate widget representing the dragged item
|
|
*/
|
|
virtual TSharedPtr<SWidget> GetDefaultDecorator() const override
|
|
{
|
|
return SNew(SBorder)
|
|
.BorderImage(FEditorStyle::GetBrush("Graph.ConnectorFeedback.Border"))
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(0,0,3,0)
|
|
[
|
|
SNew(SImage)
|
|
.Image(this, &FSourceControlHistoryRowDragDropOp::GetIcon)
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &FSourceControlHistoryRowDragDropOp::GetHoverText)
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Easy accessor function for getting at the HoverText variable (provides a
|
|
* default one if HoverText is empty).
|
|
*
|
|
* @return HoverText if it's not empty, otherwise: a default string describing that dropping would result in nothing.
|
|
*/
|
|
FText GetHoverText() const
|
|
{
|
|
return !HoverText.IsEmpty()
|
|
? HoverText
|
|
: NSLOCTEXT("SourceControlHistory", "DropActionToolTip_InvalidDropTarget", "Cannot drop here.");
|
|
}
|
|
|
|
/**
|
|
* Returns a icon brush corresponding to this operation's pending drop action.
|
|
*
|
|
* @return An 'error' icon if there is no pending action, otherwise an 'OK' icon.
|
|
*/
|
|
FSlateBrush const* GetIcon() const
|
|
{
|
|
return PendingDropAction != EDropAction::None
|
|
? FEditorStyle::GetBrush(TEXT("Graph.ConnectorFeedback.OK"))
|
|
: FEditorStyle::GetBrush(TEXT("Graph.ConnectorFeedback.Error"));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Class used to construct the ordered row content for revision data
|
|
*/
|
|
class SHistoryRevisionListRowContent : public SMultiColumnTableRow< TSharedPtr<FHistoryTreeItem> >
|
|
{
|
|
public:
|
|
|
|
SLATE_BEGIN_ARGS( SHistoryRevisionListRowContent )
|
|
: _RevisionListItem()
|
|
{}
|
|
SLATE_EVENT( FOnDragDetected, OnDragDetected )
|
|
SLATE_EVENT( FOnTableRowDragEnter, OnDragEnter )
|
|
SLATE_EVENT( FOnTableRowDragLeave, OnDragLeave )
|
|
SLATE_EVENT( FOnTableRowDrop, OnDrop )
|
|
|
|
SLATE_ARGUMENT( TSharedPtr<FHistoryRevisionListViewItem>, RevisionListItem )
|
|
|
|
/** Whether we should display the expander for this item as it has children */
|
|
SLATE_ARGUMENT( bool, HasChildren )
|
|
|
|
SLATE_END_ARGS()
|
|
|
|
/**
|
|
* Construct the widget
|
|
*
|
|
* @param InArgs A declaration from which to construct the widget
|
|
*/
|
|
void Construct( const FArguments& InArgs, const TSharedRef<STableViewBase>& InOwnerTableView )
|
|
{
|
|
RevisionListItem = InArgs._RevisionListItem;
|
|
check(RevisionListItem.IsValid());
|
|
|
|
bHasChildren = InArgs._HasChildren;
|
|
|
|
SMultiColumnTableRow< TSharedPtr<FHistoryTreeItem> >::Construct(
|
|
FSuperRowType::FArguments()
|
|
.OnDragDetected(InArgs._OnDragDetected)
|
|
.OnDragEnter(InArgs._OnDragEnter)
|
|
.OnDragLeave(InArgs._OnDragLeave)
|
|
.OnDrop(InArgs._OnDrop),
|
|
InOwnerTableView
|
|
);
|
|
}
|
|
|
|
virtual TSharedRef<SWidget> GenerateWidgetForColumn( const FName& ColumnName ) override
|
|
{
|
|
check(RevisionListItem.IsValid());
|
|
|
|
if ( ColumnName == TEXT("Revision") )
|
|
{
|
|
|
|
FString SCCAction = RevisionListItem->Action;
|
|
FName ResourceKey;
|
|
if (SCCAction == FString(TEXT("add")))
|
|
{
|
|
ResourceKey = TEXT("SourceControl.Add");
|
|
}
|
|
else if (SCCAction == FString(TEXT("edit")))
|
|
{
|
|
ResourceKey = TEXT("SourceControl.Edit");
|
|
}
|
|
else if (SCCAction == FString(TEXT("delete")))
|
|
{
|
|
ResourceKey = TEXT("SourceControl.Delete");
|
|
}
|
|
else if (SCCAction == FString(TEXT("branch")))
|
|
{
|
|
ResourceKey = TEXT("SourceControl.Branch");
|
|
}
|
|
else if (SCCAction == FString(TEXT("integrate")))
|
|
{
|
|
ResourceKey = TEXT("SourceControl.Integrate");
|
|
}
|
|
else
|
|
{
|
|
ResourceKey = TEXT("SourceControl.Edit");
|
|
}
|
|
|
|
// Rows in a tree need to show an SExpanderArrow (it also indents!) to give the appearance of being a tree.
|
|
return
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.HAlign(HAlign_Right)
|
|
.VAlign(VAlign_Fill)
|
|
[
|
|
SNew(SExpanderArrow, SharedThis(this) )
|
|
.Visibility(this, &SHistoryRevisionListRowContent::GetExpanderVisibility)
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(10,0,10,0)
|
|
.HAlign(HAlign_Center)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(SImage)
|
|
.Image(FEditorStyle::GetBrush(ResourceKey))
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
SNew(STextBlock)
|
|
.Text( FText::FromString(RevisionListItem->Revision) )
|
|
];
|
|
}
|
|
else if (ColumnName == TEXT("Changelist"))
|
|
{
|
|
return
|
|
SNew(STextBlock)
|
|
.Text( FText::AsNumber( RevisionListItem->ChangelistNumber, NULL, FInternationalization::Get().GetInvariantCulture() ) ) ;
|
|
}
|
|
else if (ColumnName == TEXT("Date"))
|
|
{
|
|
return
|
|
SNew(STextBlock)
|
|
.Text( RevisionListItem->Date > FDateTime::MinValue() == 0 ? FText() : FText::AsDateTime( RevisionListItem->Date ) );
|
|
}
|
|
else if (ColumnName == TEXT("UserName"))
|
|
{
|
|
return
|
|
SNew(STextBlock)
|
|
.Text( FText::FromString( RevisionListItem->UserName ) );
|
|
}
|
|
else if (ColumnName == TEXT("Description"))
|
|
{
|
|
// Cut down the description to a single line for the list view
|
|
FString SingleLineDescription = RevisionListItem->Description;
|
|
int32 NewLinePos;
|
|
if (SingleLineDescription.FindChar(TCHAR('\n'), NewLinePos))
|
|
{
|
|
SingleLineDescription = SingleLineDescription.Left(NewLinePos);
|
|
}
|
|
|
|
// Trim any trailing new-line characters from the description for the tooltip
|
|
FString TooltipDescription = RevisionListItem->Description;
|
|
while(TooltipDescription.Len() && FChar::IsLinebreak(TooltipDescription[TooltipDescription.Len() - 1]))
|
|
{
|
|
TooltipDescription.RemoveAt(TooltipDescription.Len() - 1, 1, false);
|
|
}
|
|
|
|
return
|
|
SNew(STextBlock)
|
|
.Text(FText::FromString(SingleLineDescription))
|
|
.ToolTipText(FText::FromString(TooltipDescription));
|
|
}
|
|
else
|
|
{
|
|
return
|
|
SNew(STextBlock)
|
|
. Text( FText::Format( NSLOCTEXT("SourceControlHistory", "UnsupportedColumn", "Unsupported Column: {0}"), FText::FromName( ColumnName ) ) );
|
|
}
|
|
}
|
|
|
|
EVisibility GetExpanderVisibility() const
|
|
{
|
|
return bHasChildren ? EVisibility::Visible : EVisibility::Collapsed;
|
|
}
|
|
|
|
private:
|
|
TSharedPtr<FHistoryRevisionListViewItem> RevisionListItem;
|
|
|
|
/** Whether we should display the expander for this item as it has children */
|
|
bool bHasChildren;
|
|
};
|
|
|
|
/** Panel designed to display the revision history of a package */
|
|
class SSourceControlHistoryWidget : public SCompoundWidget
|
|
{
|
|
public:
|
|
SLATE_BEGIN_ARGS( SSourceControlHistoryWidget )
|
|
: _ParentWindow()
|
|
, _SourceControlStates()
|
|
{}
|
|
|
|
SLATE_ATTRIBUTE( TSharedPtr<SWindow>, ParentWindow )
|
|
SLATE_ATTRIBUTE( TArray< FSourceControlStateRef >, SourceControlStates)
|
|
|
|
SLATE_END_ARGS()
|
|
|
|
|
|
SSourceControlHistoryWidget()
|
|
{
|
|
}
|
|
|
|
void Construct( const FArguments& InArgs )
|
|
{
|
|
AddHistoryInfo(InArgs._SourceControlStates.Get());
|
|
|
|
TSharedRef<SHeaderRow> HeaderRow = SNew(SHeaderRow);
|
|
|
|
const bool bUsesChangelists = ISourceControlModule::Get().GetProvider().UsesChangelists();
|
|
|
|
HeaderRow->AddColumn(SHeaderRow::FColumn::FArguments().ColumnId("Revision") .DefaultLabel(NSLOCTEXT("SourceControl.HistoryPanel.Header", "Revision", "Revision")) .FillWidth(bUsesChangelists ? 100 : 250));
|
|
if(bUsesChangelists)
|
|
{
|
|
HeaderRow->AddColumn(SHeaderRow::FColumn::FArguments().ColumnId("Changelist") .DefaultLabel(NSLOCTEXT("SourceControl.HistoryPanel.Header", "Changelist", "ChangeList")) .FillWidth(150));
|
|
}
|
|
HeaderRow->AddColumn(SHeaderRow::FColumn::FArguments().ColumnId("Date") .DefaultLabel(NSLOCTEXT("SourceControl.HistoryPanel.Header", "Date", "Date Submitted")) .FillWidth(250));
|
|
HeaderRow->AddColumn(SHeaderRow::FColumn::FArguments().ColumnId("UserName") .DefaultLabel(NSLOCTEXT("SourceControl.HistoryPanel.Header", "UserName", "Submitted By")) .FillWidth(200));
|
|
HeaderRow->AddColumn(SHeaderRow::FColumn::FArguments().ColumnId("Description") .DefaultLabel(NSLOCTEXT("SourceControl.HistoryPanel.Header", "Description", "Description")) .FillWidth(300));
|
|
|
|
ChildSlot
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
.BorderBackgroundColor(FLinearColor(0.5f,0.5f,0.5f,1.f))
|
|
[
|
|
SNew(SSplitter)
|
|
.Orientation(Orient_Vertical)
|
|
+SSplitter::Slot()
|
|
.Value(0.5f)
|
|
[
|
|
SNew(SBorder)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(600)
|
|
[
|
|
SAssignNew( MainHistoryListView, SHistoryFileListType)
|
|
.TreeItemsSource( &HistoryCollection )
|
|
.ItemHeight(25.f)
|
|
.SelectionMode(ESelectionMode::Multi)
|
|
.OnSelectionChanged(this, &SSourceControlHistoryWidget::OnRevisionPropertyChanged)
|
|
.OnGenerateRow( this, &SSourceControlHistoryWidget::OnGenerateRowForHistoryFileList )
|
|
.OnGetChildren( this, &SSourceControlHistoryWidget::OnGetChildrenForHistoryFileList )
|
|
.OnContextMenuOpening(this, &SSourceControlHistoryWidget::OnCreateContextMenu )
|
|
.HeaderRow
|
|
(
|
|
HeaderRow
|
|
)
|
|
]
|
|
]
|
|
]
|
|
|
|
+SSplitter::Slot()
|
|
.Value(0.5f)
|
|
[
|
|
SAssignNew(AdditionalInfoItemsControl,SBorder)
|
|
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
[
|
|
GetAdditionalInfoItemsControlContent()
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
//expand the top level nodes...
|
|
for (int32 i=0; i<HistoryCollection.Num(); i++)
|
|
{
|
|
MainHistoryListView->SetItemExpansion(HistoryCollection[i],true);
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
/**
|
|
* Constructs the "Additional Info" panel that displays specific revision info
|
|
*/
|
|
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
|
TSharedRef<SWidget> GetAdditionalInfoItemsControlContent()
|
|
{
|
|
const float Padding = 2.f;
|
|
|
|
return
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(0.25f)
|
|
[
|
|
//Text Column
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "Revision", "Revision:"))
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "Date", "Date Submitted:"))
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "SubmittedBy", "Submitted By:"))
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "Action", "Action:"))
|
|
]
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(0.25f)
|
|
.Padding(20,0)
|
|
[
|
|
//Data column
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetRevisionNumber)
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetDate)
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetUserName)
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetAction)
|
|
]
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(0.25f)
|
|
.Padding(50,0)
|
|
[
|
|
//Text Column
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
//empty for spacing
|
|
SNullWidget::NullWidget
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "Changelist", "Changelist:"))
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "Workspace", "Workspace:"))
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "FileSize", "File Size:"))
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "BranchedFrom", "Branched From:"))
|
|
]
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(0.25f)
|
|
.Padding(20,0)
|
|
[
|
|
//Data column
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
//empty for spacing
|
|
SNullWidget::NullWidget
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetChangelistNumber)
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetClientSpec)
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetFileSize)
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(0.25f)
|
|
.Padding(Padding)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetBranchedFrom)
|
|
]
|
|
]
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(Padding, 10, Padding, 5)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SourceControl.HistoryPanel.Info", "Description", "Description:"))
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(1.0f)
|
|
[
|
|
SNew(SBorder)
|
|
[
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(5)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SSourceControlHistoryWidget::GetDescription)
|
|
]
|
|
]
|
|
]
|
|
;
|
|
}
|
|
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
|
|
|
/** Get the last selected revision's revision number */
|
|
FText GetRevisionNumber() const
|
|
{
|
|
if(LastSelectedRevisionItem.IsValid())
|
|
{
|
|
return FText::FromString(LastSelectedRevisionItem.Pin()->Revision);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/** Get the last selected revision's date */
|
|
FText GetDate() const
|
|
{
|
|
if(LastSelectedRevisionItem.IsValid() && LastSelectedRevisionItem.Pin()->Date != 0)
|
|
{
|
|
return FText::AsDateTime(LastSelectedRevisionItem.Pin()->Date);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/** Get the last selected revision's username */
|
|
FText GetUserName() const
|
|
{
|
|
if(LastSelectedRevisionItem.IsValid())
|
|
{
|
|
return FText::FromString(LastSelectedRevisionItem.Pin()->UserName);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/** Get the last selected revision's revision number */
|
|
FText GetAction() const
|
|
{
|
|
if(LastSelectedRevisionItem.IsValid())
|
|
{
|
|
return FText::FromString(LastSelectedRevisionItem.Pin()->Action);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/** Get the last selected revision's changelist number */
|
|
FText GetChangelistNumber() const
|
|
{
|
|
static const bool bUsesChangelists = ISourceControlModule::Get().GetProvider().UsesChangelists();
|
|
if(LastSelectedRevisionItem.IsValid() && bUsesChangelists)
|
|
{
|
|
// don't group the CL# as Perforce doesn't display it that way
|
|
return FText::AsNumber(LastSelectedRevisionItem.Pin()->ChangelistNumber, &FNumberFormattingOptions::DefaultNoGrouping());
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/** Get the last selected revision's client spec */
|
|
FText GetClientSpec() const
|
|
{
|
|
if(LastSelectedRevisionItem.IsValid())
|
|
{
|
|
return FText::FromString(LastSelectedRevisionItem.Pin()->ClientSpec);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/** Get the last selected revision's file size */
|
|
FText GetFileSize() const
|
|
{
|
|
if(LastSelectedRevisionItem.IsValid())
|
|
{
|
|
static const FNumberFormattingOptions FileSizeFormatOptions = FNumberFormattingOptions()
|
|
.SetMinimumFractionalDigits(1)
|
|
.SetMaximumFractionalDigits(1);
|
|
return FText::Format(
|
|
NSLOCTEXT("SourceControlHistory", "FileSizeInMBFmt", "{0} MB"),
|
|
FText::AsNumber(((float)LastSelectedRevisionItem.Pin()->FileSize) / (1024.f * 1024.f), &FileSizeFormatOptions)
|
|
);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/** Get the last selected revision's description */
|
|
FText GetDescription() const
|
|
{
|
|
if(LastSelectedRevisionItem.IsValid())
|
|
{
|
|
return FText::FromString(LastSelectedRevisionItem.Pin()->Description);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/** Get the last selected revision's description */
|
|
FText GetBranchedFrom() const
|
|
{
|
|
if(LastSelectedRevisionItem.IsValid())
|
|
{
|
|
return FText::FromString(LastSelectedRevisionItem.Pin()->BranchSource);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
/**
|
|
* Generates the content of each row, displaying a the File or Revision data for its corresponding type
|
|
*/
|
|
TSharedRef<ITableRow> OnGenerateRowForHistoryFileList( TSharedPtr<FHistoryTreeItem> TreeItemPtr, const TSharedRef<STableViewBase>& OwnerTable )
|
|
{
|
|
TSharedPtr<SWidget> RowContent;
|
|
if (TreeItemPtr->FileListItem.IsValid())
|
|
{
|
|
TSharedPtr<FHistoryFileListViewItem> FileListItem = TreeItemPtr->FileListItem;
|
|
|
|
return
|
|
SNew(STableRow< TSharedPtr<FName> >, OwnerTable)
|
|
[
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(5)
|
|
[
|
|
SNew( STextBlock )
|
|
.Font( FEditorStyle::GetFontStyle( TEXT("BoldFont") ))
|
|
.Text( FText::FromString(FileListItem->FileName) )
|
|
]
|
|
]
|
|
.OnDragDetected(this, &SSourceControlHistoryWidget::OnRowDragDetected)
|
|
.OnDragEnter(this, &SSourceControlHistoryWidget::OnRowDragEnter, TreeItemPtr)
|
|
.OnDragLeave(this, &SSourceControlHistoryWidget::OnRowDragLeave)
|
|
.OnDrop(this, &SSourceControlHistoryWidget::OnRowDrop, TreeItemPtr);
|
|
}
|
|
else if (TreeItemPtr->RevisionListItem.IsValid())
|
|
{
|
|
TSharedPtr<FHistoryRevisionListViewItem> RevisionListItem = TreeItemPtr->RevisionListItem;
|
|
|
|
return
|
|
SNew(SHistoryRevisionListRowContent, OwnerTable)
|
|
.RevisionListItem(RevisionListItem)
|
|
.OnDragDetected(this, &SSourceControlHistoryWidget::OnRowDragDetected)
|
|
.OnDragEnter(this, &SSourceControlHistoryWidget::OnRowDragEnter, TreeItemPtr)
|
|
.OnDragLeave(this, &SSourceControlHistoryWidget::OnRowDragLeave)
|
|
.OnDrop(this, &SSourceControlHistoryWidget::OnRowDrop, TreeItemPtr)
|
|
.HasChildren(TreeItemPtr->Children.Num() > 0);
|
|
}
|
|
|
|
//we should never get here...
|
|
return
|
|
SNew(STableRow< TSharedPtr<FName> >, OwnerTable)
|
|
[
|
|
SNew( STextBlock )
|
|
.Text( NSLOCTEXT("SourceControlHistory", "ErrorMessage", "---ERROR---") )
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Fill out the tree structure with the SSC data
|
|
*/
|
|
void AddHistoryInfo( const TArray< FSourceControlStateRef >& InStates )
|
|
{
|
|
// Construct a new observable collection to serve as the items source for the main list view. It will contain each history file item.
|
|
for( TArray< FSourceControlStateRef >::TConstIterator Iter(InStates); Iter; Iter++)
|
|
{
|
|
FSourceControlStateRef SourceControlState = *Iter;
|
|
TSharedPtr<FHistoryTreeItem> FileItem = MakeShareable(new FHistoryTreeItem());
|
|
FileItem->FileListItem = MakeShareable(new FHistoryFileListViewItem( SourceControlState->GetFilename() ));
|
|
|
|
// Add each file revision
|
|
for ( int HistoryIndex = 0; HistoryIndex < SourceControlState->GetHistorySize(); HistoryIndex++ )
|
|
{
|
|
TSharedPtr<ISourceControlRevision, ESPMode::ThreadSafe> Revision = SourceControlState->GetHistoryItem(HistoryIndex);
|
|
check(Revision.IsValid());
|
|
TSharedPtr<FHistoryTreeItem> RevisionItem = MakeShareable(new FHistoryTreeItem());
|
|
RevisionItem->RevisionListItem = MakeShareable(new FHistoryRevisionListViewItem( Revision.ToSharedRef() ));
|
|
FileItem->Children.Add(RevisionItem);
|
|
RevisionItem->Parent = FileItem;
|
|
|
|
// add branch items if we have one
|
|
if(Revision->GetBranchSource().IsValid())
|
|
{
|
|
TSharedPtr<FHistoryTreeItem> BranchFileItem = MakeShareable(new FHistoryTreeItem());
|
|
|
|
const FString BranchRevisionName = FString::Printf(TEXT("%s #%d"), *Revision->GetBranchSource()->GetFilename(), Revision->GetBranchSource()->GetRevisionNumber());
|
|
BranchFileItem->FileListItem = MakeShareable(new FHistoryFileListViewItem( BranchRevisionName ));
|
|
RevisionItem->Children.Add(BranchFileItem);
|
|
BranchFileItem->Parent = RevisionItem;
|
|
}
|
|
}
|
|
|
|
HistoryCollection.Add(FileItem);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Callback returns the revision history (Children) nodes for the file (InItem) node
|
|
*/
|
|
void OnGetChildrenForHistoryFileList( TSharedPtr< FHistoryTreeItem > InItem, TArray< TSharedPtr<FHistoryTreeItem> >& OutChildren )
|
|
{
|
|
OutChildren = InItem->Children;
|
|
}
|
|
|
|
/**
|
|
* Called whenever the IsSelected property on a MHistoryRevisionListViewItem changes. Used to specify the last selected revision item.
|
|
*
|
|
* @param Owner Object which triggered the event
|
|
* @param Args Event arguments for the property change
|
|
*/
|
|
void OnRevisionPropertyChanged(TSharedPtr<FHistoryTreeItem> Item, ESelectInfo::Type SelectInfo)
|
|
{
|
|
LastSelectedRevisionItem.Reset();
|
|
if (Item.IsValid())
|
|
{
|
|
if (Item->RevisionListItem.IsValid())
|
|
{
|
|
LastSelectedRevisionItem = Item->RevisionListItem;
|
|
}
|
|
else if (Item->Children.Num() > 0 && Item->Children[0]->RevisionListItem.IsValid())
|
|
{
|
|
LastSelectedRevisionItem = Item->Children[0]->RevisionListItem;
|
|
}
|
|
}
|
|
|
|
|
|
AdditionalInfoItemsControl->SetContent(GetAdditionalInfoItemsControlContent());
|
|
}
|
|
|
|
/** Called to create a context menu when right-clicking on a history item */
|
|
TSharedPtr< SWidget > OnCreateContextMenu()
|
|
{
|
|
FMenuBuilder MenuBuilder( true, NULL );
|
|
|
|
MenuBuilder.AddMenuEntry(
|
|
NSLOCTEXT("SourceControl.HistoryWindow.Menu", "DiffAgainstPrev", "Diff Against Previous Revision"),
|
|
NSLOCTEXT("SourceControl.HistoryWindow.Menu", "DiffAgainstPrevTooltip", "See changes between this revision and the previous one."),
|
|
FSlateIcon(),
|
|
FUIAction(
|
|
FExecuteAction::CreateSP( this, &SSourceControlHistoryWidget::OnDiffAgainstPreviousRev ),
|
|
FCanExecuteAction::CreateSP(this, &SSourceControlHistoryWidget::CanDiffAgainstPreviousRev)
|
|
)
|
|
);
|
|
|
|
if (CanDiffSelected())
|
|
{
|
|
MenuBuilder.AddMenuEntry(
|
|
NSLOCTEXT("SourceControl.HistoryWindow.Menu", "DiffSelected", "Diff Selected"),
|
|
NSLOCTEXT("SourceControl.HistoryWindow.Menu", "DiffSelectedTooltip", "Diff the two assets that you have selected."),
|
|
FSlateIcon(),
|
|
FUIAction(
|
|
FExecuteAction::CreateSP(this, &SSourceControlHistoryWidget::OnDiffSelected)
|
|
)
|
|
);
|
|
}
|
|
|
|
return MenuBuilder.MakeWidget();
|
|
}
|
|
|
|
/** See if we should enabled the 'diff against previous' option */
|
|
bool CanDiffAgainstPreviousRev() const
|
|
{
|
|
// Only allow option if we selected one item and it was a revision, not a file entry
|
|
TArray< TSharedPtr<FHistoryTreeItem> > SelectedRevs = MainHistoryListView->GetSelectedItems();
|
|
return( SelectedRevs.Num() == 1 && SelectedRevs[0].IsValid() );
|
|
}
|
|
|
|
/** Try and perfom a diff between the selected revision and the previous one */
|
|
void OnDiffAgainstPreviousRev()
|
|
{
|
|
TArray< TSharedPtr<FHistoryTreeItem> > SelectedRevs = MainHistoryListView->GetSelectedItems();
|
|
|
|
if(SelectedRevs.Num() > 0 && SelectedRevs[0].IsValid())
|
|
{
|
|
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
|
|
|
|
TSharedPtr<FHistoryTreeItem> SelectedItem = SelectedRevs[0];
|
|
UObject* SelectedAsset = GetAssetRevisionObject(SelectedItem);
|
|
|
|
if (SelectedItem->RevisionListItem.IsValid())
|
|
{
|
|
TSharedPtr<FHistoryTreeItem> FileItem = SelectedItem->Parent.Pin();
|
|
check(FileItem.IsValid());
|
|
|
|
// Now we need to find previous revision
|
|
TSharedPtr<FHistoryTreeItem> PreRevisionItem;
|
|
|
|
// First, find index of selected revision in its parent file item
|
|
// NB. 0 is newest, increasing index means older
|
|
int32 RevIndex = FileItem->Children.Find(SelectedItem);
|
|
check(RevIndex != INDEX_NONE);
|
|
if(RevIndex == FileItem->Children.Num()-1) // If oldest revision of this file
|
|
{
|
|
// .. see if we have an older file
|
|
int32 FileIndex = HistoryCollection.Find(FileItem);
|
|
check(FileIndex != INDEX_NONE);
|
|
// Do nothing if we selected the newest revision of the newest file...
|
|
if(FileIndex < HistoryCollection.Num()-1)
|
|
{
|
|
// Previous revision is a different file, so get the newest revision of the older file
|
|
TSharedPtr<FHistoryTreeItem> PrevFileItem = HistoryCollection[FileIndex+1];
|
|
check(PrevFileItem.IsValid());
|
|
if(PrevFileItem->Children.Num() > 0)
|
|
{
|
|
PreRevisionItem = PrevFileItem->Children[0];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Not the oldest revision of this file, grab the older entry and get revision number
|
|
PreRevisionItem = FileItem->Children[RevIndex+1];
|
|
}
|
|
|
|
UObject* PreviousAsset = GetAssetRevisionObject(PreRevisionItem);
|
|
|
|
if ((SelectedAsset != NULL) && (PreviousAsset != NULL))
|
|
{
|
|
FRevisionInfo OldRevisionInfo;
|
|
GetRevisionInfo(PreRevisionItem, OldRevisionInfo);
|
|
FRevisionInfo NewRevisionInfo;
|
|
GetRevisionInfo(SelectedItem, NewRevisionInfo);
|
|
|
|
AssetToolsModule.Get().DiffAssets(PreviousAsset, SelectedAsset, OldRevisionInfo, NewRevisionInfo);
|
|
}
|
|
else
|
|
{
|
|
FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("SourceControl.HistoryWindow", "UnableToLoadAssets", "Unable to load assets to diff. Content may no longer be supported?"));
|
|
}
|
|
}
|
|
else if (SelectedAsset != NULL)
|
|
{
|
|
// this should be a file list-item (representing the current working version)
|
|
check(SelectedItem->FileListItem.IsValid());
|
|
|
|
FString const AssetName = SelectedAsset->GetName();
|
|
FString const PackageName = FPackageName::FilenameToLongPackageName(SelectedItem->FileListItem->FileName);
|
|
AssetToolsModule.Get().DiffAgainstDepot(SelectedAsset, PackageName, AssetName);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks to see if the selected history-tree items can be diffed against each other.
|
|
*
|
|
* @return True if the selected items can be diffed, false if not.
|
|
*/
|
|
bool CanDiffSelected() const
|
|
{
|
|
// throw away text so we can utilize a shared utility method
|
|
FText ThrowAwayErrorText;
|
|
|
|
TArray< TSharedPtr<FHistoryTreeItem> > SelectedRevs = MainHistoryListView->GetSelectedItems();
|
|
return CanDiffSelectedItems(SelectedRevs, ThrowAwayErrorText);
|
|
}
|
|
|
|
/**
|
|
* Takes the two selected history items and finds a UObject asset for each,
|
|
* then attempts to open a diff window to compare them.
|
|
*/
|
|
void OnDiffSelected() const
|
|
{
|
|
TArray< TSharedPtr<FHistoryTreeItem> > SelectedRevs = MainHistoryListView->GetSelectedItems();
|
|
if (SelectedRevs.Num() >= 2)
|
|
{
|
|
if (!DiffHistoryItems(SelectedRevs[0], SelectedRevs[1]))
|
|
{
|
|
FMessageDialog::Open(EAppMsgType::Ok, NSLOCTEXT("SourceControl.HistoryWindow", "UnableToLoadAssets", "Unable to load assets to diff. Content may no longer be supported?"));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An event handler for mouse drag detection events. Intended to be used as a delegate for
|
|
* history tree rows. Creates a FSourceControlHistoryRowDragDropOp (if the drag was with
|
|
* the left mouse-button) and assumes that all the selected items are the objects being dragged.
|
|
*
|
|
* @param MyGeometry The geometry for the dragged widget.
|
|
* @param MouseEvent Describes the mouse drag action (from when the drag was detected).
|
|
* @return A reply detailing how this event was handled ("Unhandled" if the click was not a left-click).
|
|
*/
|
|
FReply OnRowDragDetected(FGeometry const& MyGeometry, FPointerEvent const& MouseEvent) const
|
|
{
|
|
if (MouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton)) //can only drag when editing
|
|
{
|
|
TSharedRef<FSourceControlHistoryRowDragDropOp> DragOperation = FSourceControlHistoryRowDragDropOp::New();
|
|
|
|
// assume that what we're dragging is what we have selected
|
|
DragOperation->SelectedItems = MainHistoryListView->GetSelectedItems();
|
|
check(DragOperation->SelectedItems.Num() > 0);
|
|
|
|
return FReply::Handled().BeginDragDrop(DragOperation);
|
|
}
|
|
else
|
|
{
|
|
return FReply::Unhandled();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An event handler for mouse drag enter events. Intended to be used as a delegate for
|
|
* history tree rows. Only handles FSourceControlHistoryRowDragDropOp drag/drop operations.
|
|
* Updates the FSourceControlHistoryRowDragDropOp to reflect if a drop action is doable
|
|
* (when over this item).
|
|
*
|
|
* @param DragDropEvent The drag/drop operation that triggered this handler.
|
|
* @param HoveredItem The history tree item that is conceptually being hovered over.
|
|
*/
|
|
void OnRowDragEnter(FDragDropEvent const& DragDropEvent, TSharedPtr<FHistoryTreeItem> const HoveredItem) const
|
|
{
|
|
TSharedPtr<FSourceControlHistoryRowDragDropOp> DragRowOp = DragDropEvent.GetOperationAs<FSourceControlHistoryRowDragDropOp>();
|
|
if (DragRowOp.IsValid())
|
|
{
|
|
DragRowOp->PendingDropAction = FSourceControlHistoryRowDragDropOp::EDropAction::None;
|
|
|
|
TArray< TSharedPtr<FHistoryTreeItem> > DiffingItems = DragRowOp->SelectedItems;
|
|
check(HoveredItem.IsValid());
|
|
DiffingItems.Add(HoveredItem);
|
|
|
|
if (CanDiffSelectedItems(DiffingItems, DragRowOp->HoverText))
|
|
{
|
|
DragRowOp->PendingDropAction = FSourceControlHistoryRowDragDropOp::EDropAction::Diff;
|
|
|
|
FText const RevisionFormatText = NSLOCTEXT("SourceControlHistory", "Revision", "Revision {0}");
|
|
FText const CurrentRevisionText = NSLOCTEXT("SourceControlHistory", "CurrentRevsion", "Current Revision");
|
|
|
|
check(DragRowOp->SelectedItems.Num() > 0);
|
|
TSharedPtr<FHistoryTreeItem> DraggedItem = DiffingItems[0];
|
|
// set text identifying the dragged item's revision (current version vs. revision X)
|
|
FText DraggedRevisionText = CurrentRevisionText;
|
|
if (DraggedItem->RevisionListItem.IsValid())
|
|
{
|
|
DraggedRevisionText = FText::Format(RevisionFormatText, FText::FromString(DraggedItem->RevisionListItem->Revision));
|
|
}
|
|
|
|
// set text identifying the hovered item's revision (current version vs. revision X)
|
|
FText HoveredRevisionText = CurrentRevisionText;
|
|
if (HoveredItem->RevisionListItem.IsValid())
|
|
{
|
|
HoveredRevisionText = FText::Format(RevisionFormatText, FText::FromString(HoveredItem->RevisionListItem->Revision));
|
|
}
|
|
|
|
TSharedPtr<FHistoryFileListViewItem> const DraggedFileItem = GetFileListItem(DraggedItem);
|
|
// convert DraggedRevisionText from the form "revision X" (or "the current version") to
|
|
// "revision X of <filename>"
|
|
FString const DraggedFileName = FPaths::GetBaseFilename(DraggedFileItem->FileName);
|
|
FText const NamedRevisionTextFormat = NSLOCTEXT("SourceControlHistory", "NamedRevision", "{0} ({1})");
|
|
DraggedRevisionText = FText::Format(NamedRevisionTextFormat, FText::FromString(DraggedFileName), DraggedRevisionText);
|
|
|
|
TSharedPtr<FHistoryFileListViewItem> const HoveredFileItem = GetFileListItem(HoveredItem);
|
|
// if we're diffing two separate files against each other
|
|
if (DraggedFileItem != HoveredFileItem)
|
|
{
|
|
// need to separately identify the hovered over item
|
|
FString const HoveredFileName = FPaths::GetBaseFilename(HoveredFileItem->FileName);
|
|
HoveredRevisionText = FText::Format(NamedRevisionTextFormat, FText::FromString(HoveredFileName), HoveredRevisionText);
|
|
}
|
|
|
|
FText const DropToDiffTextFormat = NSLOCTEXT("SourceControlHistory", "DropToDiff", "Drop {0} to diff against: {1}.");
|
|
DragRowOp->HoverText = FText::Format(DropToDiffTextFormat, DraggedRevisionText, HoveredRevisionText);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An event handler for mouse drag leave events. Intended to be used as a delegate for
|
|
* history tree rows. Only handles FSourceControlHistoryRowDragDropOp drag/drop operations.
|
|
* Clears any pending drop actions from the FSourceControlHistoryRowDragDropOp.
|
|
*
|
|
* @param DragDropEvent The drag/drop operation that triggered this handler.
|
|
*/
|
|
void OnRowDragLeave(FDragDropEvent const& DragDropEvent) const
|
|
{
|
|
TSharedPtr<FSourceControlHistoryRowDragDropOp> DragRowOp = DragDropEvent.GetOperationAs<FSourceControlHistoryRowDragDropOp>();
|
|
if (DragRowOp.IsValid())
|
|
{
|
|
DragRowOp->HoverText = FText::GetEmpty();
|
|
DragRowOp->PendingDropAction = FSourceControlHistoryRowDragDropOp::EDropAction::None;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An event handler for mouse drop events. Intended to be used as a delegate for
|
|
* history tree rows. Only handles FSourceControlHistoryRowDragDropOp drag/drop operations.
|
|
* Executes the pending FSourceControlHistoryRowDragDropOp action (diff, etc.)
|
|
*
|
|
* @param DragDropEvent The drag/drop operation that triggered this handler.
|
|
* @param HoveredItem The history tree item that is conceptually being dropped on to.
|
|
* @return A reply detailing how this event was handled ("Unhandled" if the operation was not a FSourceControlHistoryRowDragDropOp).
|
|
*/
|
|
FReply OnRowDrop(FDragDropEvent const& DragDropEvent, TSharedPtr<FHistoryTreeItem> const HoveredItem) const
|
|
{
|
|
TSharedPtr<FSourceControlHistoryRowDragDropOp> DragRowOp = DragDropEvent.GetOperationAs<FSourceControlHistoryRowDragDropOp>();
|
|
if (DragRowOp.IsValid())
|
|
{
|
|
if (DragRowOp->PendingDropAction == FSourceControlHistoryRowDragDropOp::EDropAction::Diff)
|
|
{
|
|
check(DragRowOp->SelectedItems.Num() > 0);
|
|
DiffHistoryItems(DragRowOp->SelectedItems[0], HoveredItem);
|
|
|
|
return FReply::Handled();
|
|
}
|
|
}
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
/** Main list view of the panel, displays each file history item */
|
|
typedef STreeView< TSharedPtr<FHistoryTreeItem> > SHistoryFileListType;
|
|
|
|
/** ListBox for selecting which object to consolidate */
|
|
TSharedPtr< SHistoryFileListType > MainHistoryListView;
|
|
|
|
/** Items control for the "additional information" subpanel */
|
|
TSharedPtr<SBorder> AdditionalInfoItemsControl;
|
|
|
|
/** All file history items the panel should display */
|
|
TArray< TSharedPtr<FHistoryTreeItem> > HistoryCollection;
|
|
|
|
/** The last selected revision item; Displayed in the "additional information" subpanel */
|
|
TWeakPtr<FHistoryRevisionListViewItem> LastSelectedRevisionItem;
|
|
};
|
|
|
|
void FSourceControlWindows::DisplayRevisionHistory( const TArray<FString>& InPackageNames )
|
|
{
|
|
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
|
|
|
|
// Query for the file history for the provided packages
|
|
TArray<FString> PackageFilenames = SourceControlHelpers::PackageFilenames(InPackageNames);
|
|
TSharedRef<FUpdateStatus, ESPMode::ThreadSafe> UpdateStatusOperation = ISourceControlOperation::Create<FUpdateStatus>();
|
|
UpdateStatusOperation->SetUpdateHistory(true);
|
|
if(SourceControlProvider.Execute(UpdateStatusOperation, PackageFilenames))
|
|
{
|
|
TArray< FSourceControlStateRef > SourceControlStates;
|
|
SourceControlProvider.GetState(PackageFilenames, SourceControlStates, EStateCacheUsage::Use);
|
|
|
|
TSharedRef<SWindow> NewWindow = SNew(SWindow)
|
|
.Title( NSLOCTEXT("SourceControl.HistoryWindow", "Title", "File History") )
|
|
.SizingRule(ESizingRule::UserSized)
|
|
.AutoCenter(EAutoCenter::PreferredWorkArea)
|
|
.ClientSize(FVector2D(700, 400));
|
|
|
|
TSharedRef<SSourceControlHistoryWidget> SourceControlWidget =
|
|
SNew(SSourceControlHistoryWidget)
|
|
.ParentWindow(NewWindow)
|
|
.SourceControlStates(SourceControlStates);
|
|
|
|
|
|
NewWindow->SetContent( SourceControlWidget );
|
|
|
|
TSharedPtr<SWindow> RootWindow = FGlobalTabmanager::Get()->GetRootWindow();
|
|
if(RootWindow.IsValid())
|
|
{
|
|
FSlateApplication::Get().AddWindowAsNativeChild(NewWindow, RootWindow.ToSharedRef());
|
|
}
|
|
else
|
|
{
|
|
FSlateApplication::Get().AddWindow(NewWindow);
|
|
}
|
|
}
|
|
}
|