using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEditor.IMGUI.Controls; using UnityEngine; using Codice.Client.Common; using Codice.Client.Common.WebApi; using Codice.CM.Common; using PlasticGui; using PlasticGui.WorkspaceWindow.Home.Repositories; using PlasticGui.WorkspaceWindow.Servers; using Unity.PlasticSCM.Editor.Tool; using Unity.PlasticSCM.Editor.UI; using Unity.PlasticSCM.Editor.UI.Progress; using Unity.PlasticSCM.Editor.UI.Tree; namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs { internal class RepositoryExplorerDialog : PlasticDialog, KnownServersListOperations.IKnownServersList, FillRepositoriesTable.IGetFilterText { protected override Rect DefaultRect { get { var baseRect = base.DefaultRect; return new Rect(baseRect.x, baseRect.y, 750, 450); } } internal static string BrowseRepository( EditorWindow parentWindow, IPlasticWebRestApi plasticWebRestApi, string defaultServer) { RepositoryExplorerDialog dialog = Create( plasticWebRestApi, defaultServer, new UnityPlasticGuiMessage()); ResponseType dialogResult = dialog.RunModal(parentWindow); if (dialogResult != ResponseType.Ok) return null; return dialog.mRepositoriesListView.GetSelectedRepository(); } void OnDisable() { mSearchField.downOrUpArrowKeyPressed -= SearchField_OnDownOrUpArrowKeyPressed; } protected override void SaveSettings() { TreeHeaderSettings.Save( mRepositoriesListView.multiColumnHeader.state, UnityConstants.REPOSITORIES_TABLE_SETTINGS_NAME); } protected override void DoComponentsArea() { if (Event.current.type == EventType.Layout) { mProgressControls.ProgressData.CopyInto( mState.ProgressData); } bool isEnabled = !mProgressControls.ProgressData.IsWaitingAsyncResult; DoToolbarArea( mSearchField, mRepositoriesListView, isEnabled, Refresh, OnServerSelected, ref mState); GUILayout.Space(10); DoListArea( mRepositoriesListView, isEnabled); } protected override string GetTitle() { return PlasticLocalization.GetString(PlasticLocalization.Name.ChooseRepositoryTitle); } protected override string GetExplanation() { return PlasticLocalization.Name.SelectRepositoryBelow.GetString(); } void SearchField_OnDownOrUpArrowKeyPressed() { mRepositoriesListView.SetFocusAndEnsureSelectedItem(); } void Refresh() { string resolvedServer = OrganizationsInformation.TryResolveServerFromInput(mState.SelectedServer); // Even if the server input cannot be resolved, we still want to fill the table so it gets reset mFillRepositoriesTable.FillTable( mRepositoriesListView, null, mProgressControls, null, new FillRepositoriesTable.SaveLastUsedServer(true), mGuiMessage, null, null, this, resolvedServer != null ? resolvedServer : mState.SelectedServer, false, false, true); } 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); } mState.AvailableServers = knownServers.Select(ResolveServer.ToDisplayString).ToList(); mState.AvailableServers.Sort(); Refresh(); } string FillRepositoriesTable.IGetFilterText.Get() { return mRepositoriesListView.searchString; } void OnServerSelected(object server) { mState.SelectedServer = server.ToString(); Repaint(); Refresh(); } static void DoToolbarArea( SearchField searchField, RepositoriesListView listView, bool isEnabled, Action refreshAction, GenericMenu.MenuFunction2 selectServerAction, ref State state) { GUILayout.BeginHorizontal(); GUILayout.Label( PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryExplorerServerLabel)); GUI.enabled = isEnabled; state.SelectedServer = DoDropDownTextField( state.SelectedServer, state.AvailableServers, selectServerAction, refreshAction); var refreshText = PlasticLocalization.GetString(PlasticLocalization.Name.RefreshButton); if (GUILayout.Button(refreshText, EditorStyles.miniButton)) refreshAction(); GUILayout.FlexibleSpace(); DrawSearchField.For(searchField, listView, SEARCH_FIELD_WIDTH); GUI.enabled = true; GUILayout.EndHorizontal(); } static void DoListArea( RepositoriesListView listView, bool isEnabled) { GUI.enabled = isEnabled; Rect treeRect = GUILayoutUtility.GetRect(0, 100000, 0, 100000); listView.OnGUI(treeRect); GUI.enabled = true; } static string DoDropDownTextField( string text, List options, GenericMenu.MenuFunction2 selectServerAction, Action enterKeyAction) { bool isEnterKeyPressed = false; Event e = Event.current; if (Keyboard.IsReturnOrEnterKeyPressed(e)) { isEnterKeyPressed = true; } string result = DropDownTextField.DoDropDownTextField( text, DROPDOWN_CONTROL_NAME, options, selectServerAction, GUILayout.Width(DROPDOWN_WIDTH)); if (isEnterKeyPressed && GUI.GetNameOfFocusedControl() == DROPDOWN_CONTROL_NAME) { e.Use(); enterKeyAction(); } return result; } static RepositoryExplorerDialog Create( IPlasticWebRestApi plasticWebRestApi, string defaultServer, GuiMessage.IGuiMessage guiMessage) { var instance = CreateInstance(); instance.mGuiMessage = guiMessage; instance.mEnterKeyAction = instance.OkButtonAction; instance.mEscapeKeyAction = instance.CancelButtonAction; instance.BuildComponents(defaultServer, plasticWebRestApi); return instance; } void BuildComponents( string defaultServer, IPlasticWebRestApi plasticWebRestApi) { mSearchField = new SearchField(); mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed; RepositoriesListHeaderState headerState = RepositoriesListHeaderState.GetDefault(); TreeHeaderSettings.Load(headerState, UnityConstants.REPOSITORIES_TABLE_SETTINGS_NAME, (int)RepositoriesListColumn.Name); mRepositoriesListView = new RepositoriesListView( headerState, RepositoriesListHeaderState.GetColumnNames(), OkButtonAction); mRepositoriesListView.Reload(); mFillRepositoriesTable = new FillRepositoriesTable( new LocalRepositoriesProvider()); mState = new State() { SelectedServer = ResolveServer.ToDisplayString(defaultServer), ProgressData = new ProgressControlsForDialogs.Data() }; KnownServersListOperations.GetCombinedServers( true, new List(), mProgressControls, this, plasticWebRestApi, CmConnection.Get().GetProfileManager()); } SearchField mSearchField; RepositoriesListView mRepositoriesListView; FillRepositoriesTable mFillRepositoriesTable; State mState; GuiMessage.IGuiMessage mGuiMessage; const string DROPDOWN_CONTROL_NAME = "RepositoryExplorerDialog.ServerDropdown"; const float DROPDOWN_WIDTH = 250; const float SEARCH_FIELD_WIDTH = 450; class State { internal List AvailableServers { get; set; } internal string SelectedServer { get; set; } internal ProgressControlsForDialogs.Data ProgressData { get; set; } } } }