using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using Codice.Client.Common; using Codice.Client.Common.Threading; using Codice.CM.Common; using PlasticGui; using PlasticGui.WorkspaceWindow.Home.Repositories; using PlasticGui.WebApi; using PlasticGui.WorkspaceWindow.Servers; using Unity.PlasticSCM.Editor.Tool; using Unity.PlasticSCM.Editor.UI; using Unity.PlasticSCM.Editor.UI.Progress; namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs { internal class CreateRepositoryDialog : PlasticDialog, KnownServersListOperations.IKnownServersList { protected override Rect DefaultRect { get { var baseRect = base.DefaultRect; return new Rect(baseRect.x, baseRect.y, 600, 340); } } internal static RepositoryCreationData CreateRepository( EditorWindow parentWindow, IPlasticWebRestApi plasticWebRestApi, string proposedRepositoryName, string proposedServer, string lastUsedRepServer, string clientConfServer) { string server = CreateRepositoryDialogUserAssistant.GetProposedServer( proposedServer, lastUsedRepServer, clientConfServer); CreateRepositoryDialog dialog = Create( plasticWebRestApi, new ProgressControlsForDialogs(), proposedRepositoryName, server); ResponseType dialogResult = dialog.RunModal(parentWindow); bool dialogResultOk = dialogResult == ResponseType.Ok; RepositoryCreationData result = dialogResultOk ? dialog.BuildCreationData() : new RepositoryCreationData(); result.Result = dialogResultOk; return result; } protected override void OnModalGUI() { Title(PlasticLocalization.Name.NewRepositoryTitle.GetString()); Paragraph(PlasticLocalization.Name.NewRepositoryExplanation.GetString()); Paragraph(PlasticLocalization.Name.CreateRepositoryDialogDetailedExplanation.GetString()); if (Event.current.type == EventType.Layout) { mProgressControls.ProgressData.CopyInto(mProgressData); } GUILayout.Space(5); DoEntriesArea(); DrawProgressForDialogs.For(mProgressControls.ProgressData); GUILayout.FlexibleSpace(); DoButtonsArea(); mProgressControls.ForcedUpdateProgress(this); } protected override string GetTitle() { return PlasticLocalization.Name.NewRepositoryTitle.GetString(); } void KnownServersListOperations.IKnownServersList.FillValues(List knownServers) { // Filter out local server if there is no local installation // TODO Remove if a unified solution is applied to the unityplastic library if (knownServers.Contains(LocalOnlyServer.Alias) && !IsExeAvailable.ForLocalServer()) { knownServers.Remove(LocalOnlyServer.Alias); } mKnownServers = knownServers.Select(ResolveServer.ToDisplayString).ToList(); mKnownServers.Sort(); OnServerSelected(mSelectedServer); } void DoEntriesArea() { mRepositoryName = TextEntry( PlasticLocalization.Name.RepositoryNameShortLabel.GetString(), mRepositoryName, REPONAME_CONTROL_NAME, ENTRY_WIDTH, ENTRY_X); if (!mFocusIsAreadySet) { mFocusIsAreadySet = true; GUI.FocusControl(REPONAME_CONTROL_NAME); } GUILayout.Space(5); mSelectedServer = ComboBox( PlasticLocalization.Name.RepositoryServerOrOrganizationLabel.GetString(), mSelectedServer, mKnownServers, OnServerSelected, ENTRY_WIDTH, ENTRY_X); if (OrganizationsInformation.IsUnityOrganization(mSelectedServer) && mKnownServers.Contains(mSelectedServer)) { GUILayout.Space(5); DoOrganizationProjectsDropdown(); DoCreateOrganizationProjectLink(); } else { mSelectedProject = null; mCurrentServerProjects = null; } } void DoOrganizationProjectsDropdown() { if (mIsLoadingProjects || mSelectedProject == null) { GUI.enabled = false; } ComboBox( PlasticLocalization.Name.OrganizationProjectLabel.GetString(), mSelectedProject, mCurrentServerProjects, OnProjectSelected, ENTRY_WIDTH, ENTRY_X); GUI.enabled = true; } void DoCreateOrganizationProjectLink() { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button( PlasticLocalization.Name.CreateOrganizationProjectLabel.GetString(), UnityStyles.LinkLabel, GUILayout.Height(20))) { string resolvedServer = OrganizationsInformation.TryResolveServerFromInput(mSelectedServer); if (!string.IsNullOrEmpty(resolvedServer)) { string organizationName = ServerOrganizationParser.GetOrganizationFromServer(resolvedServer); Application.OpenURL(UnityUrl.UnityDashboard.UnityOrganizations.GetProjectsUrl(organizationName)); } } GUILayout.EndHorizontal(); } void OnServerSelected(object server) { ((IProgressControls) mProgressControls).HideProgress(); mProgressControls.ProgressData.StatusMessage = string.Empty; mProgressControls.ProgressData.StatusType = MessageType.None; mIsLoadingProjects = false; if (server == null || string.IsNullOrEmpty(server.ToString())) { mSelectedServer = null; mSelectedProject = null; mCurrentServerProjects = null; return; } mSelectedServer = server.ToString(); // We need to ensure it is a known server because the dropdown is editable if (OrganizationsInformation.IsUnityOrganization(mSelectedServer) && mKnownServers.Contains(mSelectedServer)) { LoadServerProjects(mSelectedServer); } else { mSelectedProject = null; } Repaint(); } void OnFocus() { OnServerSelected(mSelectedServer); } void OnProjectSelected(object project) { mSelectedProject = project.ToString(); Repaint(); } void LoadServerProjects(string server) { mIsLoadingProjects = true; mCurrentServerProjects = null; ((IProgressControls) mProgressControls).ShowProgress( PlasticLocalization.Name.RetrievingServerProjects.GetString()); List serverProjects = null; IThreadWaiter waiter = ThreadWaiter.GetWaiter(); waiter.Execute( /*threadOperationDelegate*/ delegate { string serverName = ResolveServer.FromUserInput(server, CmConnection.Get().UnityOrgResolver); serverProjects = OrganizationsInformation.GetOrganizationProjects(serverName); }, /*afterOperationDelegate*/ delegate { mIsLoadingProjects = false; if (waiter.Exception != null) { ((IProgressControls) mProgressControls).ShowError( PlasticLocalization.Name.ErrorRetrievingServerProjects.GetString()); } mCurrentServerProjects = serverProjects; if (mCurrentServerProjects == null || mCurrentServerProjects.Count == 0) { mSelectedProject = null; mProposedProject = null; ((IProgressControls) mProgressControls).ShowError( PlasticLocalization.Name.NoServerProjectsFound.GetString()); return; } if (!string.IsNullOrEmpty(mProposedProject)) { mSelectedProject = mProposedProject; mProposedProject = null; } if (string.IsNullOrEmpty(mSelectedProject) || !mCurrentServerProjects.Contains(mSelectedProject)) { mSelectedProject = mCurrentServerProjects.First(); } ((IProgressControls) mProgressControls).HideProgress(); }); } void DoButtonsArea() { using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); if (Application.platform == RuntimePlatform.WindowsEditor) { DoOkButton(); DoCancelButton(); return; } DoCancelButton(); DoOkButton(); } } void DoOkButton() { if (mIsLoadingProjects || (OrganizationsInformation.IsUnityOrganization(mSelectedServer) && string.IsNullOrEmpty(mSelectedProject))) { GUI.enabled = false; } if (AcceptButton(PlasticLocalization.Name.OkButton.GetString())) { OkButtonWithValidationAction(); } GUI.enabled = true; } void DoCancelButton() { if (!NormalButton(PlasticLocalization.Name.CancelButton.GetString())) return; CancelButtonAction(); } void OkButtonWithValidationAction() { // If the validation goes OK, this method closes the dialog RepositoryCreationValidation.AsyncValidation( BuildCreationData(), this, mProgressControls); } void OnEnterKeyAction() { if (!OrganizationsInformation.IsUnityOrganization(mSelectedServer)) { OkButtonWithValidationAction(); return; } if (mKnownServers.Contains(mSelectedServer)) { if (string.IsNullOrEmpty(mSelectedProject)) { OnServerSelected(mSelectedServer); } else { OkButtonWithValidationAction(); } } } RepositoryCreationData BuildCreationData() { string resolvedServer = OrganizationsInformation.TryResolveServerFromInput(mSelectedServer); string repositoryName = mSelectedProject != null ? string.Format("{0}/{1}", mSelectedProject, mRepositoryName) : mRepositoryName; return new RepositoryCreationData( repositoryName, resolvedServer != null ? resolvedServer : mSelectedServer); } static CreateRepositoryDialog Create( IPlasticWebRestApi plasticWebRestApi, ProgressControlsForDialogs progressControls, string proposedRepositoryName, string proposedServer) { var instance = CreateInstance(); instance.mEnterKeyAction = instance.OnEnterKeyAction; instance.mEscapeKeyAction = instance.CancelButtonAction; instance.mPlasticWebRestApi = plasticWebRestApi; instance.mProgressControls = progressControls; instance.BuildComponents(proposedRepositoryName, proposedServer); return instance; } void BuildComponents(string proposedRepositoryName, string proposedServer) { mSelectedServer = ResolveServer.ToDisplayString(proposedServer); mRepositoryName = proposedRepositoryName; if (OrganizationsInformation.IsUnityOrganization(proposedServer)) { string[] repositoryNameParts = proposedRepositoryName.Split('/'); if (repositoryNameParts.Length > 1) { mProposedProject = repositoryNameParts[0].Trim(); mRepositoryName = repositoryNameParts[repositoryNameParts.Length - 1].Trim(); } } KnownServersListOperations.GetCombinedServers( true, GetExtraServers(proposedServer), mProgressControls, this, mPlasticWebRestApi, CmConnection.Get().GetProfileManager()); } static List GetExtraServers(string proposedServer) { List result = new List(); if (!string.IsNullOrEmpty(proposedServer)) result.Add(proposedServer); return result; } IPlasticWebRestApi mPlasticWebRestApi; bool mFocusIsAreadySet; string mRepositoryName; string mSelectedServer; string mSelectedProject; string mProposedProject; bool mIsLoadingProjects; List mCurrentServerProjects; List mKnownServers = new List(); ProgressControlsForDialogs.Data mProgressData = new ProgressControlsForDialogs.Data(); ProgressControlsForDialogs mProgressControls; const float ENTRY_WIDTH = 400; const float ENTRY_X = 175f; const string REPONAME_CONTROL_NAME = "CreateRepositoryDialog.RepositoryName"; } }