Просмотр исходного кода

WIP: Linux port
- File browse dialog added
- Generic "open" file/URL command added

Marko Pintera 8 лет назад
Родитель
Сommit
68084885cb

+ 3 - 0
Documentation/GitHub/compiling.md

@@ -75,6 +75,9 @@ The following dependencies will need to be installed manually. Which ones are re
     - Debian/Ubuntu: *apt-get install libx11-dev libxcursor-dev libxrandr-dev*
   - **LibUUID**
     - Debian/Ubuntu: *apt-get install uuid-dev*
+  - **GTK+ 3.0** (Editor only)
+    - Optional if not building the editor
+    - Debian/Ubuntu: *apt-get install libgtk-3-dev*
   - (Or equivalent packages for your distribution)
 
 **All OS**

+ 1 - 2
Source/BansheeCore/CMakeSources.cmake

@@ -593,7 +593,6 @@ set(BS_BANSHEECORE_SRC_PLATFORM
 set(BS_BANSHEECORE_SRC_PLATFORM_WIN32
 	"Win32/BsWin32FolderMonitor.cpp"
 	"Win32/BsWin32Platform.cpp"
-	"Win32/BsWin32BrowseDialogs.cpp"
 )
 
 set(BS_BANSHEECORE_INC_PLATFORM_UNIX
@@ -707,4 +706,4 @@ set(BS_BANSHEECORE_SRC
 	${BS_BANSHEECORE_SRC_IMAGE}
 	${BS_BANSHEECORE_INC_MESH}
 	${BS_BANSHEECORE_SRC_MESH}
-)
+)

+ 13 - 0
Source/BansheeCore/Linux/BsLinuxPlatform.cpp

@@ -478,6 +478,19 @@ namespace bs
 		return L"";
 	}
 
+	void Platform::openFolder(const Path& path)
+	{
+		String pathString = path.toString();
+
+		const char* commandPattern = "xdg-open '%s'";
+
+		char* commandStr = (char*)bs_stack_alloc((UINT32)pathString.size() + (UINT32)strlen(commandPattern) + 1);
+		sprintf(commandStr, commandPattern, pathString.c_str());
+
+		system(commandStr);
+		bs_stack_free(commandStr);
+	}
+
 	/**
 	 * Converts an X11 KeySym code into an input command, if possible. Returns true if conversion was done.
 	 *

+ 3 - 9
Source/BansheeCore/Platform/BsPlatform.h

@@ -331,17 +331,11 @@ namespace bs
 		static void destroyDropTarget(OSDropTarget& target);
 
 		/**
-		 * Displays a platform specific file/folder open/save dialog.
+		 * Opens the provided folder using the default application, as specified by the operating system.
 		 *
-		 * @param[in]	type		Type of dialog to open.
-		 * @param[in]	defaultPath	Initial path the dialog will be set to once opened.
-		 * @param[in]	filterList	Semi-colon separated list of file names or types to display in the dialog, 
-		 *							for example "exe;txt;png". Ignored if dialog is to display folders instead of files.
-		 * @param[out]	paths		Output list of selected file or folder paths (if any).
-		 * @return					True if file was selected and false if selection was canceled.
+		 * @param[in]	path	Absolute path to the folder to open.
 		 */
