Skip to content

Commit

Permalink
Merge pull request #24 from tolgee/feature/sync-rework
Browse files Browse the repository at this point in the history
Rework sync feature (Upload, Purge, Fetch) into an unified action
  • Loading branch information
pasotee authored Apr 22, 2024
2 parents 7dac62a + 6cb4db0 commit 4807f24
Show file tree
Hide file tree
Showing 8 changed files with 517 additions and 176 deletions.
6 changes: 5 additions & 1 deletion Source/Tolgee/Public/TolgeeLocalizationSubsystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ class TOLGEE_API UTolgeeLocalizationSubsystem : public UEngineSubsystem
UFUNCTION(BlueprintCallable, Category = "Tolgee Localization")
void ManualFetch();
/**
* @brief Returns the localized dictionary used the the TolgeeTextSource
* @brief Returns true if a request to retrieve the translation from the backend server is currently ongoing
*/
bool IsFetchInprogress() const { return bFetchInProgress; }
/**
* @brief Returns the localized dictionary used the TolgeeTextSource
*/
const FLocalizedDictionary& GetLocalizedDictionary() const;

Expand Down
202 changes: 202 additions & 0 deletions Source/TolgeeEditor/Private/STolgeeSyncDialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
// Copyright (c) Tolgee 2022-2023. All Rights Reserved.

#include "STolgeeSyncDialog.h"

#include <Brushes/SlateRoundedBoxBrush.h>
#include <Styling/StyleColors.h>
#include <Widgets/Layout/SUniformGridPanel.h>

void STolgeeSyncDialog::Construct(const FArguments& InArgs, int NumToUpload, int NumToUpdate, int NumToDelete)
{
UploadNew.Title = INVTEXT("Upload new");
UploadNew.NumberOfKeys = NumToUpload;

UpdateOutdated.Title = INVTEXT("Update outdated");
UpdateOutdated.NumberOfKeys = NumToUpdate;

DeleteUnused.Title = INVTEXT("Delete unused");
DeleteUnused.NumberOfKeys = NumToDelete;

SWindow::Construct(SWindow::FArguments()
.Title(INVTEXT("Tolgee Sync"))
.SizingRule(ESizingRule::Autosized)
.SupportsMaximize(false)
.SupportsMinimize(false)
[
SNew(SBorder)
.Padding(4.f)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
MakeOperationCheckBox(UploadNew)
]

+ SVerticalBox::Slot()
[
MakeOperationCheckBox(UpdateOutdated)
]

+ SVerticalBox::Slot()
[
MakeOperationCheckBox(DeleteUnused)
]

+ SVerticalBox::Slot()
[
SNew(SSpacer)
]

+ SVerticalBox::Slot()
[
SNew(STextBlock)
.Text(this, &STolgeeSyncDialog::GetOperationsSummary)
]

+ SVerticalBox::Slot()
.HAlign(HAlign_Right)
.VAlign(VAlign_Bottom)
.Padding(8)
[
SNew(SUniformGridPanel)
.SlotPadding(FAppStyle::GetMargin("StandardDialog.SlotPadding"))
+ SUniformGridPanel::Slot(0, 0)
[
SAssignNew(RunButton, SButton)
.Text(INVTEXT("Run"))
.OnClicked(this, &STolgeeSyncDialog::OnRunClicked)
]
+ SUniformGridPanel::Slot(1, 0)
[
SNew(SButton)
.Text(INVTEXT("Cancel"))
.HAlign(HAlign_Center)
.OnClicked(this, &STolgeeSyncDialog::OnCancelClicked)
]
]
]
]);

RefreshRunButton();
}

