Skip to content

Commit

Permalink
Added a new menu extension in the content browser to diff assets with…
Browse files Browse the repository at this point in the history
… their counterparts on origin/develop
  • Loading branch information
Michael Delva authored and TheEmidee committed Jan 4, 2023
1 parent 0346fa5 commit 4ebfb12
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 2 deletions.
118 changes: 116 additions & 2 deletions Source/GitSourceControl/Private/GitSourceControlModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@

#include "GitSourceControlModule.h"

#include "AssetToolsModule.h"
#include "EditorStyleSet.h"
#include "Misc/App.h"
#include "Modules/ModuleManager.h"
#include "Features/IModularFeatures.h"

#include "ContentBrowserModule.h"
#include "ContentBrowserDelegates.h"

#include "GitSourceControlOperations.h"
#include "GitSourceControlUtils.h"
#include "SourceControlHelpers.h"
#include "Framework/Commands/UIAction.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"

#if ENGINE_MAJOR_VERSION >= 5
#include "ContentBrowser/Public/ContentBrowserModule.h"
Expand Down Expand Up @@ -59,6 +68,10 @@ void FGitSourceControlModule::StartupModule()
CbdHandle_OnSearchBoxChanged = ContentBrowserModule.GetOnSearchBoxChanged().AddLambda( [this]( const FText&, bool ){ GitSourceControlProvider.TicksUntilNextForcedUpdate = 1; } );
CbdHandle_OnAssetSelectionChanged = ContentBrowserModule.GetOnAssetSelectionChanged().AddLambda( [this]( const TArray<FAssetData>&, bool ) { GitSourceControlProvider.TicksUntilNextForcedUpdate = 1; } );
CbdHandle_OnAssetPathChanged = ContentBrowserModule.GetOnAssetPathChanged().AddLambda( [this]( const FString& ) { GitSourceControlProvider.TicksUntilNextForcedUpdate = 2; } );

auto & extenders = ContentBrowserModule.GetAllAssetViewContextMenuExtenders();
extenders.Add( FContentBrowserMenuExtender_SelectedAssets::CreateRaw( this, &FGitSourceControlModule::OnExtendContentBrowserAssetSelectionMenu ) );
ContentBrowserAssetExtenderDelegateHandle = extenders.Last().GetHandle();
#endif
}

Expand All @@ -72,11 +85,16 @@ void FGitSourceControlModule::ShutdownModule()

#if ENGINE_MAJOR_VERSION >= 5
// Unregister ContentBrowserDelegate Handles
FContentBrowserModule& ContentBrowserModule = FModuleManager::Get().LoadModuleChecked<FContentBrowserModule>("ContentBrowser");
FContentBrowserModule & ContentBrowserModule = FModuleManager::Get().LoadModuleChecked< FContentBrowserModule >( "ContentBrowser" );
ContentBrowserModule.GetOnFilterChanged().Remove( CbdHandle_OnFilterChanged );
ContentBrowserModule.GetOnSearchBoxChanged().Remove( CbdHandle_OnSearchBoxChanged );
ContentBrowserModule.GetOnAssetSelectionChanged().Remove( CbdHandle_OnAssetSelectionChanged );
ContentBrowserModule.GetOnAssetPathChanged().Remove( CbdHandle_OnAssetPathChanged );

auto & extenders = ContentBrowserModule.GetAllAssetViewContextMenuExtenders();
extenders.RemoveAll( [ &extender_delegate = ContentBrowserAssetExtenderDelegateHandle ]( const FContentBrowserMenuExtender_SelectedAssets & delegate ) {
return delegate.GetHandle() == extender_delegate;
} );
#endif
}

Expand All @@ -99,6 +117,102 @@ void FGitSourceControlModule::SetLastErrors(const TArray<FText>& InErrors)
}
}

IMPLEMENT_MODULE(FGitSourceControlModule, GitSourceControl);
TSharedRef<FExtender> FGitSourceControlModule::OnExtendContentBrowserAssetSelectionMenu( const TArray<FAssetData> & selected_assets )
{
TSharedRef< FExtender > extender( new FExtender() );

extender->AddMenuExtension(
"AssetSourceControlActions",
EExtensionHook::After,
nullptr,
FMenuExtensionDelegate::CreateRaw( this, &FGitSourceControlModule::CreateGitContentBrowserAssetMenu, selected_assets ) );

return extender;
}

void FGitSourceControlModule::CreateGitContentBrowserAssetMenu( FMenuBuilder & menu_builder, const TArray<FAssetData> selected_assets )
{
menu_builder.AddMenuEntry(
LOCTEXT( "GitPlugin", "Diff against origin/develop" ),
LOCTEXT( "GitPlugin", "Diff that asset against the version on origin/develop." ),
FSlateIcon( FEditorStyle::GetStyleSetName(), "SourceControl.Actions.Diff" ),
FUIAction( FExecuteAction::CreateRaw( this, &FGitSourceControlModule::DiffAssetAgainstGitOriginDevelop, selected_assets ) ) );
}