-		static bool openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
-			Vector<Path>& paths);
+		static void openFolder(const Path& path);
 
 		/**
 		 * Adds a string to the clipboard.

+ 5 - 0
Source/BansheeCore/Win32/BsWin32Platform.cpp

@@ -367,6 +367,11 @@ namespace bs
 		return StringUtil::WBLANK;
 	}
 
+	void Platform::openFolder(const Path& path)
+	{
+		ShellExecuteW(nullptr, L"open", path.toWString().c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+	}
+
 	void Platform::_messagePump()
 	{
 		MSG  msg;

+ 13 - 5
Source/BansheeEditor/CMakeLists.txt

@@ -1,6 +1,12 @@
 # Source files and their filters
 include(CMakeSources.cmake)
 
+# Find packages
+if(LINUX)
+	find_package(PkgConfig REQUIRED)
+	pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
+endif()
+
 # Includes
 set(BansheeEditor_INC 
 	"./" 
@@ -8,7 +14,7 @@ set(BansheeEditor_INC
 	"../BansheeCore"
 	"../BansheeEngine")
 
-include_directories(${BansheeEditor_INC})	
+include_directories(${BansheeEditor_INC})
 
 # Target
 add_library(BansheeEditor SHARED ${BS_BANSHEEEDITOR_SRC})
@@ -18,13 +24,15 @@ target_compile_definitions(BansheeEditor PRIVATE -DBS_ED_EXPORTS)
 
 # Libraries
 ## Local libs
-target_link_libraries(BansheeEditor BansheeUtility BansheeCore BansheeEngine)	
+target_link_libraries(BansheeEditor PUBLIC BansheeUtility BansheeCore BansheeEngine)
 	
-## OS libs
 if(WIN32)
-target_link_libraries(BansheeEditor Advapi32)
+	## OS libs
+	target_link_libraries(BansheeEditor PRIVATE Advapi32)
 else()
-	# TODO_OTHER_PLATFORMS_GO_HERE
+	## External lib: GTK+ 3.0
+	include_directories(${GTK3_INCLUDE_DIRS})
+	target_link_libraries(BansheeEditor PRIVATE ${GTK3_LIBRARIES})
 endif()
 
 # IDE specific

+ 18 - 8
Source/BansheeEditor/CMakeSources.cmake

@@ -231,20 +231,28 @@ set(BS_BANSHEEEDITOR_SRC_CODEEDITOR
 	"CodeEditor/BsCodeEditor.cpp"
 )
 
-set(BS_BANSHEEEDITOR_INC_CODEEDITOR_WIN32
+set(BS_BANSHEEEDITOR_INC_WIN32
 	"Win32/BsVSCodeEditor.h"
 )
 
-set(BS_BANSHEEEDITOR_SRC_CODEEDITOR_WIN32
+set(BS_BANSHEEEDITOR_SRC_WIN32
 	"Win32/BsVSCodeEditor.cpp"
+	"Win32/BsWin32BrowseDialogs.cpp"
+)
+
+set(BS_BANSHEEEDITOR_INC_LINUX
+)
+
+set(BS_BANSHEEEDITOR_SRC_LINUX
+	"Linux/BsLinuxBrowseDialogs.cpp"
 )
 
 if(WIN32)
-	list(APPEND BS_BANSHEEEDITOR_INC_PLATFORM ${BS_BANSHEEEDITOR_INC_PLATFORM_WIN32})
-	list(APPEND BS_BANSHEEEDITOR_SRC_PLATFORM ${BS_BANSHEEEDITOR_SRC_PLATFORM_WIN32})
-	
-	list(APPEND BS_BANSHEEEDITOR_INC_CODEEDITOR ${BS_BANSHEEEDITOR_INC_CODEEDITOR_WIN32})
-	list(APPEND BS_BANSHEEEDITOR_SRC_CODEEDITOR ${BS_BANSHEEEDITOR_SRC_CODEEDITOR_WIN32})	
+	list(APPEND BS_BANSHEEEDITOR_INC_PLATFORM ${BS_BANSHEEEDITOR_INC_WIN32})
+	list(APPEND BS_BANSHEEEDITOR_SRC_PLATFORM ${BS_BANSHEEEDITOR_SRC_WIN32})
+elseif(LINUX)
+	list(APPEND BS_BANSHEEEDITOR_INC_PLATFORM ${BS_BANSHEEEDITOR_INC_LINUX})
+	list(APPEND BS_BANSHEEEDITOR_SRC_PLATFORM ${BS_BANSHEEEDITOR_SRC_LINUX})
 endif()
 
 source_group("Header Files\\Settings" FILES ${BS_BANSHEEEDITOR_INC_SETTINGS})
@@ -299,4 +307,6 @@ set(BS_BANSHEEEDITOR_SRC
 	${BS_BANSHEEEDITOR_SRC_BUILD}
 	${BS_BANSHEEEDITOR_SRC_HANDLES}
 	${BS_BANSHEEEDITOR_INC_TESTING}
-)
+	${BS_BANSHEEEDITOR_INC_PLATFORM}
+	${BS_BANSHEEEDITOR_SRC_PLATFORM}
+)

+ 98 - 0
Source/BansheeEditor/Linux/BsLinuxBrowseDialogs.cpp

@@ -0,0 +1,98 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "Utility/BsEditorUtility.h"
+#include <gtk/gtk.h>
+#include <String/BsUnicode.h>
+
+namespace bs
+{
+	// Note: Code below is the only reason we depend on GTK. Ideally we replace the GTK file dialog with built-in file
+	// dialog that can be used transparently across platforms, in which case we can also drop GTK.
+	bool EditorUtility::openBrowseDialog(FileDialogType type, const Path& defaultPath, const String& filterList,
+									Vector<Path>& paths)
+	{
+		GtkWidget* fakeParent = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+		const char* titleString;
+		const char* cancelString;
+		const char* acceptString;
+		GtkFileChooserAction action;
+
+		if(((int)type & (int)FileDialogType::OpenFile) != 0)
+		{
+			titleString = "Open File";
+			cancelString = "Cancel";
+			acceptString = "Open";
+			action = GTK_FILE_CHOOSER_ACTION_OPEN;
+		}
+		else if(((int)type & (int)FileDialogType::OpenFolder) != 0)
+		{
+			titleString = "Open Folder";
+			cancelString = "Cancel";
+			acceptString = "Open";
+			action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
+		}
+		else // Save dialog
+		{
+			titleString = "Save File";
+			cancelString = "Cancel";
+			acceptString = "Save";
+			action = GTK_FILE_CHOOSER_ACTION_SAVE;
+		}
+
+		GtkWidget* fileDialog = gtk_file_chooser_dialog_new(titleString,
+				GTK_WINDOW(fakeParent), action, cancelString, GTK_RESPONSE_CANCEL,
+				acceptString, GTK_RESPONSE_ACCEPT, nullptr);
+
+		GtkFileChooser* chooser = GTK_FILE_CHOOSER(fileDialog);
+
+		gboolean selectMultiple = ((int)type & (int)FileDialogType::Multiselect) != 0;
+		gtk_file_chooser_set_select_multiple(chooser, selectMultiple);
+		gtk_file_chooser_set_do_overwrite_confirmation(chooser, true);
+
+		String defaultPathStr = defaultPath.toString();
+		if(!defaultPathStr.empty())
+			gtk_file_chooser_set_current_folder(chooser, defaultPathStr.c_str());
+
+		if(!filterList.empty())
+		{
+			GtkFileFilter* fileFilter = gtk_file_filter_new();
+
+			gtk_file_filter_set_name(fileFilter, filterList.c_str());
+			gtk_file_filter_add_pattern(fileFilter, filterList.c_str());
+			gtk_file_chooser_add_filter(chooser, fileFilter);
+		}
+
+		// TODO - Can't set transient-for because the windows belong to two different X11 displays. I'd have to use gtk
+		// display as the primary display (which is too awkward to be worth it)
+		//GdkDisplay* gdkDisplay = gdk_x11_lookup_xdisplay(x11display);// gtk_widget_get_display(fileDialog);;
+		//GdkWindow* parentWindow = gdk_x11_window_foreign_new_for_display(gdkDisplay, xParent);
+		//gdk_window_set_transient_for(gtk_widget_get_window(fileDialog), parentWindow);
+
+		gint response = gtk_dialog_run(GTK_DIALOG(fileDialog));
+		if(response == GTK_RESPONSE_ACCEPT)
+		{
+			GSList* filenames = gtk_file_chooser_get_filenames(chooser);
+
+			guint numElems = g_slist_length(filenames);
+			for(guint i = 0; i < numElems; ++i)
+			{
+				char* filename = (char*)g_slist_nth_data(filenames, i);
+				paths.push_back(String(filename));
+
+				g_free(filename);
+			}
+
+			g_slist_free(filenames);
+		}
+
+		gtk_widget_destroy(fileDialog);
+		gtk_widget_destroy(fakeParent);
+
+		// Make sure the destroy events are processed
+		while(gtk_events_pending())
+			gtk_main_iteration();
+
+		return response == GTK_RESPONSE_ACCEPT;
+	}
+}

+ 23 - 0
Source/BansheeEditor/Utility/BsEditorUtility.h

@@ -11,6 +11,16 @@ namespace bs
 	 *  @{
 	 */
 