void STolgeeSyncDialog::RefreshRunButton()
{
constexpr float InputFocusThickness = 1.0f;
static FButtonStyle BaseButton = FAppStyle::Get().GetWidgetStyle<FButtonStyle>("Button");

static FButtonStyle UploadButton = BaseButton
.SetNormal(FSlateRoundedBoxBrush(FStyleColors::Primary, 4.0f, FStyleColors::Input, InputFocusThickness))
.SetHovered(FSlateRoundedBoxBrush(FStyleColors::PrimaryHover, 4.0f, FStyleColors::Input, InputFocusThickness))
.SetPressed(FSlateRoundedBoxBrush(FStyleColors::PrimaryPress, 4.0f, FStyleColors::Input, InputFocusThickness));


static FButtonStyle DeleteButton = BaseButton
.SetNormal(FSlateRoundedBoxBrush(COLOR("#E00000FF"), 4.0f, FStyleColors::Input, InputFocusThickness))
.SetHovered(FSlateRoundedBoxBrush(COLOR("FF0F0EFF"), 4.0f, FStyleColors::Input, InputFocusThickness))
.SetPressed(FSlateRoundedBoxBrush(COLOR("a00000"), 4.0f, FStyleColors::Input, InputFocusThickness));

static FButtonStyle WarningButton = BaseButton
.SetNormal(FSlateRoundedBoxBrush(COLOR("#E07000FF"), 4.0f, FStyleColors::Input, InputFocusThickness))
.SetHovered(FSlateRoundedBoxBrush(COLOR("#FF870EFF"), 4.0f, FStyleColors::Input, InputFocusThickness))
.SetPressed(FSlateRoundedBoxBrush(COLOR("#A05000FF"), 4.0f, FStyleColors::Input, InputFocusThickness));

if (DeleteUnused.bPerform)
{
RunButton->SetEnabled(true);
RunButton->SetButtonStyle(&DeleteButton);
}
else if (UpdateOutdated.bPerform)
{
RunButton->SetEnabled(true);
RunButton->SetButtonStyle(&WarningButton);
}
else if (UploadNew.bPerform)
{
RunButton->SetEnabled(true);
RunButton->SetButtonStyle(&UploadButton);
}
else
{
RunButton->SetEnabled(false);
RunButton->SetButtonStyle(&BaseButton);
}
}

FReply STolgeeSyncDialog::OnRunClicked()
{
RequestDestroyWindow();

return FReply::Handled();
}

FReply STolgeeSyncDialog::OnCancelClicked()
{
UploadNew.bPerform = false;
UpdateOutdated.bPerform = false;
DeleteUnused.bPerform = false;

RequestDestroyWindow();

return FReply::Handled();
}

FText STolgeeSyncDialog::GetOperationsSummary() const
{
return FText::Format(INVTEXT("{0} operations will be performed"), GetNumberOfKeysAffectedByOperations());
}

int STolgeeSyncDialog::GetNumberOfKeysAffectedByOperations() const
{
int Total = 0;
if (UploadNew.bPerform)
{
Total += UploadNew.NumberOfKeys;
}
if (UpdateOutdated.bPerform)
{
Total += UpdateOutdated.NumberOfKeys;
}
if (DeleteUnused.bPerform)
{
Total += DeleteUnused.NumberOfKeys;
}

return Total;
}

TSharedRef<SCheckBox> STolgeeSyncDialog::MakeOperationCheckBox(FTolgeeOperation& Operation)
{
return SNew(SCheckBox)
.IsChecked(this, &STolgeeSyncDialog::IsOperationChecked, &Operation)
.IsEnabled(this, &STolgeeSyncDialog::IsOperationEnabled, &Operation)
.OnCheckStateChanged(this, &STolgeeSyncDialog::OnOperationStateChanged, &Operation)
[
SNew(STextBlock)
.Text(this, &STolgeeSyncDialog::GetOperationName, &Operation)
];
}

void STolgeeSyncDialog::OnOperationStateChanged(ECheckBoxState NewCheckedState, FTolgeeOperation* Operation)
{
Operation->bPerform = NewCheckedState == ECheckBoxState::Checked;

RefreshRunButton();
}

ECheckBoxState STolgeeSyncDialog::IsOperationChecked(FTolgeeOperation* Operation) const
{
return Operation->bPerform ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
}

bool STolgeeSyncDialog::IsOperationEnabled(FTolgeeOperation* Operation) const
{
return Operation->NumberOfKeys > 0;
}

FText STolgeeSyncDialog::GetOperationName(FTolgeeOperation* Operation) const
{
return FText::Format(INVTEXT("{0}({1})"), Operation->Title, Operation->NumberOfKeys);

}
93 changes: 93 additions & 0 deletions Source/TolgeeEditor/Private/STolgeeSyncDialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) Tolgee 2022-2023. All Rights Reserved.

#pragma once

/**
* @brief Represents details about a possible operation (Upload, Update, Delete)
*/
struct FTolgeeOperation
{
/**
* Name of the operation displayed to the developer
*/
FText Title;
/**
* Number of keys this operation will be affected by running this operation
*/
int NumberOfKeys = 0;
/**
* Should we perform this operation after the dialog closes?
*/
bool bPerform = false;
};

