Files
UnrealEngineUWP/Engine/Source/Editor/MainFrame/Private/Frame/MainFrameActions.cpp
Josh Adams 1b3364e137 Copying //UE4/Dev-Platform to //UE4/Dev-Main (Source: //UE4/Dev-Platform @ 3173994)
#lockdown Nick.Penwarden

==========================
MAJOR FEATURES + CHANGES
==========================

Change 3118934 on 2016/09/08 by Jeff.Campeau

	Shader compression setting based on target platform instead of cooking host platform.

	#jira UE-35753

Change 3150366 on 2016/10/04 by Nick.Shin

	emscripten SDK 1.36.11

	windows and mac binaries will be checked in separately

	#jira UE-36562  -  //UE4/Main: Compile UE4Game HTML5 completed with errors: 2 errors

Change 3150367 on 2016/10/04 by Daniel.Lamb

	Removed caching of cooked platform data from postload.
	#test cook paragon

Change 3150368 on 2016/10/04 by Daniel.Lamb

	Added new setting to reserve the maximum amount of memory to leave free for the cooker..

Change 3151091 on 2016/10/04 by Nick.Shin

	upgrade emsdk toolchain to "tag-1.36.11"

	(along with updates to make scripts)

	#jira UEPLAT-890 - HTML5 Multithreading
	#jira UE-36562  -  //UE4/Main: Compile UE4Game HTML5 completed with errors: 2 errors

Change 3151205 on 2016/10/04 by Daniel.Lamb

	HasShaderJobs now includes the PendingFinalizedShadermaps in it's check
	#test cook paragon.

Change 3151501 on 2016/10/05 by Luke.Thatcher

	[PLATFORM] [PS4] [!] Fix memory usage in PS4 crash handler server.

	 - The ORTMAPI com object implements a Dispose method which we we're calling, so the object was leaked until it eventually gets GC'd.
	 - Whilst that object is alive, the orbis-debugserver-x64.exe process stays alive, using up to 2GB memory per instance.

	 - Also limited the server to processing a single crash dump at once, via a task queue.

Change 3151608 on 2016/10/05 by Nick.Shin

	fix CIS build warnings and errors

	this is for HTML5 platform

Change 3151851 on 2016/10/05 by Michael.Trepka

	Added DesktopRect and WorkArea to FMonitorInfo for desktop platforms and used that to fix an issue in SceneViewport where windowed fullscreen mode would be forced to primary monitor and incorrectly positioned on desktops where a taskbar/dock/etc. was on the left

	#jira FORT-30638

Change 3152085 on 2016/10/05 by Josh.Adams

	- Fixing some Wolf Launcher things (icon, string)

Change 3152451 on 2016/10/05 by Daniel.Lamb

	Enabled logging to help debug shader compiler issue.
	#test Cook Paragon.

Change 3152880 on 2016/10/05 by Dmitry.Rekman

	Linux: add support for new multiarch toolchain.

	- Redoing the change as submitted to Dev-Mobile.

Change 3152957 on 2016/10/05 by Dmitry.Rekman

	Linux: fix crosstoolchain for non-AutoSDKs case.

	- Redoing the fix for UE-36899 from Dev-Mobile.

Change 3153109 on 2016/10/06 by Keith.Judge

	Remove D3D11_RESOURCE_MISC_SHARED from XB1 D3D11.x RHI as it is invalid.

Change 3153176 on 2016/10/06 by Keith.Judge

	Xbox One - Disable engine analytics on XB1 shipping games, as per XRs. Verified http requests from devkit with Fiddler.

Change 3153213 on 2016/10/06 by Keith.Judge

	Xbox One - Plug small memory leak in the movie player.

Change 3153258 on 2016/10/06 by Josh.Adams

	- Moved Wolf OSS to proper location for Online plugins

Change 3153450 on 2016/10/06 by Josh.Adams

	wolf net driver class stub

Change 3153451 on 2016/10/06 by Josh.Adams

	- Fixed more Wolf OSS errors without special sdk