+	/** Possible type of platform file dialogs. */
+	enum class FileDialogType
+	{
+		OpenFile = 0x0,
+		OpenFolder = 0x1,
+		Save = 0x2,
+		Multiselect = 0x10000,
+		TypeMask = 0xFFFF
+	};
+
 	/**	Contains miscellaneous helper methods. */
 	class BS_ED_EXPORT EditorUtility
 	{
@@ -62,6 +72,19 @@ namespace bs
 		 */
 		static void restoreIds(const HSceneObject& restored, SceneObjProxy& proxy);
 
+		/**
+		 * Displays a platform specific file/folder open/save dialog.
+		 *
+		 * @param[in]	type		Type of dialog to open.
+		 * @param[in]	defaultPath	Initial path the dialog will be set to once opened.
+		 * @param[in]	filterList	Semi-colon separated list of file names or types to display in the dialog,
+		 *							for example "exe;txt;png". Ignored if dialog is to display folders instead of files.
+		 * @param[out]	paths		Output list of selected file or folder paths (if any).
+		 * @return					True if file was selected and false if selection was canceled.
+		 */
+		static bool openBrowseDialog(FileDialogType type, const Path& defaultPath, const String& filterList,
+									 Vector<Path>& paths);
+
 	private:
 		/**
 		 * Retrieves all components containing meshes on the specified object and outputs their bounds.

+ 8 - 6
Source/BansheeCore/Win32/BsWin32BrowseDialogs.cpp → Source/BansheeEditor/Win32/BsWin32BrowseDialogs.cpp

@@ -1,9 +1,9 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsCorePrerequisites.h"
-#include "Platform/BsPlatform.h"
+#include "Utility/BsEditorUtility.h"
 #include "Threading/BsAsyncOp.h"
 #include "CoreThread/BsCoreThread.h"
+#include "String/BsUnicode.h"
 #include "Win32/BsWin32Window.h"
 #include <ShObjIdl.h>
 
@@ -11,14 +11,16 @@ using namespace std::placeholders;
 
 namespace bs
 {
-	void addFiltersToDialog(IFileDialog* fileDialog, const WString& filterList)
+	void addFiltersToDialog(IFileDialog* fileDialog, const String& filterList)
 	{
 		const wchar_t EMPTY_WSTR[] = L"";
 
 		if (filterList.empty())
 			return;
 
-		Vector<WString> filters = StringUtil::split(filterList, L";");
+		WString wideFilterList = UTF8::toWide(filterList);
+
+		Vector<WString> filters = StringUtil::split(wideFilterList, L";");
 		UINT32 numFilters = (UINT32)filters.size();
 		if (numFilters == 0)
 			return;
@@ -77,7 +79,7 @@ namespace bs
 		}
 	}
 
-	void openBrowseDialogCore(FileDialogType type, const Path& defaultPath, const WString& filterList,
+	void openBrowseDialogCore(FileDialogType type, const Path& defaultPath, const String& filterList,
 		Vector<Path>& paths, AsyncOp& returnValue)
 	{
 		// Init COM library.
@@ -166,7 +168,7 @@ namespace bs
 		returnValue._completeOperation(finalResult);
 	}
 
-	bool Platform::openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
+	bool EditorUtility::openBrowseDialog(FileDialogType type, const Path& defaultPath, const String& filterList,
 		Vector<Path>& paths)
 	{
 		AsyncOp returnValue = gCoreThread().queueReturnCommand(std::bind(&openBrowseDialogCore, type, 

+ 0 - 18
Source/BansheeUtility/Utility/BsPlatformUtility.h

@@ -14,16 +14,6 @@ namespace bs
 
 	struct MACAddress;
 
-	/** Possible type of platform file dialogs. */
-	enum class FileDialogType
-	{
-		OpenFile = 0x0, 
-		OpenFolder = 0x1, 
-		Save = 0x2,
-		Multiselect = 0x10000,
-		TypeMask = 0xFFFF
-	};
-
 	/** Contains information about available GPUs on the system. */
 	struct GPUInfo
 	{
@@ -62,14 +52,6 @@ namespace bs
 		/** Creates a new universally unique identifier and returns it as a string. */
 		static String generateUUID();
 
-		/**
-		 * Opens the provided file or folder using the default application for that file type, as specified by the operating 
-		 * system.
-		 *
-		 * @param[in]	path	Absolute path to the file or folder to open.
-		 */
-		static void open(const Path& path);
-
 		/** @name Internal
 		 *  @{
 		 */

+ 0 - 5
Source/BansheeUtility/Win32/BsWin32PlatformUtility.cpp

@@ -138,11 +138,6 @@ namespace bs
 		return output;
 	}
 
-	void PlatformUtility::open(const Path& path)
-	{
-		ShellExecuteW(nullptr, L"open", path.toWString().c_str(), nullptr, nullptr, SW_SHOWNORMAL);
-	}
-
 	HBITMAP Win32PlatformUtility::createBitmap(const Color* pixels, UINT32 width, UINT32 height, bool premultiplyAlpha)
 	{
 		BITMAPINFO bi;

+ 5 - 5
Source/MBansheeEditor/General/EditorApplication.cs

@@ -703,12 +703,12 @@ namespace BansheeEditor
         }
 
         /// <summary>
-        /// Opens a file or a folder in the default external application.
+        /// Opens a folder in the default external application.
         /// </summary>
-        /// <param name="path">Absolute path to the file or folder to open.</param>
-        public static void OpenExternally(string path)
+        /// <param name="path">Absolute path to the folder to open.</param>
+        public static void OpenFolder(string path)
         {
-            Internal_OpenExternally(path);
+            Internal_OpenFolder(path);
         }
 
         /// <summary>
@@ -1036,7 +1036,7 @@ namespace BansheeEditor
         private static extern void Internal_ReloadAssemblies();
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_OpenExternally(string path);
+        private static extern void Internal_OpenFolder(string path);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_RunUnitTests();

+ 1 - 1
Source/MBansheeEditor/Windows/Build/BuildWindow.cs

@@ -110,7 +110,7 @@ namespace BansheeEditor
                 BuildManager.Build();
                 ProgressBar.Hide();
 
-                EditorApplication.OpenExternally(BuildManager.OutputFolder);
+                EditorApplication.OpenFolder(BuildManager.OutputFolder);
                 DialogBox.Open(new LocEdString("Build complete"), new LocEdString("Build complete"), DialogBox.Type.OK);
             }
         }

+ 2 - 2
Source/MBansheeEditor/Windows/Library/LibraryMenu.cs

@@ -182,7 +182,7 @@ namespace BansheeEditor
             if (win == null)
                 return;
 
-            EditorApplication.OpenExternally(Path.Combine(ProjectLibrary.ResourceFolder, win.SelectedEntry));
+            EditorApplication.OpenFolder(Path.Combine(ProjectLibrary.ResourceFolder, win.SelectedEntry));
         }
 
         /// <summary>
@@ -195,7 +195,7 @@ namespace BansheeEditor
             if (win == null)
                 return;
 
-            EditorApplication.OpenExternally(Path.Combine(ProjectLibrary.ResourceFolder, win.CurrentFolder));
+            EditorApplication.OpenFolder(Path.Combine(ProjectLibrary.ResourceFolder, win.CurrentFolder));
         }
     }
 

+ 8 - 6
Source/SBansheeEditor/Wrappers/BsScriptBrowseDialog.cpp

@@ -1,6 +1,7 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "Wrappers/BsScriptBrowseDialog.h"
+#include "Utility/BsEditorUtility.h"
 #include "BsScriptMeta.h"
 #include "BsMonoClass.h"
 #include "Platform/BsPlatform.h"
@@ -15,15 +16,16 @@ namespace bs
 		metaData.scriptClass->addInternalCall("Internal_SaveFile", (void*)&ScriptBrowseDialog::internal_SaveFile);
 	}
 