/**
* Window used to display the Sync dialog to chose what operations should be performed
*/
class STolgeeSyncDialog : public SWindow
{
public:
SLATE_BEGIN_ARGS(STolgeeSyncDialog) {}
SLATE_END_ARGS()

/**
* @brief Constructs the sync operations widget
*/
void Construct(const FArguments& InArgs, int NumToUpload, int NumToUpdate, int NumToDelete);
/**
* Refreshes the Run button style based on the operation that will be executed
*/
void RefreshRunButton();
/**
* Callback executed when the Run button is clicked
*/
FReply OnRunClicked();
/**
* Callback executed when the Cancel button is clicked
*/
FReply OnCancelClicked();
/**
* Constructs a text explaining all the operations that will be performed if the currently selected operations will be run
*/
FText GetOperationsSummary() const;
/**
* Calculates the total number of keys that will be affected if the currently selected operations will be run
*/
int GetNumberOfKeysAffectedByOperations() const;
/**
* Constructs a user-facing checkbox to enable/disable an operation
*/
TSharedRef<SCheckBox> MakeOperationCheckBox(FTolgeeOperation& Operation);
/**
* Callback executed when a new checkbox state is set for an operation
*/
void OnOperationStateChanged(ECheckBoxState NewCheckedState, FTolgeeOperation* Operation);
/**
* Callback executed to determine the state of a checkbox for an operation
*/
ECheckBoxState IsOperationChecked(FTolgeeOperation* Operation) const;
/**
* Callback executed to determine if a checkbox is enabled for an operation
*/
bool IsOperationEnabled(FTolgeeOperation* Operation) const;
/**
* Callback executed to determine a checkbox title for an operation
*/
FText GetOperationName(FTolgeeOperation* Operation) const;
/**
* Reference to the used to Run the selected operations
*/
TSharedPtr<SButton> RunButton;
/**
* State of the UploadNew operation
*/
FTolgeeOperation UploadNew;
/**
* State of the UpdateOutdated operation
*/
FTolgeeOperation UpdateOutdated;
/**
* State of the DeleteUnused operation
*/
FTolgeeOperation DeleteUnused;
};
1 change: 0 additions & 1 deletion Source/TolgeeEditor/Private/STolgeeTranslationTab.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#pragma once

#include <CoreMinimal.h>
#include <Widgets/SCompoundWidget.h>

class SWebBrowser;
Expand Down
39 changes: 3 additions & 36 deletions Source/TolgeeEditor/Private/TolgeeEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,50 +190,17 @@ void FTolgeeEditorModule::ExtendToolbar(FToolBarBuilder& Builder)
))
);

MenuBuilder.BeginSection(TEXT("KeyStatusCategory"), LOCTEXT("KeyStatusCategory", "Key Status"));

// clang-format off
const TSharedRef<STextBlock> StatusText = SNew(STextBlock)
.Text(LOCTEXT("KeyStatus", "All keys are up to date"))
.ColorAndOpacity(FSlateColor(FLinearColor::Red));
// clang-format on

MenuBuilder.AddMenuEntry(
LOCTEXT("FetchRemote", "Fetch remote"),
LOCTEXT("FetchRemoteTip", "Fetches the latest from the remote"),
FSlateIcon(),
FUIAction(FExecuteAction::CreateLambda(
[]()
{
GEngine->GetEngineSubsystem<UTolgeeLocalizationSubsystem>()->ManualFetch();
}
))
);
MenuBuilder.AddMenuEntry(
LOCTEXT("UploadMissing", "Upload missing keys"),
LOCTEXT("UploadMissingTip", "Upload local keys to Tolgee backend"),
LOCTEXT("Syncronize", "Syncronize"),
LOCTEXT("SyncronizeTip", "Syncronizes the state between local state and Tolgee backend, reconciling any differences"),
FSlateIcon(),
FUIAction(FExecuteAction::CreateLambda(
[]()
{
GEditor->GetEditorSubsystem<UTolgeeEditorIntegrationSubsystem>()->UploadMissingKeys();
GEditor->GetEditorSubsystem<UTolgeeEditorIntegrationSubsystem>()->Sync();
}
))
);
MenuBuilder.AddMenuEntry(
LOCTEXT("PurgeUnused", "Purge unused keys"),
LOCTEXT("PurgeUnusedTip", "Deleted unused keys from Tolgee backend"),
FSlateIcon(),
FUIAction(FExecuteAction::CreateLambda(
[]()
{
GEditor->GetEditorSubsystem<UTolgeeEditorIntegrationSubsystem>()->PurgeUnusedKeys();
}
))
);


MenuBuilder.EndSection();

return MenuBuilder.MakeWidget();
}
Expand Down
Loading

0 comments on commit 4807f24

Please sign in to comment.