Files
UnrealEngineUWP/Engine/Source/Editor/MainFrame/Private/Frame/MainFrameActions.cpp
Andrew Grant a140e73bbf Copying //UE4/Orion-Staging to //UE4/Main (Source: //Orion/Dev-General @ 3064255)
#lockdown Nick.Penwarden

Change 3063869 on 2016/07/25 by Michael.Noland@mnoland_T2801_OrionStream

	Engine: Added a cvar (t.FPSChart.OpenFolderOnDump) to control whether or not FPS charts automatically open the profiling folder when stopfpschart is executed, which can be useful to avoid a bunch of open windows while doing automated testing
	#rb marcus.wassmer
	#tests Tested startfpschart + stopfpschart with t.FPSChart.OpenFolderOnDump set to 1 and 0
	#codereview david.nikdel

Change 3063829 on 2016/07/25 by Michael.Noland@mnoland_T2801_OrionStream

	Core: Added an optional size to MallocLeak Stop and made the default filter size 128 KB for both MallocLeak Dump and MallocLeak Stop if no size was specified
	#rb marcus.wassmer
	#tests Tested using MallocLeak Stop and MallocLeak Dump

Change 3063825 on 2016/07/25 by Michael.Noland@mnoland_T2801_OrionStream

	Engine: Exposed GPU revision ID as GRHIDeviceRevision and added it to the FPS chart analytics (gathered on D3D11 and D3D12 only)
	#rb marcus.wassmer
	#tests Tested on my desktop and compared to dxdiag output

Change 3063702 on 2016/07/25 by Ryan.Gerleve@Ryan.Gerleve_T3703_Orion

	Collect garbage when scrubbing in a replay. Scrubbing generates a lot of garbage, and can lead to running out of memory.
	Can be disabled with the cvar demo.LoadCheckpointGarbageCollect.

	#jira OR-25964
	#tests bug repro
	#rb john.pollard

Change 3063426 on 2016/07/25 by Michael.Trepka@Michael.Trepka_T3244_Orion-Dev

	Borderless window support improvements:

	- the cursor changes to resize when hovering over the window edge
	- added a way for widgets to register a delegate that's called when window actions occur (maximize, restore, etc.)
	- used he window action notification for WindowTitleBarArea to improve how toggling fullscreen on double click is handled

	#rb Jeff.Campeau
	#tests Tested in editor build on PC

Change 3063358 on 2016/07/25 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 29.2 @ CL 3063307

	#RB:none
	#tests:none

	#ROBOMERGE-SOURCE: CL 3063345 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3063353 on 2016/07/25 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ben.marsh
	Merging CL 3037547 and CL 3037552 from //UE4/Dev-Build to support BuildPatchTool analytics.

	#rb none
	#tests none

	#ROBOMERGE-SOURCE: CL 3063156 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3063198 on 2016/07/25 by Matt.Kuhlenschmidt@matt.kuhlenschmidt_orion_dev

	Temp fix for broken post process volumes

	#rb none
	#tests  none

Change 3063166 on 2016/07/25 by Daniel.Lamb@daniel.lamb_T3905_6612

	Added check to Redirect collector resolve string asset references.
	#rb none
	#test cook paragon

Change 3063057 on 2016/07/25 by Michael.Trepka@Michael.Trepka_T3244_Orion-Dev

	Use round corners for windows with no system title bar and border only in windowed mode.

	#rb Peter.Sauerbrei
	#tests Tested in editor build on PC

Change 3063015 on 2016/07/25 by Andrew.Rodham@Andrew.Rodham_Orion

	Sequencer: Fixed anim notifies not working when playing animation on blueprint-driven skeletal meshes

	We now inject a new animation position into the animation system, rather than trying to 'fake' events outside of the system. This allows for much more robust event triggering when playing back through sequencer. Previously, anim notifies for trail particles would be reset every frame due to TriggerAnimNotifies being called by the animation system, and sequencer. We now defer this responsibility to the animation system entirely during playback.

	#tests Tested sequencer driven animation with animation assets and (compatible) animation blueprints. Tested some non-sequencer animation.
	#rb Benn.Gallagher

Change 3062774 on 2016/07/24 by Ben.Marsh@Ben.Marsh_T3245_Orion

	BuildGraph: Fix <Cook> tasks failing when multiple platforms are specified, due to not scanning the output directories separately.

	#rb none
	#tests preflight

Change 3062761 on 2016/07/24 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Non-unity fix
	#rb none
	#tests compiled

Change 3062324 on 2016/07/22 by Marcus.Wassmer@Marcus.Wassmer_Orion_DevGeneral

	Skipped a file
	#rb none
	#test none

Change 3062315 on 2016/07/22 by Marcus.Wassmer@Marcus.Wassmer_Orion_DevGeneral

	Allow r.SSR.MaxRoughness in shipping builds.
	Art has been tweaking with this value, but it's not being honored in shipping.
	#rb none
	#tests adjusted settings in agora_p

Change 3062306 on 2016/07/22 by Marcus.Wassmer@Marcus.Wassmer_Orion_DevGeneral

	HLOD distance scalability option (r.HLOD.DistanceScale)
	Higher values make HLODS transition further away.
	#rb Michael.Noland
	#tests Tested in agora_p

Change 3061861 on 2016/07/22 by Lina.Halper@Lina.Halper_Orion

	Fix Compression - Reduce functions to be editoronly

	#rb: Martin.Wilson
	#tests: PIE/compile editor build/noneditor

Change 3061714 on 2016/07/22 by Andrew.Rodham@Andrew.Rodham_Orion

	Sequencer: Fixed anim trails not playing in full, sequencer-driven animation.

	There were 2 issues here. Firstly, we were force-handling events and anim notifies in non-preview animation which caused undefined behaviour when the animation was also updated on tick. Secondly, On the very first frame of a game, sequencer can sometimes use the PreviewSetMatineeAnimPositionInner method because the actor it is referencing has not begun play yet. Unfortunately this function left the animation in a state where the 'real' animation update function wouldn't trigger any anim notifies properly.

	#tests Tested animation with and without anim trails to verify they work in editor, PIE and standalone game with and without sequencer open. Rendered out the announce trailer before and after my changes to verify there was no change in behaviour.

	#jira OR-25967

	#review-3061494 @Max.Chen

	#rb Benn.Gallagher

Change 3061393 on 2016/07/22 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: sam.zamani
	compile errors
	#rb none
	#tests compile

	#ROBOMERGE-SOURCE: CL 3061392 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3061384 on 2016/07/22 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: andrew.grant
	Fixed build breakage
	#rb none
	#tests compiled PS4 client

	#ROBOMERGE-SOURCE: CL 3061383 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3060894 on 2016/07/21 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ian.fox
	#Orion, #OnlineSubsystem, #OnlineGameplayFramework - Game catalog supports Price Engine sales on real-money offers
	#rb Sam.Zamani
	#tests Real-money offers that are on sale show the correct sale price / discount display
	#jira OR-21659

	#ROBOMERGE-SOURCE: CL 3060891 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3060272 on 2016/07/21 by Lina.Halper@Lina.Halper_Orion

	Fix compile issue of non editor build

	#rb: none
	#tests: compile

Change 3060161 on 2016/07/21 by Marcus.Wassmer@Marcus.Wassmer_Orion_DevGeneral

	Duplicate 3046845
	CVAR threading crash fix.
	#rb none
	#tests compiled, ran ps4

Change 3060012 on 2016/07/21 by Lina.Halper@Lina.Halper_Orion

	- Back out changelist 3056611
	- Fix additive issue and built the new animation DDC
	#rb: Martin.Wilson
	#tests: Jump_Recovery_Additive, PIE

Change 3060009 on 2016/07/21 by Rob.Cannaday@rob.cannaday_orion-stream

	When receiving NotLeader party join rejection, include the new leader id and re-attempt the join to the new leader
	#jira OR-25648
	#rb bart.bressler
	#tests frontend parties with promotions, coop matchmaking

Change 3059989 on 2016/07/21 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Fixes for applocal redist
	#rb none
	#test built locally

Change 3059832 on 2016/07/21 by Martin.Wilson@MartinWilsonOrionStream

	Fix graph linked external object saving error on re-compressed animations (dup from dev-framework CL )

	#jira UE-33567
	#rb Thomas.Sarkanen
	#tests In editor testing that animations can be recompressed and saved

Change 3059803 on 2016/07/21 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Switching Orion, UnrealCEFSubProcess, and CrashReporterClient to build with VS2015
	Added AppLocalPrerequisitesDirectory editor setting that is passed in -applocaldir during staging
	WinPlatformAutomation now stages applocaldir to project and engine binaries
	Updated OrionBuild.xml to specify -applocaldir
	#codereview Jeff.Campeau, Ben.Marsh
	#rb none
	#tests build client locally and verified DLLs are local to executables

Change 3059707 on 2016/07/21 by David.Ratti@David.Ratti_G6218_Orion.Dev-General

	fix case where DefaultGameplayTags.ini fails to update if not checked out from source control
	#rb none
	#tests add tags without source control

Change 3059679 on 2016/07/21 by Rob.Cannaday@rob.cannaday_orion-stream

	Fix nonunity compile error due to OnlinePresenceInterface.h requiring enum defined in OnlineSubsystemTypes.h
	#rb paul.moore
	#tests compile with OrionFriendItem.cpp modified