Change 3153471 on 2016/10/06 by Dmitry.Rekman

	Linux: fix always rebuilding FixDeps.

Change 3153472 on 2016/10/06 by Josh.Adams

	- Deleting some old test files

Change 3153535 on 2016/10/06 by Josh.Adams

	- And... fixed some build errors again with the special sdk

Change 3153819 on 2016/10/06 by Daniel.Lamb

	Remove some dead code in the cook on the fly server.
	#test Cook QAGame

Change 3154050 on 2016/10/06 by Dmitry.Rekman

	Linux: remove some of the clang 3.9.0 warnings.

	- Add missing destructors.
	- Deal with defined() being undefined in a #define.
	- Prevent casting nullptr to reference (or suppress that warning for third party code).
	- Case sensitivity fixes.
	- Make deoptimization work properly.

	- Code still crashes when compiling some of the editor targets.

Change 3154071 on 2016/10/06 by Josh.Adams

	- Fixed an issue with Wolf shader compiler optimizing out global array
	- Fixed Windows display internal thing

Change 3154567 on 2016/10/07 by Luke.Thatcher

	[PLATFORM] [PS4] [!] Hack fix for PS4 crash handler site leaking sony debug server processes.
	 - Find and kill the process after each task

Change 3154570 on 2016/10/07 by Keith.Judge

	Fix crash when run with -nolive. Unititialized member fix.

Change 3154572 on 2016/10/07 by Keith.Judge

	Xbox One - Small optimization I did a while ago for Paragon and forgot to submit. Removed the SRV dynamic/static distinction in the state cache and calling code, as it makes no difference since fast semantics.

Change 3154656 on 2016/10/07 by Dmitry.Rekman

	Linux: make Test configuration drop core by default.

Change 3154789 on 2016/10/07 by Dmitry.Rekman

	Linux: remove multiple instances of target platform device.

Change 3154957 on 2016/10/07 by Joe.Graf

	Changed additional plugin directories for project descriptors to be absolute in memory and path relative on disk

Change 3155298 on 2016/10/07 by Dmitry.Rekman

	Fix CIS (LinuxTargetDevice not linking).

Change 3155684 on 2016/10/07 by Josh.Adams

	- Added -PulseC option for Quickmatch

Change 3155691 on 2016/10/07 by Josh.Adams

	- New Wolf NetDriver for P2P sockets. Not working yet
	- OSS is _not_ currently usable, for reference

Change 3155750 on 2016/10/07 by Dmitry.Rekman

	Linux: fix UT server build (UE-37042).

Change 3156816 on 2016/10/10 by Josh.Adams

	- Fixed compile errors wihtout extra SDK bits

Change 3156872 on 2016/10/10 by Keith.Judge

	Xbox One - Fix corrupted screenshots. Needed a GPU/CPU sync point, which legacy D3D11.x used to do for us, but now we have to do manually.

	#jira UE-37038

Change 3156936 on 2016/10/10 by Josh.Adams

	- Backed out changes from files that got pulled into a changelist by mistake

Change 3157602 on 2016/10/10 by Josh.Adams

	- FIxed Wolf crash on level quit (at least in ShooterGame)

Change 3157676 on 2016/10/10 by Josh.Adams

	- Fixed Wolf audio playback in latest SDK

Change 3158544 on 2016/10/11 by Josh.Adams

	- Disabled one of the Wolf file mount points in Debug builds due to SDK bug

Change 3158603 on 2016/10/11 by Josh.Adams

	- FIxed type in non-Debug

Change 3159257 on 2016/10/11 by Dmitry.Rekman

	Linux: case-sensitive fixes.

Change 3159537 on 2016/10/12 by Luke.Thatcher

	[PLATFORM] [PS4] [!] Fix leaking orbis-dbgserver-x64 processes in PS4 crash handler.
	 - We needed to call Marshal.ReleaseComObject on the CoreFileAPI object to shut down the child processes.
	 - Disabled the kill process hack.

	[!] Also fixed "Unknown" usernames in PS4 crash dumps.
	 - Sony had changed the format of the PS4 settings file in system software 4.008.071.

	[!] Fixed exception getting modules from crash dump when symbols have not been loaded.
	 - Just skipping this step now, as it was only used for logging.

