Files

382 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common.WebApi;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.CloudDrive.Workspaces;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.CloudDrive;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.AssetMenu.Dialogs
{
internal class AddToCloudDriveDialog :
PlasticDialog,
FillOrganizationsAndProjects.INotify,
FillCloudWorkspaces.IAddToCloudDriveDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 600, 350);
}
}
internal static void ShowDialog(
string[] assetPaths,
IPlasticWebRestApi restApi,
IPlasticAPI plasticApi,
EditorWindow parentWindow)
{
AddToCloudDriveDialog dialog = Create(assetPaths, plasticApi);
dialog.InitializeProposedOrganizationProject(restApi);
FillOrganizationsAndProjects.LoadOrganizations(
restApi,
plasticApi,
dialog.mProgressControls,
dialog);
ResponseType dialogResult = dialog.RunModal(parentWindow);
if (dialogResult != ResponseType.Ok)
return;
CloudDriveWindow cloudDriveWindow = ShowWindow.CloudDrive();
cloudDriveWindow.CopyPaths(
dialog.mSelectedOrganization,
dialog.mSelectedProject,
dialog.mSelectedCloudDrive.WorkspaceInfo,
assetPaths,
dialog.mCloudDriveRelativePath);
}
protected override string GetTitle()
{
return PlasticLocalization.Name.AddToUnityCloudDriveTitle.GetString();
}
protected override string GetExplanation()
{
return PlasticLocalization.Name.AddToCloudDriveDescription.GetString();
}
protected override void DoComponentsArea()
{
bool isOperationRunning = mProgressControls.ProgressData.IsWaitingAsyncResult;
GUI.enabled = !isOperationRunning;
EntryBuilder.CreateComboBoxEntry(
PlasticLocalization.Name.OrganizationLabel.GetString(),
mSelectedOrganization,
mOrganizations,
OnOrganizationSelected,
ENTRY_WIDTH,
ENTRY_X);
GUILayout.Space(5);
if (CloudServer.IsUnityOrganization(mSelectedOrganization))
{
EntryBuilder.CreateComboBoxEntry(
PlasticLocalization.Name.ProjectLabel.GetString(),
mSelectedProject,
mProjects,
OnProjectSelected,
ENTRY_WIDTH,
ENTRY_X);
GUILayout.Space(5);
}
string selectedDriveName = mSelectedCloudDrive != null ?
mSelectedCloudDrive.RepositoryInfo.Name.GetLastPartFromSeparator('/') : string.Empty;
List<string> driveNames = mCloudDrives.Select(
workspace => workspace.RepositoryInfo.Name.GetLastPartFromSeparator('/')).ToList();
EntryBuilder.CreateComboBoxEntry(
PlasticLocalization.Name.CloudDriveLabel.GetString(),
selectedDriveName,
driveNames,
OnDriveSelected,
ENTRY_WIDTH,
ENTRY_X);
GUILayout.Space(10);
using (new EditorGUILayout.HorizontalScope())
{
mCloudDriveRelativePath = EntryBuilder.CreateTextEntry(
PlasticLocalization.Name.RelativePathLabel.GetString(),
mCloudDriveRelativePath,
ENTRY_WIDTH - BROWSE_BUTTON_WIDTH,
ENTRY_X);
Rect browseButtonRect = new Rect(
ENTRY_X + ENTRY_WIDTH - BROWSE_BUTTON_WIDTH + BUTTON_MARGIN,
GUILayoutUtility.GetLastRect().y,
BROWSE_BUTTON_WIDTH - BUTTON_MARGIN,
20);
if (GUI.Button(browseButtonRect, "..."))
DoBrowseForPath();
}
GUI.enabled = true;
}
void FillOrganizationsAndProjects.INotify.OrganizationsRetrieved(List<string> organizations)
{
mOrganizations = organizations;
mSelectedOrganization = GetDefaultValue(mProposedOrganization, mOrganizations);
if (mSelectedOrganization == null)
return;
OnOrganizationSelected(mSelectedOrganization);
Repaint();
}
void FillOrganizationsAndProjects.INotify.ProjectsRetrieved(List<string> projects)
{
mProjects = projects;
mSelectedProject = GetDefaultValue(mProposedProject, mProjects);
if (mSelectedProject == null)
return;
OnProjectSelected(mSelectedProject);
Repaint();
}
void FillCloudWorkspaces.IAddToCloudDriveDialog.CloudDrivesRetrieved(
List<CloudDriveWorkspace> workspaces)
{
mCloudDrives = workspaces;
if (mCloudDrives.Count > 0)
mSelectedCloudDrive = mCloudDrives[0];
Repaint();
}
static AddToCloudDriveDialog Create(string[] assetPaths, IPlasticAPI plasticApi)
{
var instance = CreateInstance<AddToCloudDriveDialog>();
instance.IsResizable = false;
instance.mPlasticApi = plasticApi;
instance.mCloudDriveRelativePath = GetProposedCloudDriveRelativePath(assetPaths);
instance.mEnterKeyAction = instance.OkButtonAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
return instance;
}
void OnOrganizationSelected(object organization)
{
mSelectedOrganization = organization != null ? organization.ToString() : null;
mProposedOrganization = mSelectedOrganization;
mSelectedProject = null;
mSelectedCloudDrive = null;
mProjects.Clear();
mCloudDrives.Clear();
if (!CloudServer.IsUnityOrganization(mSelectedOrganization))
{
OnProjectSelected(string.Empty);
return;
}
FillOrganizationsAndProjects.LoadProjects(
mSelectedOrganization, mPlasticApi, mProgressControls, this);
}
void OnProjectSelected(object project)
{
mSelectedProject = project != null ? project.ToString() : null;
mProposedProject = mSelectedProject;
mSelectedCloudDrive = null;
mCloudDrives.Clear();
if (string.IsNullOrEmpty(mSelectedOrganization))
return;
FillCloudWorkspaces.LoadWorkspaces(
mSelectedOrganization, mSelectedProject, this, mProgressControls);
}
void OnDriveSelected(object selectedDrive)
{
string driveName = selectedDrive != null ? selectedDrive.ToString() : null;
mSelectedCloudDrive = mCloudDrives.FirstOrDefault(
wkInfo =>
wkInfo.RepositoryInfo.Name.GetLastPartFromSeparator('/') == driveName);
Repaint();
}
void DoBrowseForPath()
{
if (mSelectedCloudDrive == null)
{
((IProgressControls)mProgressControls).ShowError(
PlasticLocalization.Name.SelectCloudDriveFirst.GetString());
return;
}
string workspacePath = AssetsPath.GetFullPath.ForPath(mSelectedCloudDrive.WorkspaceInfo.ClientPath);
string selectedPath = EditorUtility.SaveFolderPanel(
PlasticLocalization.Name.SelectDestinationPath.GetString(),
workspacePath,
"");
if (string.IsNullOrEmpty(selectedPath))
return;
string selectedFullPath = AssetsPath.GetFullPath.ForPath(selectedPath);
if (string.IsNullOrEmpty(selectedFullPath))
return;
if (!selectedFullPath.StartsWith(workspacePath))
{
((IProgressControls)mProgressControls).ShowError(
PlasticLocalization.Name.PathMustBeWithinWorkspace.GetString());
return;
}
((IProgressControls)mProgressControls).HideProgress();
if (selectedFullPath == workspacePath)
{
mCloudDriveRelativePath = "/";
return;
}
mCloudDriveRelativePath = selectedFullPath.Substring(workspacePath.Length).Replace('\\', '/');
}
protected override void DoOkButton()
{
bool isValid = mSelectedCloudDrive != null && mCloudDriveRelativePath.StartsWith("/");
if (!isValid || mProgressControls.ProgressData.IsWaitingAsyncResult)
GUI.enabled = false;
if (NormalButton(PlasticLocalization.Name.AddToCloudDriveButton.GetString()))
{
OkButtonAction();
}
GUI.enabled = true;
}
static string GetProposedCloudDriveRelativePath(string[] assetPaths)
{
if (assetPaths.Length == 0)
return string.Empty;
string commonRoot = Path.GetDirectoryName(
assetPaths[0].TrimEnd(
Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
for (int i = 1; i < assetPaths.Length; i++)
{
commonRoot = GetCommonRoot(
commonRoot,
Path.GetDirectoryName(
assetPaths[i].TrimEnd(
Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)));
}
return '/' + commonRoot.Replace('\\', '/');
}
static string GetCommonRoot(string path1, string path2)
{
string[] path1Parts = path1.Split(Path.DirectorySeparatorChar);
string[] path2Parts = path2.Split(Path.DirectorySeparatorChar);
int commonPartsCount = Mathf.Min(path1Parts.Length, path2Parts.Length);
for (int i = 0; i < commonPartsCount; i++)
{
if (path1Parts[i] != path2Parts[i])
{
commonPartsCount = i;
break;
}
}
return string.Join(
Path.DirectorySeparatorChar.ToString(),
path1Parts,
0,
commonPartsCount);
}
static string GetDefaultValue(string proposedValue, List<string> values)
{
if (values.Count == 0)
return null;
if (!string.IsNullOrEmpty(proposedValue) && values.Contains(proposedValue))
return proposedValue;
return values[0];
}
void InitializeProposedOrganizationProject(IPlasticWebRestApi restApi)
{
GetProposedOrganizationProject.Values proposedOrganizationProject =
GetProposedOrganizationProject.FromCloudProjectSettings();
mProposedOrganization = proposedOrganizationProject != null ?
proposedOrganizationProject.Organization :
GetDefaultServer.FromConfig(restApi);
mProposedProject = proposedOrganizationProject != null ?
proposedOrganizationProject.Project :
Application.productName;
}
List<string> mOrganizations = new List<string>();
List<string> mProjects = new List<string>();
List<CloudDriveWorkspace> mCloudDrives = new List<CloudDriveWorkspace>();
string mProposedOrganization;
string mProposedProject;
string mSelectedOrganization;
string mSelectedProject;
CloudDriveWorkspace mSelectedCloudDrive;
string mCloudDriveRelativePath;
IPlasticAPI mPlasticApi;
const float ENTRY_WIDTH = 400;
const float ENTRY_X = 120f;
const float BROWSE_BUTTON_WIDTH = 30;
const float BUTTON_MARGIN = 5;
}
}