Files
UnrealEngineUWP/Engine/Source/Developer/SharedSettingsWidgets/Private/SSettingsEditorCheckoutNotice.cpp
Dan Hertzka 1ce19a5ffa Full rename of the Slate "active tick" system to "active timer"
[CL 2394301 by Dan Hertzka in Main branch]
2014-12-19 17:44:49 -05:00

275 lines
8.8 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "SharedSettingsWidgetsPrivatePCH.h"
#include "EditorStyle.h"
#include "SSettingsEditorCheckoutNotice.h"
#include "ISourceControlModule.h"
#include "SWidgetSwitcher.h"
#include "SThrobber.h"
#include "SNotificationList.h"
#include "NotificationManager.h"
#define LOCTEXT_NAMESPACE "SSettingsEditorCheckoutNotice"
/* SSettingsEditorCheckoutNotice interface
*****************************************************************************/
void SSettingsEditorCheckoutNotice::Construct( const FArguments& InArgs )
{
OnFileProbablyModifiedExternally = InArgs._OnFileProbablyModifiedExternally;
ConfigFilePath = InArgs._ConfigFilePath;
LastDefaultConfigCheckOutTime = 0.0;
DefaultConfigCheckOutNeeded = false;
DefaultConfigQueryInProgress = true;
const int Padding = 8;
// default configuration notice
ChildSlot
[
SNew(SBorder)
.BorderImage(FEditorStyle::GetBrush("SettingsEditor.CheckoutWarningBorder"))
.BorderBackgroundColor(this, &SSettingsEditorCheckoutNotice::HandleBorderBackgroundColor)
[
SNew(SWidgetSwitcher)
.WidgetIndex(this, &SSettingsEditorCheckoutNotice::HandleNoticeSwitcherWidgetIndex)
// Locked slot
+ SWidgetSwitcher::Slot()
[
SNew(SHorizontalBox)
// Locked icon
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(Padding)
.VAlign(VAlign_Center)
[
SNew(SImage)
.Image(FEditorStyle::GetBrush("GenericLock"))
]
// Locked notice
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
.Padding(FMargin(0.f, Padding, Padding, Padding))
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(this, &SSettingsEditorCheckoutNotice::HandleLockedStatusText)
.Font(FEditorStyle::GetFontStyle("PropertyWindow.NormalFont"))
.ShadowColorAndOpacity(FLinearColor::Black.CopyWithNewOpacity(0.3f))
.ShadowOffset(FVector2D::UnitVector)
]
// Check out button
+ SHorizontalBox::Slot()
.Padding(FMargin(0.f, 0.f, Padding, 0.f))
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(SButton)
.OnClicked(this, &SSettingsEditorCheckoutNotice::HandleCheckOutButtonClicked)
.Text(this, &SSettingsEditorCheckoutNotice::HandleCheckOutButtonText)
.ToolTipText(this, &SSettingsEditorCheckoutNotice::HandleCheckOutButtonToolTip)
.Visibility(this, &SSettingsEditorCheckoutNotice::HandleCheckOutButtonVisibility)
]
// Source control status throbber
+ SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
.Padding(0.0f, 1.0f)
[
SNew(SThrobber)
.Visibility(this, &SSettingsEditorCheckoutNotice::HandleThrobberVisibility)
]
]
// Unlocked slot
+ SWidgetSwitcher::Slot()
[
SNew(SHorizontalBox)
// Unlocked icon
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(Padding)
.VAlign(VAlign_Center)
[
SNew(SImage)
.Image(FEditorStyle::GetBrush("GenericUnlock"))
]
// Unlocked notice
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(FMargin(0.f, Padding, Padding, Padding))
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Font(FEditorStyle::GetFontStyle("PropertyWindow.NormalFont"))
.Text(this, &SSettingsEditorCheckoutNotice::HandleUnlockedStatusText)
]
]
]
];
}
/* SSettingsEditorCheckoutNotice callbacks
*****************************************************************************/
FReply SSettingsEditorCheckoutNotice::HandleCheckOutButtonClicked()
{
FString TargetFilePath = ConfigFilePath.Get();
if (ISourceControlModule::Get().IsEnabled())
{
FText ErrorMessage;
if (!SourceControlHelpers::CheckoutOrMarkForAdd(TargetFilePath, FText::FromString(TargetFilePath), NULL, ErrorMessage))
{
FNotificationInfo Info(ErrorMessage);
Info.ExpireDuration = 3.0f;
FSlateNotificationManager::Get().AddNotification(Info);
}
}
else
{
if (!FPlatformFileManager::Get().GetPlatformFile().SetReadOnly(*TargetFilePath, false))
{
FText NotificationErrorText = FText::Format(LOCTEXT("FailedToMakeWritable", "Could not make {0} writable."), FText::FromString(TargetFilePath));
FNotificationInfo Info(NotificationErrorText);
Info.ExpireDuration = 3.0f;
FSlateNotificationManager::Get().AddNotification(Info);
}
}
return FReply::Handled();
}
FText SSettingsEditorCheckoutNotice::HandleCheckOutButtonText( ) const
{
if (ISourceControlModule::Get().IsEnabled() && ISourceControlModule::Get().GetProvider().IsAvailable())
{
return LOCTEXT("CheckOutFile", "Check Out File");
}
return LOCTEXT("MakeWritable", "Make Writable");
}
FText SSettingsEditorCheckoutNotice::HandleCheckOutButtonToolTip( ) const
{
if (ISourceControlModule::Get().IsEnabled() && ISourceControlModule::Get().GetProvider().IsAvailable())
{
return LOCTEXT("CheckOutFileTooltip", "Check out the default configuration file that holds these settings.");
}
return LOCTEXT("MakeWritableTooltip", "Make the default configuration file that holds these settings writable.");
}
EVisibility SSettingsEditorCheckoutNotice::HandleCheckOutButtonVisibility( ) const
{
if (ISourceControlModule::Get().IsEnabled() && ISourceControlModule::Get().GetProvider().IsAvailable())
{
return !DefaultConfigQueryInProgress ? EVisibility::Visible : EVisibility::Hidden;
}
return EVisibility::Hidden;
}
FText SSettingsEditorCheckoutNotice::HandleLockedStatusText() const
{
FText ConfigFilename = FText::FromString(FPaths::GetCleanFilename(ConfigFilePath.Get()));
if (DefaultConfigQueryInProgress)
{
return FText::Format(LOCTEXT("DefaultSettingsNotice_Source", "These settings are saved in {0}. Checking file state..."), ConfigFilename);
}
return FText::Format(ISourceControlModule::Get().IsEnabled() ?
LOCTEXT("DefaultSettingsNotice_WithSourceControl", "These settings are saved in {0}, which is currently NOT checked out.") :
LOCTEXT("DefaultSettingsNotice_Source", "These settings are saved in {0}, which is currently NOT writable."), ConfigFilename);
}
FText SSettingsEditorCheckoutNotice::HandleUnlockedStatusText() const
{
FText ConfigFilename = FText::FromString(FPaths::GetCleanFilename(ConfigFilePath.Get()));
return FText::Format(ISourceControlModule::Get().IsEnabled() ?
LOCTEXT("DefaultSettingsNotice_CheckedOut", "These settings are saved in {0}, which is currently checked out.") :
LOCTEXT("DefaultSettingsNotice_Writable", "These settings are saved in {0}, which is currently writable."), ConfigFilename);
}
EVisibility SSettingsEditorCheckoutNotice::HandleThrobberVisibility() const
{
if(ISourceControlModule::Get().IsEnabled())
{
return DefaultConfigQueryInProgress ? EVisibility::Visible : EVisibility::Collapsed;
}
return EVisibility::Collapsed;
}
FSlateColor SSettingsEditorCheckoutNotice::HandleBorderBackgroundColor() const
{
static FColor Orange(166, 137, 0);
const FLinearColor FinalColor = (IsUnlocked() || DefaultConfigQueryInProgress) ? FColor(60, 60, 60) : Orange;
return FinalColor;
}
void SSettingsEditorCheckoutNotice::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime )
{
// cache selected settings object's configuration file state (purposely not in an active timer to make sure it appears while the user is active)
if (InCurrentTime - LastDefaultConfigCheckOutTime >= 1.0f)
{
bool NewCheckOutNeeded = false;
DefaultConfigQueryInProgress = true;
FString CachedConfigFileName = ConfigFilePath.Get();
if (!CachedConfigFileName.IsEmpty())
{
if (ISourceControlModule::Get().IsEnabled())
{
// note: calling QueueStatusUpdate often does not spam status updates as an internal timer prevents this
ISourceControlModule::Get().QueueStatusUpdate(CachedConfigFileName);
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(CachedConfigFileName, EStateCacheUsage::Use);
NewCheckOutNeeded = SourceControlState.IsValid() && SourceControlState->CanCheckout();
DefaultConfigQueryInProgress = SourceControlState.IsValid() && SourceControlState->IsUnknown();
}
else
{
NewCheckOutNeeded = (FPaths::FileExists(CachedConfigFileName) && IFileManager::Get().IsReadOnly(*CachedConfigFileName));
DefaultConfigQueryInProgress = false;
}
// file has been checked in or reverted
if ((NewCheckOutNeeded == true) && (DefaultConfigCheckOutNeeded == false))
{
OnFileProbablyModifiedExternally.ExecuteIfBound();
}
}
DefaultConfigCheckOutNeeded = NewCheckOutNeeded;
LastDefaultConfigCheckOutTime = InCurrentTime;
}
}
bool SSettingsEditorCheckoutNotice::IsUnlocked() const
{
return !DefaultConfigCheckOutNeeded && !DefaultConfigQueryInProgress;
}
#undef LOCTEXT_NAMESPACE