Skip to content

Commit

Permalink
Merge pull request #107 from PlasticSCM/1004409-view-locks-window
Browse files Browse the repository at this point in the history
Add a new View Locks window similar to the recent View Branches
  • Loading branch information
juliomaqueda committed Feb 6, 2024
2 parents 15d87f9 + 32ea377 commit 5773601
Show file tree
Hide file tree
Showing 35 changed files with 1,621 additions and 102 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ Warning when trying to modify an asset that has been modified in another branch:

#### Branches

The plugin now offers full support for branches, including the ability to create, switch to and merge branches from within the Unreal Editor,
The plugin now offers full support for branches, with a new window to list and filter them, and the ability to create, switch to and merge branches from within the Unreal Editor,
reloading assets and the current level as appropriate.

To open it, use the "View Branches" menu item in the Revision Control menu, or click on the name of the current branch in the status bar.
Expand All @@ -433,6 +433,13 @@ Deleting the selected branches:

[Meet Smart Locks, a new way to reduce merge conflicts with Unity Version Control](https://blog.unity.com/engine-platform/unity-version-control-smart-locks)

The plugin now offers full support for Smart Locks, with a new window to list and filter them, and the ability to release or remove them selectively.

To open it, use the "View Locks" menu item in the Revision Control menu.

View Locks window:
![View Locks window](Screenshots/UEPlasticPlugin-Locks-Menu.png)

Smart Locks administrator context menu to configure lock rules or unlock an asset:
![Smart Locks admin context menu](Screenshots/UEPlasticPlugin-SmartLocks-Menu.png)

Expand Down
Binary file modified Screenshots/UE5PlasticPlugin-RevisionControlMenu.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/UEPlasticPlugin-Locks-Menu.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Source/PlasticSourceControl/Private/PackageUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static UWorld* GetCurrentWorld()
return nullptr;
}

