2019-12-26 15:33:43 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
Copied CL# 10088684
#jira UE-80569
#jira UE-80575
#jira UE-80577
New features (they are very related to each other, so they have been integrated together):
1) UE-80569: When the user attempts to save a custom layout, we open a Slate SWidget save dialog that no longer allows them to enter the file path where the layout will be saved, but instead the Layout Name and (optionally) Description. The file name will automatically be generated from the displayed layout name.
2) UE-80575: When attempting to save a custom layout, we prevent the OS save dialog. Since the user cannot actually save a layout anywhere other than the default save location, this streamlines the workflow and minimize confusion. Instead, the Slate SWidget detailed in point 1 is used, where the user can introduce only the displayed layout name, and the file name and its directory are automatically generated (fixed directory).
3) UE-80577: After 1 and 2, it is unclear where the layout is saved. Thus, when saving a custom layout, we provide an Editor toast notifying the user of their custom layout's save location. It is analog to the one provided when a user takes a screenshot within the Editor.
In addition, the possible messages displayed to the user when the layout file was not successfully copied have also been improved (higher details and fixed some grammar typos).
Some general and additional considerations about the new Slate layout save dialog:
1) The "Save" button will be disabled when the introduced file name is empty or an error occurs (e.g., name is too long). If any error occurs, the dialog will display the error message as well, analog to "File" --> "Save current as...".
2) An Override/Cancel dialog will be displayed if the user selects a file name that matches another existing one.
3) An automatic NSLOCTEXT key and namespace fields are generated for each profile created. This is abstracted from the user, who does not need to know about this. Translations come later from a LocRes file that we generate for the engine. Thus, only the profile files that we have included in P4 might be translated.
Some potential issues / observations:
1) The export layout remains with the old OS save dialog (as it can be saved in different directories). This makes the appearance of both of them very different, but it also makes export similar to import.
#rb rex.hill
#ROBOMERGE-SOURCE: CL 10089258 in //UE4/Release-4.24/...
#ROBOMERGE-BOT: RELEASE (Release-4.24 -> Main) (v574-10069753)
[CL 10089279 by gines hidalgo in Main branch]
2019-11-08 17:44:25 -05:00
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "CoreMinimal.h"
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* It saves the input parameters that FSaveLayoutDialogUtils::CreateSaveLayoutAsDialogInStandaloneWindow needs and the output ones that it will generate.
|
|
|
|
|
*/
|
|
|
|
|
class FSaveLayoutDialogParams
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* The constructor only contains the variables that FSaveLayoutDialogUtils::CreateSaveLayoutAsDialogInStandaloneWindow will need. The rest will be overriden.
|
|
|
|
|
*/
|
|
|
|
|
FSaveLayoutDialogParams(const FString& InDefaultDirectory, const FString& InFileExtension, const TArray<FText>& LayoutNames = TArray<FText>(),
|
|
|
|
|
const TArray<FText>& LayoutDescriptions = TArray<FText>());
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The directory where the layout will be saved.
|
|
|
|
|
*/
|
|
|
|
|
const FString DefaultDirectory;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The extension of the layout file.
|
|
|
|
|
*/
|
|
|
|
|
const FString FileExtension;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Whether the user selected files (true) or cancelled/closed the window (false)
|
|
|
|
|
*/
|
|
|
|
|
bool bWereFilesSelected;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The final full file path where the layout profile should be saved
|
|
|
|
|
*/
|
|
|
|
|
TArray<FString> LayoutFilePaths;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The displayed layout name that will be visualized in Unreal. Its initial value will be used as default.
|
|
|
|
|
*/
|
|
|
|
|
TArray<FText> LayoutNames;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The displayed layout description that will be visualized in Unreal. Its initial value will be used as default.
|
|
|
|
|
*/
|
|
|
|
|
TArray<FText> LayoutDescriptions;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Some convenient UI functions regarding SWidgets for saving the layout
|
|
|
|
|
*/
|
|
|
|
|
class FSaveLayoutDialogUtils
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* Any special character (i.e., any non-alphanumeric character) will be turned into an underscore.
|
|
|
|
|
*/
|
|
|
|
|
static void SanitizeText(FString& InOutString);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* It will show a text asking whether you wanna override the existing UI Layout ini file.
|
|
|
|
|
* @param LayoutIniFileName The file path that might be overridden.
|
|
|
|
|
* @return True if the user agrees on overriding the file, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
static bool OverrideLayoutDialog(const FString& LayoutIniFileName);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Self-contained function that creates a standalone SWindow, the SSaveLayoutDialog widget, and that blocks the thread until the dialog is finished
|
|
|
|
|
* @param InSaveLayoutDialogParams The FSaveLayoutDialogParams parameters used in the construction of SSaveLayoutDialog. Looking at its values:
|
|
|
|
|
* 1) DefaultDirectory and FileExtension will only be read.
|
|
|
|
|
* 2) bWereFilesSelected and LayoutFilePaths will only be written (i.e., their initial value will be overridden).
|
|
|
|
|
* 3) LayoutNames and LayoutDescriptions will only be written, but their initial values will also be used as default.
|
|
|
|
|
*/
|
|
|
|
|
static bool CreateSaveLayoutAsDialogInStandaloneWindow(const TSharedRef<FSaveLayoutDialogParams>& InSaveLayoutDialogParams);
|
|
|
|
|
};
|