Change 3159581 on 2016/10/12 by Joe.Conley

	Wolf support for TPri_Lowest was missing, so I added that and the corresponding WolfThreadPriority_Lowest

Change 3159749 on 2016/10/12 by Luke.Thatcher

	[PLATFORM] [PS4] [~] Re-enable kill process hack in PS4 crash server. The ReleaseComObject fix hasn't solved the leaking processes on the server.

Change 3160336 on 2016/10/12 by Daniel.Lamb

	Fix for skip editor content flag being passed throught o UAT.
	#jira UE-37223

Change 3160341 on 2016/10/12 by Dmitry.Rekman

	Linux: fixes for Fortnite and Orion editors.

	- Also, again disable XGE because clang 3.9.0-based toolchain crashes when compiling those with XGE.

Change 3160473 on 2016/10/12 by Nick.Shin

	remove old emsdk

Change 3160528 on 2016/10/12 by Michael.Trepka

	Copy of CL 3160314 from //Fortnite/Main

	Fixed incorrect rect initialization in Mac GetDisplayMetrics

Change 3160591 on 2016/10/12 by Josh.Adams

	- Fixed wolf coimpiling without stats
	#jira UE-37230

Change 3160866 on 2016/10/12 by Dmitry.Rekman

	OpenGL: fix swapped arguments.

	- Cengiz noticed this while working on one of bugs.

Change 3160978 on 2016/10/12 by Josh.Adams

	- Fixed issue with running out of Wolf audio pools on large games

Change 3160979 on 2016/10/12 by Josh.Adams

	- Enabled Curl HTTP on Wolf, along with basic SSL (no local cert importing yet)

Change 3161025 on 2016/10/12 by Dmitry.Rekman

	Disable poison proxy.

	- Malloc::GetAllocationSize() may not account for alignment for mallocs like Binned and Binned2, resulting in a memory stomp.

Change 3161034 on 2016/10/12 by Josh.Adams

	-Wolf Http changes - load .pem files if they exist (although they aren't being staged automatically yet)
	- Added network pause to make sure its ready before we Http

Change 3161046 on 2016/10/12 by Dmitry.Rekman

	TestPAL: adding a test for Malloc::GetAllocationSize().

Change 3161212 on 2016/10/13 by Dan.Mahashin

	- Upgraded to new NXCP API. Confirmed to run ok with SunTemple on 0.11.2 SDK.

Change 3161624 on 2016/10/13 by Josh.Adams

	- Fixed MAX_PATH usage, should be PLATFORM_MAX_FILEPATH_LENGTH

Change 3161639 on 2016/10/13 by Josh.Adams

	- Added curl to main Wolf build since now it's used not just with OSS

Change 3161737 on 2016/10/13 by Josh.Adams

	- Added support for staging .pem files for SSL peer verification

Change 3161923 on 2016/10/13 by Dmitry.Rekman

	Linux: provide choice between RTLD_GLOBAL/LOCAL when opening DSOs (UE-36716).

	- By default, Unreal modules will be opened with RTLD_LOCAL (so the hot reload has a chance to work).
	- However, if "ue4_module_options" symbol is exported (a string with comma-separated options), and "linux_global_symbols" is present in that string, RTLD_LAZY will be used.
	- DSOs that don't have either ue4_module_options nor are recognized as UE4 modules will be loaded RTLD_GLOBAL.

	- PR #2823 by 20tab.

Change 3163532 on 2016/10/14 by Michael.Trepka

	Copy of CL 3162466

	By default, do not compile Mac OpenGL and Metal SM4 shaders while cooking

	#jira UE-37088

Change 3163550 on 2016/10/14 by Josh.Stoddard

	Fix key event processing during movies using FDefaultGameMoviePlayer
	#jira UE-37294

Change 3163687 on 2016/10/14 by Josh.Adams

	- Added a workaround for Wolf crashing inside vswprintf with %p

Change 3163693 on 2016/10/14 by Josh.Adams

	- Added a delegate for getting extra on-screen messages (like the Shaders to compile, etc).

Change 3163725 on 2016/10/14 by Josh.Adams

	- Added high level Wolf network transition functions for Wolf

Change 3163745 on 2016/10/14 by Josh.Adams

	- Wolf OSS changes for new high level networking logic, cleaned up includes, added on screen messages with status

Change 3164455 on 2016/10/17 by Josh.Adams

	- SOmehow a file wasn't checked out, but writable. Checking in now

Change 3164630 on 2016/10/17 by Michael.Trepka

	Copy of CL 3162062

	Replaced FWindowsCursor hack for warping the mouse cursor to the center of the viewport with a better fix for the original problem (users being able to resize the window while the cursor is hidden and the mouse controls the camera). This change removes round window corners in borderless window mode and disables window resizing when the cursor is hidden.

Change 3164975 on 2016/10/17 by Joe.Graf

	Changed the New Plugin Wizard to only show plugin types available for that project type (content only or code)

Change 3165213 on 2016/10/17 by Josh.Adams

	- Fixed some perf testing by disabling the startup benchmark for UT on non-desktop platforms

Change 3165576 on 2016/10/18 by Dan.Mahashin

	- Fix broken colors in QAGame UE-37197: depth write cannot work without depth test being enabled.

Change 3165809 on 2016/10/18 by Josh.Stoddard

	Enforce UMaterialExpressionActorPositionWS dependency on primitive uniform buffer #jira UE-37425 #rb chris.bunner

Change 3165948 on 2016/10/18 by Owen.Stupka

	Fix exception when creating an exception to say we don't have a 32-bit VC compiler installed.

Change 3166330 on 2016/10/18 by Dmitry.Rekman

	Linux: disable XGE on Windows (UE-37446).

	- XGE does not seem to handle new clang 3.9.0 toolchain well, with very reproducible crashes.

Change 3166456 on 2016/10/18 by Dmitry.Rekman

	Fix build breakage with clang 3.8.1.

	- always_inline was still applied to debug builds and as such was ignored.

Change 3166457 on 2016/10/18 by Chris.Babcock

	Add missing MultiviewOVR functions for Android deferred
	#jira UE-37401
	#ue4
	#android

Change 3166469 on 2016/10/18 by Dmitry.Rekman

	Linux: make target platform modules independent (UE-37370).

	- Module load order is different for target platform modules between UE4Editor and UE4Editor-Cmd, and dependent modules may end up being loaded first.

Change 3166755 on 2016/10/18 by Joe.Barnes

	[UE-35552] Enable PLATFORM_ENABLE_VECTORINTRINSICS_NEON on Wolf.

Change 3166757 on 2016/10/18 by Joe.Barnes

	[UE-35552] Optimized platform specific implementation of some common math functions.

Change 3166761 on 2016/10/18 by Joe.Barnes

	Use new 64 bit Power of 2 function.

Change 3167865 on 2016/10/19 by Josh.Adams

	- Wolf P2P/NAT stuff working!
	- Minor Wolf net mode fixes

Change 3167869 on 2016/10/19 by Josh.Adams

	- Moved  a blocking net call for Wolf Http into a thread

Change 3168100 on 2016/10/19 by Joe.Barnes

	#include <NVN/nvn_CppMethods.h>. Fixes a compiler problem with some inline functions not being available during compile phase.

Change 3168101 on 2016/10/19 by Joe.Barnes

	Exposed a function to create a platform based filename

Change 3168141 on 2016/10/19 by Dmitry.Rekman

	TestPAL: better test for allocation sizes.

Change 3168144 on 2016/10/19 by Dmitry.Rekman

	Fix for FMallocBinned::GetAllocationSize() for aligned allocations.

	Redoing SteveR's fix in 4.13/4.14.

	Copied from CL# 3165739.

	#jira UE-37249
	#jira UE-37243

Change 3168213 on 2016/10/19 by Josh.Adams

	- Wolf OSS function rename

Change 3168313 on 2016/10/19 by Josh.Adams

	Rename/move file(s)

Change 3168691 on 2016/10/20 by Dan.Mahashin

	- Fixed application teardown and memory leak:
	- NVNCommandContext was failing to free the last frame resources on shutdown (resources were thought to be in use because never actually processed by GPU)
	- NVNCommandContext was leaking a FSyncedFrameDestruction at each frame
	- NVNTempBlockManager was not freeing all of its temp blocks upon shutdown

Change 3168986 on 2016/10/20 by Josh.Adams

	- Removed some log spam

Change 3168990 on 2016/10/20 by Josh.Adams

	- Removed dead code

Change 3169091 on 2016/10/20 by Josh.Adams

	Moved UT's OnlineGameplayFramework plugin into NotForLicensees so licensees don't need Mcp

Change 3169262 on 2016/10/20 by Josh.Adams

	- Updated the OnScreenMessages to use a TMap of severity to message, so we can have multiple colors, etc
	- Also has some fixes needed from a merge down (oops)

Change 3169363 on 2016/10/20 by Dmitry.Rekman

	TestPAL: final synth test for stomp.

Change 3169436 on 2016/10/20 by Michael.Trepka

	Change the minimum supported macOS version setting in Info.plists to 10.11.6

Change 3169510 on 2016/10/20 by Dmitry.Rekman

	TestPAL: added stomp test with poison proxy.

Change 3169972 on 2016/10/20 by Dmitry.Rekman

	Re-enable PoisonProxy.

Change 3170000 on 2016/10/20 by Dmitry.Rekman

	Linux: minor code cleanup.

Change 3170400 on 2016/10/21 by Josh.Adams

	- Added a comment with current supported SDK in UEBuildWolf.cs

Change 3170929 on 2016/10/21 by Josh.Adams

	- Added generic Elf symbol parser to MemoryProfiler2 app. It uses nm.exe, and any platform that uses it would need to subclass it (which Wolf now does)

Change 3171266 on 2016/10/21 by Dmitry.Rekman

	Linux: fix Setup.sh on Ubuntu 16.10 (UE-37621)

Change 3172847 on 2016/10/24 by Josh.Adams

	- Added a null Material check to the recent change to UMaterialExpressionActorPositionWS
	#jira UE-37730

Change 3173535 on 2016/10/25 by Josh.Adams

	- Helping clean up some misplaced files, since obliterate caused problems with BulletProofSync

[CL 3174242 by Josh Adams in Main branch]
2016-10-25 18:15:13 -04:00

1086 lines
44 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 | EModifierKey::Shift, 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, "Support...", "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(" -SkipCookingEditorContent");
}
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);*/
SaveAll();
// 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;
}
UProjectPackagingSettings* PackagingSettings = Cast<UProjectPackagingSettings>(UProjectPackagingSettings::StaticClass()->GetDefaultObject());
{
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 main frame
bool UnrecoverableError = false;
// 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
);
UnrecoverableError = true;
}
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
);
UnrecoverableError = true;
}
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
);
UnrecoverableError = true;
}
if ((Result & ETargetPlatformReadyStatus::ManifestNotFound) != 0)
{
AddMessageLog(
LOCTEXT("ManifestNotFound", "Manifest not found."),
LOCTEXT("ManifestNotFoundMessageDetail", "The generated application manifest could not be found."),
NotInstalledTutorialLink
);
UnrecoverableError = true;
}
if ((Result & ETargetPlatformReadyStatus::RemoveServerNameEmpty) != 0 && (bProjectHasCode || (!FApp::GetEngineIsPromotedBuild() && !FApp::IsEngineInstalled()) || PackagingSettings->bNativizeBlueprintAssets))
{
AddMessageLog(
LOCTEXT("RemoveServerNameNotFound", "Remote compiling requires a server name. "),
LOCTEXT("RemoveServerNameNotFoundDetail", "Please specify one in the Remote Server Name settings field."),
NotInstalledTutorialLink
);
UnrecoverableError = true;
}
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;
}
// 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