Created unity project

This commit is contained in:
2024-12-07 20:55:50 +01:00
parent 539250d964
commit 54fe327198
13758 changed files with 865324 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5294f667272fcb2438a79369c92cc7e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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()
};
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 41633509da720014cbd77f755b378ce7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cecb087091caedf48adcc1cd3b0ebd6d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61f74d0a8a3f1f542b8afe99e65686df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: da6a50477d2d7ff4f81d1c21c58a5b0e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c18598e9d808edb4583a6aa724ffc268
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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; }
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b29af44841cd6644e876233cd057bc18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 83882c7718d0fc34f8a05141328ceac1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 788db2c7ca3c2804d912f447ffc19856
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29e0becc4ce852c439ff3e642f0375bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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 = '|';
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60f5fb7fb3626214f9d97215fe186cbf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: