You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
218 lines
7.2 KiB
C++
218 lines
7.2 KiB
C++
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "XCodeSourceCodeAccessPrivatePCH.h"
|
|
#include "XCodeSourceCodeAccessor.h"
|
|
#include "DesktopPlatformModule.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"
|
|
;
|
|
|
|
static const char* SaveAllXcodeDocuments =
|
|
" on SaveAllXcodeDocuments()\n"
|
|
" tell application \"Xcode\"\n"
|
|
" save documents\n"
|
|
" end tell\n"
|
|
" end SaveAllXcodeDocuments\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", "Xcode");
|
|
}
|
|
|
|
FText FXCodeSourceCodeAccessor::GetDescriptionText() const
|
|
{
|
|
return LOCTEXT("XCodeDisplayDesc", "Open source code files in XCode");
|
|
}
|
|
|
|
bool FXCodeSourceCodeAccessor::OpenSolution()
|
|
{
|
|
FString SolutionPath;
|
|
if(FDesktopPlatformModule::Get()->GetSolutionPath(SolutionPath))
|
|
{
|
|
const FString FullPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead( *SolutionPath );
|
|
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++;
|
|
}
|
|
|
|
FString SolutionPath;
|
|
if(FDesktopPlatformModule::Get()->GetSolutionPath(SolutionPath))
|
|
{
|
|
FString ProjPath = FPaths::ConvertRelativePathToFull(*SolutionPath);
|
|
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
|
|
{
|
|
bool ExecutionSucceeded = false;
|
|
|
|
NSAppleScript* AppleScript = nil;
|
|
|
|
NSString* AppleScriptString = [NSString stringWithCString:SaveAllXcodeDocuments 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:@"SaveAllXcodeDocuments"] forKeyword:'snam'];
|
|
|
|
NSDictionary* ExecutionError = nil;
|
|
[AppleScript executeAppleEvent:ContainerEvent error:&ExecutionError];
|
|
if(ExecutionError == nil)
|
|
{
|
|
ExecutionSucceeded = true;
|
|
}
|
|
|
|
[AppleScript release];
|
|
return ExecutionSucceeded;
|
|
}
|
|
|
|
void FXCodeSourceCodeAccessor::Tick(const float DeltaTime)
|
|
{
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE |