/* * Copyright 2013-2016 consulo.io * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package consulo.unity3d.jsonApi; import java.awt.Window; import java.io.File; import java.util.Collections; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.intellij.ide.actions.ImportModuleAction; import com.intellij.ide.util.newProjectWizard.AddModuleWizard; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkTable; import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.WindowManager; import com.intellij.ui.mac.foundation.Foundation; import com.intellij.ui.mac.foundation.ID; import com.intellij.ui.mac.foundation.MacUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.WinDef; import consulo.buildInWebServer.api.JsonPostRequestHandler; import consulo.buildInWebServer.api.RequestFocusHttpRequestHandler; import consulo.unity3d.bundle.Unity3dBundleType; import consulo.unity3d.projectImport.Unity3dModuleImportProvider; import consulo.unity3d.projectImport.UnityModuleImportContext; /** * @author VISTALL * @since 14.11.2015 */ public class UnityOpenFilePostHandler extends JsonPostRequestHandler<UnityOpenFilePostHandlerRequest> { private static final Set<String> ourSupportedContentTypes = ContainerUtil.newHashSet("UnityEditor.MonoScript", "UnityEngine.Shader"); public UnityOpenFilePostHandler() { super("unityOpenFile", UnityOpenFilePostHandlerRequest.class); } @NotNull @Override public JsonResponse handle(@NotNull final UnityOpenFilePostHandlerRequest body) { String contentType = body.contentType; if(!ourSupportedContentTypes.contains(contentType)) { return JsonResponse.asError("unsupported-content-type"); } UIUtil.invokeLaterIfNeeded(() -> { VirtualFile projectVirtualFile = LocalFileSystem.getInstance().findFileByPath(body.projectPath); if(projectVirtualFile != null) { Project openedProject = null; Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); for(Project openProject : openProjects) { if(projectVirtualFile.equals(openProject.getBaseDir())) { openedProject = openProject; break; } } if(openedProject == null) { if(!new File(projectVirtualFile.getPath(), Project.DIRECTORY_STORE_FOLDER).exists()) { String sdkPath = SystemInfo.isMac ? body.editorPath : new File(body.editorPath).getParentFile().getParentFile().getPath(); VirtualFile sdkFileHome = LocalFileSystem.getInstance().findFileByPath(sdkPath); if(sdkFileHome == null) { RequestFocusHttpRequestHandler.activateFrame(WindowManager.getInstance().findVisibleFrame()); Messages.showErrorDialog("Unity path is not resolved: " + sdkPath, "Consulo"); return; } Sdk targetSdk = null; List<Sdk> sdksOfType = SdkTable.getInstance().getSdksOfType(Unity3dBundleType.getInstance()); for(Sdk sdk : sdksOfType) { VirtualFile homeDirectory = sdk.getHomeDirectory(); if(sdkFileHome.equals(homeDirectory)) { targetSdk = sdk; break; } } if(targetSdk == null) { targetSdk = SdkConfigurationUtil.createAndAddSDK(sdkPath, Unity3dBundleType.getInstance(), false); } if(targetSdk == null) { RequestFocusHttpRequestHandler.activateFrame(WindowManager.getInstance().findVisibleFrame()); Messages.showErrorDialog("Unity SDK cant add by path: " + sdkPath, "Consulo"); return; } Unity3dModuleImportProvider importProvider = new Unity3dModuleImportProvider(); AddModuleWizard wizard = ImportModuleAction.createImportWizard(null, null, projectVirtualFile, Collections.singletonList(importProvider)); if(wizard == null) { return; } UnityModuleImportContext importContext = (UnityModuleImportContext) wizard.getWizardContext().getModuleImportContext(importProvider); importContext.setSdk(targetSdk); importContext.setRequestor(body); List<Module> fromWizard = ImportModuleAction.createFromWizard(null, wizard); if(fromWizard.isEmpty()) { return; } wizard.close(DialogWrapper.OK_EXIT_CODE); final Project temp = fromWizard.get(0).getProject(); activateFrame(temp, body); } else { try { openedProject = ProjectManager.getInstance().loadAndOpenProject(projectVirtualFile.getPath()); } catch(Exception e) { Messages.showErrorDialog("Fail to open project by path: " + projectVirtualFile.getPath(), "Consulo"); } activateFrame(openedProject, body); openFile(openedProject, body); } } else { activateFrame(openedProject, body); openFile(openedProject, body); } } }); return JsonResponse.asSuccess(null); } private void activateFrame(@Nullable Project openedProject, @NotNull UnityOpenFilePostHandlerRequest body) { if(openedProject == null) { return; } IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(openedProject); if(SystemInfo.isMac) { RequestFocusHttpRequestHandler.activateFrame(ideFrame); ID id = MacUtil.findWindowFromJavaWindow((Window) ideFrame); if(id != null) { Foundation.invoke(id, "makeKeyAndOrderFront:", ID.NIL); } } else if(SystemInfo.isWindows) { Pointer windowPointer = Native.getWindowPointer((Window) ideFrame); User32.INSTANCE.SetForegroundWindow(new WinDef.HWND(windowPointer)); } else { RequestFocusHttpRequestHandler.activateFrame(ideFrame); } } public static void openFile(@Nullable Project openedProject, @NotNull UnityOpenFilePostHandlerRequest body) { if(openedProject == null) { return; } VirtualFile fileByPath = LocalFileSystem.getInstance().findFileByPath(body.filePath); if(fileByPath != null) { OpenFileDescriptor descriptor = new OpenFileDescriptor(openedProject, fileByPath, body.line - 1, -1); FileEditorManager.getInstance(openedProject).openTextEditor(descriptor, true); } } }