void FGitSourceControlModule::DiffAssetAgainstGitOriginDevelop( const TArray<FAssetData> selected_assets ) const
{
for ( int32 AssetIdx = 0; AssetIdx < selected_assets.Num(); AssetIdx++ )
{
// Get the actual asset (will load it)
const FAssetData & AssetData = selected_assets[ AssetIdx ];

if ( UObject * CurrentObject = AssetData.GetAsset() )
{
const FString PackagePath = AssetData.PackageName.ToString();
const FString PackageName = AssetData.AssetName.ToString();
DiffAgainstOriginDevelop( CurrentObject, PackagePath, PackageName );
}
}
}

void FGitSourceControlModule::DiffAgainstOriginDevelop( UObject * InObject, const FString & InPackagePath, const FString & InPackageName ) const
{
check( InObject );

const FGitSourceControlModule & GitSourceControl = FModuleManager::GetModuleChecked< FGitSourceControlModule >( "GitSourceControl" );
const auto PathToGitBinary = GitSourceControl.AccessSettings().GetBinaryPath();
const auto PathToRepositoryRoot = GitSourceControl.GetProvider().GetPathToRepositoryRoot();

ISourceControlProvider & SourceControlProvider = ISourceControlModule::Get().GetProvider();

const FAssetToolsModule & AssetToolsModule = FModuleManager::GetModuleChecked< FAssetToolsModule >( "AssetTools" );

// Get the SCC state
const FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState( SourceControlHelpers::PackageFilename( InPackagePath ), EStateCacheUsage::Use );

// If we have an asset and its in SCC..
if ( SourceControlState.IsValid() && InObject != nullptr && SourceControlState->IsSourceControlled() )
{
// Get the file name of package
FString RelativeFileName;
if ( FPackageName::DoesPackageExist( InPackagePath, &RelativeFileName ) )
{
//if(SourceControlState->GetHistorySize() > 0)
{
TArray< FString > Errors;
const auto Revision = GitSourceControlUtils::GetOriginDevelopRevision( PathToGitBinary, PathToRepositoryRoot, RelativeFileName, Errors );

check( Revision.IsValid() );

FString TempFileName;
if ( Revision->Get( TempFileName ) )
{
// Try and load that package
UPackage * TempPackage = LoadPackage( nullptr, *TempFileName, LOAD_ForDiff | LOAD_DisableCompileOnLoad );
if ( TempPackage != nullptr )
{
// Grab the old asset from that old package
UObject * OldObject = FindObject< UObject >( TempPackage, *InPackageName );
if ( OldObject != nullptr )
{
/* Set the revision information*/
FRevisionInfo OldRevision;
OldRevision.Changelist = Revision->GetCheckInIdentifier();
OldRevision.Date = Revision->GetDate();
OldRevision.Revision = Revision->GetRevision();

FRevisionInfo NewRevision;
NewRevision.Revision = TEXT( "" );

AssetToolsModule.Get().DiffAssets( OldObject, InObject, OldRevision, NewRevision );
}
}
}
}
}
}
}

IMPLEMENT_MODULE( FGitSourceControlModule, GitSourceControl );

#undef LOCTEXT_NAMESPACE
8 changes: 8 additions & 0 deletions Source/GitSourceControl/Private/GitSourceControlModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@

#include "GitSourceControlSettings.h"
#include "GitSourceControlProvider.h"
#include "Framework/MultiBox/MultiBoxExtender.h"

struct FAssetData;
/**
UEGitPlugin is a simple Git Source Control Plugin for Unreal Engine
Expand Down Expand Up @@ -122,6 +124,11 @@ class FGitSourceControlModule : public IModuleInterface
static void SetLastErrors(const TArray<FText>& InErrors);

private:
TSharedRef< FExtender > OnExtendContentBrowserAssetSelectionMenu( const TArray< FAssetData > & selected_assets );
void CreateGitContentBrowserAssetMenu( FMenuBuilder & menu_builder, const TArray< FAssetData > selected_assets );
void DiffAssetAgainstGitOriginDevelop( const TArray< FAssetData > selected_assets ) const;
void DiffAgainstOriginDevelop( UObject * InObject, const FString & InPackagePath, const FString & InPackageName ) const;

/** The one and only Git source control provider */
FGitSourceControlProvider GitSourceControlProvider;

Expand All @@ -137,5 +144,6 @@ class FGitSourceControlModule : public IModuleInterface
FDelegateHandle CbdHandle_OnAssetSelectionChanged;
FDelegateHandle CbdHandle_OnSourcesViewChanged;
FDelegateHandle CbdHandle_OnAssetPathChanged;
FDelegateHandle ContentBrowserAssetExtenderDelegateHandle;
#endif
};

0 comments on commit 4ebfb12

Please sign in to comment.