Created unity project
This commit is contained in:
@@ -0,0 +1,336 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
using Codice.Client.Common;
|
||||
using Codice.Client.Common.Threading;
|
||||
using Codice.CM.Common;
|
||||
using PlasticGui;
|
||||
using PlasticGui.Configuration.CloudEdition;
|
||||
using PlasticGui.WorkspaceWindow.Home.Repositories;
|
||||
using PlasticGui.WorkspaceWindow.Home.Workspaces;
|
||||
using PlasticGui.WebApi;
|
||||
using Unity.PlasticSCM.Editor.AssetUtils.Processor;
|
||||
using Unity.PlasticSCM.Editor.UI.Progress;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
|
||||
{
|
||||
internal class CreateWorkspaceView :
|
||||
IPlasticDialogCloser,
|
||||
IWorkspacesRefreshableView
|
||||
{
|
||||
internal interface ICreateWorkspaceListener
|
||||
{
|
||||
void OnWorkspaceCreated(WorkspaceInfo wkInfo, bool isGluonMode);
|
||||
}
|
||||
|
||||
internal CreateWorkspaceView(
|
||||
PlasticWindow parentWindow,
|
||||
ICreateWorkspaceListener listener,
|
||||
IPlasticAPI plasticApi,
|
||||
IPlasticWebRestApi plasticWebRestApi,
|
||||
string workspacePath)
|
||||
{
|
||||
mParentWindow = parentWindow;
|
||||
mCreateWorkspaceListener = listener;
|
||||
mWorkspacePath = workspacePath;
|
||||
mPlasticWebRestApi = plasticWebRestApi;
|
||||
|
||||
mProgressControls = new ProgressControlsForViews();
|
||||
mWorkspaceOperations = new WorkspaceOperations(this, mProgressControls, null);
|
||||
mCreateWorkspaceState = CreateWorkspaceViewState.BuildForProjectDefaults();
|
||||
|
||||
Initialize(plasticApi, plasticWebRestApi);
|
||||
}
|
||||
|
||||
internal void Update()
|
||||
{
|
||||
mProgressControls.UpdateProgress(mParentWindow);
|
||||
}
|
||||
|
||||
internal void OnGUI()
|
||||
{
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
mProgressControls.ProgressData.CopyInto(
|
||||
mCreateWorkspaceState.ProgressData);
|
||||
}
|
||||
|
||||
string repository = mCreateWorkspaceState.Repository;
|
||||
|
||||
DrawCreateWorkspace.ForState(
|
||||
SelectRepository,
|
||||
CreateRepository,
|
||||
ValidateAndCreateWorkspace,
|
||||
mParentWindow,
|
||||
mPlasticWebRestApi,
|
||||
mDefaultServer,
|
||||
ref mCreateWorkspaceState);
|
||||
|
||||
if (repository == mCreateWorkspaceState.Repository)
|
||||
return;
|
||||
|
||||
SynchronizeRepositoryAndWorkspace();
|
||||
}
|
||||
|
||||
void Initialize(IPlasticAPI plasticApi, IPlasticWebRestApi plasticWebRestApi)
|
||||
{
|
||||
((IProgressControls)mProgressControls).ShowProgress(string.Empty);
|
||||
|
||||
WorkspaceInfo[] allWorkspaces = null;
|
||||
IList allRepositories = null;
|
||||
string repositoryProject = null;
|
||||
|
||||
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
|
||||
waiter.Execute(
|
||||
/*threadOperationDelegate*/ delegate
|
||||
{
|
||||
mDefaultServer = GetDefaultServer.ToCreateWorkspace(plasticWebRestApi);
|
||||
|
||||
allWorkspaces = plasticApi.GetAllWorkspacesArray();
|
||||
allRepositories = plasticApi.GetAllRepositories(mDefaultServer, true);
|
||||
|
||||
if (OrganizationsInformation.IsUnityOrganization(mDefaultServer))
|
||||
{
|
||||
List<string> serverProjects = OrganizationsInformation.GetOrganizationProjects(mDefaultServer);
|
||||
|
||||
if (serverProjects.Count > 0)
|
||||
{
|
||||
repositoryProject = serverProjects.First();
|
||||
}
|
||||
}
|
||||
},
|
||||
/*afterOperationDelegate*/ delegate
|
||||
{
|
||||
((IProgressControls) mProgressControls).HideProgress();
|
||||
|
||||
if (waiter.Exception != null)
|
||||
{
|
||||
DisplayException(mProgressControls, waiter.Exception);
|
||||
return;
|
||||
}
|
||||
|
||||
string serverSpecPart = string.Format("@{0}", ResolveServer.ToDisplayString(mDefaultServer));
|
||||
|
||||
mCreateWorkspaceState.Repository = ValidRepositoryName.Get(
|
||||
string.Format("{0}{1}", mCreateWorkspaceState.Repository, serverSpecPart),
|
||||
allRepositories);
|
||||
|
||||
if (repositoryProject != null)
|
||||
{
|
||||
mCreateWorkspaceState.Repository = string.Format("{0}/{1}", repositoryProject, mCreateWorkspaceState.Repository);
|
||||
}
|
||||
|
||||
string proposedWorkspaceName = mCreateWorkspaceState.Repository.Replace(serverSpecPart, string.Empty);
|
||||
|
||||
mCreateWorkspaceState.WorkspaceName = CreateWorkspaceDialogUserAssistant.GetNonExistingWkNameForName(
|
||||
proposedWorkspaceName, allWorkspaces);
|
||||
|
||||
mDialogUserAssistant = CreateWorkspaceDialogUserAssistant.ForWkPathAndName(
|
||||
mWorkspacePath,
|
||||
allWorkspaces);
|
||||
|
||||
SynchronizeRepositoryAndWorkspace();
|
||||
});
|
||||
}
|
||||
|
||||
void SynchronizeRepositoryAndWorkspace()
|
||||
{
|
||||
if (mDialogUserAssistant == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mDialogUserAssistant.RepositoryChanged(
|
||||
mCreateWorkspaceState.Repository,
|
||||
mCreateWorkspaceState.WorkspaceName,
|
||||
mWorkspacePath);
|
||||
|
||||
mCreateWorkspaceState.WorkspaceName = mDialogUserAssistant.GetProposedWorkspaceName();
|
||||
}
|
||||
|
||||
void SelectRepository(string repository)
|
||||
{
|
||||
mCreateWorkspaceState.Repository = repository;
|
||||
SynchronizeRepositoryAndWorkspace();
|
||||
}
|
||||
|
||||
void CreateRepository(RepositoryCreationData data)
|
||||
{
|
||||
if (!data.Result)
|
||||
return;
|
||||
|
||||
((IProgressControls)mProgressControls).ShowProgress(
|
||||
PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.CreatingRepository,
|
||||
data.RepName));
|
||||
|
||||
RepositoryInfo createdRepository = null;
|
||||
|
||||
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
|
||||
waiter.Execute(
|
||||
/*threadOperationDelegate*/ delegate
|
||||
{
|
||||
createdRepository = PlasticGui.Plastic.API.CreateRepository(
|
||||
data.ServerName, data.RepName);
|
||||
},
|
||||
/*afterOperationDelegate*/ delegate
|
||||
{
|
||||
((IProgressControls)mProgressControls).HideProgress();
|
||||
|
||||
if (waiter.Exception != null)
|
||||
{
|
||||
DisplayException(mProgressControls, waiter.Exception);
|
||||
return;
|
||||
}
|
||||
|
||||
if (createdRepository == null)
|
||||
return;
|
||||
|
||||
mCreateWorkspaceState.Repository = createdRepository.GetRepSpec().ToDisplayString();
|
||||
|
||||
SynchronizeRepositoryAndWorkspace();
|
||||
});
|
||||
}
|
||||
|
||||
void ValidateAndCreateWorkspace(CreateWorkspaceViewState state)
|
||||
{
|
||||
// We need a conversion here because the actual repSpec is used during the AsyncValidation
|
||||
// to call UpdateLastUsedRepositoryPreference. Also, it is the one to be used during wk creation
|
||||
RepositorySpec repSpec = OrganizationsInformation.TryResolveRepositorySpecFromInput(state.Repository);
|
||||
|
||||
if (repSpec == null)
|
||||
{
|
||||
((IProgressControls) mProgressControls).ShowError(
|
||||
PlasticLocalization.Name.UnresolvedRepository.GetString(state.Repository));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mWkCreationData = BuildCreationDataFromState(state, mWorkspacePath, repSpec);
|
||||
|
||||
// AsyncValidation calls IPlasticDialogCloser.CloseDialog() when the validation is ok
|
||||
WorkspaceCreationValidation.AsyncValidation(mWkCreationData, this, mProgressControls);
|
||||
}
|
||||
|
||||
void IPlasticDialogCloser.CloseDialog()
|
||||
{
|
||||
((IProgressControls) mProgressControls).ShowProgress(string.Empty);
|
||||
|
||||
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
|
||||
waiter.Execute(
|
||||
/*threadOperationDelegate*/ delegate
|
||||
{
|
||||
RepositorySpec repSpec = new SpecGenerator().GenRepositorySpec(
|
||||
false, mWkCreationData.Repository, CmConnection.Get().UnityOrgResolver);
|
||||
|
||||
bool repositoryExist = PlasticGui.Plastic.API.CheckRepositoryExists(
|
||||
repSpec.Server, repSpec.Name);
|
||||
|
||||
if (!repositoryExist)
|
||||
PlasticGui.Plastic.API.CreateRepository(repSpec.Server, repSpec.Name);
|
||||
},
|
||||
/*afterOperationDelegate*/ delegate
|
||||
{
|
||||
((IProgressControls)mProgressControls).HideProgress();
|
||||
|
||||
if (waiter.Exception != null)
|
||||
{
|
||||
DisplayException(mProgressControls, waiter.Exception);
|
||||
return;
|
||||
}
|
||||
|
||||
mWkCreationData.Result = true;
|
||||
mWorkspaceOperations.CreateWorkspace(mWkCreationData);
|
||||
|
||||
// the operation calls IWorkspacesRefreshableView.RefreshAndSelect
|
||||
// when the workspace is created
|
||||
});
|
||||
}
|
||||
|
||||
void IWorkspacesRefreshableView.RefreshAndSelect(WorkspaceInfo wkInfo)
|
||||
{
|
||||
UnityCloudProjectLinkMonitor.CheckCloudProjectAlignmentAsync(wkInfo);
|
||||
|
||||
PerformInitialCheckin.IfRepositoryIsEmpty(
|
||||
wkInfo,
|
||||
mWkCreationData.Repository,
|
||||
mWkCreationData.IsGluonWorkspace,
|
||||
PlasticGui.Plastic.API,
|
||||
mProgressControls,
|
||||
mCreateWorkspaceListener,
|
||||
mParentWindow);
|
||||
}
|
||||
|
||||
static WorkspaceCreationData BuildCreationDataFromState(
|
||||
CreateWorkspaceViewState state,
|
||||
string workspacePath,
|
||||
RepositorySpec repSpec)
|
||||
{
|
||||
return new WorkspaceCreationData(
|
||||
state.WorkspaceName,
|
||||
workspacePath,
|
||||
repSpec.ToString(),
|
||||
state.WorkspaceMode == CreateWorkspaceViewState.WorkspaceModes.Gluon,
|
||||
false);
|
||||
}
|
||||
|
||||
static void DisplayException(
|
||||
IProgressControls progressControls,
|
||||
Exception ex)
|
||||
{
|
||||
ExceptionsHandler.LogException(
|
||||
"CreateWorkspaceView", ex);
|
||||
|
||||
progressControls.ShowError(
|
||||
ExceptionsHandler.GetCorrectExceptionMessage(ex));
|
||||
}
|
||||
|
||||
class GetDefaultServer
|
||||
{
|
||||
internal static string ToCreateWorkspace(IPlasticWebRestApi plasticWebRestApi)
|
||||
{
|
||||
string clientConfServer = PlasticGui.Plastic.ConfigAPI.GetClientConfServer();
|
||||
|
||||
if (!EditionToken.IsCloudEdition())
|
||||
return clientConfServer;
|
||||
|
||||
string cloudServer = PlasticGuiConfig.Get().
|
||||
Configuration.DefaultCloudServer;
|
||||
|
||||
if (!string.IsNullOrEmpty(cloudServer))
|
||||
return cloudServer;
|
||||
|
||||
CloudEditionCreds.Data config =
|
||||
CloudEditionCreds.GetFromClientConf();
|
||||
|
||||
cloudServer = GetFirstCloudServer.
|
||||
GetCloudServer(plasticWebRestApi, config.Email, config.Password);
|
||||
|
||||
if (string.IsNullOrEmpty(cloudServer))
|
||||
return clientConfServer;
|
||||
|
||||
SaveCloudServer.ToPlasticGuiConfig(cloudServer);
|
||||
|
||||
return cloudServer;
|
||||
}
|
||||
}
|
||||
|
||||
WorkspaceCreationData mWkCreationData;
|
||||
CreateWorkspaceViewState mCreateWorkspaceState;
|
||||
|
||||
CreateWorkspaceDialogUserAssistant mDialogUserAssistant;
|
||||
|
||||
string mDefaultServer;
|
||||
|
||||
readonly WorkspaceOperations mWorkspaceOperations;
|
||||
readonly ProgressControlsForViews mProgressControls;
|
||||
readonly string mWorkspacePath;
|
||||
readonly ICreateWorkspaceListener mCreateWorkspaceListener;
|
||||
readonly PlasticWindow mParentWindow;
|
||||
readonly IPlasticWebRestApi mPlasticWebRestApi;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5294f667272fcb2438a79369c92cc7e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using UnityEngine;
|
||||
|
||||
using Unity.PlasticSCM.Editor.UI.Progress;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
|
||||
{
|
||||
internal class CreateWorkspaceViewState
|
||||
{
|
||||
internal enum WorkspaceModes
|
||||
{
|
||||
Developer,
|
||||
Gluon
|
||||
}
|
||||
|
||||
internal string Repository { get; set; }
|
||||
internal string WorkspaceName { get; set; }
|
||||
internal WorkspaceModes WorkspaceMode { get; set; }
|
||||
internal ProgressControlsForViews.Data ProgressData { get; set; }
|
||||
|
||||
internal static CreateWorkspaceViewState BuildForProjectDefaults()
|
||||
{
|
||||
string projectName = Application.productName;
|
||||
|
||||
return new CreateWorkspaceViewState()
|
||||
{
|
||||
Repository = projectName,
|
||||
WorkspaceName = projectName,
|
||||
WorkspaceMode = WorkspaceModes.Developer,
|
||||
ProgressData = new ProgressControlsForViews.Data()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41633509da720014cbd77f755b378ce7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cecb087091caedf48adcc1cd3b0ebd6d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,430 @@
|
||||
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<string> 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<string> 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;
|
||||
|
||||
((IProgressControls) mProgressControls).ShowError(
|
||||
PlasticLocalization.Name.NoServerProjectsFound.GetString());
|
||||
}
|
||||
else
|
||||
{
|
||||
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<CreateRepositoryDialog>();
|
||||
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)
|
||||
{
|
||||
mRepositoryName = repositoryNameParts[repositoryNameParts.Length - 1].Trim();
|
||||
}
|
||||
}
|
||||
|
||||
KnownServersListOperations.GetCombinedServers(
|
||||
true,
|
||||
GetExtraServers(proposedServer),
|
||||
mProgressControls,
|
||||
this,
|
||||
mPlasticWebRestApi,
|
||||
CmConnection.Get().GetProfileManager());
|
||||
}
|
||||
|
||||
static List<string> GetExtraServers(string proposedServer)
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
if (!string.IsNullOrEmpty(proposedServer))
|
||||
result.Add(proposedServer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IPlasticWebRestApi mPlasticWebRestApi;
|
||||
bool mFocusIsAreadySet;
|
||||
|
||||
string mRepositoryName;
|
||||
string mSelectedServer;
|
||||
string mSelectedProject;
|
||||
bool mIsLoadingProjects;
|
||||
List<string> mCurrentServerProjects;
|
||||
|
||||
List<string> mKnownServers = new List<string>();
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61f74d0a8a3f1f542b8afe99e65686df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
using PlasticGui;
|
||||
using Unity.PlasticSCM.Editor.UI.Tree;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
|
||||
{
|
||||
internal enum RepositoriesListColumn
|
||||
{
|
||||
Name,
|
||||
Server
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal class RepositoriesListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
|
||||
{
|
||||
internal static RepositoriesListHeaderState GetDefault()
|
||||
{
|
||||
return new RepositoriesListHeaderState(BuildColumns());
|
||||
}
|
||||
|
||||
internal static List<string> GetColumnNames()
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn));
|
||||
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.ServerColumn));
|
||||
return result;
|
||||
}
|
||||
|
||||
static string GetColumnName(RepositoriesListColumn column)
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case RepositoriesListColumn.Name:
|
||||
return PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn);
|
||||
case RepositoriesListColumn.Server:
|
||||
return PlasticLocalization.GetString(PlasticLocalization.Name.ServerColumn);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
if (mHeaderTitles != null)
|
||||
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
static Column[] BuildColumns()
|
||||
{
|
||||
return new Column[]
|
||||
{
|
||||
new Column()
|
||||
{
|
||||
width = 320,
|
||||
headerContent = new GUIContent(
|
||||
GetColumnName(RepositoriesListColumn.Name)),
|
||||
minWidth = 200,
|
||||
allowToggleVisibility = false,
|
||||
sortingArrowAlignment = TextAlignment.Right
|
||||
},
|
||||
new Column()
|
||||
{
|
||||
width = 200,
|
||||
headerContent = new GUIContent(
|
||||
GetColumnName(RepositoriesListColumn.Server)),
|
||||
minWidth = 200,
|
||||
allowToggleVisibility = false,
|
||||
sortingArrowAlignment = TextAlignment.Right
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
RepositoriesListHeaderState(Column[] columns)
|
||||
: base(columns)
|
||||
{
|
||||
if (mHeaderTitles == null)
|
||||
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
string[] mHeaderTitles;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da6a50477d2d7ff4f81d1c21c58a5b0e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,252 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Codice.Client.Common;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
using Codice.CM.Common;
|
||||
using PlasticGui;
|
||||
using PlasticGui.WorkspaceWindow.Home.Repositories;
|
||||
using Unity.PlasticSCM.Editor.UI;
|
||||
using Unity.PlasticSCM.Editor.UI.Tree;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
|
||||
{
|
||||
internal class RepositoriesListView :
|
||||
TreeView,
|
||||
IPlasticTable<RepositoryInfo>
|
||||
{
|
||||
internal RepositoriesListView(
|
||||
RepositoriesListHeaderState headerState,
|
||||
List<string> columnNames,
|
||||
Action doubleClickAction)
|
||||
: base(new TreeViewState())
|
||||
{
|
||||
mColumnNames = columnNames;
|
||||
mDoubleClickAction = doubleClickAction;
|
||||
|
||||
multiColumnHeader = new MultiColumnHeader(headerState);
|
||||
multiColumnHeader.canSort = true;
|
||||
multiColumnHeader.sortingChanged += SortingChanged;
|
||||
|
||||
mColumnComparers = RepositoriesTableDefinition.BuildColumnComparers();
|
||||
|
||||
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
|
||||
showAlternatingRowBackgrounds = false;
|
||||
}
|
||||
|
||||
public override IList<TreeViewItem> GetRows()
|
||||
{
|
||||
return mRows;
|
||||
}
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
return new TreeViewItem(0, -1, string.Empty);
|
||||
}
|
||||
|
||||
protected override IList<TreeViewItem> BuildRows(
|
||||
TreeViewItem rootItem)
|
||||
{
|
||||
RegenerateRows(
|
||||
this, mRepositories, rootItem, mRows);
|
||||
|
||||
return mRows;
|
||||
}
|
||||
|
||||
protected override void SearchChanged(string newSearch)
|
||||
{
|
||||
Refilter();
|
||||
|
||||
Sort();
|
||||
|
||||
Reload();
|
||||
|
||||
TableViewOperations.ScrollToSelection(this);
|
||||
}
|
||||
|
||||
protected override void DoubleClickedItem(int id)
|
||||
{
|
||||
mDoubleClickAction();
|
||||
}
|
||||
|
||||
protected override void BeforeRowsGUI()
|
||||
{
|
||||
int firstRowVisible;
|
||||
int lastRowVisible;
|
||||
GetFirstAndLastVisibleRows(out firstRowVisible, out lastRowVisible);
|
||||
|
||||
GUI.DrawTexture(new Rect(0,
|
||||
firstRowVisible * rowHeight,
|
||||
GetRowRect(0).width,
|
||||
(lastRowVisible * rowHeight) + 1000),
|
||||
Images.GetTreeviewBackgroundTexture());
|
||||
|
||||
DrawTreeViewItem.InitializeStyles();
|
||||
base.BeforeRowsGUI();
|
||||
}
|
||||
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
if (args.item is RepositoryListViewItem)
|
||||
{
|
||||
RepositoryListViewItemGUI(
|
||||
(RepositoryListViewItem)args.item,
|
||||
args,
|
||||
rowHeight);
|
||||
return;
|
||||
}
|
||||
|
||||
base.RowGUI(args);
|
||||
}
|
||||
|
||||
internal string GetSelectedRepository()
|
||||
{
|
||||
IList<TreeViewItem> selectedItems = FindRows(GetSelection());
|
||||
|
||||
if (selectedItems.Count == 0)
|
||||
return null;
|
||||
|
||||
return ((RepositoryListViewItem) selectedItems[0])
|
||||
.Repository.GetRepSpec().ToDisplayString();
|
||||
}
|
||||
|
||||
void IPlasticTable<RepositoryInfo>.FillEntriesAndSelectRows(
|
||||
IList<RepositoryInfo> entries,
|
||||
List<RepositoryInfo> entriesToSelect,
|
||||
string currentFilter)
|
||||
{
|
||||
mUnfilteredRepositories = entries;
|
||||
|
||||
Refilter();
|
||||
|
||||
Sort();
|
||||
|
||||
Reload();
|
||||
}
|
||||
|
||||
void Refilter()
|
||||
{
|
||||
mRepositories = RepositoriesTableDefinition.TableFilter.Filter(
|
||||
searchString,
|
||||
mUnfilteredRepositories);
|
||||
}
|
||||
|
||||
void Sort()
|
||||
{
|
||||
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
|
||||
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
|
||||
|
||||
IComparer<RepositoryInfo> comparer = mColumnComparers[
|
||||
mColumnNames[sortedColumnIdx]];
|
||||
|
||||
((List<RepositoryInfo>)mRepositories).Sort(new SortOrderComparer<RepositoryInfo>(
|
||||
comparer, sortAscending));
|
||||
}
|
||||
|
||||
void SortingChanged(MultiColumnHeader multiColumnHeader)
|
||||
{
|
||||
Sort();
|
||||
|
||||
Reload();
|
||||
}
|
||||
|
||||
static void RegenerateRows(
|
||||
RepositoriesListView listView,
|
||||
IList<RepositoryInfo> repositories,
|
||||
TreeViewItem rootItem,
|
||||
List<TreeViewItem> rows)
|
||||
{
|
||||
ClearRows(rootItem, rows);
|
||||
|
||||
if (repositories.Count == 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < repositories.Count; i++)
|
||||
{
|
||||
RepositoryListViewItem repositoryListViewItem =
|
||||
new RepositoryListViewItem(i + 1, (RepositoryInfo)repositories[i]);
|
||||
|
||||
rootItem.AddChild(repositoryListViewItem);
|
||||
rows.Add(repositoryListViewItem);
|
||||
}
|
||||
|
||||
listView.SetSelection(new List<int> { 1 });
|
||||
}
|
||||
|
||||
static void ClearRows(
|
||||
TreeViewItem rootItem,
|
||||
List<TreeViewItem> rows)
|
||||
{
|
||||
if (rootItem.hasChildren)
|
||||
rootItem.children.Clear();
|
||||
|
||||
rows.Clear();
|
||||
}
|
||||
|
||||
static void RepositoryListViewItemGUI(
|
||||
RepositoryListViewItem item,
|
||||
RowGUIArgs args,
|
||||
float rowHeight)
|
||||
{
|
||||
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
|
||||
{
|
||||
Rect cellRect = args.GetCellRect(visibleColumnIdx);
|
||||
|
||||
RepositoriesListColumn column =
|
||||
(RepositoriesListColumn)args.GetColumn(visibleColumnIdx);
|
||||
|
||||
RepositoryListViewItemCellGUI(
|
||||
cellRect,
|
||||
item,
|
||||
column,
|
||||
rowHeight,
|
||||
args.selected,
|
||||
args.focused);
|
||||
}
|
||||
}
|
||||
|
||||
static void RepositoryListViewItemCellGUI(
|
||||
Rect rect,
|
||||
RepositoryListViewItem item,
|
||||
RepositoriesListColumn column,
|
||||
float rowHeight,
|
||||
bool isSelected,
|
||||
bool isFocused)
|
||||
{
|
||||
if (column == RepositoriesListColumn.Name)
|
||||
{
|
||||
DrawTreeViewItem.ForItemCell(
|
||||
rect,
|
||||
rowHeight,
|
||||
0,
|
||||
Images.GetRepositoryIcon(),
|
||||
null,
|
||||
item.Repository.Name,
|
||||
isSelected,
|
||||
isFocused,
|
||||
false,
|
||||
false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DrawTreeViewItem.ForSecondaryLabel(
|
||||
rect,
|
||||
item.ServerDisplayName,
|
||||
isSelected,
|
||||
isFocused,
|
||||
false);
|
||||
}
|
||||
|
||||
List<TreeViewItem> mRows = new List<TreeViewItem>();
|
||||
|
||||
IList<RepositoryInfo> mUnfilteredRepositories = new List<RepositoryInfo>();
|
||||
IList<RepositoryInfo> mRepositories = new List<RepositoryInfo>();
|
||||
|
||||
readonly Dictionary<string, IComparer<RepositoryInfo>> mColumnComparers;
|
||||
readonly List<string> mColumnNames;
|
||||
readonly Action mDoubleClickAction;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c18598e9d808edb4583a6aa724ffc268
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,347 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
using Codice.Client.Common;
|
||||
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;
|
||||
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,
|
||||
new ProgressControlsForDialogs(),
|
||||
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 OnModalGUI()
|
||||
{
|
||||
Title(PlasticLocalization.GetString(PlasticLocalization.Name.ChooseRepositoryTitle));
|
||||
|
||||
Paragraph(PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.SelectRepositoryBelow));
|
||||
|
||||
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);
|
||||
|
||||
DrawProgressForDialogs.For(
|
||||
mProgressControls.ProgressData);
|
||||
|
||||
DoButtonsArea();
|
||||
|
||||
mProgressControls.ForcedUpdateProgress(this);
|
||||
}
|
||||
|
||||
protected override string GetTitle()
|
||||
{
|
||||
return PlasticLocalization.GetString(PlasticLocalization.Name.ExploreRepositories);
|
||||
}
|
||||
|
||||
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<string> 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<string> 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;
|
||||
}
|
||||
|
||||
void DoButtonsArea()
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (Application.platform == RuntimePlatform.WindowsEditor)
|
||||
{
|
||||
DoOkButton();
|
||||
DoCancelButton();
|
||||
return;
|
||||
}
|
||||
|
||||
DoCancelButton();
|
||||
DoOkButton();
|
||||
}
|
||||
}
|
||||
|
||||
void DoOkButton()
|
||||
{
|
||||
if (!AcceptButton(PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.OkButton)))
|
||||
return;
|
||||
|
||||
OkButtonAction();
|
||||
}
|
||||
|
||||
void DoCancelButton()
|
||||
{
|
||||
if (!NormalButton(PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.CancelButton)))
|
||||
return;
|
||||
|
||||
CancelButtonAction();
|
||||
}
|
||||
|
||||
static RepositoryExplorerDialog Create(
|
||||
IPlasticWebRestApi plasticWebRestApi,
|
||||
ProgressControlsForDialogs progressControls,
|
||||
string defaultServer,
|
||||
GuiMessage.IGuiMessage guiMessage)
|
||||
{
|
||||
var instance = CreateInstance<RepositoryExplorerDialog>();
|
||||
instance.mGuiMessage = guiMessage;
|
||||
instance.mEscapeKeyAction = instance.CancelButtonAction;
|
||||
instance.mProgressControls = progressControls;
|
||||
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<string>(),
|
||||
mProgressControls,
|
||||
this,
|
||||
plasticWebRestApi,
|
||||
CmConnection.Get().GetProfileManager());
|
||||
}
|
||||
|
||||
SearchField mSearchField;
|
||||
RepositoriesListView mRepositoriesListView;
|
||||
ProgressControlsForDialogs mProgressControls;
|
||||
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<string> AvailableServers { get; set; }
|
||||
internal string SelectedServer { get; set; }
|
||||
internal ProgressControlsForDialogs.Data ProgressData { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b29af44841cd6644e876233cd057bc18
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
using Codice.Client.Common;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
|
||||
using Codice.CM.Common;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
|
||||
{
|
||||
internal class RepositoryListViewItem : TreeViewItem
|
||||
{
|
||||
internal RepositoryInfo Repository { get; private set; }
|
||||
|
||||
internal string ServerDisplayName { get; private set; }
|
||||
|
||||
internal RepositoryListViewItem(int id, RepositoryInfo repository)
|
||||
: base(id, 0)
|
||||
{
|
||||
Repository = repository;
|
||||
ServerDisplayName = ResolveServer.ToDisplayString(repository.Server);
|
||||
|
||||
displayName = repository.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83882c7718d0fc34f8a05141328ceac1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,507 @@
|
||||
using System;
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using Codice.Client.Common;
|
||||
using Codice.CM.Common;
|
||||
using PlasticGui;
|
||||
using PlasticGui.WebApi;
|
||||
using PlasticGui.WorkspaceWindow.Home.Repositories;
|
||||
using Unity.PlasticSCM.Editor.UI;
|
||||
using Unity.PlasticSCM.Editor.UI.Progress;
|
||||
using Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
|
||||
{
|
||||
internal static class DrawCreateWorkspace
|
||||
{
|
||||
internal static void ForState(
|
||||
Action<string> selectRepositoryAction,
|
||||
Action<RepositoryCreationData> createRepositoryAction,
|
||||
Action<CreateWorkspaceViewState> createWorkspaceAction,
|
||||
EditorWindow parentWindow,
|
||||
IPlasticWebRestApi plasticWebRestApi,
|
||||
string defaultServer,
|
||||
ref CreateWorkspaceViewState state)
|
||||
{
|
||||
DoTitle();
|
||||
|
||||
GUILayout.Space(15);
|
||||
|
||||
DoFieldsArea(
|
||||
selectRepositoryAction,
|
||||
createRepositoryAction,
|
||||
parentWindow,
|
||||
plasticWebRestApi,
|
||||
defaultServer,
|
||||
ref state);
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
DoRadioButtonsArea(ref state);
|
||||
|
||||
GUILayout.Space(3);
|
||||
|
||||
DoHelpLabel();
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
DoCreateWorkspaceButton(
|
||||
createWorkspaceAction,
|
||||
ref state);
|
||||
|
||||
GUILayout.Space(5);
|
||||
|
||||
DoNotificationArea(state.ProgressData);
|
||||
}
|
||||
|
||||
static void DoTitle()
|
||||
{
|
||||
GUILayout.Label(
|
||||
PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.NewWorkspace),
|
||||
UnityStyles.Dialog.MessageTitle);
|
||||
|
||||
GUILayout.Label(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.WorkspacesExplanationLabel),
|
||||
EditorStyles.wordWrappedLabel);
|
||||
}
|
||||
|
||||
static void DoFieldsArea(
|
||||
Action<string> selectRepositoryAction,
|
||||
Action<RepositoryCreationData> createRepositoryAction,
|
||||
EditorWindow parentWindow,
|
||||
IPlasticWebRestApi plasticWebRestApi,
|
||||
string defaultServer,
|
||||
ref CreateWorkspaceViewState state)
|
||||
{
|
||||
DoRepositoryField(
|
||||
selectRepositoryAction,
|
||||
createRepositoryAction,
|
||||
parentWindow,
|
||||
plasticWebRestApi,
|
||||
defaultServer,
|
||||
ref state);
|
||||
|
||||
DoWorkspaceField(ref state);
|
||||
}
|
||||
|
||||
static void DoRepositoryField(
|
||||
Action<string> selectRepositoryAction,
|
||||
Action<RepositoryCreationData> createRepositoryAction,
|
||||
EditorWindow parentWindow,
|
||||
IPlasticWebRestApi plasticWebRestApi,
|
||||
string defaultServer,
|
||||
ref CreateWorkspaceViewState state)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
DoLabel(PlasticLocalization.GetString(PlasticLocalization.Name.Repository));
|
||||
|
||||
state.Repository = DoTextField(
|
||||
state.Repository,
|
||||
!state.ProgressData.IsOperationRunning,
|
||||
LABEL_WIDTH,
|
||||
TEXTBOX_WIDTH - BROWSE_BUTTON_WIDTH);
|
||||
|
||||
float browseButtonX =
|
||||
LABEL_WIDTH + TEXTBOX_WIDTH + BUTTON_MARGIN -
|
||||
BROWSE_BUTTON_WIDTH;
|
||||
float browseButtonWidth =
|
||||
BROWSE_BUTTON_WIDTH - BUTTON_MARGIN;
|
||||
|
||||
if (DoButton(
|
||||
"...",
|
||||
!state.ProgressData.IsOperationRunning,
|
||||
browseButtonX,
|
||||
browseButtonWidth))
|
||||
{
|
||||
DoBrowseRepositoryButton(
|
||||
selectRepositoryAction,
|
||||
parentWindow,
|
||||
plasticWebRestApi,
|
||||
defaultServer);
|
||||
|
||||
EditorGUIUtility.ExitGUI();
|
||||
}
|
||||
|
||||
float newButtonX =
|
||||
LABEL_WIDTH + TEXTBOX_WIDTH + BUTTON_MARGIN;
|
||||
float newButtonWidth =
|
||||
NEW_BUTTON_WIDTH - BUTTON_MARGIN;
|
||||
|
||||
if (DoButton(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.NewButton),
|
||||
!state.ProgressData.IsOperationRunning,
|
||||
newButtonX, newButtonWidth))
|
||||
{
|
||||
DoNewRepositoryButton(
|
||||
createRepositoryAction,
|
||||
parentWindow,
|
||||
plasticWebRestApi,
|
||||
state.Repository,
|
||||
defaultServer);
|
||||
|
||||
EditorGUIUtility.ExitGUI();
|
||||
}
|
||||
|
||||
ValidationResult validationResult = ValidateRepository(state.Repository);
|
||||
|
||||
if (!validationResult.IsValid)
|
||||
DoWarningLabel(validationResult.ErrorMessage,
|
||||
LABEL_WIDTH + TEXTBOX_WIDTH + NEW_BUTTON_WIDTH + LABEL_MARGIN);
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void DoWorkspaceField(
|
||||
ref CreateWorkspaceViewState state)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
DoLabel(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.WorkspaceName));
|
||||
|
||||
state.WorkspaceName = DoTextField(
|
||||
state.WorkspaceName,
|
||||
!state.ProgressData.IsOperationRunning,
|
||||
LABEL_WIDTH,
|
||||
TEXTBOX_WIDTH - BROWSE_BUTTON_WIDTH);
|
||||
|
||||
ValidationResult validationResult = ValidateWorkspaceName(
|
||||
state.WorkspaceName);
|
||||
|
||||
if (!validationResult.IsValid)
|
||||
DoWarningLabel(validationResult.ErrorMessage,
|
||||
LABEL_WIDTH + TEXTBOX_WIDTH - BROWSE_BUTTON_WIDTH + LABEL_MARGIN);
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void DoRadioButtonsArea(
|
||||
ref CreateWorkspaceViewState state)
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
DoLabel(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.WorkPreferenceQuestion));
|
||||
|
||||
if (DoRadioButton(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.WorkPreferenceAnswerUnityVCS),
|
||||
state.WorkspaceMode == CreateWorkspaceViewState.WorkspaceModes.Developer,
|
||||
!state.ProgressData.IsOperationRunning,
|
||||
RADIO_BUTTON_MARGIN))
|
||||
state.WorkspaceMode = CreateWorkspaceViewState.WorkspaceModes.Developer;
|
||||
|
||||
if (DoRadioButton(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.WorkPreferenceAnswerGluon),
|
||||
state.WorkspaceMode == CreateWorkspaceViewState.WorkspaceModes.Gluon,
|
||||
!state.ProgressData.IsOperationRunning,
|
||||
RADIO_BUTTON_MARGIN))
|
||||
state.WorkspaceMode = CreateWorkspaceViewState.WorkspaceModes.Gluon;
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
static void DoCreateWorkspaceButton(
|
||||
Action<CreateWorkspaceViewState> createWorkspaceAction,
|
||||
ref CreateWorkspaceViewState state)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
bool isButtonEnabled =
|
||||
IsValidState(state) &&
|
||||
!state.ProgressData.IsOperationRunning;
|
||||
|
||||
string buttonText = PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.CreateWorkspace);
|
||||
|
||||
bool isButtonClicked = DoButton(buttonText, isButtonEnabled,
|
||||
CREATE_WORKSPACE_BUTTON_MARGIN, CREATE_WORKSPACE_BUTTON_WIDTH);
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
if (state.ProgressData.IsOperationRunning)
|
||||
{
|
||||
DoProgress(state.ProgressData,
|
||||
CREATE_WORKSPACE_BUTTON_MARGIN +
|
||||
PROGRESS_MARGIN +
|
||||
CREATE_WORKSPACE_BUTTON_WIDTH);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (isButtonClicked)
|
||||
createWorkspaceAction(state);
|
||||
}
|
||||
|
||||
static void DoBrowseRepositoryButton(
|
||||
Action<string> selectRepositoryAction,
|
||||
EditorWindow parentWindow,
|
||||
IPlasticWebRestApi plasticWebRestApi,
|
||||
string defaultServer)
|
||||
{
|
||||
string selectedRepository = RepositoryExplorerDialog.BrowseRepository(
|
||||
parentWindow,
|
||||
plasticWebRestApi,
|
||||
defaultServer);
|
||||
|
||||
if (string.IsNullOrEmpty(selectedRepository))
|
||||
return;
|
||||
|
||||
selectRepositoryAction(selectedRepository);
|
||||
}
|
||||
|
||||
static void DoNewRepositoryButton(
|
||||
Action<RepositoryCreationData> createRepositoryAction,
|
||||
EditorWindow parentWindow,
|
||||
IPlasticWebRestApi plasticWebRestApi,
|
||||
string repositorySpecInput,
|
||||
string defaultServer)
|
||||
{
|
||||
string proposedRepositoryName;
|
||||
string proposedServer;
|
||||
|
||||
RepositorySpec repSpec = OrganizationsInformation.TryResolveRepositorySpecFromInput(repositorySpecInput);
|
||||
|
||||
if (repSpec != null)
|
||||
{
|
||||
proposedRepositoryName = repSpec.Name;
|
||||
proposedServer = repSpec.Server;
|
||||
}
|
||||
else
|
||||
{
|
||||
proposedRepositoryName = ExtractRepositoryName(repositorySpecInput);
|
||||
proposedServer = defaultServer;
|
||||
}
|
||||
|
||||
RepositoryCreationData creationData = CreateRepositoryDialog.CreateRepository(
|
||||
parentWindow,
|
||||
plasticWebRestApi,
|
||||
proposedRepositoryName,
|
||||
proposedServer,
|
||||
defaultServer,
|
||||
ClientConfig.Get().GetWorkspaceServer());
|
||||
|
||||
createRepositoryAction(creationData);
|
||||
}
|
||||
|
||||
static string ExtractRepositoryName(string repositorySpec)
|
||||
{
|
||||
string[] repositoryParts = repositorySpec.Split('@');
|
||||
|
||||
return repositoryParts.Length > 0 ? repositoryParts[0] : string.Empty;
|
||||
}
|
||||
|
||||
static void DoHelpLabel()
|
||||
{
|
||||
string linkText =PlasticLocalization.Name.HereLink.GetString();
|
||||
string labelText = PlasticLocalization.Name.LearnMoreDifferencesUnityVCS.GetString();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel);
|
||||
labelStyle.richText = true;
|
||||
labelStyle.stretchWidth = false;
|
||||
labelStyle.margin = new RectOffset();
|
||||
labelStyle.padding.left = LEARN_MORE_LABEL_LEFT_PADDING;
|
||||
|
||||
GUILayout.Label(labelText, labelStyle);
|
||||
|
||||
GUIStyle linkStyle = new GUIStyle(UnityStyles.LinkLabel);
|
||||
linkStyle.fontSize = EditorStyles.miniLabel.fontSize;
|
||||
linkStyle.stretchWidth = false;
|
||||
linkStyle.margin = new RectOffset();
|
||||
|
||||
if (GUILayout.Button(linkText, linkStyle))
|
||||
{
|
||||
Application.OpenURL(PlasticLocalization.Name.PlasticSCMFullVsPartialWorkspaceLink.GetString());
|
||||
}
|
||||
|
||||
EditorGUIUtility.AddCursorRect(
|
||||
GUILayoutUtility.GetLastRect(), MouseCursor.Link);
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void DoNotificationArea(ProgressControlsForViews.Data progressData)
|
||||
{
|
||||
if (string.IsNullOrEmpty(progressData.NotificationMessage))
|
||||
return;
|
||||
|
||||
DrawProgressForViews.ForNotificationArea(progressData);
|
||||
}
|
||||
|
||||
static void DoLabel(string labelText)
|
||||
{
|
||||
GUIStyle labelStyle = new GUIStyle(EditorStyles.label);
|
||||
|
||||
Rect rect = GUILayoutUtility.GetRect(
|
||||
new GUIContent(labelText),
|
||||
labelStyle);
|
||||
|
||||
GUI.Label(rect, labelText, labelStyle);
|
||||
}
|
||||
|
||||
static string DoTextField(
|
||||
string entryValue,
|
||||
bool enabled,
|
||||
float textBoxLeft,
|
||||
float textBoxWidth)
|
||||
{
|
||||
GUI.enabled = enabled;
|
||||
|
||||
var rect = GUILayoutUtility.GetRect(
|
||||
new GUIContent(entryValue),
|
||||
UnityStyles.Dialog.EntryLabel);
|
||||
rect.width = textBoxWidth;
|
||||
rect.x = textBoxLeft;
|
||||
|
||||
string result = GUI.TextField(rect, entryValue);
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool DoButton(
|
||||
string text,
|
||||
bool isEnabled,
|
||||
float buttonLeft,
|
||||
float buttonWidth)
|
||||
{
|
||||
GUI.enabled = isEnabled;
|
||||
|
||||
var rect = GUILayoutUtility.GetRect(
|
||||
new GUIContent(text),
|
||||
UnityStyles.Dialog.EntryLabel);
|
||||
|
||||
rect.width = buttonWidth;
|
||||
rect.x = buttonLeft;
|
||||
|
||||
bool result = GUI.Button(rect, text);
|
||||
GUI.enabled = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool DoRadioButton(
|
||||
string text,
|
||||
bool isChecked,
|
||||
bool isEnabled,
|
||||
float buttonLeft)
|
||||
{
|
||||
GUI.enabled = isEnabled;
|
||||
|
||||
GUIStyle radioButtonStyle = new GUIStyle(EditorStyles.radioButton);
|
||||
radioButtonStyle.padding.left = RADIO_BUTTON_LEFT_PADDING;
|
||||
|
||||
var rect = GUILayoutUtility.GetRect(
|
||||
new GUIContent(text),
|
||||
radioButtonStyle);
|
||||
|
||||
rect.x = buttonLeft;
|
||||
|
||||
bool result = GUI.Toggle(
|
||||
rect,
|
||||
isChecked,
|
||||
text,
|
||||
radioButtonStyle);
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DoWarningLabel(
|
||||
string labelText,
|
||||
float labelLeft)
|
||||
{
|
||||
Rect rect = GUILayoutUtility.GetRect(
|
||||
new GUIContent(labelText),
|
||||
EditorStyles.label);
|
||||
|
||||
rect.x = labelLeft;
|
||||
|
||||
GUI.Label(rect,
|
||||
new GUIContent(labelText, Images.GetWarnIcon()),
|
||||
UnityStyles.HeaderWarningLabel);
|
||||
}
|
||||
|
||||
static void DoProgress(
|
||||
ProgressControlsForViews.Data data,
|
||||
float progressLeft)
|
||||
{
|
||||
if (string.IsNullOrEmpty(data.ProgressMessage))
|
||||
return;
|
||||
|
||||
var rect = GUILayoutUtility.GetRect(
|
||||
new GUIContent(data.ProgressMessage),
|
||||
UnityStyles.Dialog.EntryLabel);
|
||||
|
||||
rect.x = progressLeft;
|
||||
|
||||
GUI.Label(rect, data.ProgressMessage);
|
||||
}
|
||||
|
||||
static bool IsValidState(
|
||||
CreateWorkspaceViewState state)
|
||||
{
|
||||
if (!ValidateRepository(state.Repository).IsValid)
|
||||
return false;
|
||||
|
||||
if (!ValidateWorkspaceName(state.WorkspaceName).IsValid)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static ValidationResult ValidateRepository(string repository)
|
||||
{
|
||||
ValidationResult result = new ValidationResult();
|
||||
|
||||
if (string.IsNullOrEmpty(repository))
|
||||
{
|
||||
result.ErrorMessage = PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryNameEmpty);
|
||||
result.IsValid = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.IsValid = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
static ValidationResult ValidateWorkspaceName(string workspaceName)
|
||||
{
|
||||
ValidationResult result = new ValidationResult();
|
||||
|
||||
if (string.IsNullOrEmpty(workspaceName))
|
||||
{
|
||||
result.ErrorMessage = PlasticLocalization.GetString(PlasticLocalization.Name.WorkspaceNameEmpty);
|
||||
result.IsValid = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.IsValid = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
class ValidationResult
|
||||
{
|
||||
internal string ErrorMessage;
|
||||
internal bool IsValid;
|
||||
}
|
||||
|
||||
const float LABEL_WIDTH = 150;
|
||||
const float TEXTBOX_WIDTH = 400;
|
||||
const float BROWSE_BUTTON_WIDTH = 25;
|
||||
const float NEW_BUTTON_WIDTH = 60;
|
||||
const float BUTTON_MARGIN = 2;
|
||||
const float LABEL_MARGIN = 2;
|
||||
const float RADIO_BUTTON_MARGIN = 38;
|
||||
const int RADIO_BUTTON_LEFT_PADDING = 20;
|
||||
const float PROGRESS_MARGIN = 5;
|
||||
const float CREATE_WORKSPACE_BUTTON_MARGIN = 32;
|
||||
const float CREATE_WORKSPACE_BUTTON_WIDTH = 160;
|
||||
const int LEARN_MORE_LABEL_LEFT_PADDING = 10;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 788db2c7ca3c2804d912f447ffc19856
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using Codice.Client.BaseCommands;
|
||||
using Codice.Client.Commands;
|
||||
using Codice.Client.Commands.CheckIn;
|
||||
using Codice.Client.Common;
|
||||
using Codice.Client.Common.Threading;
|
||||
using Codice.CM.Common;
|
||||
using Codice.CM.Common.Checkin.Partial;
|
||||
using Codice.Client.GameUI.Checkin;
|
||||
using PlasticGui;
|
||||
using PlasticGui.Help.Conditions;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
|
||||
{
|
||||
internal static class PerformInitialCheckin
|
||||
{
|
||||
internal static void IfRepositoryIsEmpty(
|
||||
WorkspaceInfo wkInfo,
|
||||
string repository,
|
||||
bool isGluonWorkspace,
|
||||
IPlasticAPI plasticApi,
|
||||
IProgressControls progressControls,
|
||||
CreateWorkspaceView.ICreateWorkspaceListener createWorkspaceListener,
|
||||
PlasticWindow plasticWindow)
|
||||
{
|
||||
RepositoryInfo repInfo = null;
|
||||
bool isEmptyRepository = false;
|
||||
|
||||
progressControls.ShowProgress(string.Empty);
|
||||
|
||||
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
|
||||
waiter.Execute(
|
||||
/*threadOperationDelegate*/ delegate
|
||||
{
|
||||
RepositorySpec repSpec = new SpecGenerator().
|
||||
GenRepositorySpec(false, repository, CmConnection.Get().UnityOrgResolver);
|
||||
|
||||
repInfo = plasticApi.GetRepositoryInfo(repSpec);
|
||||
|
||||
isEmptyRepository = IsEmptyRepositoryCondition.
|
||||
Evaluate(wkInfo, repSpec, plasticApi);
|
||||
},
|
||||
/*afterOperationDelegate*/ delegate
|
||||
{
|
||||
progressControls.HideProgress();
|
||||
|
||||
if (waiter.Exception != null)
|
||||
{
|
||||
DisplayException(progressControls, waiter.Exception);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isEmptyRepository)
|
||||
{
|
||||
plasticWindow.RefreshWorkspaceUI();
|
||||
return;
|
||||
}
|
||||
|
||||
CheckinPackagesAndProjectSettingsFolders(
|
||||
wkInfo, isGluonWorkspace, plasticApi,
|
||||
progressControls, createWorkspaceListener);
|
||||
});
|
||||
}
|
||||
|
||||
static void CheckinPackagesAndProjectSettingsFolders(
|
||||
WorkspaceInfo wkInfo,
|
||||
bool isGluonWorkspace,
|
||||
IPlasticAPI plasticApi,
|
||||
IProgressControls progressControls,
|
||||
CreateWorkspaceView.ICreateWorkspaceListener createWorkspaceListener)
|
||||
{
|
||||
progressControls.ShowProgress(PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.UnityInitialCheckinProgress));
|
||||
|
||||
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
|
||||
waiter.Execute(
|
||||
/*threadOperationDelegate*/ delegate
|
||||
{
|
||||
PerformCheckinPackagesAndProjectSettingsFolders(
|
||||
wkInfo, isGluonWorkspace, plasticApi);
|
||||
},
|
||||
/*afterOperationDelegate*/ delegate
|
||||
{
|
||||
progressControls.HideProgress();
|
||||
|
||||
if (waiter.Exception != null &&
|
||||
!IsMergeNeededException(waiter.Exception))
|
||||
{
|
||||
DisplayException(progressControls, waiter.Exception);
|
||||
return;
|
||||
}
|
||||
|
||||
createWorkspaceListener.OnWorkspaceCreated(wkInfo, isGluonWorkspace);
|
||||
});
|
||||
}
|
||||
|
||||
internal static void PerformCheckinPackagesAndProjectSettingsFolders(
|
||||
WorkspaceInfo wkInfo,
|
||||
bool isGluonWorkspace,
|
||||
IPlasticAPI plasticApi)
|
||||
{
|
||||
List<string> paths = new List<string> {
|
||||
Path.Combine(wkInfo.ClientPath, "Packages"),
|
||||
Path.Combine(wkInfo.ClientPath, "ProjectSettings")
|
||||
};
|
||||
|
||||
string comment = PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.UnityInitialCheckinComment);
|
||||
|
||||
PerformAdd(paths, plasticApi);
|
||||
|
||||
PerformCheckinForMode(wkInfo, paths, comment, isGluonWorkspace);
|
||||
}
|
||||
|
||||
static void PerformAdd(
|
||||
List<string> paths,
|
||||
IPlasticAPI plasticApi)
|
||||
{
|
||||
AddOptions options = new AddOptions();
|
||||
options.AddPrivateParents = true;
|
||||
options.CheckoutParent = true;
|
||||
options.Recurse = true;
|
||||
options.SearchForPrivatePaths = true;
|
||||
options.SkipIgnored = true;
|
||||
|
||||
IList checkouts;
|
||||
plasticApi.Add(paths.ToArray(), options, out checkouts);
|
||||
}
|
||||
|
||||
static void PerformCheckinForMode(
|
||||
WorkspaceInfo wkInfo,
|
||||
List<string> paths,
|
||||
string comment,
|
||||
bool isGluonWorkspace)
|
||||
{
|
||||
if (isGluonWorkspace)
|
||||
{
|
||||
new BaseCommandsImpl().PartialCheckin(wkInfo, paths, comment);
|
||||
return;
|
||||
}
|
||||
|
||||
CheckinParams ciParams = new CheckinParams();
|
||||
ciParams.paths = paths.ToArray();
|
||||
ciParams.comment = comment;
|
||||
ciParams.time = DateTime.MinValue;
|
||||
ciParams.flags = CheckinFlags.Recurse | CheckinFlags.ProcessSymlinks;
|
||||
|
||||
new BaseCommandsImpl().CheckIn(ciParams);
|
||||
}
|
||||
|
||||
static bool IsMergeNeededException(Exception exception)
|
||||
{
|
||||
if (exception == null)
|
||||
return false;
|
||||
|
||||
// Check the check-in exception for gluon
|
||||
if (exception is CheckinConflictsException)
|
||||
return true;
|
||||
|
||||
// Check the check-in exceptions for plastic
|
||||
return exception is CmClientMergeNeededException;
|
||||
}
|
||||
|
||||
static void DisplayException(
|
||||
IProgressControls progressControls,
|
||||
Exception ex)
|
||||
{
|
||||
ExceptionsHandler.LogException(
|
||||
"PerformInitialCheckin", ex);
|
||||
|
||||
progressControls.ShowError(
|
||||
ExceptionsHandler.GetCorrectExceptionMessage(ex));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29e0becc4ce852c439ff3e642f0375bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Collections;
|
||||
|
||||
using Codice.CM.Common;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
|
||||
{
|
||||
internal static class ValidRepositoryName
|
||||
{
|
||||
internal static string Get(string repositoryName, IList repositories)
|
||||
{
|
||||
string validRepositoryName = GetValidRepositoryName(repositoryName);
|
||||
string result = validRepositoryName;
|
||||
|
||||
int i = 2;
|
||||
|
||||
while (RepositoryExists(result, repositories))
|
||||
{
|
||||
result = validRepositoryName + "_" + i.ToString();
|
||||
i++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool RepositoryExists(string repositoryName, IList repositories)
|
||||
{
|
||||
if (repositories == null)
|
||||
return false;
|
||||
|
||||
foreach (RepositoryInfo repInfo in repositories)
|
||||
{
|
||||
if (repInfo.Name.Equals(repositoryName))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static string GetValidRepositoryName(string newRepository)
|
||||
{
|
||||
string result = newRepository.Replace(SUBMODULE_SEPARATOR, '-');
|
||||
result = result.Replace(PIPE_CHARACTER, '-');
|
||||
return result;
|
||||
}
|
||||
|
||||
const char SUBMODULE_SEPARATOR = '/';
|
||||
const char PIPE_CHARACTER = '|';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60f5fb7fb3626214f9d97215fe186cbf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user