BsMDCodeEditor.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "CodeEditor/BsMDCodeEditor.h"
  4. #include "FileSystem/BsFileSystem.h"
  5. #include "FileSystem/BsDataStream.h"
  6. #include "String/BsUnicode.h"
  7. #include "Linux/BsLinuxPlatform.h"
  8. #if BS_PLATFORM == BS_PLATFORM_WIN32
  9. #include <Windows.h>
  10. #endif
  11. namespace bs
  12. {
  13. #if BS_PLATFORM == BS_PLATFORM_WIN32
  14. /**
  15. * Reads a string value from the specified key in the registry.
  16. *
  17. * @param[in] key Registry key to read from.
  18. * @param[in] name Identifier of the value to read from.
  19. * @param[in] value Output value read from the key.
  20. * @param[in] defaultValue Default value to return if the key or identifier doesn't exist.
  21. */
  22. static LONG getRegistryStringValue(HKEY hKey, const WString& name, WString& value, const WString& defaultValue)
  23. {
  24. value = defaultValue;
  25. wchar_t strBuffer[512];
  26. DWORD strBufferSize = sizeof(strBuffer);
  27. ULONG result = RegQueryValueExW(hKey, name.c_str(), 0, nullptr, (LPBYTE)strBuffer, &strBufferSize);
  28. if (result == ERROR_SUCCESS)
  29. value = strBuffer;
  30. return result;
  31. }
  32. #else
  33. #endif
  34. MDCodeEditor::MDCodeEditor(const Path& execPath)
  35. :mExecPath(execPath)
  36. {
  37. }
  38. void MDCodeEditor::openFile(const Path& solutionPath, const Path& filePath, UINT32 lineNumber) const
  39. {
  40. WString args = L"--no-splash \"" + solutionPath.toWString() + L"\" \"" + filePath.toWString() + L";" + toWString(lineNumber) + L"\"";
  41. #if BS_PLATFORM == BS_PLATFORM_WIN32
  42. WString pathStr = mExecPath.toWString();
  43. ShellExecuteW(0, L"open", pathStr.c_str(), args.c_str(), NULL, SW_HIDE);
  44. #elif BS_PLATFORM == BS_PLATFORM_LINUX
  45. String narrowArgs = UTF8::fromWide(args);
  46. const char* commandPattern = "flatpak run com.xamarin.MonoDevelop %s";
  47. char* commandStr = (char*)bs_stack_alloc((UINT32)narrowArgs.size() + (UINT32)strlen(commandPattern) + 1);
  48. sprintf(commandStr, commandPattern, narrowArgs.c_str());
  49. system(commandStr);
  50. bs_stack_free(commandStr);
  51. #endif
  52. }
  53. void MDCodeEditor::syncSolution(const CodeSolutionData& data, const Path& outputPath) const
  54. {
  55. String solutionString = CSProject::writeSolution(CSProjectVersion::MonoDevelop, data);
  56. solutionString = StringUtil::replaceAll(solutionString, "\n", "\r\n");
  57. Path solutionPath = outputPath;
  58. solutionPath.append(data.name + L".sln");
  59. for (auto& project : data.projects)
  60. {
  61. String projectString = CSProject::writeProject(CSProjectVersion::MonoDevelop, project);
  62. projectString = StringUtil::replaceAll(projectString, "\n", "\r\n");
  63. Path projectPath = outputPath;
  64. projectPath.append(project.name + L".csproj");
  65. SPtr<DataStream> projectStream = FileSystem::createAndOpenFile(projectPath);
  66. projectStream->write(projectString.c_str(), projectString.size() * sizeof(String::value_type));
  67. projectStream->close();
  68. }
  69. SPtr<DataStream> solutionStream = FileSystem::createAndOpenFile(solutionPath);
  70. solutionStream->write(solutionString.c_str(), solutionString.size() * sizeof(String::value_type));
  71. solutionStream->close();
  72. }
  73. MDCodeEditorFactory::MDCodeEditorFactory()
  74. {
  75. #if BS_PLATFORM == BS_PLATFORM_WIN32
  76. #if BS_ARCH_TYPE == BS_ARCHITECTURE_x86_64
  77. BOOL is64bit = 1;
  78. #else
  79. BOOL is64bit = 0;
  80. HANDLE process = GetCurrentProcess();
  81. IsWow64Process(process, (PBOOL)&is64bit);
  82. #endif
  83. WString registryKeyRoot;
  84. if (is64bit)
  85. registryKeyRoot = L"SOFTWARE\\Wow6432Node\\";
  86. else
  87. registryKeyRoot = L"SOFTWARE\\";
  88. WString registryKey = registryKeyRoot + L"\\Xamarin\\XamarinStudio";
  89. HKEY regKey;
  90. LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, registryKey.c_str(), 0, KEY_READ, &regKey);
  91. if (result != ERROR_SUCCESS)
  92. return;
  93. WString installPath;
  94. getRegistryStringValue(regKey, L"Path", installPath, StringUtil::WBLANK);
  95. if (installPath.empty())
  96. return;
  97. mInstallPath = Path(installPath) + Path("XamarinStudio.exe");
  98. #elif BS_PLATFORM == BS_PLATFORM_LINUX
  99. Path monoDevelopDir = LinuxPlatform::getHomeDir();
  100. monoDevelopDir.append(".local/share/flatpak/app/com.xamarin.MonoDevelop");
  101. if(FileSystem::exists(monoDevelopDir))
  102. mInstallPath = monoDevelopDir;
  103. #endif
  104. if (!mInstallPath.isEmpty())
  105. mSupportedEditors.push_back(CodeEditorType::MonoDevelop);
  106. }
  107. CodeEditor* MDCodeEditorFactory::create(CodeEditorType type) const
  108. {
  109. if (mInstallPath.isEmpty())
  110. return nullptr;
  111. if (type != CodeEditorType::MonoDevelop)
  112. return nullptr;
  113. return bs_new<MDCodeEditor>(mInstallPath);
  114. }
  115. }