TArray<FString> AssetDateToFileNames(const TArray<FAssetData>& InAssetObjectPaths)
TArray<FString> AssetDataToFileNames(const TArray<FAssetData>& InAssetObjectPaths)
{
TArray<FString> FileNames;
FileNames.Reserve(InAssetObjectPaths.Num());
Expand Down
2 changes: 1 addition & 1 deletion Source/PlasticSourceControl/Private/PackageUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace PackageUtils
{
TArray<FString> AssetDateToFileNames(const TArray<FAssetData>& InAssetObjectPaths);
TArray<FString> AssetDataToFileNames(const TArray<FAssetData>& InAssetObjectPaths);

bool SaveDirtyPackages();
TArray<FString> ListAllPackages();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@
class FPlasticSourceControlBranch
{
public:
FPlasticSourceControlBranch() = default;
FPlasticSourceControlBranch(const FString& InName, const FString& InRepository, const FString& InCreatedBy, const FDateTime& InDate, const FString& InComment)
: Name(InName)
, Repository(InRepository)
, CreatedBy(InCreatedBy)
, Date(InDate)
, Comment(InComment)
{}
FString Name;
FString Repository;
FString CreatedBy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@
#include "PlasticSourceControlStyle.h"
#include "SPlasticSourceControlBranchesWidget.h"

#define LOCTEXT_NAMESPACE "PlasticSourceControlWindow"
#define LOCTEXT_NAMESPACE "PlasticSourceControlBranchesWindow"

static const FName PlasticSourceControlWindowTabName("PlasticSourceControlWindow");
static const FName PlasticSourceControlBranchesWindowTabName("PlasticSourceControlBranchesWindow");

void FPlasticSourceControlBranchesWindow::Register()
{
FPlasticSourceControlStyle::Initialize();
FPlasticSourceControlStyle::ReloadTextures();

FGlobalTabmanager::Get()->RegisterNomadTabSpawner(PlasticSourceControlWindowTabName, FOnSpawnTab::CreateRaw(this, &FPlasticSourceControlBranchesWindow::OnSpawnTab))
.SetDisplayName(LOCTEXT("PlasticSourceControlWindowTabTitle", "View Branches"))
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(PlasticSourceControlBranchesWindowTabName, FOnSpawnTab::CreateRaw(this, &FPlasticSourceControlBranchesWindow::OnSpawnTab))
.SetDisplayName(LOCTEXT("PlasticSourceControlBranchesWindowTabTitle", "View Branches"))
.SetMenuType(ETabSpawnerMenuType::Hidden)
.SetIcon(FSlateIcon(FPlasticSourceControlStyle::Get().GetStyleSetName(), "PlasticSourceControl.PluginIcon.Small"));
}

void FPlasticSourceControlBranchesWindow::Unregister()
{
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(PlasticSourceControlWindowTabName);
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(PlasticSourceControlBranchesWindowTabName);

FPlasticSourceControlStyle::Shutdown();
}
Expand All @@ -40,7 +40,7 @@ TSharedRef<SDockTab> FPlasticSourceControlBranchesWindow::OnSpawnTab(const FSpaw

void FPlasticSourceControlBranchesWindow::OpenTab()
{
FGlobalTabmanager::Get()->TryInvokeTab(PlasticSourceControlWindowTabName);
FGlobalTabmanager::Get()->TryInvokeTab(PlasticSourceControlBranchesWindowTabName);
}

TSharedPtr<SWidget> FPlasticSourceControlBranchesWindow::CreateBranchesWidget()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#if ENGINE_MAJOR_VERSION == 5

#include "ISourceControlChangelistState.h"
#include "ISourceControlState.h"

#include "PlasticSourceControlChangelist.h"

Expand Down
32 changes: 32 additions & 0 deletions Source/PlasticSourceControl/Private/PlasticSourceControlLock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2024 Unity Technologies

#pragma once

#include "CoreMinimal.h"

#include "ISourceControlState.h"

class FPlasticSourceControlLock
{
public:
int32 ItemId = ISourceControlState::INVALID_REVISION;
FString Path;
FString Status;
bool bIsLocked = false;
FDateTime Date;
FString Owner;
FString DestinationBranch;
FString Branch;
FString Workspace;

void PopulateSearchString(TArray<FString>& OutStrings) const
{
OutStrings.Emplace(Path);
OutStrings.Emplace(Owner);
OutStrings.Emplace(Branch);
OutStrings.Emplace(Workspace);
}
};

typedef TSharedRef<class FPlasticSourceControlLock, ESPMode::ThreadSafe> FPlasticSourceControlLockRef;
typedef TSharedPtr<class FPlasticSourceControlLock, ESPMode::ThreadSafe> FPlasticSourceControlLockPtr;
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2024 Unity Technologies

#include "PlasticSourceControlLocksWindow.h"

#include "Widgets/Docking/SDockTab.h"

#include "PlasticSourceControlStyle.h"
#include "SPlasticSourceControlLocksWidget.h"

#define LOCTEXT_NAMESPACE "PlasticSourceControlLocksWindow"

static const FName PlasticSourceControlLocksWindowTabName("PlasticSourceControlLocksWindow");

void FPlasticSourceControlLocksWindow::Register()
{
FPlasticSourceControlStyle::Initialize();
FPlasticSourceControlStyle::ReloadTextures();

FGlobalTabmanager::Get()->RegisterNomadTabSpawner(PlasticSourceControlLocksWindowTabName, FOnSpawnTab::CreateRaw(this, &FPlasticSourceControlLocksWindow::OnSpawnTab))
.SetDisplayName(LOCTEXT("PlasticSourceControlLocksWindowTabTitle", "View Locks"))
.SetMenuType(ETabSpawnerMenuType::Hidden)
.SetIcon(FSlateIcon(FPlasticSourceControlStyle::Get().GetStyleSetName(), "PlasticSourceControl.PluginIcon.Small"));
}

void FPlasticSourceControlLocksWindow::Unregister()
{
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(PlasticSourceControlLocksWindowTabName);

FPlasticSourceControlStyle::Shutdown();
}

TSharedRef<SDockTab> FPlasticSourceControlLocksWindow::OnSpawnTab(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
CreateLocksWidget().ToSharedRef()
];
}

void FPlasticSourceControlLocksWindow::OpenTab()
{
FGlobalTabmanager::Get()->TryInvokeTab(PlasticSourceControlLocksWindowTabName);
}

TSharedPtr<SWidget> FPlasticSourceControlLocksWindow::CreateLocksWidget()
{
return SNew(SPlasticSourceControlLocksWidget);
}

#undef LOCTEXT_NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2024 Unity Technologies

#pragma once

#include "CoreMinimal.h"

// Nomad tab window to hold the widget with the list of Locks, see SPlasticSourceControlLocksWidget
class FPlasticSourceControlLocksWindow
{
public:
void Register();
void Unregister();

void OpenTab();

private:
TSharedRef<class SDockTab> OnSpawnTab(const class FSpawnTabArgs& SpawnTabArgs);

TSharedPtr<SWidget> CreateLocksWidget();
};
45 changes: 39 additions & 6 deletions Source/PlasticSourceControl/Private/PlasticSourceControlMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

#include "PlasticSourceControlMenu.h"

#include "PlasticSourceControlBranchesWindow.h"
#include "PlasticSourceControlModule.h"
#include "PlasticSourceControlOperations.h"
#include "PlasticSourceControlProvider.h"
#include "PlasticSourceControlStyle.h"
#include "PlasticSourceControlUtils.h"
#include "PlasticSourceControlVersions.h"
#include "SPlasticSourceControlStatusBar.h"

#include "ISourceControlModule.h"
Expand Down Expand Up @@ -126,6 +126,7 @@ void FPlasticSourceControlMenu::ExtendRevisionControlMenu()
if (FToolMenuSection* Section = ToolsMenu->FindSection("Source Control"))
{
AddViewBranches(*Section);
AddViewLocks(*Section);
}
}
#endif
Expand Down Expand Up @@ -192,7 +193,7 @@ void FPlasticSourceControlMenu::GeneratePlasticAssetContextMenu(FMenuBuilder& Me
{
MenuBuilder.AddMenuEntry(
LOCTEXT("PlasticReleaseLock", "Release Lock"),
LOCTEXT("PlasticReleaseLockTooltip", "Release Lock(s) on the selected assets. Requires administrator privileges on the server."),
LOCTEXT("PlasticReleaseLockTooltip", "Release Lock(s) on the selected assets.\nReleasing locks will allow other users to keep working on these files and retrieve locks (on the same branch, in the latest revision)."),
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 1
FSlateIcon(FAppStyle::GetAppStyleSetName(), "PropertyWindow.Unlocked"),
#else
Expand All @@ -208,7 +209,7 @@ void FPlasticSourceControlMenu::GeneratePlasticAssetContextMenu(FMenuBuilder& Me
{
MenuBuilder.AddMenuEntry(
LOCTEXT("PlasticRemoveLock", "Remove Lock"),
LOCTEXT("PlasticRemoveLockTooltip", "Remove/Delete Lock(s) on the selected assets. Requires administrator privileges on the server."),
LOCTEXT("PlasticRemoveLockTooltip", "Remove Lock(s) on the selected assets.\nRemoving locks will allow other users to edit these files anywhere (on any branch) increasing the risk of future merge conflicts."),
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 1
FSlateIcon(FAppStyle::GetAppStyleSetName(), "PropertyWindow.Unlocked"),
#else
Expand Down Expand Up @@ -244,7 +245,7 @@ void FPlasticSourceControlMenu::GeneratePlasticAssetContextMenu(FMenuBuilder& Me

bool FPlasticSourceControlMenu::CanReleaseLocks(TArray<FAssetData> InAssetObjectPaths) const
{
const TArray<FString> Files = PackageUtils::AssetDateToFileNames(InAssetObjectPaths);
const TArray<FString> Files = PackageUtils::AssetDataToFileNames(InAssetObjectPaths);

for (const FString& File : Files)
{
Expand All @@ -262,7 +263,7 @@ bool FPlasticSourceControlMenu::CanReleaseLocks(TArray<FAssetData> InAssetObject

bool FPlasticSourceControlMenu::CanRemoveLocks(TArray<FAssetData> InAssetObjectPaths) const
{
const TArray<FString> Files = PackageUtils::AssetDateToFileNames(InAssetObjectPaths);
const TArray<FString> Files = PackageUtils::AssetDataToFileNames(InAssetObjectPaths);

for (const FString& File : Files)
{
Expand Down Expand Up @@ -292,7 +293,7 @@ void FPlasticSourceControlMenu::ExecuteUnlock(const TArray<FAssetData>& InAssetO
{
if (!Notification.IsInProgress())
{
const TArray<FString> Files = PackageUtils::AssetDateToFileNames(InAssetObjectPaths);
const TArray<FString> Files = PackageUtils::AssetDataToFileNames(InAssetObjectPaths);

// Launch a custom "Release/Remove Lock" operation
FPlasticSourceControlProvider& Provider = FPlasticSourceControlModule::Get().GetProvider();
Expand Down Expand Up @@ -552,6 +553,11 @@ void FPlasticSourceControlMenu::OpenBranchesWindow() const
FPlasticSourceControlModule::Get().GetBranchesWindow().OpenTab();
}

void FPlasticSourceControlMenu::OpenLocksWindow() const
{
FPlasticSourceControlModule::Get().GetLocksWindow().OpenTab();
}

void FPlasticSourceControlMenu::OnSyncAllOperationComplete(const FSourceControlOperationRef& InOperation, ECommandResult::Type InResult)
{
OnSourceControlOperationComplete(InOperation, InResult);
Expand Down Expand Up @@ -794,6 +800,7 @@ void FPlasticSourceControlMenu::AddMenuExtension(FToolMenuSection& Menu)
);

AddViewBranches(Menu);
AddViewLocks(Menu);
}

#if ENGINE_MAJOR_VERSION == 4
Expand Down Expand Up @@ -822,6 +829,32 @@ void FPlasticSourceControlMenu::AddViewBranches(FToolMenuSection& Menu)
);
}

#if ENGINE_MAJOR_VERSION == 4
void FPlasticSourceControlMenu::AddViewLocks(FMenuBuilder& Menu)
#elif ENGINE_MAJOR_VERSION == 5
void FPlasticSourceControlMenu::AddViewLocks(FToolMenuSection& Menu)
#endif
{
const bool bVersionSupportsSmartLocks = FPlasticSourceControlModule::Get().GetProvider().GetPlasticScmVersion() >= PlasticSourceControlVersions::SmartLocks;

Menu.AddMenuEntry(
#if ENGINE_MAJOR_VERSION == 5
TEXT("PlasticLocksWindow"),
#endif
LOCTEXT("PlasticLocksWindow", "View Locks"),
LOCTEXT("PlasticLocksWindowTooltip", "Open the Locks window."),
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 1
FSlateIcon(FAppStyle::GetAppStyleSetName(), "PropertyWindow.Locked"),
#else
FSlateIcon(FEditorStyle::GetStyleSetName(), "PropertyWindow.Locked"),
#endif
FUIAction(
FExecuteAction::CreateRaw(this, &FPlasticSourceControlMenu::OpenLocksWindow),
FCanExecuteAction::CreateLambda([bVersionSupportsSmartLocks]() { return bVersionSupportsSmartLocks; })
)
);
}

#if ENGINE_MAJOR_VERSION == 4
TSharedRef<FExtender> FPlasticSourceControlMenu::OnExtendLevelEditorViewMenu(const TSharedRef<FUICommandList> CommandList)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,21 @@ class FPlasticSourceControlMenu
void VisitLockRulesURLClicked(const FString InOrganizationName) const;
void OpenDeskoptApp() const;
void OpenBranchesWindow() const;
void OpenLocksWindow() const;

private:
bool IsSourceControlConnected() const;

#if ENGINE_MAJOR_VERSION == 4
void AddMenuExtension(FMenuBuilder& Menu);
void AddViewBranches(FMenuBuilder& Menu);
void AddViewLocks(FMenuBuilder& Menu);

TSharedRef<class FExtender> OnExtendLevelEditorViewMenu(const TSharedRef<class FUICommandList> CommandList);
#elif ENGINE_MAJOR_VERSION == 5
void AddMenuExtension(FToolMenuSection& Menu);
void AddViewBranches(FToolMenuSection& Menu);
void AddViewLocks(FToolMenuSection& Menu);
#endif

/** Extends the UE5 toolbar with a status bar widget to display the current branch and open the branch tab */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ void FPlasticSourceControlModule::StartupModule()
// Bind our source control provider to the editor
IModularFeatures::Get().RegisterModularFeature("SourceControl", &PlasticSourceControlProvider);

/// Register our tab Window here as it needs to be ready for the editor to reload at startup
/// Register our tab windows here as they needs to be ready for the editor to reload at startup
PlasticSourceControlBranchesWindow.Register();
PlasticSourceControlLocksWindow.Register();
}

void FPlasticSourceControlModule::ShutdownModule()
Expand All @@ -29,6 +30,7 @@ void FPlasticSourceControlModule::ShutdownModule()
PlasticSourceControlProvider.Close();

PlasticSourceControlBranchesWindow.Unregister();
PlasticSourceControlLocksWindow.Unregister();

// unbind provider from editor
IModularFeatures::Get().UnregisterModularFeature("SourceControl", &PlasticSourceControlProvider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "PlasticSourceControlWorkspaceCreation.h"

#include "PlasticSourceControlBranchesWindow.h"
#include "PlasticSourceControlLocksWindow.h"

/**
* PlasticSourceControl is the official Unity Version Control Plugin for Unreal Engine
Expand Down Expand Up @@ -43,6 +44,11 @@ class FPlasticSourceControlModule : public IModuleInterface
return PlasticSourceControlBranchesWindow;
}

FPlasticSourceControlLocksWindow& GetLocksWindow()
{
return PlasticSourceControlLocksWindow;
}

/**
* Singleton-like access to this module's interface. This is just for convenience!
* Beware of calling this during the shutdown phase, though. Your module might have been unloaded already.
Expand All @@ -67,7 +73,9 @@ class FPlasticSourceControlModule : public IModuleInterface
/** The Plastic source control provider */
FPlasticSourceControlProvider PlasticSourceControlProvider;

/** Dockable windows adding advanced features to the plugin */
FPlasticSourceControlBranchesWindow PlasticSourceControlBranchesWindow;
FPlasticSourceControlLocksWindow PlasticSourceControlLocksWindow;

/** Logic to create a new workspace */
FPlasticSourceControlWorkspaceCreation PlasticSourceControlWorkspaceCreation;
Expand Down

0 comments on commit 5773601

Please sign in to comment.