You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#summary Source code access is now done via plugins
#ttp 330039 EDITOR: Platform-agnostic editor code depends on Windows-only VSAccessor headers #detail Source code access is now extensible via plugins, so any new editors can be easily added. #add Added SourceCodeAccess module that routes access via plugins. #change Moved much of the old VSAccessor code into a new VisualStudioSourceCodeAccess plugin. #add Added a counterpart XCode plugin & migrated the code from FSourceCodeNavigation (Applescript etc.) into there. #remove Removed applescript for XCode access (it is now done via code). #remove Removed source code access functionality from platform layer. #add Added details customization for source code access settings, so users can choose their own accessor. #remove Removed dependencies on VSAccessor. #change Changed API in SWidget to not require building a string to be parsed, instead this acesses and forwards filenames & line numbers. #extra Tested on Mac by Mark S. reviewed by Andrew.Brown [CL 2048697 by Thomas Sarkanen in Main branch]
This commit is contained in:
committed by
UnrealBot
parent
23173e178d
commit
2e3d1f5aae
@@ -0,0 +1,19 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "XCodeSourceCodeAccessPrivatePCH.h"
|
||||
#include "Runtime/Core/Public/Features/IModularFeatures.h"
|
||||
#include "XCodeSourceCodeAccessModule.h"
|
||||
|
||||
IMPLEMENT_MODULE( FXCodeSourceCodeAccessModule, XCodeSourceCodeAccess );
|
||||
|
||||
void FXCodeSourceCodeAccessModule::StartupModule()
|
||||
{
|
||||
// Bind our source control provider to the editor
|
||||
IModularFeatures::Get().RegisterModularFeature(TEXT("SourceCodeAccessor"), &XCodeSourceCodeAccessor );
|
||||
}
|
||||
|
||||
void FXCodeSourceCodeAccessModule::ShutdownModule()
|
||||
{
|
||||
// unbind provider from editor
|
||||
IModularFeatures::Get().UnregisterModularFeature(TEXT("SourceCodeAccessor"), &XCodeSourceCodeAccessor);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "XCodeSourceCodeAccessor.h"
|
||||
|
||||
class FXCodeSourceCodeAccessModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() OVERRIDE;
|
||||
virtual void ShutdownModule() OVERRIDE;
|
||||
|
||||
private:
|
||||
FXCodeSourceCodeAccessor XCodeSourceCodeAccessor;
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Core.h"
|
||||
#include "ModuleManager.h"
|
||||
#include "ISourceCodeAccessModule.h"
|
||||
@@ -0,0 +1,184 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "XCodeSourceCodeAccessPrivatePCH.h"
|
||||
#include "XCodeSourceCodeAccessor.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "XCodeSourceCodeAccessor"
|
||||
|
||||
/** Applescript we use to open XCode */
|
||||
static const char* OpenXCodeAtFileAndLineAppleScript =
|
||||
" on OpenXcodeAtFileAndLine(filepath, linenumber)\n"
|
||||
" set theOffset to offset of \"/\" in filepath\n"
|
||||
" tell application \"Xcode\"\n"
|
||||
" activate\n"
|
||||
" if theOffset is 1 then\n"
|
||||
" open filepath\n"
|
||||
" end if\n"
|
||||
" tell application \"System Events\"\n"
|
||||
" tell process \"Xcode\"\n"
|
||||
" if theOffset is not 1 then\n"
|
||||
" keystroke \"o\" using {command down, shift down}\n"
|
||||
" repeat until window \"Open Quickly\" exists\n"
|
||||
" end repeat\n"
|
||||
" click text field 1 of window \"Open Quickly\"\n"
|
||||
" set value of text field 1 of window \"Open Quickly\" to filepath\n"
|
||||
" keystroke return\n"
|
||||
" end if\n"
|
||||
" keystroke \"l\" using command down\n"
|
||||
" repeat until window \"Open Quickly\" exists\n"
|
||||
" end repeat\n"
|
||||
" click text field 1 of window \"Open Quickly\"\n"
|
||||
" set value of text field 1 of window \"Open Quickly\" to linenumber\n"
|
||||
" keystroke return\n"
|
||||
" keystroke return\n"
|
||||
" end tell\n"
|
||||
" end tell\n"
|
||||
" end tell\n"
|
||||
" end OpenXcodeAtFileAndLine\n"
|
||||
;
|
||||
|
||||
bool FXCodeSourceCodeAccessor::CanAccessSourceCode() const
|
||||
{
|
||||
return IFileManager::Get().DirectoryExists(TEXT("/Applications/Xcode.app"));
|
||||
}
|
||||
|
||||
FName FXCodeSourceCodeAccessor::GetFName() const
|
||||
{
|
||||
return FName("XCodeSourceCodeAccessor");
|
||||
}
|
||||
|
||||
FText FXCodeSourceCodeAccessor::GetNameText() const
|
||||
{
|
||||
return LOCTEXT("XCodeDisplayName", "Visual Studio");
|
||||
}
|
||||
|
||||
FText FXCodeSourceCodeAccessor::GetDescriptionText() const
|
||||
{
|
||||
return LOCTEXT("XCodeDisplayDesc", "Open source code files in XCode");
|
||||
}
|
||||
|
||||
bool FXCodeSourceCodeAccessor::OpenSolution()
|
||||
{
|
||||
const FString FullPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead( *FModuleManager::Get().GetSolutionFilepath() );
|
||||
if ( FPaths::FileExists( FullPath ) )
|
||||
{
|
||||
FPlatformProcess::LaunchFileInDefaultExternalApplication( *FullPath );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FXCodeSourceCodeAccessor::OpenFileAtLine(const FString& FullPath, int32 LineNumber, int32 ColumnNumber)
|
||||
{
|
||||
ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>(TEXT("SourceCodeAccess"));
|
||||
|
||||
// column & line numbers are 1-based, so dont allow zero
|
||||
if(LineNumber == 0)
|
||||
{
|
||||
LineNumber++;
|
||||
}
|
||||
if(ColumnNumber == 0)
|
||||
{
|
||||
ColumnNumber++;
|
||||
}
|
||||
|
||||
if (!FPaths::FileExists(FullPath))
|
||||
{
|
||||
SourceCodeAccessModule.OnOpenFileFailed().Broadcast(FullPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( FModuleManager::Get().IsSolutionFilePresent() )
|
||||
{
|
||||
FString ProjPath = FPaths::ConvertRelativePathToFull(FModuleManager::Get().GetSolutionFilepath());
|
||||
CFStringRef ProjPathString = FPlatformString::TCHARToCFString(*ProjPath);
|
||||
NSString* ProjectPath = [(NSString*)ProjPathString stringByDeletingLastPathComponent];
|
||||
[[NSWorkspace sharedWorkspace] openFile:ProjectPath withApplication:@"Xcode" andDeactivate:YES];
|
||||
}
|
||||
|
||||
bool ExecutionSucceeded = false;
|
||||
|
||||
NSAppleScript* AppleScript = nil;
|
||||
|
||||
NSString* AppleScriptString = [NSString stringWithCString:OpenXCodeAtFileAndLineAppleScript encoding:NSUTF8StringEncoding];
|
||||
AppleScript = [[NSAppleScript alloc] initWithSource:AppleScriptString];
|
||||
|
||||
int PID = [[NSProcessInfo processInfo] processIdentifier];
|
||||
NSAppleEventDescriptor* ThisApplication = [NSAppleEventDescriptor descriptorWithDescriptorType:typeKernelProcessID bytes:&PID length:sizeof(PID)];
|
||||
|
||||
NSAppleEventDescriptor* ContainerEvent = [NSAppleEventDescriptor appleEventWithEventClass:'ascr' eventID:'psbr' targetDescriptor:ThisApplication returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
|
||||
|
||||
[ContainerEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:@"OpenXcodeAtFileAndLine"] forKeyword:'snam'];
|
||||
|
||||
{
|
||||
NSAppleEventDescriptor* Arguments = [[NSAppleEventDescriptor alloc] initListDescriptor];
|
||||
|
||||
CFStringRef FileString = FPlatformString::TCHARToCFString(*FullPath);
|
||||
NSString* Path = (NSString*)FileString;
|
||||
|
||||
if([Path isAbsolutePath] == NO)
|
||||
{
|
||||
NSString* CurDir = [[NSFileManager defaultManager] currentDirectoryPath];
|
||||
NSString* ResolvedPath = [[NSString stringWithFormat:@"%@/%@", CurDir, Path] stringByResolvingSymlinksInPath];
|
||||
if([[NSFileManager defaultManager] fileExistsAtPath:ResolvedPath])
|
||||
{
|
||||
Path = ResolvedPath;
|
||||
}
|
||||
else // If it doesn't exist, supply only the filename, we'll use Open Quickly to try and find it from Xcode
|
||||
{
|
||||
Path = [Path lastPathComponent];
|
||||
}
|
||||
}
|
||||
|
||||
[Arguments insertDescriptor:[NSAppleEventDescriptor descriptorWithString:Path] atIndex:([Arguments numberOfItems] + 1)];
|
||||
CFRelease(FileString);
|
||||
|
||||
CFStringRef LineString = FPlatformString::TCHARToCFString(*FString::FromInt(LineNumber));
|
||||
if(LineString)
|
||||
{
|
||||
[Arguments insertDescriptor:[NSAppleEventDescriptor descriptorWithString:(NSString*)LineString] atIndex:([Arguments numberOfItems] + 1)];
|
||||
CFRelease(LineString);
|
||||
}
|
||||
else
|
||||
{
|
||||
[Arguments insertDescriptor:[NSAppleEventDescriptor descriptorWithString:@"1"] atIndex:([Arguments numberOfItems] + 1)];
|
||||
}
|
||||
|
||||
[ContainerEvent setParamDescriptor:Arguments forKeyword:keyDirectObject];
|
||||
[Arguments release];
|
||||
}
|
||||
|
||||
NSDictionary* ExecutionError = nil;
|
||||
[AppleScript executeAppleEvent:ContainerEvent error:&ExecutionError];
|
||||
if(ExecutionError == nil)
|
||||
{
|
||||
ExecutionSucceeded = true;
|
||||
}
|
||||
|
||||
[AppleScript release];
|
||||
|
||||
// Fallback to trivial implementation when something goes wrong (like not having permission for UI scripting)
|
||||
if(ExecutionSucceeded == false)
|
||||
{
|
||||
FPlatformProcess::LaunchFileInDefaultExternalApplication(*FullPath);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FXCodeSourceCodeAccessor::OpenSourceFiles(const TArray<FString>& AbsoluteSourcePaths)
|
||||
{
|
||||
for ( const FString& SourcePath : AbsoluteSourcePaths )
|
||||
{
|
||||
FPlatformProcess::LaunchFileInDefaultExternalApplication(*SourcePath);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FXCodeSourceCodeAccessor::SaveAllOpenDocuments() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ISourceCodeAccessor.h"
|
||||
|
||||
class FXCodeSourceCodeAccessor : public ISourceCodeAccessor
|
||||
{
|
||||
public:
|
||||
/** ISourceCodeAccessor implementation */
|
||||
virtual bool CanAccessSourceCode() const OVERRIDE;
|
||||
virtual FName GetFName() const OVERRIDE;
|
||||
virtual FText GetNameText() const OVERRIDE;
|
||||
virtual FText GetDescriptionText() const OVERRIDE;
|
||||
virtual bool OpenSolution() OVERRIDE;
|
||||
virtual bool OpenFileAtLine(const FString& FullPath, int32 LineNumber, int32 ColumnNumber = 0) OVERRIDE;
|
||||
virtual bool OpenSourceFiles(const TArray<FString>& AbsoluteSourcePaths) OVERRIDE;
|
||||
virtual bool SaveAllOpenDocuments() const OVERRIDE;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
namespace UnrealBuildTool.Rules
|
||||
{
|
||||
public class XCodeSourceCodeAccess : ModuleRules
|
||||
{
|
||||
public XCodeSourceCodeAccess(TargetInfo Target)
|
||||
{
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"SourceCodeAccess"
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user