-	bool ScriptBrowseDialog::internal_OpenFile(MonoString* defaultFolder, MonoString* filterList, bool allowMultiselect, MonoArray** outPaths)
+	bool ScriptBrowseDialog::internal_OpenFile(MonoString* defaultFolder, MonoString* filterList, bool allowMultiselect,
+											   MonoArray** outPaths)
 	{
 		Path defaultFolderNative = MonoUtil::monoToWString(defaultFolder);
-		WString filterListNative = MonoUtil::monoToWString(filterList);
+		String filterListNative = MonoUtil::monoToString(filterList);
 		
 		FileDialogType type = (FileDialogType)((UINT32)FileDialogType::OpenFile | (UINT32)FileDialogType::Multiselect);
 
 		Vector<Path> paths;
-		if (Platform::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
+		if (EditorUtility::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
 		{
 			ScriptArray pathArray(MonoUtil::getStringClass(), (UINT32)paths.size());
 
@@ -50,7 +52,7 @@ namespace bs
 		FileDialogType type = FileDialogType::OpenFolder;
 
 		Vector<Path> paths;
-		if (Platform::openBrowseDialog(type, defaultFolderNative, L"", paths))
+		if (EditorUtility::openBrowseDialog(type, defaultFolderNative, "", paths))
 		{
 			if (paths.size() > 0)
 				*outPath = MonoUtil::wstringToMono(paths[0].toWString());
@@ -69,12 +71,12 @@ namespace bs
 	bool ScriptBrowseDialog::internal_SaveFile(MonoString* defaultFolder, MonoString* filterList, MonoString** outPath)
 	{
 		Path defaultFolderNative = MonoUtil::monoToWString(defaultFolder);
-		WString filterListNative = MonoUtil::monoToWString(filterList);
+		String filterListNative = MonoUtil::monoToString(filterList);
 
 		FileDialogType type = FileDialogType::Save;
 
 		Vector<Path> paths;
-		if (Platform::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
+		if (EditorUtility::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
 		{
 			if (paths.size() > 0)
 				*outPath = MonoUtil::wstringToMono(paths[0].toWString());

+ 3 - 3
Source/SBansheeEditor/Wrappers/BsScriptEditorApplication.cpp

@@ -61,7 +61,7 @@ namespace bs
 		metaData.scriptClass->addInternalCall("Internal_UnloadProject", (void*)&ScriptEditorApplication::internal_UnloadProject);
 		metaData.scriptClass->addInternalCall("Internal_CreateProject", (void*)&ScriptEditorApplication::internal_CreateProject);
 		metaData.scriptClass->addInternalCall("Internal_ReloadAssemblies", (void*)&ScriptEditorApplication::internal_ReloadAssemblies);
-		metaData.scriptClass->addInternalCall("Internal_OpenExternally", (void*)&ScriptEditorApplication::internal_OpenExternally);
+		metaData.scriptClass->addInternalCall("Internal_OpenFolder", (void*) &ScriptEditorApplication::internal_OpenFolder);
 		metaData.scriptClass->addInternalCall("Internal_RunUnitTests", (void*)&ScriptEditorApplication::internal_RunUnitTests);
 		metaData.scriptClass->addInternalCall("Internal_Quit", (void*)&ScriptEditorApplication::internal_Quit);
 		metaData.scriptClass->addInternalCall("Internal_ToggleToolbarItem", (void*)&ScriptEditorApplication::internal_ToggleToolbarItem);
@@ -272,11 +272,11 @@ namespace bs
 		mRequestAssemblyReload = true;
 	}
 
-	void ScriptEditorApplication::internal_OpenExternally(MonoString* path)
+	void ScriptEditorApplication::internal_OpenFolder(MonoString* path)
 	{
 		Path nativePath = MonoUtil::monoToWString(path);
 
-		PlatformUtility::open(nativePath);
+		Platform::openFolder(nativePath);
 	}
 
 	void ScriptEditorApplication::internal_RunUnitTests()

+ 1 - 1
Source/SBansheeEditor/Wrappers/BsScriptEditorApplication.h

@@ -62,7 +62,7 @@ namespace bs
 		static void internal_UnloadProject();
 		static void internal_CreateProject(MonoString* path);
 		static void internal_ReloadAssemblies();
-		static void internal_OpenExternally(MonoString* path);
+		static void internal_OpenFolder(MonoString* path);
 		static void internal_RunUnitTests();
 		static void internal_Quit();
 		static void internal_ToggleToolbarItem(MonoString* name, bool on);