Change 3059518 on 2016/07/21 by Andrew.Grant@andrew.grant.T6730.orion.floating

	AppLcoalDependencies required by VS2015

Change 3059477 on 2016/07/21 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 29.2 @ CL 3059419

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 3059476 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3059455 on 2016/07/21 by Graeme.Thornton@GThornton_Orion_DevGeneral

	Linux build fix (bad case on #include filename)

	#rb robert.manuszewski
	#tests compiled Paragon on a linux machine

Change 3059258 on 2016/07/21 by Simon.Tovey@Simon.Tovey_OrionDev

	Implementing 3050352 in Dev-General.

	#rb none
	#tests Editor

	#codereview Marcus.Wassmer

Change 3058989 on 2016/07/21 by Michael.Noland@mnoland_T2801_OrionStream

	Audio: Disabling the audio thread to prevent a crash in async line trace code (it is already disabled in UE4 main)
	#rb none
	#codereview andrew.grant, ori.cohen

Change 3058773 on 2016/07/20 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ian.fox
	#Orion - Remove QoS* from junk manifest
	#review-3058772 @Rob.Cannaday
	#rb none
	#tests QoS module doesn't get nuked every build

	#ROBOMERGE-SOURCE: CL 3058771 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3058717 on 2016/07/20 by Daniel.Lamb@daniel.lamb_T3905_6612

	Added submitted CL to success email for rebuild lighting commandlet.
	Removed nosimplygon from resave lighting commandlet commandline.
	#rb Daniel.Wright
	#test rebuildlighting paragon devgeneral.

Change 3058565 on 2016/07/20 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ian.fox
	#Orion - Fix debug/non-development builds
	#rb Rob.Cannaday
	#tests it builds (and doesn't crash on login) on Debug Editor -debug -game!

	#ROBOMERGE-SOURCE: CL 3058563 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3058082 on 2016/07/20 by Daniel.Lamb@daniel.lamb_T3905_6612

	Added error to the lighting build whent it fails to build.
	#test Rebuild lighting commandlet
	#rb Daniel.Wright

Change 3057945 on 2016/07/20 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Fix for NAN issue introduced in 3032847
	#rb Jeff.Farris
	#tests none

Change 3057840 on 2016/07/20 by David.Ratti@David.Ratti_G6218_Orion.Dev-General

	fix developer tags not properly adding to perforce when creating a new file

	#rb none
	#tests developer tags

Change 3057553 on 2016/07/20 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 29.2 @ CL 3057330

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 3057549 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3057313 on 2016/07/20 by bruce.nesbit@BNesbit_Orion_Stream_1

	Fixed shadowvariable in FAnalyticsEventEntry

	#rb none

	#tests compiled

	#codereview Wes.Hunt

Change 3056802 on 2016/07/19 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ryan.gerleve
	Fix issue where replicated map-placed actors with ability system components would cache an incorrect Role value.
	This could cause predicted gameplay effects in the fast TArray to have MarkItemDirty called on them, which in turn increments the item's ReplicationID, potentially causing a conflict with the server's ReplicationID.
	Since the Role may not be correct during OnRegister for these components, also cache it BeginPlay.

	#jira OR-25234
	#rb david.ratti
	#tests golden path, bug repro

	#ROBOMERGE-SOURCE: CL 3056801 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3056797 on 2016/07/19 by Wes.Hunt@WHUNT-ORION-STREAM

	OrionAnalytics updates.
	* Added IAnalyticsProviderET::SetDefaultEventAttributes to use to set the GameSessionID on all Orion Analytics events.
	* Removed OrionAnalyticsProvider as it was no longer necessary.
	* Updated all Orion code to use IAnalyticsProviderET directly in the code to be able to access all the new APIs.
	#rb sam.zamani, jason.bestimt
	#tests run dedicated server with 10 bot clients, observe analytics events sending correctly. Ran PIE.
	#jira UE-30980

Change 3056611 on 2016/07/19 by Lina.Halper@Lina.Halper_Orion

	Fix for additive broken with remove linear key
	- DDC key has been changed, so it will require to build DDC from this

	#rb: Martin.Wilson
	#tests: Jump_Recovery_Additive in editor, and PIE

Change 3056226 on 2016/07/19 by Lukasz.Furman@Lukasz.Furman_T7320_OrionStream

	extended gameplay debugger's ability category to show locally owned gameplay tags
	#orion
	#rb none
	#tests PIE

Change 3056204 on 2016/07/19 by Jeff.Campeau@jeff.campeau_3753_Orion

	Fix offset rendering of maximized borderless game window on Windows.
	#review-3055205 @michael.trepka
	#rb Michael.Trepka
	#tests Tested in editor build on PC (editor window normal and maximized, game window borderless normal and maximized, game window bordered normal and maximized).

Change 3056028 on 2016/07/19 by Rob.Cannaday@rob.cannaday_orion-stream

	Add moved modules to JunkManifest.txt

Change 3055650 on 2016/07/19 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - ACTUAL Merge 29.2 @ CL 3055553

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 3055647 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3055620 on 2016/07/19 by Dmitry.Rekman@RCL_Win_Stream-ORMAIN

	Attempts to fix rare server crashes (OR-24947, OR-24952).

	- Rearranging to avoid AddDefaulted(), that might be triggering a compiler bug (conjecture).

	#rb Steve.Robb
	#codereview Steve.Robb
	#tests Compiled Windows client and Linux server, played a match.

Change 3054587 on 2016/07/18 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Merging from //UE4/Main @ 3043787 through //UE4/Orion-Staging
	#rb none
	#tests Smoked by engine and dev QA

Change 3054491 on 2016/07/18 by Frank.Gigliotti@Frank.Gig_T4217_Orion_Stream

	Removed warning when client miss-predicts ability activation.

	* It is valid for the client to miss-predict.  Warning was only added to track down a bug.

	#CodeReview David.Ratti
	#RB None
	#Tests None

Change 3053850 on 2016/07/18 by David.Ratti@David.Ratti_G6218_Orion.Dev-General

	Missed checkins on ability system engine work:
	-Register debug delegate on module startup for easier debugging
	-Fallback to actor location if no hit impact is specified in default engine GC notify class

	#rb none
	#tests ability system sample project

Change 3053825 on 2016/07/18 by David.Ratti@David.Ratti_G6218_Orion.Dev-General

	Fix issue where config file not actually flushed at right time when adding new tags

	Fix issue where orion projecetile tags that are auto generated was generating tags for non gameplay tag properties

	#rb DanY
	#codereview Dan.Youhon
	#tests pie

Change 3053438 on 2016/07/18 by David.Ratti@David.Ratti_G6218_Orion.Dev-General

	-Remove developer tags from master tag list before saving to ini file
	-inline some stuff (wip for gc tag translator system)

	#rb none
	#test adding tags

Change 3053414 on 2016/07/18 by Robert.Manuszewski@Robert_Manuszewski_NCL_Orion

	Fixing rare crash when async loading objects caused by linker being detached too early (before other package's import has been fully processed)

	#jira OR-24955
	#jira OR-25183
	#rb Graeme.Thornton
	#tests Win64 cooked client golden path (solo vs AI)

Change 3052009 on 2016/07/15 by Dmitry.Rekman@RCL_Win_Stream-ORMAIN

	Overhaul of behavior of headless applications (server, client) (OR-23529).

	- Removed FApp::ShouldUseNullRHI(). Rationale: FApp::CanEverRender() answers a higher level question and the code shouldn't predicate on the type of RHI used.
	- Multiple code paths updated to prevent code execution on headless clients (some of this is optimization, some was causing crashes).
	- Most of these changes originated from a shelved CL by BradA.

	#rb Michael.Noland
	#codereview Michael.Noland, Brad.Angelcyk, Andrew.Grant, Chris.Wood, Matt.Schembari
	#tests Cooked Windows client and server, Linux client and server. Ran Windows client and server, played a match, ran Linux bot (headless client, requires local changes not in this CL), ran the Windows editor (tried PIE).

Change 3051926 on 2016/07/15 by Marcus.Wassmer@Marcus.Wassmer_Orion_DevGeneral

	Reinstate color grading changes.
	Fix broken config file.
	#rb none
	#tests Agora_p color grading and warning check

Change 3051759 on 2016/07/15 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ryan.gerleve
	Don't record predicted elements of fast TArrays into client replays.
	Fixes issue where the client was incrementing the ReplicationID of predicted elements, potentially conflicting with the IDs of elements received by the server.

	#jira OR-25234, OR-25413, OR-25403
	#tests golden path, bug repo using 'net pktlag', replays
	#rb john.pollard, david.ratti

	#ROBOMERGE-SOURCE: CL 3051758 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3051702 on 2016/07/15 by Daniel.Lamb@daniel.lamb_T3905_6612

	Added jordan walker to rebuild lighting emails.
	Removed peter.sauerbrei.
	#rb Peter.Sauerbrei
	#test none

Change 3051661 on 2016/07/15 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ben.marsh
	Merging support for precompiled binaries in CIS from Release-29.

	#rb none
	#tests none

	#ROBOMERGE-SOURCE: CL 3051660 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3051466 on 2016/07/15 by Marcus.Wassmer@Marcus.Wassmer_Orion_DevGeneral

	Allow seamless upgrade from FVector -> FVector4 for UProperties.
	#rb Robert.Manuszewski
	#tests Color grading property changes.

Change 3050680 on 2016/07/14 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ian.fox
	#Mcp, #Orion - Fix initalization values of CatalogServiceMcp
	#rb none
	#tests Real money offers show in the store again

	#ROBOMERGE-SOURCE: CL 3050563 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3050520 on 2016/07/14 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - MERGING DUI @ CL 3047139

	#RB:none
	#Tests:none

	[CodeReviewed]: kerrington.smith, dan.hertzka, matt.schembari, benjamin.crocker, jaymee.stanford, alex.conner

	#ROBOMERGE-SOURCE: CL 3050519 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3050465 on 2016/07/14 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: ryan.gerleve
	Don't check IsClientOnly() to detemine whether a player controller is local or not.
	For client replay recording, the replay spectator controller should not return true from IsLocallyControlled(). This change fixes that case in client builds.
	Fixes issue where the SignificanceManager was using the replay spectator to influence significance values, causing them to be incorrect for the game player controller.

	#jira OR-25258
	#tests bug repro, golden path, replays
	#rb john.pollard
	[CodeReviewed] zak.middleton, josh.markiewicz

	#ROBOMERGE-SOURCE: CL 3050462 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3050326 on 2016/07/14 by Dan.Youhon@Dan.Youhon.Paragon

	Set CameraLensEffects position before activation so that initial significance values are correct, specifically to fix quick camera lens effects being culled out due to incorrect significance #OR-18321
	- Moves location determination code from AEmitterCameraLensEffectBase::UpdateLocation into a separate static GetAttachedEmitterTransform function, which is now called both from UpdateLocation and in APlayerCameraManager::AddCameraLensEffect to determine SpawnTransform for the LensEffect SpawnActor call
	- Unshelved from Jeff.Farris. Thanks Jeff!

	#rb Dan.Youhon
	#tests MultiPIE
	#codereview Jeff.Farris

Change 3049749 on 2016/07/14 by Daniel.Lamb@daniel.lamb_T3905_6612

	Added skipskin verify to rebuild lighting commandlet.
	#rb None
	#test Rebuild lighting commandlet

Change 3049728 on 2016/07/14 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: buildmachine
	Remove simplygon from rebuild lighting commandlet
	#rb none
	#test rebuild lighting

	#ROBOMERGE-SOURCE: CL 3049727 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3049721 on 2016/07/14 by buildmachine@buildmachine_Z4560_OrionDevGeneral

	Remove simplygon from rebuild lighting commandlet
	#rb none
	#test rebuild lighting

Change 3049325 on 2016/07/13 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Back out changelist 3049037 due to incompatibility with current assets
	#rb none
	#tests Cooked content and verified warnings & errors are gone.
	#codereview Marcus.Wasmer, Brian.Karis, HaarmPieter.Duiker

Change 3049319 on 2016/07/13 by Andrew.Grant@andrew.grant.T6730.orion.floating

	More work on content filtering (still disabled)
	#rb none
	#tests cooked content and verified filtered content is not found.

Change 3049298 on 2016/07/13 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 28.2/29 @ CL 3049113

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 3049296 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 3049269 on 2016/07/13 by Mieszko.Zielinski@mieszko.zielinski_T4675_Orion

	Constified FObjectFinder::Succeeded because why not #UE4

	#rb none
	#test golden path

Change 3049104 on 2016/07/13 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Created delegate for object name resolution and moved existing package localization code to use it.
	Orion code to filter out unreleased heroes and other data, but correnty disabled due to a cooking bug.
	#rb none
	#tests ran editor, ran cooker, verified object resolution is equivalent to before.

Change 3049037 on 2016/07/13 by HaarmPieter.Duiker@HPD-Dev-General

	Adding shadows, midtones and highlights color correction controls
	#rb brian.karis, marcus.wassmer
	#tests "postprocess color correction"

Change 3048457 on 2016/07/13 by Cody.Haskell@OrionStream

	#UE4

	- Adding a delegate that fires off when LastUserInteractionTime is updated

	#codereview Matt.Kuhlenschmidt
	#rb none
	#tests PIE

Change 3048420 on 2016/07/13 by Dmitry.Rekman@RCL_Lnx_CaseIns_Stream-ORMAIN

	Fix double #undef LOCTEXT_NAMESPACE in editor case.

	#rb none
	#codereview Nick.Darnell, Andrew.Grant
	#tests Compiled Linux editor (for running -server).

Change 3047891 on 2016/07/13 by Michael.Trepka@Michael.Trepka_T3244_Orion-Dev

	Rollback //Orion/Dev-General/Engine/Source/Runtime/Core/Private/Windows/WindowsWindow.cpp to revision 12

	#rb none
	#tests Tested in editor on PC

Change 3047216 on 2016/07/12 by Dmitry.Rekman@RCL_Lnx_CaseIns_Stream-ORMAIN

	Changes to Linux application specific to Linux client.

	#rb none
	#codereview Brad.Angelcyk
	#tests Ran Paragon Linux client (headless) locally.

Change 3047140 on 2016/07/12 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Fix for PS4
	#rb #tests na

Change 3047107 on 2016/07/12 by Andrew.Grant@andrew.grant.T6730.orion.floating

	Moved timeguards out of stats.h
	#rb none
	#tests compiled editor & shipping client

Change 3046996 on 2016/07/12 by Ryan.Gerleve@Ryan.Gerleve_T3703_Orion

	Don't check bTearOff when deciding whether to swap roles for client replay recording and improve the comment.
	Fixes an assert that could occur if a torn-off actor happened to get recorded into a checkpoint of a client replay.

	#tests golden path
	#rb john.pollard

Change 3046975 on 2016/07/12 by Michael.Trepka@Michael.Trepka_T3244_Orion-Dev

	Support for making the game window borderless (no system border or title bar). Disabled by default. Enabling requires adding bUseBorderlessWindow=True to [/Script/EngineSettings.GeneralProjectSettings] in DefaultGame.ini. The game using this is responsible for adding WindowTitleBarArea widget to its UI, as well as window minimize/maximize/close buttons.

	#codereview Dan.Hertzka
	#rb Jeff.Campeau
	#tests Tested in editor build on PC

Change 3046812 on 2016/07/12 by Michael.Trepka@Michael.Trepka_T3244_Orion-Dev

	New UI for selecting fullscreen mode in Paragon video settings

	#rb Dan.Hertzka
	#tests Tested in editor build on PC

Change 3046803 on 2016/07/12 by Michael.Trepka@Michael.Trepka_T3244_Orion-Dev

	Added an option to WindowTitleBarArea widget to make it toggle fullscreen mode instead of maximizing the window.

	#rb Dan.Hertzka
	#tests Tested in editor build on PC

Change 3045374 on 2016/07/11 by John.Pollard@John.Pollard_T2802_Orion_DevGeneral

	Fix assert in channel cleanup code that could occur if the connection was cleaned up, and there were KeepProcessingActorChannelBunchesMap in-flight still

	#rb RyanG
	#tests Replays

Change 3044696 on 2016/07/11 by Daniel.Lamb@daniel.lamb_T3905_6612

	Added additional checks to ResavePackagesCommandlet so people don't miss the required allowcommandletrendering flag when using buildlighting option.
	#test rebuild lighting using resave packages paragon
	#rb None

Change 3044690 on 2016/07/11 by Daniel.Lamb@daniel.lamb_T3905_6612

	Changed MBWritten cooker stats to report mb instead of bytes...
	#rb Wes.Hunt.
	#test cook paragon.

Change 3044439 on 2016/07/11 by Jason.Bestimt@Robomerge_Orion_DevGeneral

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 28.2 @ CL 3043960

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 3044428 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

[CL 3070724 by Andrew Grant in Main branch]
2016-07-29 17:10:25 -04:00

1071 lines
43 KiB
C++

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "MainFramePrivatePCH.h"
#include "MessageLog.h"
#include "SDockTab.h"
#include "SNotificationList.h"
#include "NotificationManager.h"
#include "GenericCommands.h"
#include "EngineBuildSettings.h"
#include "SourceCodeNavigation.h"
#include "SOutputLogDialog.h"
#include "IUATHelperModule.h"
#include "Settings/EditorSettings.h"
#include "AnalyticsEventAttribute.h"
#define LOCTEXT_NAMESPACE "MainFrameActions"
DEFINE_LOG_CATEGORY_STATIC(MainFrameActions, Log, All);
TSharedRef< FUICommandList > FMainFrameCommands::ActionList( new FUICommandList() );
TWeakPtr<SNotificationItem> FMainFrameActionCallbacks::ChoosePackagesToCheckInNotification;
FMainFrameCommands::FMainFrameCommands()
: TCommands<FMainFrameCommands>(
TEXT("MainFrame"), // Context name for fast lookup
LOCTEXT( "MainFrame", "Main Frame" ), // Localized context name for displaying
NAME_None, // No parent context
FEditorStyle::GetStyleSetName() ), // Icon Style Set
ToggleFullscreenConsoleCommand(
TEXT( "MainFrame.ToggleFullscreen" ),
TEXT( "Toggles the editor between \"full screen\" mode and \"normal\" mode. In full screen mode, the task bar and window title area are hidden." ),
FConsoleCommandDelegate::CreateStatic( &FMainFrameActionCallbacks::ToggleFullscreen_Execute ) )
{ }
void FMainFrameCommands::RegisterCommands()
{
if ( !IsRunningCommandlet() )
{
// The global action list was created at static initialization time. Create a handler for otherwise unhandled keyboard input to route key commands through this list.
FSlateApplication::Get().SetUnhandledKeyDownEventHandler( FOnKeyEvent::CreateStatic( &FMainFrameActionCallbacks::OnUnhandledKeyDownEvent ) );
}
// Make a default can execute action that disables input when in debug mode
FCanExecuteAction DefaultExecuteAction = FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::DefaultCanExecuteAction );
UI_COMMAND( SaveAll, "Save All", "Saves all unsaved levels and assets to disk", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control, EKeys::S ) );
ActionList->MapAction( SaveAll, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::SaveAll ), FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::CanSaveWorld ) );
UI_COMMAND( ChooseFilesToSave, "Choose Files to Save...", "Opens a dialog with save options for content and levels", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( ChooseFilesToSave, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::ChoosePackagesToSave ), FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::CanSaveWorld ) );
UI_COMMAND( ChooseFilesToCheckIn, "Submit to Source Control...", "Opens a dialog with check in options for content and levels", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( ChooseFilesToCheckIn, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::ChoosePackagesToCheckIn ), FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::CanChoosePackagesToCheckIn ) );
UI_COMMAND( ConnectToSourceControl, "Connect To Source Control...", "Connect to source control to allow source control operations to be performed on content and levels.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( ConnectToSourceControl, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::ConnectToSourceControl ), DefaultExecuteAction );
UI_COMMAND( NewProject, "New Project...", "Opens a dialog to create a new game project", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( NewProject, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::NewProject, false, true), DefaultExecuteAction );
UI_COMMAND( OpenProject, "Open Project...", "Opens a dialog to choose a game project to open", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( OpenProject, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::NewProject, true, false), DefaultExecuteAction );
UI_COMMAND( AddCodeToProject, "New C++ Class...", "Adds C++ code to the project. The code can only be compiled if you have an appropriate C++ compiler installed.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( AddCodeToProject, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::AddCodeToProject ));
UI_COMMAND( RefreshCodeProject, "Refresh code project", "Refreshes your C++ code project.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( RefreshCodeProject, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::RefreshCodeProject ), FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::IsCodeProject ) );
UI_COMMAND( OpenIDE, "Open IDE", "Opens your C++ code in an integrated development environment.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( OpenIDE, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::OpenIDE ), FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::IsCodeProject ) );
UI_COMMAND( ZipUpProject, "Zip Up Project", "Zips up the project into a zip file.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction(ZipUpProject, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::ZipUpProject ), DefaultExecuteAction);
UI_COMMAND( PackagingSettings, "Packaging Settings...", "Opens the settings for project packaging", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( PackagingSettings, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::PackagingSettings ), DefaultExecuteAction );
//UI_COMMAND( LocalizeProject, "Localize Project...", "Opens the dashboard for managing project localization data.", EUserInterfaceActionType::Button, FInputChord() );
//ActionList->MapAction( LocalizeProject, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::LocalizeProject ), DefaultExecuteAction );
const int32 MaxProjects = 20;
for( int32 CurProjectIndex = 0; CurProjectIndex < MaxProjects; ++CurProjectIndex )
{
// NOTE: The actual label and tool-tip will be overridden at runtime when the command is bound to a menu item, however
// we still need to set one here so that the key bindings UI can function properly
FFormatNamedArguments Arguments;
Arguments.Add(TEXT("CurrentProjectIndex"), CurProjectIndex);
const FText Message = FText::Format( LOCTEXT( "SwitchProject", "Switch Project {CurrentProjectIndex}" ), Arguments );
TSharedRef< FUICommandInfo > SwitchProject =
FUICommandInfoDecl(
this->AsShared(),
FName( *FString::Printf( TEXT( "SwitchProject%i" ), CurProjectIndex ) ),
Message,
LOCTEXT( "SwitchProjectToolTip", "Restarts the editor and switches to selected project" ) )
.UserInterfaceType( EUserInterfaceActionType::Button )
.DefaultChord( FInputChord() );
SwitchProjectCommands.Add( SwitchProject );
ActionList->MapAction( SwitchProjectCommands[ CurProjectIndex ], FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::SwitchProjectByIndex, CurProjectIndex ),
FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::CanSwitchToProject, CurProjectIndex ),
FIsActionChecked::CreateStatic( &FMainFrameActionCallbacks::IsSwitchProjectChecked, CurProjectIndex ) );
}
UI_COMMAND( Exit, "Exit", "Exits the application", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( Exit, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::Exit ), DefaultExecuteAction );
ActionList->MapAction( FGenericCommands::Get().Undo, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::ExecuteExecCommand, FString( TEXT("TRANSACTION UNDO") ) ), FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::Undo_CanExecute ) );
ActionList->MapAction( FGenericCommands::Get().Redo, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::ExecuteExecCommand, FString( TEXT("TRANSACTION REDO") ) ), FCanExecuteAction::CreateStatic( &FMainFrameActionCallbacks::Redo_CanExecute ) );
UI_COMMAND( OpenDeviceManagerApp, "Device Manager", "Opens up the device manager app", EUserInterfaceActionType::Check, FInputChord() );
ActionList->MapAction( OpenDeviceManagerApp,
FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::OpenSlateApp, FName( TEXT( "DeviceManager" ) ) ),
FCanExecuteAction(),
FIsActionChecked::CreateStatic( &FMainFrameActionCallbacks::OpenSlateApp_IsChecked, FName( TEXT( "DeviceManager" ) ) ) );
UI_COMMAND( OpenSessionManagerApp, "Session Manager", "Opens up the session manager app", EUserInterfaceActionType::Check, FInputChord() );
ActionList->MapAction( OpenSessionManagerApp,
FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::OpenSlateApp, FName( "SessionFrontend" ) ),
FCanExecuteAction(),
FIsActionChecked::CreateStatic( &FMainFrameActionCallbacks::OpenSlateApp_IsChecked, FName("SessionFrontend" ) ) );
UI_COMMAND(VisitWiki, "Wiki...", "Go to the Unreal Engine Wiki page to view community-created resources, or to create your own.", EUserInterfaceActionType::Button, FInputChord());
ActionList->MapAction(VisitWiki, FExecuteAction::CreateStatic(&FMainFrameActionCallbacks::VisitWiki));
UI_COMMAND(VisitForums, "Forums...", "Go the the Unreal Engine forums to view announcements and engage in discussions with other developers.", EUserInterfaceActionType::Button, FInputChord());
ActionList->MapAction(VisitForums, FExecuteAction::CreateStatic(&FMainFrameActionCallbacks::VisitForums));
UI_COMMAND( VisitAskAQuestionPage, "Ask a Question...", "Have a question? Go here to ask about anything and everything related to Unreal.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( VisitAskAQuestionPage, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::VisitAskAQuestionPage ) );
UI_COMMAND( VisitSearchForAnswersPage, "Answer Hub...", "Go to the AnswerHub to ask questions, search existing answers, and share your knowledge with other UE4 developers.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( VisitSearchForAnswersPage, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::VisitSearchForAnswersPage ) );
UI_COMMAND( VisitSupportWebSite, "Unreal Engine Support Web Site...", "Navigates to the Unreal Engine Support web site's main page.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( VisitSupportWebSite, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::VisitSupportWebSite ) );
UI_COMMAND( VisitEpicGamesDotCom, "Visit UnrealEngine.com...", "Navigates to UnrealEngine.com where you can learn more about Unreal Technology.", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( VisitEpicGamesDotCom, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::VisitEpicGamesDotCom ) );
UI_COMMAND( AboutUnrealEd, "About Editor...", "Displays application credits and copyright information", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( AboutUnrealEd, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::AboutUnrealEd_Execute ) );
UI_COMMAND( CreditsUnrealEd, "Credits", "Displays application credits", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( CreditsUnrealEd, FExecuteAction::CreateStatic(&FMainFrameActionCallbacks::CreditsUnrealEd_Execute) );
UI_COMMAND( ResetLayout, "Reset Layout...", "Make a backup of your user settings and reset the layout customizations", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( ResetLayout, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::ResetLayout) );
UI_COMMAND( SaveLayout, "Save Layout", "Save the layout customizations", EUserInterfaceActionType::Button, FInputChord() );
ActionList->MapAction( SaveLayout, FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::SaveLayout) );
UI_COMMAND( ToggleFullscreen, "Enable Fullscreen", "Enables fullscreen mode for the application, expanding across the entire monitor", EUserInterfaceActionType::ToggleButton, FInputChord(EModifierKey::Shift, EKeys::F11) );
ActionList->MapAction( ToggleFullscreen,
FExecuteAction::CreateStatic( &FMainFrameActionCallbacks::ToggleFullscreen_Execute ),
FCanExecuteAction(),
FIsActionChecked::CreateStatic( &FMainFrameActionCallbacks::FullScreen_IsChecked )
);
UI_COMMAND(OpenWidgetReflector, "Open Widget Reflector", "Opens the Widget Reflector", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift | EModifierKey::Control , EKeys::W));
ActionList->MapAction(OpenWidgetReflector, FExecuteAction::CreateStatic(&FMainFrameActionCallbacks::OpenWidgetReflector_Execute));
FGlobalEditorCommonCommands::MapActions(ActionList);
}
FReply FMainFrameActionCallbacks::OnUnhandledKeyDownEvent(const FKeyEvent& InKeyEvent)
{
if ( FMainFrameCommands::ActionList->ProcessCommandBindings( InKeyEvent ) )
{
return FReply::Handled();
}
return FReply::Unhandled();
}
bool FMainFrameActionCallbacks::DefaultCanExecuteAction()
{
return FSlateApplication::Get().IsNormalExecution();
}
void FMainFrameActionCallbacks::ChoosePackagesToSave()
{
const bool bPromptUserToSave = true;
const bool bSaveMapPackages = true;
const bool bSaveContentPackages = true;
const bool bFastSave = false;
const bool bClosingEditor = false;
const bool bNotifyNoPackagesSaved = true;
const bool bCanBeDeclined = false;
FEditorFileUtils::SaveDirtyPackages( bPromptUserToSave, bSaveMapPackages, bSaveContentPackages, bFastSave, bNotifyNoPackagesSaved, bCanBeDeclined );
}
void FMainFrameActionCallbacks::ChoosePackagesToCheckIn()
{
FSourceControlWindows::ChoosePackagesToCheckIn();
}
bool FMainFrameActionCallbacks::CanChoosePackagesToCheckIn()
{
return FSourceControlWindows::CanChoosePackagesToCheckIn();
}
void FMainFrameActionCallbacks::ConnectToSourceControl()
{
ELoginWindowMode::Type Mode = !FSlateApplication::Get().GetActiveModalWindow().IsValid() ? ELoginWindowMode::Modeless : ELoginWindowMode::Modal;
ISourceControlModule::Get().ShowLoginDialog(FSourceControlLoginClosed(), Mode);
}
bool FMainFrameActionCallbacks::CanSaveWorld()
{
return FSlateApplication::Get().IsNormalExecution() && (!GUnrealEd || !GUnrealEd->GetPackageAutoSaver().IsAutoSaving());
}
void FMainFrameActionCallbacks::SaveAll()
{
const bool bPromptUserToSave = false;
const bool bSaveMapPackages = true;
const bool bSaveContentPackages = true;
const bool bFastSave = false;
const bool bNotifyNoPackagesSaved = false;
const bool bCanBeDeclined = false;
FEditorFileUtils::SaveDirtyPackages( bPromptUserToSave, bSaveMapPackages, bSaveContentPackages, bFastSave, bNotifyNoPackagesSaved, bCanBeDeclined );
}
TArray<FString> FMainFrameActionCallbacks::ProjectNames;
void FMainFrameActionCallbacks::CacheProjectNames()
{
ProjectNames.Empty();
// The switch project menu is filled with recently opened project files
ProjectNames = GetDefault<UEditorSettings>()->RecentlyOpenedProjectFiles;
}
void FMainFrameActionCallbacks::NewProject( bool bAllowProjectOpening, bool bAllowProjectCreate )
{
if (GUnrealEd->WarnIfLightingBuildIsCurrentlyRunning())
{
return;
}
FText Title;
if (bAllowProjectOpening && bAllowProjectCreate)
{
Title = LOCTEXT( "SelectProjectWindowHeader", "Select Project");
}
else if (bAllowProjectOpening)
{
Title = LOCTEXT( "OpenProjectWindowHeader", "Open Project");
}
else
{
Title = LOCTEXT( "NewProjectWindowHeader", "New Project");
}
TSharedRef<SWindow> NewProjectWindow =
SNew(SWindow)
.Title(Title)
.ClientSize( FMainFrameModule::GetProjectBrowserWindowSize() )
.SizingRule( ESizingRule::UserSized )
.SupportsMinimize(false) .SupportsMaximize(false);
NewProjectWindow->SetContent( FGameProjectGenerationModule::Get().CreateGameProjectDialog(bAllowProjectOpening, bAllowProjectCreate) );
IMainFrameModule& MainFrameModule = FModuleManager::GetModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
if (MainFrameModule.GetParentWindow().IsValid())
{
FSlateApplication::Get().AddWindowAsNativeChild(NewProjectWindow, MainFrameModule.GetParentWindow().ToSharedRef());
}
else
{
FSlateApplication::Get().AddWindow(NewProjectWindow);
}
}
void FMainFrameActionCallbacks::AddCodeToProject()
{
FGameProjectGenerationModule::Get().OpenAddCodeToProjectDialog();
}
/**
* Gets compilation flags for UAT for this system.
*/
const TCHAR* GetUATCompilationFlags()
{
// We never want to compile editor targets when invoking UAT in this context.
// If we are installed or don't have a compiler, we must assume we have a precompiled UAT.
return (FApp::GetEngineIsPromotedBuild() || FApp::IsEngineInstalled())
? TEXT("-nocompile -nocompileeditor")
: TEXT("-nocompileeditor");
}
FString GetCookingOptionalParams()
{
FString OptionalParams;
const UProjectPackagingSettings* const PackagingSettings = GetDefault<UProjectPackagingSettings>();
if (PackagingSettings->bSkipEditorContent)
{
OptionalParams += TEXT(" -SKIPEDITORCONTENT");
}
return OptionalParams;
}
void FMainFrameActionCallbacks::CookContent(const FName InPlatformInfoName)
{
const PlatformInfo::FPlatformInfo* const PlatformInfo = PlatformInfo::FindPlatformInfo(InPlatformInfoName);
check(PlatformInfo);
if (FInstalledPlatformInfo::Get().IsPlatformMissingRequiredFile(PlatformInfo->BinaryFolderName))
{
if (!FInstalledPlatformInfo::OpenInstallerOptions())
{
FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("MissingPlatformFilesCook", "Missing required files to cook for this platform."));
}
return;
}
FString OptionalParams;
if (!FModuleManager::LoadModuleChecked<IProjectTargetPlatformEditorModule>("ProjectTargetPlatformEditor").ShowUnsupportedTargetWarning(PlatformInfo->VanillaPlatformName))
{
return;
}
if (PlatformInfo->SDKStatus == PlatformInfo::EPlatformSDKStatus::NotInstalled)
{
IMainFrameModule& MainFrameModule = FModuleManager::GetModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
MainFrameModule.BroadcastMainFrameSDKNotInstalled(PlatformInfo->TargetPlatformName.ToString(), PlatformInfo->SDKTutorial);
return;
}
// Append any extra UAT flags specified for this platform flavor
if (!PlatformInfo->UATCommandLine.IsEmpty())
{
OptionalParams += TEXT(" ");
OptionalParams += PlatformInfo->UATCommandLine;
}
else
{
OptionalParams += TEXT(" -targetplatform=");
OptionalParams += *PlatformInfo->TargetPlatformName.ToString();
}
OptionalParams += GetCookingOptionalParams();
const bool bRunningDebug = FParse::Param(FCommandLine::Get(), TEXT("debug"));
if (bRunningDebug)
{
OptionalParams += TEXT(" -UseDebugParamForEditorExe");
}
FString ProjectPath = FPaths::IsProjectFilePathSet() ? FPaths::ConvertRelativePathToFull(FPaths::GetProjectFilePath()) : FPaths::RootDir() / FApp::GetGameName() / FApp::GetGameName() + TEXT(".uproject");
FString CommandLine = FString::Printf(TEXT("BuildCookRun %s%s -nop4 -project=\"%s\" -cook -ue4exe=%s %s"),
GetUATCompilationFlags(),
FApp::IsEngineInstalled() ? TEXT(" -installed") : TEXT(""),
*ProjectPath,
*FUnrealEdMisc::Get().GetExecutableForCommandlets(),
*OptionalParams
);
IUATHelperModule::Get().CreateUatTask(CommandLine, PlatformInfo->DisplayName, LOCTEXT("CookingContentTaskName", "Cooking content"), LOCTEXT("CookingTaskName", "Cooking"), FEditorStyle::GetBrush(TEXT("MainFrame.CookContent")));
}
bool FMainFrameActionCallbacks::CookContentCanExecute( const FName PlatformInfoName )
{
return true;
}
void FMainFrameActionCallbacks::PackageBuildConfiguration( EProjectPackagingBuildConfigurations BuildConfiguration )
{
UProjectPackagingSettings* PackagingSettings = Cast<UProjectPackagingSettings>(UProjectPackagingSettings::StaticClass()->GetDefaultObject());
PackagingSettings->BuildConfiguration = BuildConfiguration;
}
bool FMainFrameActionCallbacks::CanPackageBuildConfiguration( EProjectPackagingBuildConfigurations BuildConfiguration )
{
UProjectPackagingSettings* PackagingSettings = Cast<UProjectPackagingSettings>(UProjectPackagingSettings::StaticClass()->GetDefaultObject());
if (PackagingSettings->ForDistribution && BuildConfiguration != PPBC_Shipping)
{
return false;
}
return true;
}
bool FMainFrameActionCallbacks::PackageBuildConfigurationIsChecked( EProjectPackagingBuildConfigurations BuildConfiguration )
{
return (GetDefault<UProjectPackagingSettings>()->BuildConfiguration == BuildConfiguration);
}
void FMainFrameActionCallbacks::PackageProject( const FName InPlatformInfoName )
{
GUnrealEd->CancelPlayingViaLauncher();
TArray<FString> Packages;
GUnrealEd->SaveWorldForPlay(Packages);
// does the project have any code?
FGameProjectGenerationModule& GameProjectModule = FModuleManager::LoadModuleChecked<FGameProjectGenerationModule>(TEXT("GameProjectGeneration"));
bool bProjectHasCode = GameProjectModule.Get().ProjectRequiresBuild(InPlatformInfoName);
const PlatformInfo::FPlatformInfo* const PlatformInfo = PlatformInfo::FindPlatformInfo(InPlatformInfoName);
check(PlatformInfo);
if (FInstalledPlatformInfo::Get().IsPlatformMissingRequiredFile(PlatformInfo->BinaryFolderName))
{
if (!FInstalledPlatformInfo::OpenInstallerOptions())
{
FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("MissingPlatformFilesPackage", "Missing required files to package this platform."));
}
return;
}
if (PlatformInfo->SDKStatus == PlatformInfo::EPlatformSDKStatus::NotInstalled || (bProjectHasCode && PlatformInfo->bUsesHostCompiler && !FSourceCodeNavigation::IsCompilerAvailable()))
{
IMainFrameModule& MainFrameModule = FModuleManager::GetModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
MainFrameModule.BroadcastMainFrameSDKNotInstalled(PlatformInfo->TargetPlatformName.ToString(), PlatformInfo->SDKTutorial);
TArray<FAnalyticsEventAttribute> ParamArray;
ParamArray.Add(FAnalyticsEventAttribute(TEXT("Time"), 0.0));
FEditorAnalytics::ReportEvent(TEXT("Editor.Package.Failed"), PlatformInfo->TargetPlatformName.ToString(), bProjectHasCode, EAnalyticsErrorCodes::SDKNotFound, ParamArray);
return;
}
{
const ITargetPlatform* const Platform = GetTargetPlatformManager()->FindTargetPlatform(PlatformInfo->TargetPlatformName.ToString());
if (Platform)
{
FString NotInstalledTutorialLink;
FString ProjectPath = FPaths::IsProjectFilePathSet() ? FPaths::ConvertRelativePathToFull(FPaths::GetProjectFilePath()) : FPaths::RootDir() / FApp::GetGameName() / FApp::GetGameName() + TEXT(".uproject");
int32 Result = Platform->CheckRequirements(ProjectPath, bProjectHasCode, NotInstalledTutorialLink);
// report to analytics
FEditorAnalytics::ReportBuildRequirementsFailure(TEXT("Editor.Package.Failed"), PlatformInfo->TargetPlatformName.ToString(), bProjectHasCode, Result);
// report to message log
if ((Result & ETargetPlatformReadyStatus::SDKNotFound) != 0)
{
AddMessageLog(
LOCTEXT("SdkNotFoundMessage", "Software Development Kit (SDK) not found."),
FText::Format(LOCTEXT("SdkNotFoundMessageDetail", "Please install the SDK for the {0} target platform!"), Platform->DisplayName()),
NotInstalledTutorialLink
);
}
if ((Result & ETargetPlatformReadyStatus::ProvisionNotFound) != 0)
{
AddMessageLog(
LOCTEXT("ProvisionNotFoundMessage", "Provision not found."),
LOCTEXT("ProvisionNotFoundMessageDetail", "A provision is required for deploying your app to the device."),
NotInstalledTutorialLink
);
}
if ((Result & ETargetPlatformReadyStatus::SigningKeyNotFound) != 0)
{
AddMessageLog(
LOCTEXT("SigningKeyNotFoundMessage", "Signing key not found."),
LOCTEXT("SigningKeyNotFoundMessageDetail", "The app could not be digitally signed, because the signing key is not configured."),
NotInstalledTutorialLink
);
}
if ((Result & ETargetPlatformReadyStatus::ManifestNotFound) != 0)
{
AddMessageLog(
LOCTEXT("ManifestNotFound", "Manifest not found."),
LOCTEXT("ManifestNotFoundMessageDetail", "The generated application manifest could not be found."),
NotInstalledTutorialLink
);
}
// report to main frame
bool UnrecoverableError = false;
if ((Result & ETargetPlatformReadyStatus::CodeUnsupported) != 0)
{
FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("NotSupported_SelectedPlatform", "Sorry, packaging a code-based project for the selected platform is currently not supported. This feature may be available in a future release."));
UnrecoverableError = true;
}
else if ((Result & ETargetPlatformReadyStatus::PluginsUnsupported) != 0)
{
FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("NotSupported_ThirdPartyPlugins", "Sorry, packaging a project with third-party plugins is currently not supported for the selected platform. This feature may be available in a future release."));
UnrecoverableError = true;
}
if (UnrecoverableError)
{
return;
}
}
}
if (!FModuleManager::LoadModuleChecked<IProjectTargetPlatformEditorModule>("ProjectTargetPlatformEditor").ShowUnsupportedTargetWarning(PlatformInfo->VanillaPlatformName))
{
return;
}
UProjectPackagingSettings* PackagingSettings = Cast<UProjectPackagingSettings>(UProjectPackagingSettings::StaticClass()->GetDefaultObject());
// let the user pick a target directory
if (PackagingSettings->StagingDirectory.Path.IsEmpty())
{
PackagingSettings->StagingDirectory.Path = FPaths::GameDir();
}
FString OutFolderName;
void* ParentWindowWindowHandle = nullptr;
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
const TSharedPtr<SWindow>& MainFrameParentWindow = MainFrameModule.GetParentWindow();
if ( MainFrameParentWindow.IsValid() && MainFrameParentWindow->GetNativeWindow().IsValid() )
{
ParentWindowWindowHandle = MainFrameParentWindow->GetNativeWindow()->GetOSWindowHandle();
}
if (!FDesktopPlatformModule::Get()->OpenDirectoryDialog(ParentWindowWindowHandle, LOCTEXT("PackageDirectoryDialogTitle", "Package project...").ToString(), PackagingSettings->StagingDirectory.Path, OutFolderName))
{
return;
}
PackagingSettings->StagingDirectory.Path = OutFolderName;
PackagingSettings->SaveConfig();
// create the packager process
FString OptionalParams;
if (PackagingSettings->FullRebuild)
{
OptionalParams += TEXT(" -clean");
}
if ( PackagingSettings->bCompressed )
{
OptionalParams += TEXT(" -compressed");
}
OptionalParams += GetCookingOptionalParams();
if (PackagingSettings->UsePakFile)
{
if (PlatformInfo->TargetPlatformName != FName("HTML5"))
{
OptionalParams += TEXT(" -pak");
}
}
if (PackagingSettings->IncludePrerequisites)
{
OptionalParams += TEXT(" -prereqs");
}
if (!PackagingSettings->ApplocalPrerequisitesDirectory.Path.IsEmpty())
{
OptionalParams += FString::Printf(TEXT(" -applocaldirectory=\"%s\""), *(PackagingSettings->ApplocalPrerequisitesDirectory.Path));
}
if (PackagingSettings->ForDistribution)
{
OptionalParams += TEXT(" -distribution");
}
if (!PackagingSettings->IncludeDebugFiles)
{
OptionalParams += TEXT(" -nodebuginfo");
}
if (PackagingSettings->bNativizeBlueprintAssets)
{
OptionalParams += TEXT(" -nativizeAssets");
}
if (PackagingSettings->bGenerateChunks)
{
OptionalParams += TEXT(" -manifests");
}
bool bTargetPlatformCanUseCrashReporter = true;
if (PlatformInfo->TargetPlatformName == FName("WindowsNoEditor") && PlatformInfo->PlatformFlavor == TEXT("Win32"))
{
FString MinumumSupportedWindowsOS;
GConfig->GetString(TEXT("/Script/WindowsTargetPlatform.WindowsTargetSettings"), TEXT("MinimumOSVersion"), MinumumSupportedWindowsOS, GEngineIni);
if (MinumumSupportedWindowsOS == TEXT("MSOS_XP"))
{
OptionalParams += TEXT(" -SpecifiedArchitecture=_xp");
bTargetPlatformCanUseCrashReporter = false;
}
}
// Append any extra UAT flags specified for this platform flavor
if (!PlatformInfo->UATCommandLine.IsEmpty())
{
OptionalParams += TEXT(" ");
OptionalParams += PlatformInfo->UATCommandLine;
}
else
{
OptionalParams += TEXT(" -targetplatform=");
OptionalParams += *PlatformInfo->TargetPlatformName.ToString();
}
// only build if the project has code that might need to be built
if (bProjectHasCode || (!FApp::GetEngineIsPromotedBuild() && !FApp::IsEngineInstalled()) || PackagingSettings->bNativizeBlueprintAssets)
{
OptionalParams += TEXT(" -build");
}
// Whether to include the crash reporter.
if (PackagingSettings->IncludeCrashReporter && bTargetPlatformCanUseCrashReporter)
{
OptionalParams += TEXT( " -CrashReporter" );
}
if (PackagingSettings->bBuildHttpChunkInstallData)
{
OptionalParams += FString::Printf(TEXT(" -manifests -createchunkinstall -chunkinstalldirectory=\"%s\" -chunkinstallversion=%s"), *(PackagingSettings->HttpChunkInstallDataDirectory.Path), *(PackagingSettings->HttpChunkInstallDataVersion));
}
int32 NumCookers = GetDefault<UEditorExperimentalSettings>()->MultiProcessCooking;
if (NumCookers > 0 )
{
OptionalParams += FString::Printf(TEXT(" -NumCookersToSpawn=%d"), NumCookers);
}
const bool bRunningDebug = FParse::Param(FCommandLine::Get(), TEXT("debug"));
if (bRunningDebug)
{
OptionalParams += TEXT(" -UseDebugParamForEditorExe");
}
FString Configuration = FindObject<UEnum>(ANY_PACKAGE, TEXT("EProjectPackagingBuildConfigurations"))->GetEnumName(PackagingSettings->BuildConfiguration);
Configuration = Configuration.Replace(TEXT("PPBC_"), TEXT(""));
FString ProjectPath = FPaths::IsProjectFilePathSet() ? FPaths::ConvertRelativePathToFull(FPaths::GetProjectFilePath()) : FPaths::RootDir() / FApp::GetGameName() / FApp::GetGameName() + TEXT(".uproject");
FString CommandLine = FString::Printf(TEXT("-ScriptsForProject=\"%s\" BuildCookRun %s%s -nop4 -project=\"%s\" -cook -stage -archive -archivedirectory=\"%s\" -package -clientconfig=%s -ue4exe=%s %s -utf8output"),
*ProjectPath,
GetUATCompilationFlags(),
FApp::IsEngineInstalled() ? TEXT(" -installed") : TEXT(""),
*ProjectPath,
*PackagingSettings->StagingDirectory.Path,
*Configuration,
*FUnrealEdMisc::Get().GetExecutableForCommandlets(),
*OptionalParams
);
IUATHelperModule::Get().CreateUatTask( CommandLine, PlatformInfo->DisplayName, LOCTEXT("PackagingProjectTaskName", "Packaging project"), LOCTEXT("PackagingTaskName", "Packaging"), FEditorStyle::GetBrush(TEXT("MainFrame.PackageProject")) );
}
bool FMainFrameActionCallbacks::PackageProjectCanExecute( const FName PlatformInfoName )
{
return true;
}
void FMainFrameActionCallbacks::RefreshCodeProject()
{
if ( !FSourceCodeNavigation::IsCompilerAvailable() )
{
// Attempt to trigger the tutorial if the user doesn't have a compiler installed for the project.
FSourceCodeNavigation::AccessOnCompilerNotFound().Broadcast();
}
FText FailReason, FailLog;
if(!FGameProjectGenerationModule::Get().UpdateCodeProject(FailReason, FailLog))
{
SOutputLogDialog::Open(LOCTEXT("RefreshProject", "Refresh Project"), FailReason, FailLog, FText::GetEmpty());
}
}
bool FMainFrameActionCallbacks::IsCodeProject()
{
// Not particularly rigorous, but assume it's a code project if it can find a Source directory
const bool bIsCodeProject = IFileManager::Get().DirectoryExists(*FPaths::GameSourceDir());
return bIsCodeProject;
}
void FMainFrameActionCallbacks::OpenIDE()
{
if ( !FSourceCodeNavigation::IsCompilerAvailable() )
{
// Attempt to trigger the tutorial if the user doesn't have a compiler installed for the project.
FSourceCodeNavigation::AccessOnCompilerNotFound().Broadcast();
}
else
{
if ( !FSourceCodeNavigation::OpenModuleSolution() )
{
FString SolutionPath;
if(FDesktopPlatformModule::Get()->GetSolutionPath(SolutionPath))
{
const FString FullPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead( *SolutionPath );
const FText Message = FText::Format( LOCTEXT( "OpenIDEFailed_MissingFile", "Could not open {0} for project {1}" ), FSourceCodeNavigation::GetSuggestedSourceCodeIDE(), FText::FromString( FullPath ) );
FMessageDialog::Open( EAppMsgType::Ok, Message );
}
else
{
FMessageDialog::Open( EAppMsgType::Ok, LOCTEXT("OpenIDEFailed_MissingSolution", "Couldn't find solution"));
}
}
}
}
void FMainFrameActionCallbacks::ZipUpProject()
{
#if PLATFORM_WINDOWS
FText PlatformName = LOCTEXT("PlatformName_Windows", "Windows");
#elif PLATFORM_MAC
FText PlatformName = LOCTEXT("PlatformName_Mac", "Mac");
#elif PLATFORM_LINUX
FText PlatformName = LOCTEXT("PlatformName_Linux", "Linux");
#else
FText PlatformName = LOCTEXT("PlatformName_Other", "Other OS");
#endif
bool bOpened = false;
TArray<FString> SaveFilenames;
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
if (DesktopPlatform != NULL)
{
bOpened = DesktopPlatform->SaveFileDialog(
NULL,
NSLOCTEXT("UnrealEd", "ZipUpProject", "Zip file location").ToString(),
FPaths::GameDir(),
FApp::GetGameName(),
TEXT("Zip file|*.zip"),
EFileDialogFlags::None,
SaveFilenames);
}
if (bOpened)
{
for (FString FileName : SaveFilenames)
{
// Ensure path is full rather than relative (for macs)
FString FinalFileName = FPaths::ConvertRelativePathToFull(FileName);
FString ProjectPath = FPaths::IsProjectFilePathSet() ? FPaths::ConvertRelativePathToFull(FPaths::GameDir()) : FPaths::RootDir() / FApp::GetGameName();
FString CommandLine = FString::Printf(TEXT("ZipProjectUp -project=\"%s\" -install=\"%s\""), *ProjectPath, *FinalFileName);
IUATHelperModule::Get().CreateUatTask( CommandLine, PlatformName, LOCTEXT("ZipTaskName", "Zipping Up Project"),
LOCTEXT("ZipTaskShortName", "Zip Project Task"), FEditorStyle::GetBrush(TEXT("MainFrame.CookContent")));
}
}
}
void FMainFrameActionCallbacks::PackagingSettings()
{
FModuleManager::LoadModuleChecked<ISettingsModule>("Settings").ShowViewer("Project", "Project", "Packaging");
}
//void FMainFrameActionCallbacks::LocalizeProject()
//{
// FModuleManager::LoadModuleChecked<ILocalizationDashboardModule>("LocalizationDashboard").Show();
//}
void FMainFrameActionCallbacks::SwitchProjectByIndex( int32 ProjectIndex )
{
FUnrealEdMisc::Get().SwitchProject( ProjectNames[ ProjectIndex ] );
}
void FMainFrameActionCallbacks::SwitchProject(const FString& GameOrProjectFileName)
{
FUnrealEdMisc::Get().SwitchProject( GameOrProjectFileName );
}
void FMainFrameActionCallbacks::OpenBackupDirectory( FString BackupFile )
{
FPlatformProcess::LaunchFileInDefaultExternalApplication(*FPaths::GetPath(FPaths::ConvertRelativePathToFull(BackupFile)));
}
void FMainFrameActionCallbacks::ResetLayout()
{
if(EAppReturnType::Ok != OpenMsgDlgInt(EAppMsgType::OkCancel, LOCTEXT( "ActionRestartMsg", "This action requires the editor to restart; you will be prompted to save any changes. Continue?" ), LOCTEXT( "ResetUILayout_Title", "Reset UI Layout" ) ) )
{
return;
}
// make a backup
GetMutableDefault<UEditorPerProjectUserSettings>()->SaveConfig();
FString BackupEditorLayoutIni = FString::Printf(TEXT("%s_Backup.ini"), *FPaths::GetBaseFilename(GEditorLayoutIni, false));
if( COPY_Fail == IFileManager::Get().Copy(*BackupEditorLayoutIni, *GEditorLayoutIni) )
{
FMessageLog EditorErrors("EditorErrors");
if(!FPaths::FileExists(GEditorLayoutIni))
{
FFormatNamedArguments Arguments;
Arguments.Add(TEXT("FileName"), FText::FromString(GEditorLayoutIni));
EditorErrors.Warning(FText::Format(LOCTEXT("UnsuccessfulBackup_NoExist_Notification", "Unsuccessful backup! {FileName} does not exist!"), Arguments));
}
else if(IFileManager::Get().IsReadOnly(*BackupEditorLayoutIni))
{
FFormatNamedArguments Arguments;
Arguments.Add(TEXT("FileName"), FText::FromString(FPaths::ConvertRelativePathToFull(BackupEditorLayoutIni)));
EditorErrors.Warning(FText::Format(LOCTEXT("UnsuccessfulBackup_ReadOnly_Notification", "Unsuccessful backup! {FileName} is read-only!"), Arguments));
}
else
{
// We don't specifically know why it failed, this is a fallback.
FFormatNamedArguments Arguments;
Arguments.Add(TEXT("SourceFileName"), FText::FromString(GEditorLayoutIni));
Arguments.Add(TEXT("BackupFileName"), FText::FromString(FPaths::ConvertRelativePathToFull(BackupEditorLayoutIni)));
EditorErrors.Warning(FText::Format(LOCTEXT("UnsuccessfulBackup_Fallback_Notification", "Unsuccessful backup of {SourceFileName} to {BackupFileName}"), Arguments));
}
EditorErrors.Notify(LOCTEXT("BackupUnsuccessful_Title", "Backup Unsuccessful!"));
}
else
{
FNotificationInfo ErrorNotification( FText::GetEmpty() );
ErrorNotification.bFireAndForget = true;
ErrorNotification.ExpireDuration = 3.0f;
ErrorNotification.bUseThrobber = true;
ErrorNotification.Hyperlink = FSimpleDelegate::CreateStatic(&FMainFrameActionCallbacks::OpenBackupDirectory, BackupEditorLayoutIni);
ErrorNotification.HyperlinkText = LOCTEXT("SuccessfulBackup_Notification_Hyperlink", "Open Directory");
ErrorNotification.Text = LOCTEXT("SuccessfulBackup_Notification", "Backup Successful!");
ErrorNotification.Image = FEditorStyle::GetBrush(TEXT("NotificationList.SuccessImage"));
FSlateNotificationManager::Get().AddNotification(ErrorNotification);
}
// reset layout & restart Editor
FUnrealEdMisc::Get().AllowSavingLayoutOnClose(false);
FUnrealEdMisc::Get().RestartEditor(false);
}
void FMainFrameActionCallbacks::SaveLayout()
{
FGlobalTabmanager::Get()->SaveAllVisualState();
// Write the saved state's config to disk
GConfig->Flush( false, GEditorLayoutIni );
}
void FMainFrameActionCallbacks::ToggleFullscreen_Execute()
{
if ( GIsEditor && FApp::HasGameName() )
{
static TWeakPtr<SDockTab> LevelEditorTabPtr = FGlobalTabmanager::Get()->InvokeTab(FTabId("LevelEditor"));
const TSharedPtr<SWindow> LevelEditorWindow = FSlateApplication::Get().FindWidgetWindow( LevelEditorTabPtr.Pin().ToSharedRef() );
if (LevelEditorWindow->GetWindowMode() == EWindowMode::Windowed)
{
LevelEditorWindow->SetWindowMode(EWindowMode::WindowedFullscreen);
}
else
{
LevelEditorWindow->SetWindowMode(EWindowMode::Windowed);
}
}
}
bool FMainFrameActionCallbacks::FullScreen_IsChecked()
{
const TSharedPtr<SDockTab> LevelEditorTabPtr = FModuleManager::Get().GetModuleChecked<FLevelEditorModule>( "LevelEditor" ).GetLevelEditorTab();
const TSharedPtr<SWindow> LevelEditorWindow = LevelEditorTabPtr.IsValid()
? LevelEditorTabPtr->GetParentWindow()
: TSharedPtr<SWindow>();
return (LevelEditorWindow.IsValid())
? (LevelEditorWindow->GetWindowMode() != EWindowMode::Windowed)
: false;
}
bool FMainFrameActionCallbacks::CanSwitchToProject( int32 InProjectIndex )
{
if (FApp::HasGameName() && ProjectNames[InProjectIndex].StartsWith(FApp::GetGameName()))
{
return false;
}
if ( FPaths::IsProjectFilePathSet() && ProjectNames[ InProjectIndex ] == FPaths::GetProjectFilePath() )
{
return false;
}
return true;
}
bool FMainFrameActionCallbacks::IsSwitchProjectChecked( int32 InProjectIndex )
{
return CanSwitchToProject( InProjectIndex ) == false;
}
void FMainFrameActionCallbacks::Exit()
{
FSlateApplication::Get().LeaveDebuggingMode();
// Shut down the editor
// NOTE: We can't close the editor from within this stack frame as it will cause various DLLs
// (such as MainFrame) to become unloaded out from underneath the code pointer. We'll shut down
// as soon as it's safe to do so.
GEngine->DeferredCommands.Add( TEXT("CLOSE_SLATE_MAINFRAME"));
}
bool FMainFrameActionCallbacks::Undo_CanExecute()
{
return GUnrealEd->Trans->CanUndo() && FSlateApplication::Get().IsNormalExecution();
}
bool FMainFrameActionCallbacks::Redo_CanExecute()
{
return GUnrealEd->Trans->CanRedo() && FSlateApplication::Get().IsNormalExecution();
}
void FMainFrameActionCallbacks::ExecuteExecCommand( FString Command )
{
GUnrealEd->Exec( GEditor->GetEditorWorldContext(false).World(), *Command );
}
void FMainFrameActionCallbacks::OpenSlateApp_ViaModule( FName AppName, FName ModuleName )
{
FModuleManager::Get().LoadModule( ModuleName );
OpenSlateApp( AppName );
}
void FMainFrameActionCallbacks::OpenSlateApp( FName AppName )
{
FGlobalTabmanager::Get()->InvokeTab(FTabId(AppName));
}
bool FMainFrameActionCallbacks::OpenSlateApp_IsChecked( FName AppName )
{
return false;
}
void FMainFrameActionCallbacks::VisitAskAQuestionPage()
{
FString AskAQuestionURL;
if(FUnrealEdMisc::Get().GetURL( TEXT("AskAQuestionURL"), AskAQuestionURL, true ))
{
FPlatformProcess::LaunchURL( *AskAQuestionURL, NULL, NULL );
}
}
void FMainFrameActionCallbacks::VisitSearchForAnswersPage()
{
FString SearchForAnswersURL;
if(FUnrealEdMisc::Get().GetURL( TEXT("SearchForAnswersURL"), SearchForAnswersURL, true ))
{
FPlatformProcess::LaunchURL( *SearchForAnswersURL, NULL, NULL );
}
}
void FMainFrameActionCallbacks::VisitSupportWebSite()
{
FString SupportWebsiteURL;
if(FUnrealEdMisc::Get().GetURL( TEXT("SupportWebsiteURL"), SupportWebsiteURL, true ))
{
FPlatformProcess::LaunchURL( *SupportWebsiteURL, NULL, NULL );
}
}
void FMainFrameActionCallbacks::VisitEpicGamesDotCom()
{
FString EpicGamesURL;
if(FUnrealEdMisc::Get().GetURL( TEXT("EpicGamesURL"), EpicGamesURL ))
{
FPlatformProcess::LaunchURL( *EpicGamesURL, NULL, NULL );
}
}
void FMainFrameActionCallbacks::VisitWiki()
{
FString URL;
if (FUnrealEdMisc::Get().GetURL(TEXT("WikiURL"), URL))
{
FPlatformProcess::LaunchURL(*URL, NULL, NULL);
}
}
void FMainFrameActionCallbacks::VisitForums()
{
FString URL;
if (FUnrealEdMisc::Get().GetURL(TEXT("ForumsURL"), URL))
{
FPlatformProcess::LaunchURL(*URL, NULL, NULL);
}
}
void FMainFrameActionCallbacks::AboutUnrealEd_Execute()
{
const FText AboutWindowTitle = LOCTEXT( "AboutUnrealEditor", "About Unreal Editor" );
TSharedPtr<SWindow> AboutWindow =
SNew(SWindow)
.Title( AboutWindowTitle )
.ClientSize(FVector2D(600.f, 200.f))
.SupportsMaximize(false) .SupportsMinimize(false)
.SizingRule( ESizingRule::FixedSize )
[
SNew(SAboutScreen)
];
IMainFrameModule& MainFrame = FModuleManager::LoadModuleChecked<IMainFrameModule>( "MainFrame" );
TSharedPtr<SWindow> ParentWindow = MainFrame.GetParentWindow();
if ( ParentWindow.IsValid() )
{
FSlateApplication::Get().AddModalWindow(AboutWindow.ToSharedRef(), ParentWindow.ToSharedRef());
}
else
{
FSlateApplication::Get().AddWindow(AboutWindow.ToSharedRef());
}
}
void FMainFrameActionCallbacks::CreditsUnrealEd_Execute()
{
const FText CreditsWindowTitle = LOCTEXT("CreditsUnrealEditor", "Credits");
TSharedPtr<SWindow> CreditsWindow =
SNew(SWindow)
.Title(CreditsWindowTitle)
.ClientSize(FVector2D(600.f, 700.f))
.SupportsMaximize(false)
.SupportsMinimize(false)
.SizingRule(ESizingRule::FixedSize)
[
SNew(SCreditsScreen)
];
IMainFrameModule& MainFrame = FModuleManager::LoadModuleChecked<IMainFrameModule>("MainFrame");
TSharedPtr<SWindow> ParentWindow = MainFrame.GetParentWindow();
if ( ParentWindow.IsValid() )
{
FSlateApplication::Get().AddModalWindow(CreditsWindow.ToSharedRef(), ParentWindow.ToSharedRef());
}
else
{
FSlateApplication::Get().AddWindow(CreditsWindow.ToSharedRef());
}
}
void FMainFrameActionCallbacks::OpenWidgetReflector_Execute()
{
FGlobalTabmanager::Get()->InvokeTab(FTabId("WidgetReflector"));
}
/* FMainFrameActionCallbacks implementation
*****************************************************************************/
void FMainFrameActionCallbacks::AddMessageLog( const FText& Text, const FText& Detail, const FString& TutorialLink )
{
TSharedRef<FTokenizedMessage> Message = FTokenizedMessage::Create(EMessageSeverity::Error);
Message->AddToken(FTextToken::Create(Text));
Message->AddToken(FTextToken::Create(Detail));
Message->AddToken(FTutorialToken::Create(TutorialLink));
Message->AddToken(FDocumentationToken::Create(TEXT("Platforms/iOS/QuickStart/6")));
FMessageLog MessageLog("PackagingResults");
MessageLog.AddMessage(Message);
MessageLog.Open();
}
#undef LOCTEXT_NAMESPACE