bool FCodeLiteSourceCodeAccessor::OpenSolution() { FString Filename = FPaths::GetBaseFilename(GetSolutionPath()) + ".workspace"; FString Directory = FPaths::GetPath(GetSolutionPath()); FString Solution = "\"" + Directory + "/" + Filename + "\""; FString CodeLitePath; if(!CanRunCodeLite(CodeLitePath)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSolution: Cannot find CodeLite binary")); return false; } UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSolution: %s %s"), *CodeLitePath, *Solution); #ifdef USE_DBUS // // TODO Somehow codelite is not opening the workspace using GetWorkspace()->Open(...) // DBusMessage* message = nullptr; DBusMessageIter args; // Create new message. message = dbus_message_new_signal ("/org/codelite/command", "org.codelite.command", "OpenWorkSpace"); char* fileName = TCHAR_TO_ANSI(*Solution); // Add parameters to the message. dbus_message_iter_init_append(message, &args); if(!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &fileName)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("Sdbus_message_iter_append_basic failed.")); return false; } // Send the message. dbus_connection_send(DBusConnection, message, nullptr); if(dbus_error_is_set(&DBusError)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("dbus_connection_send failed: %s"), DBusError.message); return false; } // Free the message resources. dbus_message_unref(message); return true; #else FProcHandle Proc = FPlatformProcess::CreateProc(*CodeLitePath, *Solution, true, false, false, nullptr, 0, nullptr, nullptr); if(Proc.IsValid()) { FPlatformProcess::CloseProc(Proc); return true; } return false; #endif }
bool FVisualStudioSourceCodeAccessor::OpenVisualStudioSolutionViaProcess() { ::DWORD ProcessID = 0; FString Path; const FString SolutionPath = GetSolutionPath(); switch (AccessVisualStudioViaProcess(ProcessID, Path, SolutionPath, GetPrioritizedVisualStudioVersions(SolutionPath))) { case EAccessVisualStudioResult::VSInstanceIsOpen: { // Try to bring Visual Studio to the foreground ::HWND VisualStudioHwnd = GetTopWindowForProcess(ProcessID); if (VisualStudioHwnd) { // SwitchToThisWindow isn't really intended for general use, however it can switch to // the VS window, where SetForegroundWindow will fail due to process permissions ::SwitchToThisWindow(VisualStudioHwnd, 0); } return true; } break; case EAccessVisualStudioResult::VSInstanceIsNotOpen: return RunVisualStudioAndOpenSolution(); default: // Do nothing if we failed the VS detection, otherwise we could get stuck in a loop of constantly // trying to open a VS instance since we can't detect that one is already running break; } return false; }
bool FVisualStudioSourceCodeAccessor::OpenVisualStudioFilesInternalViaProcess(const TArray<FileOpenRequest>& Requests) { ::DWORD ProcessID = 0; FString Path; const FString SolutionPath = GetSolutionPath(); switch (AccessVisualStudioViaProcess(ProcessID, Path, SolutionPath, GetPrioritizedVisualStudioVersions(SolutionPath))) { case EAccessVisualStudioResult::VSInstanceIsOpen: return RunVisualStudioAndOpenSolutionAndFiles(Path, "", &Requests); case EAccessVisualStudioResult::VSInstanceIsNotOpen: if (CanRunVisualStudio(Path, SolutionPath)) { return RunVisualStudioAndOpenSolutionAndFiles(Path, SolutionPath, &Requests); } break; default: // Do nothing if we failed the VS detection, otherwise we could get stuck in a loop of constantly // trying to open a VS instance since we can't detect that one is already running break; } return false; }
void FKDevelopSourceCodeAccessor::Startup() { // Cache this so we don't have to do it on a background thread GetSolutionPath(); // FIXME: look for kdevelop and cache the path }
bool FCodeLiteSourceCodeAccessor::OpenSolution() { if (!Location.IsValid()) { return false; } return OpenSolutionAtPath(GetSolutionPath()); }
bool FVisualStudioSourceCodeAccessor::RunVisualStudioAndOpenSolution() const { FString Path; const FString SolutionPath = GetSolutionPath(); if (CanRunVisualStudio(Path, SolutionPath)) { return RunVisualStudioAndOpenSolutionAndFiles(Path, SolutionPath, nullptr); } return false; }
bool FVisualStudioSourceCodeAccessor::OpenVisualStudioSolutionViaDTE() { // Initialize the com library, if not already by this thread if (!FWindowsPlatformMisc::CoInitialize()) { UE_LOG(LogVSAccessor, Error, TEXT( "ERROR - Could not initialize COM library!" )); return false; } bool bSuccess = false; TComPtr<EnvDTE::_DTE> DTE; const FString SolutionPath = GetSolutionPath(); switch (AccessVisualStudioViaDTE(DTE, SolutionPath, GetPrioritizedVisualStudioVersions(SolutionPath))) { case EAccessVisualStudioResult::VSInstanceIsOpen: { // Set Focus on Visual Studio TComPtr<EnvDTE::Window> MainWindow; if (SUCCEEDED(DTE->get_MainWindow(&MainWindow)) && SUCCEEDED(MainWindow->Activate())) { bSuccess = true; } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't set focus on Visual Studio.")); } } break; case EAccessVisualStudioResult::VSInstanceIsNotOpen: { // Automatically fail if there's already an attempt in progress if (!IsVSLaunchInProgress()) { bSuccess = RunVisualStudioAndOpenSolution(); } } break; default: // Do nothing if we failed the VS detection, otherwise we could get stuck in a loop of constantly // trying to open a VS instance since we can't detect that one is already running break; } // Uninitialize the com library, if we initialized it above (don't call if S_FALSE) FWindowsPlatformMisc::CoUninitialize(); return bSuccess; }
bool FCodeLiteSourceCodeAccessor::OpenSolution() { FString Filename = FPaths::GetBaseFilename(GetSolutionPath()) + ".workspace"; FString Directory = FPaths::GetPath(GetSolutionPath()); FString Solution = "\"" + Directory + "/" + Filename + "\""; FString CodeLitePath; if(!CanRunCodeLite(CodeLitePath)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSolution: Cannot find CodeLite binary")); return false; } UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSolution: %s %s"), *CodeLitePath, *Solution); FProcHandle Proc = FPlatformProcess::CreateProc(*CodeLitePath, *Solution, true, false, false, nullptr, 0, nullptr, nullptr); if(Proc.IsValid()) { FPlatformProcess::CloseProc(Proc); return true; } return false; }
void FVisualStudioSourceCodeAccessor::Startup() { VSLaunchTime = 0.0; #if WITH_EDITOR // Setup compilation for saving all VS documents upon compilation start SaveVisualStudioDocumentsDelegateHandle = IHotReloadModule::Get().OnModuleCompilerStarted().AddStatic( &OnModuleCompileStarted ); #endif // Cache this so we don't have to do it on a background thread GetSolutionPath(); RefreshAvailability(); }
bool FCodeLiteSourceCodeAccessor::OpenFileAtLine(const FString& FullPath, int32 LineNumber, int32 ColumnNumber) { if (!Location.IsValid()) { return false; } LineNumber = LineNumber > 0 ? LineNumber : 1; FString SolutionDir = GetSolutionPath(); TArray<FString> Args; Args.Add(MakePath(FullPath) + FString::Printf(TEXT(" --line=%d"), LineNumber)); return Launch(Args); }
void FCodeLiteSourceCodeAccessor::Startup() { // Cache this so we don't have to do it on a background thread GetSolutionPath(); #ifdef USE_DBUS dbus_error_init (&DBusError); DBusConnection = dbus_bus_get(DBUS_BUS_SESSION, &DBusError); if(dbus_error_is_set(&DBusError)) { printf("Error connecting to the daemon bus: %s",DBusError.message); } UE_LOG(LogCodeLiteAccessor, Warning, TEXT("Successfully connected to CodeLite DBus server.")); #endif }
bool FCodeLiteSourceCodeAccessor::OpenSourceFiles(const TArray<FString>& AbsoluteSourcePaths) { if (!Location.IsValid()) { return false; } FString SolutionDir = GetSolutionPath(); TArray<FString> Args; Args.Add(MakePath(SolutionDir)); for (const FString& SourcePath : AbsoluteSourcePaths) { Args.Add(MakePath(SourcePath)); } return Launch(Args); }
bool FVisualStudioSourceCodeAccessor::SaveAllOpenDocuments() const { bool bSuccess = false; // Initialize the com library, if not already by this thread if (!FWindowsPlatformMisc::CoInitialize()) { UE_LOG(LogVSAccessor, Error, TEXT( "ERROR - Could not initialize COM library!" )); return bSuccess; } TComPtr<EnvDTE::_DTE> DTE; const FString SolutionPath = GetSolutionPath(); if (AccessVisualStudioViaDTE(DTE, SolutionPath, GetPrioritizedVisualStudioVersions(SolutionPath)) == EAccessVisualStudioResult::VSInstanceIsOpen) { // Save all documents TComPtr<EnvDTE::Documents> Documents; if (SUCCEEDED(DTE->get_Documents(&Documents)) && SUCCEEDED(Documents->SaveAll())) { bSuccess = true; } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't save all documents")); } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't access Visual Studio")); } // Uninitialize the com library, if we initialized it above (don't call if S_FALSE) FWindowsPlatformMisc::CoUninitialize(); return bSuccess; }
bool FVisualStudioSourceCodeAccessor::AddSourceFiles(const TArray<FString>& AbsoluteSourcePaths, const TArray<FString>& AvailableModules) { // This requires DTE - there is no fallback for this operation when DTE is not available #if VSACCESSOR_HAS_DTE bool bSuccess = true; struct FModuleNameAndPath { FString ModuleBuildFilePath; FString ModulePath; FName ModuleName; }; TArray<FModuleNameAndPath> ModuleNamesAndPaths; ModuleNamesAndPaths.Reserve(AvailableModules.Num()); for (const FString& AvailableModule : AvailableModules) { static const int32 BuildFileExtensionLen = FString(TEXT(".Build.cs")).Len(); // AvailableModule is the relative path to the .Build.cs file FModuleNameAndPath ModuleNameAndPath; ModuleNameAndPath.ModuleBuildFilePath = FPaths::ConvertRelativePathToFull(AvailableModule); ModuleNameAndPath.ModulePath = FPaths::GetPath(ModuleNameAndPath.ModuleBuildFilePath); ModuleNameAndPath.ModuleName = *FPaths::GetCleanFilename(ModuleNameAndPath.ModuleBuildFilePath).LeftChop(BuildFileExtensionLen); ModuleNamesAndPaths.Add(ModuleNameAndPath); } struct FModuleNewSourceFiles { FModuleNameAndPath ModuleNameAndPath; TArray<FString> NewSourceFiles; }; // Work out which module each source file will be in TMap<FName, FModuleNewSourceFiles> ModuleToNewSourceFiles; { const FModuleNameAndPath* LastSourceFilesModule = nullptr; for (const FString& SourceFile : AbsoluteSourcePaths) { // First check to see if this source file is in the same module as the last source file - this is usually the case, and saves us a lot of string compares if (LastSourceFilesModule && SourceFile.StartsWith(LastSourceFilesModule->ModulePath)) { FModuleNewSourceFiles& ModuleNewSourceFiles = ModuleToNewSourceFiles.FindChecked(LastSourceFilesModule->ModuleName); ModuleNewSourceFiles.NewSourceFiles.Add(SourceFile); continue; } // Look for the module which will contain this file LastSourceFilesModule = nullptr; for (const FModuleNameAndPath& ModuleNameAndPath : ModuleNamesAndPaths) { if (SourceFile.StartsWith(ModuleNameAndPath.ModulePath)) { LastSourceFilesModule = &ModuleNameAndPath; FModuleNewSourceFiles& ModuleNewSourceFiles = ModuleToNewSourceFiles.FindOrAdd(ModuleNameAndPath.ModuleName); ModuleNewSourceFiles.ModuleNameAndPath = ModuleNameAndPath; ModuleNewSourceFiles.NewSourceFiles.Add(SourceFile); break; } } // Failed to find the module for this source file? if (!LastSourceFilesModule) { UE_LOG(LogVSAccessor, Warning, TEXT("Cannot add source file '%s' as it doesn't belong to a known module"), *SourceFile); bSuccess = false; } } } TComPtr<EnvDTE::_DTE> DTE; const FString SolutionPath = GetSolutionPath(); if (AccessVisualStudioViaDTE(DTE, SolutionPath, GetPrioritizedVisualStudioVersions(SolutionPath)) == EAccessVisualStudioResult::VSInstanceIsOpen) { TComPtr<EnvDTE::_Solution> Solution; if (SUCCEEDED(DTE->get_Solution(&Solution)) && Solution) { // Process each module for (const auto& ModuleNewSourceFilesKeyValue : ModuleToNewSourceFiles) { const FModuleNewSourceFiles& ModuleNewSourceFiles = ModuleNewSourceFilesKeyValue.Value; const FString& ModuleBuildFilePath = ModuleNewSourceFiles.ModuleNameAndPath.ModuleBuildFilePath; auto ANSIModuleBuildFilePath = StringCast<ANSICHAR>(*ModuleBuildFilePath); FComBSTR COMStrModuleBuildFilePath(ANSIModuleBuildFilePath.Get()); TComPtr<EnvDTE::ProjectItem> BuildFileProjectItem; if (SUCCEEDED(Solution->FindProjectItem(COMStrModuleBuildFilePath, &BuildFileProjectItem)) && BuildFileProjectItem) { // We found the .Build.cs file in the existing solution - now we need its parent ProjectItems as that's what we'll be adding new content to TComPtr<EnvDTE::ProjectItems> ModuleProjectFolder; if (SUCCEEDED(BuildFileProjectItem->get_Collection(&ModuleProjectFolder)) && ModuleProjectFolder) { for (const FString& SourceFile : AbsoluteSourcePaths) { const FString ProjectRelativeSourceFilePath = SourceFile.Mid(ModuleNewSourceFiles.ModuleNameAndPath.ModulePath.Len()); TArray<FString> SourceFileParts; ProjectRelativeSourceFilePath.ParseIntoArray(SourceFileParts, TEXT("/"), true); if (SourceFileParts.Num() == 0) { // This should never happen as it means we somehow have no filename within the project directory bSuccess = false; continue; } TComPtr<EnvDTE::ProjectItems> CurProjectItems = ModuleProjectFolder; // Firstly we need to make sure that all the folders we need exist - this also walks us down to the correct place to add the file for (int32 FilePartIndex = 0; FilePartIndex < SourceFileParts.Num() - 1 && CurProjectItems; ++FilePartIndex) { const FString& SourceFilePart = SourceFileParts[FilePartIndex]; auto ANSIPart = StringCast<ANSICHAR>(*SourceFilePart); FComBSTR COMStrFilePart(ANSIPart.Get()); ::VARIANT vProjectItemName; vProjectItemName.vt = VT_BSTR; vProjectItemName.bstrVal = COMStrFilePart; TComPtr<EnvDTE::ProjectItem> ProjectItem; if (SUCCEEDED(CurProjectItems->Item(vProjectItemName, &ProjectItem)) && !ProjectItem) { // Add this part CurProjectItems->AddFolder(COMStrFilePart, nullptr, &ProjectItem); } if (ProjectItem) { ProjectItem->get_ProjectItems(&CurProjectItems); } else { CurProjectItems = nullptr; } } if (!CurProjectItems) { // Failed to find or add all the path parts bSuccess = false; continue; } // Now we add the file to the project under the last folder we found along its path auto ANSIPath = StringCast<ANSICHAR>(*SourceFile); FComBSTR COMStrFileName(ANSIPath.Get()); TComPtr<EnvDTE::ProjectItem> FileProjectItem; if (SUCCEEDED(CurProjectItems->AddFromFile(COMStrFileName, &FileProjectItem))) { bSuccess &= true; } } // Save the updated project to avoid a message when closing VS TComPtr<EnvDTE::Project> Project; if (SUCCEEDED(ModuleProjectFolder->get_ContainingProject(&Project)) && Project) { Project->Save(nullptr); } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Cannot add source files as we failed to get the parent items container for the '%s' item"), *ModuleBuildFilePath); bSuccess = false; } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Cannot add source files as we failed to find '%s' in the solution"), *ModuleBuildFilePath); bSuccess = false; } } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Cannot add source files as Visual Studio failed to return a solution when queried")); bSuccess = false; } } else { UE_LOG(LogVSAccessor, Verbose, TEXT("Cannot add source files as Visual Studio is either not open or not responding")); bSuccess = false; } return bSuccess; #endif return false; }
void FCodeLiteSourceCodeAccessor::Startup() { GetSolutionPath(); }
bool FVisualStudioSourceCodeAccessor::OpenVisualStudioFilesInternalViaDTE(const TArray<FileOpenRequest>& Requests, bool& bWasDeferred) { ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>(TEXT("SourceCodeAccess")); // Initialize the com library, if not already by this thread if (!FWindowsPlatformMisc::CoInitialize()) { UE_LOG(LogVSAccessor, Error, TEXT( "ERROR - Could not initialize COM library!" )); return false; } bool bDefer = false, bSuccess = false; TComPtr<EnvDTE::_DTE> DTE; const FString SolutionPath = GetSolutionPath(); switch (AccessVisualStudioViaDTE(DTE, SolutionPath, GetPrioritizedVisualStudioVersions(SolutionPath))) { case EAccessVisualStudioResult::VSInstanceIsOpen: { // Set Focus on Visual Studio TComPtr<EnvDTE::Window> MainWindow; if (SUCCEEDED(DTE->get_MainWindow(&MainWindow)) && SUCCEEDED(MainWindow->Activate())) { // Get ItemOperations TComPtr<EnvDTE::ItemOperations> ItemOperations; if (SUCCEEDED(DTE->get_ItemOperations(&ItemOperations))) { for ( const FileOpenRequest& Request : Requests ) { // Check that the file actually exists first if ( !FPaths::FileExists(Request.FullPath) ) { SourceCodeAccessModule.OnOpenFileFailed().Broadcast(Request.FullPath); bSuccess |= false; continue; } // Open File auto ANSIPath = StringCast<ANSICHAR>(*Request.FullPath); FComBSTR COMStrFileName(ANSIPath.Get()); FComBSTR COMStrKind(EnvDTE::vsViewKindTextView); TComPtr<EnvDTE::Window> Window; if ( SUCCEEDED(ItemOperations->OpenFile(COMStrFileName, COMStrKind, &Window)) ) { // If we've made it this far - we've opened the file. it doesn't matter if // we successfully get to the line number. Everything else is gravy. bSuccess |= true; // Scroll to Line Number TComPtr<EnvDTE::Document> Document; TComPtr<IDispatch> SelectionDispatch; TComPtr<EnvDTE::TextSelection> Selection; if ( SUCCEEDED(DTE->get_ActiveDocument(&Document)) && SUCCEEDED(Document->get_Selection(&SelectionDispatch)) && SelectionDispatch && SUCCEEDED(SelectionDispatch->QueryInterface(&Selection)) && SUCCEEDED(Selection->GotoLine(Request.LineNumber, VARIANT_TRUE)) ) { if ( !SUCCEEDED(Selection->MoveToLineAndOffset(Request.LineNumber, Request.ColumnNumber, false)) ) { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't goto column number '%i' of line '%i' in '%s'"), Request.ColumnNumber, Request.LineNumber, *Request.FullPath); } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't goto line number '%i' in '%s'"), Request.LineNumber, *Request.FullPath); } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't open file '%s'."), *Request.FullPath); } } VSLaunchFinished( true ); } else { UE_LOG(LogVSAccessor, Log, TEXT("Couldn't get item operations. Visual Studio may still be initializing.")); bDefer = true; } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't set focus on Visual Studio.")); } } break; case EAccessVisualStudioResult::VSInstanceIsNotOpen: { bDefer = true; // We can't process until we're in the main thread, if we aren't initially defer until we are if ( IsInGameThread() ) { // If we haven't already attempted to launch VS do so now if ( !IsVSLaunchInProgress() ) { // If there's no valid instance of VS running, run one if we have it installed if ( !RunVisualStudioAndOpenSolution() ) { bDefer = false; } else { VSLaunchStarted(); } } } } break; case EAccessVisualStudioResult::VSInstanceIsBlocked: { // VS may be open for the solution we want, but we can't query it right now as it's blocked for some reason // Defer this operation so we can try it again later should VS become unblocked bDefer = true; } break; default: // Do nothing if we failed the VS detection, otherwise we could get stuck in a loop of constantly // trying to open a VS instance since we can't detect that one is already running bDefer = false; break; } if ( !bSuccess ) { // If we have attempted to launch VS, and it's taken too long, timeout so the user can try again if ( IsVSLaunchInProgress() && ( FPlatformTime::Seconds() - VSLaunchTime ) > 300 ) { // We need todo this in case the process died or was kill prior to the code gaining focus of it bDefer = false; VSLaunchFinished(false); // We failed to open the solution and file, so lets just use the platforms default opener. for ( const FileOpenRequest& Request : Requests ) { FPlatformProcess::LaunchFileInDefaultExternalApplication(*Request.FullPath); } } // Defer the request until VS is available to take hold of if ( bDefer ) { FScopeLock Lock(&DeferredRequestsCriticalSection); DeferredRequests.Append(Requests); } else if ( !bSuccess ) { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't access Visual Studio")); } } // Uninitialize the com library, if we initialized it above (don't call if S_FALSE) FWindowsPlatformMisc::CoUninitialize(); bWasDeferred = bDefer; return bSuccess; }
bool FCodeLiteSourceCodeAccessor::DoesSolutionExist() const { return FPaths::FileExists(GetSolutionPath()); }
CString CCompiler::GetExePath( ) { return GetSolutionPath() + "bin\\"; }
bool FQtCreatorSourceCodeAccessor::DoesSolutionExist() const { FString SolutionPath = GetSolutionPath(); return FPaths::FileExists(SolutionPath); }
void FCodeLiteSourceCodeAccessor::Startup() { // Cache this so we don't have to do it on a background thread GetSolutionPath(); }
bool FQtCreatorSourceCodeAccessor::OpenSolution() { FString SolutionPath = GetSolutionPath(); return OpenSolutionAtPath(SolutionPath); }
CString CCompiler::GetCompiledExeFilePath() { return GetSolutionPath() +"bin\\CompilerDummy.exe"; }
bool FKDevelopSourceCodeAccessor::OpenSolution() { if (IsIDERunning()) { // use qdbus to open the project within session? STUBBED("OpenSolution: KDevelop is running, use qdbus to open the project within session?"); return false; } FString Solution = GetSolutionPath(); FString IDEPath; if (!CanRunKDevelop(IDEPath)) { UE_LOG(LogKDevelopAccessor, Warning, TEXT("FKDevelopSourceCodeAccessor::OpenSourceFiles: cannot find kdevelop binary")); return false; } FProcHandle Proc = FPlatformProcess::CreateProc(*IDEPath, *Solution, true, false, false, nullptr, 0, nullptr, nullptr); if (Proc.IsValid()) { FPlatformProcess::CloseProc(Proc); return true; } return false; }