Commit 1c847220 authored by jang dong hyeok's avatar jang dong hyeok
Browse files

.

parent 076f0c68
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 RepositoryListViewItem(int id, RepositoryInfo repository)
: base(id, 0)
{
Repository = repository;
displayName = repository.Name;
}
}
}
using System;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WebApi;
using PlasticGui.SwitcherWindow.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<RepositoryCreationData> createRepositoryAction,
Action<CreateWorkspaceViewState> createWorkspaceAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer,
ref CreateWorkspaceViewState state)
{
DoTitle();
GUILayout.Space(15);
DoFieldsArea(
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<RepositoryCreationData> createRepositoryAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer,
ref CreateWorkspaceViewState state)
{
DoRepositoryField(
createRepositoryAction,
parentWindow,
plasticWebRestApi,
defaultServer,
ref state);
DoWorkspaceField(ref state);
}
static void DoRepositoryField(
Action<RepositoryCreationData> createRepositoryAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer,
ref CreateWorkspaceViewState state)
{
EditorGUILayout.BeginHorizontal();
DoLabel(
PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryName));
state.RepositoryName = DoTextField(
state.RepositoryName,
!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(
parentWindow,
plasticWebRestApi,
defaultServer,
ref state);
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.RepositoryName,
defaultServer);
EditorGUIUtility.ExitGUI();
}
ValidationResult validationResult = ValidateRepositoryName(
state.RepositoryName);
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.WorkPreferenceAnswerPlastic),
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(
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer,
ref CreateWorkspaceViewState state)
{
string result = RepositoryExplorerDialog.BrowseRepository(
parentWindow,
plasticWebRestApi,
defaultServer);
if (string.IsNullOrEmpty(result))
return;
state.RepositoryName = result;
}
static void DoNewRepositoryButton(
Action<RepositoryCreationData> createRepositoryAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string repositoryName,
string defaultServer)
{
string proposedRepositoryName = string.Empty;
string proposedServer = string.Empty;
RepositorySpec repSpec = GetRepSpecFromName(repositoryName);
if (repSpec != null)
{
proposedRepositoryName = repSpec.Name;
proposedServer = repSpec.Server;
}
RepositoryCreationData creationData = CreateRepositoryDialog.CreateRepository(
parentWindow,
plasticWebRestApi,
proposedRepositoryName,
proposedServer,
defaultServer,
ClientConfig.Get().GetWorkspaceServer());
createRepositoryAction(creationData);
}
static void DoHelpLabel()
{
string linkText = PlasticLocalization.GetString(PlasticLocalization.Name.HereLink);
string labelText = string.Format(
PlasticLocalization.GetString(PlasticLocalization.Name.LearnMoreDifferences),
UnityStyles.HexColors.LINK_COLOR,
linkText);
EditorGUILayout.BeginHorizontal();
if (DoLinkLabel(labelText, linkText, RADIO_BUTTON_MARGIN))
Application.OpenURL(
PlasticLocalization.GetString(PlasticLocalization.Name.PlasticSCMFullVsPartialWorkspaceLink));
EditorGUILayout.EndHorizontal();
}
static void DoNotificationArea(ProgressControlsForViews.Data progressData)
{
if (string.IsNullOrEmpty(progressData.NotificationMessage))
return;
DrawProgressForViews.ForNotificationArea(progressData);
}
static void DoLabel(string labelText)
{
GUIStyle labelStyle = 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 =
EditorStyles.radioButton;
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.IncomingChangesTab.HeaderWarningLabel);
}
static bool DoLinkLabel(
string labelText,
string linkText,
float labelLeft)
{
GUIContent labelContent = new GUIContent(labelText);
GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel);
labelStyle.richText = true;
Rect rect = GUILayoutUtility.GetRect(
labelContent,
labelStyle);
rect.x = labelLeft;
Rect linkRect = GetLinkRect(
labelText,
linkText,
labelContent,
labelStyle,
rect);
EditorGUIUtility.AddCursorRect(linkRect, MouseCursor.Link);
GUI.Label(rect, labelText, labelStyle);
return Mouse.IsLeftMouseButtonPressed(Event.current)
&& linkRect.Contains(Event.current.mousePosition);
}
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 Rect GetLinkRect(
string labelText,
string linkText,
GUIContent labelContent,
GUIStyle labelStyle,
Rect rect)
{
int beginLinkChar = labelText.IndexOf(linkText);
int endLinkChar = beginLinkChar + linkText.Length;
Vector2 beginPos = labelStyle.GetCursorPixelPosition(
rect, labelContent, beginLinkChar);
Vector2 endPos = labelStyle.GetCursorPixelPosition(
rect, labelContent, endLinkChar);
Rect linkRect = new Rect(
beginPos.x,
beginPos.y,
endPos.x - beginPos.x,
labelStyle.lineHeight * 1.2f);
return linkRect;
}
static bool IsValidState(
CreateWorkspaceViewState state)
{
if (!ValidateRepositoryName(state.RepositoryName).IsValid)
return false;
if (!ValidateWorkspaceName(state.WorkspaceName).IsValid)
return false;
return true;
}
static ValidationResult ValidateRepositoryName(string repositoryName)
{
ValidationResult result = new ValidationResult();
if (string.IsNullOrEmpty(repositoryName))
{
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;
}
static RepositorySpec GetRepSpecFromName(string repositoryName)
{
if (string.IsNullOrEmpty(repositoryName))
return null;
return new SpecGenerator().
GenRepositorySpec(false, repositoryName);
}
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 float PROGRESS_MARGIN = 5;
const float CREATE_WORKSPACE_BUTTON_MARGIN = 32;
const float CREATE_WORKSPACE_BUTTON_WIDTH = 160;
}
}
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 = '|';
}
}
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class ChangeCategoryTreeViewItem : TreeViewItem
{
internal ChangeCategory Category { get; private set; }
internal ChangeCategoryTreeViewItem(
int id, int depth, ChangeCategory category)
: base(id, depth, category.GetHeaderText())
{
Category = category;
}
}
}
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class ClientDiffTreeViewItem : TreeViewItem
{
internal ClientDiffInfo Difference { get; private set; }
internal ClientDiffTreeViewItem(
int id, int depth, ClientDiffInfo diff)
: base(id, depth)
{
Difference = diff;
displayName = diff.PathString;
}
}
}
using System.IO;
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.Diff;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.Diff.Dialogs
{
internal class GetRestorePathDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 600, 205);
}
}
internal static GetRestorePathData GetRestorePath(
string wkPath,
string restorePath,
string explanation,
bool isDirectory,
bool showSkipButton,
EditorWindow parentWindow)
{
GetRestorePathDialog dialog = Create(
new ProgressControlsForDialogs(),
wkPath,
GetProposedRestorePath.For(restorePath),
explanation,
isDirectory,
showSkipButton);
ResponseType dialogResult = dialog.RunModal(parentWindow);
GetRestorePathData result = dialog.BuildGetRestorePathResult();
result.Result = GetRestorePathResultType(dialogResult);
return result;
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.EnterRestorePathFormTitle));
Paragraph(mExplanation);
DoEntryArea();
GUILayout.Space(10);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
DoButtonsArea();
mProgressControls.ForcedUpdateProgress(this);
}
void DoEntryArea()
{
GUILayout.Label(PlasticLocalization.GetString(
PlasticLocalization.Name.EnterRestorePathFormTextBoxExplanation),
EditorStyles.label);
GUILayout.BeginHorizontal();
mRestorePath = GUILayout.TextField(
mRestorePath, GUILayout.Width(TEXTBOX_WIDTH));
if (GUILayout.Button("...", EditorStyles.miniButton))
{
mRestorePath = (mIsDirectory) ?
DoOpenFolderPanel(mRestorePath) :
DoOpenFilePanel(mRestorePath);
}
GUILayout.EndHorizontal();
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.EnterRestorePathFormTitle);
}
static string DoOpenFolderPanel(string actualPath)
{
string parentDirectory = null;
string directoryName = null;
if (!string.IsNullOrEmpty(actualPath))
{
parentDirectory = Path.GetDirectoryName(actualPath);
directoryName = Path.GetFileName(actualPath);
}
string result = EditorUtility.SaveFolderPanel(
PlasticLocalization.GetString(PlasticLocalization.Name.SelectPathToRestore),
parentDirectory,
directoryName);
if (string.IsNullOrEmpty(result))
return actualPath;
return Path.GetFullPath(result);
}
static string DoOpenFilePanel(string actualPath)
{
string parentDirectory = null;
string fileName = null;
string extension = null;
if (!string.IsNullOrEmpty(actualPath))
{
parentDirectory = Path.GetDirectoryName(actualPath);
fileName = Path.GetFileName(actualPath);
extension = Path.GetExtension(actualPath);
}
string result = EditorUtility.SaveFilePanel(
PlasticLocalization.GetString(PlasticLocalization.Name.SelectPathToRestore),
parentDirectory,
fileName,
extension);
if (string.IsNullOrEmpty(result))
return actualPath;
return Path.GetFullPath(result);
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoSkipButton(mShowSkipButton);
DoCancelButton();
return;
}
DoCancelButton();
DoSkipButton(mShowSkipButton);
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.OkButton)))
return;
OkButtonWithValidationAction();
}
void DoSkipButton(bool showSkipButton)
{
if (!showSkipButton)
return;
if (!NormalButton(PlasticLocalization.GetString(PlasticLocalization.Name.SkipRestoreButton)))
return;
CloseButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void OkButtonWithValidationAction()
{
GetRestorePathValidation.Validation(
mWkPath, BuildGetRestorePathResult(),
this, mProgressControls);
}
GetRestorePathData BuildGetRestorePathResult()
{
return new GetRestorePathData(mRestorePath);
}
static GetRestorePathData.ResultType GetRestorePathResultType(
ResponseType dialogResult)
{
switch (dialogResult)
{
case ResponseType.None:
return GetRestorePathData.ResultType.Skip;
case ResponseType.Ok:
return GetRestorePathData.ResultType.OK;
case ResponseType.Cancel:
return GetRestorePathData.ResultType.Cancel;
}
return GetRestorePathData.ResultType.Cancel;
}
static GetRestorePathDialog Create(
ProgressControlsForDialogs progressControls,
string wkPath,
string restorePath,
string explanation,
bool isDirectory,
bool showSkipButton)
{
var instance = CreateInstance<GetRestorePathDialog>();
instance.mWkPath = wkPath;
instance.mRestorePath = restorePath;
instance.mExplanation = explanation;
instance.mIsDirectory = isDirectory;
instance.mShowSkipButton = showSkipButton;
instance.mEnterKeyAction = instance.OkButtonWithValidationAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mProgressControls = progressControls;
return instance;
}
bool mIsDirectory;
bool mShowSkipButton;
string mExplanation = string.Empty;
string mRestorePath = string.Empty;
string mWkPath = string.Empty;
ProgressControlsForDialogs mProgressControls;
const float TEXTBOX_WIDTH = 520;
}
}
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Diff;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.Views.Diff.Dialogs;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class DiffPanel :
IDiffTreeViewMenuOperations,
DiffTreeViewMenu.IMetaMenuOperations,
UndeleteClientDiffsOperation.IGetRestorePathDialog
{
internal DiffPanel(
WorkspaceInfo wkInfo,
IWorkspaceWindow workspaceWindow,
IViewSwitcher viewSwitcher,
IHistoryViewLauncher historyViewLauncher,
EditorWindow parentWindow)
{
mWkInfo = wkInfo;
mWorkspaceWindow = workspaceWindow;
mViewSwitcher = viewSwitcher;
mHistoryViewLauncher = historyViewLauncher;
mParentWindow = parentWindow;
mGuiMessage = new UnityPlasticGuiMessage(parentWindow);
BuildComponents();
mProgressControls = new ProgressControlsForViews();
}
internal void ClearInfo()
{
ClearData();
mParentWindow.Repaint();
}
internal void UpdateInfo(
MountPointWithPath mountWithPath,
ChangesetInfo csetInfo)
{
FillData(mountWithPath, csetInfo);
mParentWindow.Repaint();
}
internal void OnDisable()
{
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
}
internal void Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
EditorGUILayout.BeginVertical();
DoActionsToolbar(
mDiffs,
mProgressControls,
GetHeaderLabelText(mSelectedChangesetInfo),
mIsSkipMergeTrackingButtonVisible,
mIsSkipMergeTrackingButtonChecked,
mSearchField,
mDiffTreeView);
DoDiffTreeViewArea(
mDiffTreeView,
mProgressControls.IsOperationRunning());
if (mProgressControls.HasNotification())
{
DrawProgressForViews.ForNotificationArea(
mProgressControls.ProgressData);
}
EditorGUILayout.EndVertical();
}
SelectedDiffsGroupInfo IDiffTreeViewMenuOperations.GetSelectedDiffsGroupInfo()
{
return SelectedDiffsGroupInfo.BuildFromSelectedNodes(
DiffSelection.GetSelectedDiffsWithoutMeta(mDiffTreeView));
}
void IDiffTreeViewMenuOperations.Diff()
{
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
DiffOperation.DiffClientDiff(
mWkInfo,
clientDiffInfo.DiffWithMount.Mount.Mount,
clientDiffInfo.DiffWithMount.Difference,
xDiffLauncher: null,
imageDiffLauncher: null);
}
void IDiffTreeViewMenuOperations.History()
{
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
mHistoryViewLauncher.ShowHistoryView(
clientDiffInfo.DiffWithMount.Mount.RepSpec,
clientDiffInfo.DiffWithMount.Difference.RevInfo.ItemId,
clientDiffInfo.DiffWithMount.Difference.Path,
clientDiffInfo.DiffWithMount.Difference.IsDirectory);
}
void IDiffTreeViewMenuOperations.RevertChanges()
{
RevertClientDiffsOperation.RevertChanges(
mWkInfo,
DiffSelection.GetSelectedDiffs(mDiffTreeView),
mWorkspaceWindow,
mProgressControls,
mGuiMessage,
AfterRevertOrUndeleteOperation);
}
void IDiffTreeViewMenuOperations.Undelete()
{
UndeleteClientDiffsOperation.Undelete(
mWkInfo,
DiffSelection.GetSelectedDiffs(mDiffTreeView),
mWorkspaceWindow,
mProgressControls,
this,
mGuiMessage,
AfterRevertOrUndeleteOperation);
}
void IDiffTreeViewMenuOperations.UndeleteToSpecifiedPaths()
{
UndeleteClientDiffsOperation.UndeleteToSpecifiedPaths(
mWkInfo,
DiffSelection.GetSelectedDiffs(mDiffTreeView),
mWorkspaceWindow,
mProgressControls,
this,
mGuiMessage,
AfterRevertOrUndeleteOperation);
}
bool DiffTreeViewMenu.IMetaMenuOperations.SelectionHasMeta()
{
return mDiffTreeView.SelectionHasMeta();
}
void DiffTreeViewMenu.IMetaMenuOperations.DiffMeta()
{
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
ClientDiffInfo clientDiffInfoMeta =
mDiffTreeView.GetMetaDiff(clientDiffInfo);
DiffOperation.DiffClientDiff(
mWkInfo,
clientDiffInfoMeta.DiffWithMount.Mount.Mount,
clientDiffInfoMeta.DiffWithMount.Difference,
xDiffLauncher: null,
imageDiffLauncher: null);
}
GetRestorePathData
UndeleteClientDiffsOperation.IGetRestorePathDialog.GetRestorePath(
string wkPath, string restorePath, string explanation,
bool isDirectory, bool showSkipButton)
{
return GetRestorePathDialog.GetRestorePath(
wkPath, restorePath, explanation, isDirectory,
showSkipButton, mParentWindow);
}
void DiffTreeViewMenu.IMetaMenuOperations.HistoryMeta()
{
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
ClientDiffInfo clientDiffInfoMeta =
mDiffTreeView.GetMetaDiff(clientDiffInfo);
mHistoryViewLauncher.ShowHistoryView(
clientDiffInfoMeta.DiffWithMount.Mount.RepSpec,
clientDiffInfoMeta.DiffWithMount.Difference.RevInfo.ItemId,
clientDiffInfoMeta.DiffWithMount.Difference.Path,
clientDiffInfoMeta.DiffWithMount.Difference.IsDirectory);
}
void SearchField_OnDownOrUpArrowKeyPressed()
{
mDiffTreeView.SetFocusAndEnsureSelectedItem();
}
void AfterRevertOrUndeleteOperation()
{
RefreshAsset.UnityAssetDatabase();
mViewSwitcher.ShowPendingChanges();
}
void ClearData()
{
mSelectedMountWithPath = null;
mSelectedChangesetInfo = null;
mDiffs = null;
ClearDiffs();
}
void FillData(
MountPointWithPath mountWithPath,
ChangesetInfo csetInfo)
{
mSelectedMountWithPath = mountWithPath;
mSelectedChangesetInfo = csetInfo;
((IProgressControls)mProgressControls).ShowProgress(
PlasticLocalization.GetString(PlasticLocalization.Name.Loading));
mIsSkipMergeTrackingButtonVisible = false;
IThreadWaiter waiter = ThreadWaiter.GetWaiter(100);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
mDiffs = Plastic.API.GetChangesetDifferences(
mountWithPath, csetInfo);
},
/*afterOperationDelegate*/ delegate
{
((IProgressControls)mProgressControls).HideProgress();
if (waiter.Exception != null)
{
ExceptionsHandler.DisplayException(waiter.Exception);
return;
}
if (mSelectedMountWithPath != mountWithPath ||
mSelectedChangesetInfo != csetInfo)
return;
if (mDiffs == null || mDiffs.Count == 0)
{
ClearDiffs();
return;
}
mIsSkipMergeTrackingButtonVisible =
ClientDiffList.HasMerges(mDiffs);
bool skipMergeTracking =
mIsSkipMergeTrackingButtonVisible &&
mIsSkipMergeTrackingButtonChecked;
UpdateDiffTreeView(
mDiffs, skipMergeTracking, mDiffTreeView);
});
}
void ClearDiffs()
{
mIsSkipMergeTrackingButtonVisible = false;
ClearDiffTreeView(mDiffTreeView);
((IProgressControls)mProgressControls).ShowNotification(
PlasticLocalization.GetString(PlasticLocalization.Name.NoContentToCompare));
}
static void ClearDiffTreeView(
DiffTreeView diffTreeView)
{
diffTreeView.ClearModel();
diffTreeView.Reload();
}
static void UpdateDiffTreeView(
List<ClientDiff> diffs,
bool skipMergeTracking,
DiffTreeView diffTreeView)
{
diffTreeView.BuildModel(
diffs, skipMergeTracking);
diffTreeView.Refilter();
diffTreeView.Sort();
diffTreeView.Reload();
}
static string GetHeaderLabelText(
ChangesetInfo changesetInfo)
{
if (changesetInfo == null)
return PlasticLocalization.GetString(PlasticLocalization.Name.ChangesLabelPlural);
return string.Format(
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesOfChangeset),
changesetInfo.ChangesetId);
}
void DoActionsToolbar(
List<ClientDiff> diffs,
ProgressControlsForViews progressControls,
string headerLabelText,
bool isSkipMergeTrackingButtonVisible,
bool isSkipMergeTrackingButtonChecked,
SearchField searchField,
DiffTreeView diffTreeView)
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.Label(headerLabelText,
UnityStyles.DiffPanel.HeaderLabel);
if (progressControls.IsOperationRunning())
{
DrawProgressForViews.ForIndeterminateProgress(
progressControls.ProgressData);
}
GUILayout.FlexibleSpace();
if (isSkipMergeTrackingButtonVisible)
{
DoSkipMergeTrackingButton(
diffs,
isSkipMergeTrackingButtonChecked,
diffTreeView);
}
DrawSearchField.For(
searchField,
diffTreeView,
UnityConstants.SEARCH_FIELD_WIDTH);
EditorGUILayout.EndHorizontal();
}
void DoSkipMergeTrackingButton(
List<ClientDiff> diffs,
bool isSkipMergeTrackingButtonChecked,
DiffTreeView diffTreeView)
{
bool wasChecked = isSkipMergeTrackingButtonChecked;
GUIContent buttonContent = new GUIContent(
PlasticLocalization.GetString(
PlasticLocalization.Name.SkipDiffMergeTracking));
GUIStyle buttonStyle = EditorStyles.toolbarButton;
float buttonWidth = buttonStyle.CalcSize(buttonContent).x + 10;
Rect toggleRect = GUILayoutUtility.GetRect(
buttonContent, buttonStyle, GUILayout.Width(buttonWidth));
bool isChecked = GUI.Toggle(
toggleRect, wasChecked, buttonContent, buttonStyle);
if (wasChecked == isChecked)
return;
UpdateDiffTreeView(diffs, isChecked, diffTreeView);
mIsSkipMergeTrackingButtonChecked = isChecked;
}
static void DoDiffTreeViewArea(
DiffTreeView diffTreeView,
bool isOperationRunning)
{
GUI.enabled = !isOperationRunning;
Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
diffTreeView.OnGUI(rect);
GUI.enabled = true;
}
void BuildComponents()
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
mDiffTreeView = new DiffTreeView(
new DiffTreeViewMenu(this, this));
mDiffTreeView.Reload();
}
volatile List<ClientDiff> mDiffs;
bool mIsSkipMergeTrackingButtonVisible;
bool mIsSkipMergeTrackingButtonChecked;
SearchField mSearchField;
DiffTreeView mDiffTreeView;
ChangesetInfo mSelectedChangesetInfo;
MountPointWithPath mSelectedMountWithPath;
readonly ProgressControlsForViews mProgressControls;
readonly GuiMessage.IGuiMessage mGuiMessage;
readonly EditorWindow mParentWindow;
readonly IWorkspaceWindow mWorkspaceWindow;
readonly IHistoryViewLauncher mHistoryViewLauncher;
readonly IViewSwitcher mViewSwitcher;
readonly WorkspaceInfo mWkInfo;
}
}
using System.Collections.Generic;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal static class DiffSelection
{
internal static List<ClientDiffInfo> GetSelectedDiffs(
DiffTreeView treeView)
{
return treeView.GetSelectedDiffs(true);
}
internal static List<ClientDiffInfo> GetSelectedDiffsWithoutMeta(
DiffTreeView treeView)
{
return treeView.GetSelectedDiffs(false);
}
internal static ClientDiffInfo GetSelectedDiff(
DiffTreeView treeView)
{
if (!treeView.HasSelection())
return null;
return treeView.GetSelectedDiffs(false)[0];
}
}
}
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Commands;
using Codice.Utils;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Diff;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class DiffTreeView : TreeView
{
internal DiffTreeView(DiffTreeViewMenu menu)
: base(new TreeViewState())
{
mMenu = menu;
customFoldoutYOffset = UnityConstants.TREEVIEW_FOLDOUT_Y_OFFSET;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = true;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
public override void OnGUI(Rect rect)
{
base.OnGUI(rect);
Event e = Event.current;
if (e.type != EventType.KeyDown)
return;
bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e);
if (isProcessed)
e.Use();
}
protected override bool CanChangeExpandedState(TreeViewItem item)
{
return item is ChangeCategoryTreeViewItem
|| item is MergeCategoryTreeViewItem;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem rootItem)
{
try
{
RegenerateRows(
mDiffTree,
mTreeViewItemIds,
this,
rootItem,
mRows,
mExpandCategories);
}
finally
{
mExpandCategories = false;
}
return mRows;
}
protected override void CommandEventHandling()
{
// NOTE - empty override to prevent crash when pressing ctrl-a in the treeview
}
protected override void SearchChanged(string newSearch)
{
mCooldownFilterAction.Ping();
}
protected override void ContextClickedItem(int id)
{
mMenu.Popup();
Repaint();
}
protected override void RowGUI(RowGUIArgs args)
{
DrawTreeViewItem.InitializeStyles();
if (args.item is MergeCategoryTreeViewItem)
{
MergeCategoryTreeViewItemGUI(
args.rowRect,
rowHeight,
(MergeCategoryTreeViewItem)args.item,
args.selected,
args.focused);
return;
}
if (args.item is ChangeCategoryTreeViewItem)
{
ChangeCategoryTreeViewItemGUI(
args.rowRect,
rowHeight,
(ChangeCategoryTreeViewItem)args.item,
args.selected,
args.focused);
return;
}
if (args.item is ClientDiffTreeViewItem)
{
ClientDiffTreeViewItemGUI(
args.rowRect,
rowHeight,
mDiffTree,
(ClientDiffTreeViewItem)args.item,
args.selected,
args.focused);
return;
}
base.RowGUI(args);
}
internal void ClearModel()
{
mTreeViewItemIds.Clear();
mDiffTree = new UnityDiffTree();
}
internal void BuildModel(
List<ClientDiff> diffs,
bool skipMergeTracking)
{
mTreeViewItemIds.Clear();
mDiffTree.BuildCategories(diffs, skipMergeTracking);
}
internal void Refilter()
{
Filter filter = new Filter(searchString);
mDiffTree.Filter(filter, ColumnsNames);
mExpandCategories = true;
}
internal void Sort()
{
mDiffTree.Sort(
PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn),
sortAscending: true);
}
internal ClientDiffInfo GetMetaDiff(ClientDiffInfo diff)
{
return mDiffTree.GetMetaDiff(diff);
}
internal bool SelectionHasMeta()
{
if (!HasSelection())
return false;
ClientDiffInfo selectedDiff = GetSelectedDiffs(false)[0];
if (selectedDiff == null)
return false;
return mDiffTree.HasMeta(selectedDiff);
}
internal List<ClientDiffInfo> GetSelectedDiffs(bool includeMetaFiles)
{
List<ClientDiffInfo> result = new List<ClientDiffInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<ITreeViewNode, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
if (!(item.Key is ClientDiffInfo))
continue;
result.Add((ClientDiffInfo)item.Key);
}
if (includeMetaFiles)
mDiffTree.FillWithMeta(result);
return result;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
static void RegenerateRows(
UnityDiffTree diffTree,
TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds,
TreeView treeView,
TreeViewItem rootItem,
List<TreeViewItem> rows,
bool expandCategories)
{
ClearRows(rootItem, rows);
List<IDiffCategory> categories = diffTree.GetNodes();
if (categories == null)
return;
foreach (IDiffCategory category in categories)
{
if (category is MergeCategory)
{
AddMergeCategory(
rootItem,
category,
rows,
treeViewItemIds,
treeView,
expandCategories);
}
if (category is ChangeCategory)
{
AddChangeCategory(
rootItem,
category,
rows,
treeViewItemIds,
treeView,
expandCategories);
}
}
if (!expandCategories)
return;
treeView.state.expandedIDs = treeViewItemIds.GetCategoryIds();
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void AddMergeCategory(
TreeViewItem rootItem,
IDiffCategory category,
List<TreeViewItem> rows,
TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds,
TreeView treeView,
bool expandCategories)
{
int categoryId;
if (!treeViewItemIds.TryGetCategoryItemId(category, out categoryId))
categoryId = treeViewItemIds.AddCategoryItem(category);
MergeCategoryTreeViewItem mergeCategoryTreeViewItem =
new MergeCategoryTreeViewItem(
categoryId,
rootItem.depth + 1,
(MergeCategory)category);
rootItem.AddChild(mergeCategoryTreeViewItem);
rows.Add(mergeCategoryTreeViewItem);
if (!expandCategories &&
!treeView.IsExpanded(mergeCategoryTreeViewItem.id))
return;
for (int i = 0; i < category.GetChildrenCount(); i++)
{
IDiffCategory child = (IDiffCategory)((ITreeViewNode)category)
.GetChild(i);
AddChangeCategory(
mergeCategoryTreeViewItem,
child,
rows,
treeViewItemIds,
treeView,
expandCategories);
}
}
static void AddChangeCategory(
TreeViewItem parentItem,
IDiffCategory category,
List<TreeViewItem> rows,
TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds,
TreeView treeView,
bool expandCategories)
{
int categoryId;
if (!treeViewItemIds.TryGetCategoryItemId(category, out categoryId))
categoryId = treeViewItemIds.AddCategoryItem(category);
ChangeCategoryTreeViewItem changeCategoryTreeViewItem =
new ChangeCategoryTreeViewItem(
categoryId,
parentItem.depth + 1,
(ChangeCategory)category);
parentItem.AddChild(changeCategoryTreeViewItem);
rows.Add(changeCategoryTreeViewItem);
if (!expandCategories &&
!treeView.IsExpanded(changeCategoryTreeViewItem.id))
return;
AddClientDiffs(
changeCategoryTreeViewItem,
(ITreeViewNode)category,
rows,
treeViewItemIds);
}
static void AddClientDiffs(
TreeViewItem parentItem,
ITreeViewNode parentNode,
List<TreeViewItem> rows,
TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds)
{
for (int i = 0; i < parentNode.GetChildrenCount(); i++)
{
ITreeViewNode child = parentNode.GetChild(i);
int nodeId;
if (!treeViewItemIds.TryGetInfoItemId(child, out nodeId))
nodeId = treeViewItemIds.AddInfoItem(child);
TreeViewItem changeTreeViewItem =
new ClientDiffTreeViewItem(
nodeId,
parentItem.depth + 1,
(ClientDiffInfo)child);
parentItem.AddChild(changeTreeViewItem);
rows.Add(changeTreeViewItem);
}
}
static void MergeCategoryTreeViewItemGUI(
Rect rowRect,
float rowHeight,
MergeCategoryTreeViewItem item,
bool isSelected,
bool isFocused)
{
Texture icon = Images.GetImage(Images.Name.IconMergeCategory);
string label = item.Category.GetHeaderText();
DrawTreeViewItem.ForCategoryItem(
rowRect,
rowHeight,
item.depth,
icon, label,
isSelected,
isFocused);
}
static void ChangeCategoryTreeViewItemGUI(
Rect rowRect,
float rowHeight,
ChangeCategoryTreeViewItem item,
bool isSelected,
bool isFocused)
{
Texture icon = GetChangeCategoryIcon(item.Category);
string label = item.Category.GetHeaderText();
DrawTreeViewItem.ForCategoryItem(
rowRect,
rowHeight,
item.depth,
icon, label,
isSelected,
isFocused);
}
static void ClientDiffTreeViewItemGUI(
Rect rowRect,
float rowHeight,
UnityDiffTree diffTree,
ClientDiffTreeViewItem item,
bool isSelected,
bool isFocused)
{
string label = ClientDiffView.GetColumnText(
item.Difference.DiffWithMount.Mount.RepSpec,
item.Difference.DiffWithMount.Difference,
PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn));
if (diffTree.HasMeta(item.Difference))
label = string.Concat(label, UnityConstants.TREEVIEW_META_LABEL);
Texture icon = GetClientDiffIcon(
item.Difference.DiffWithMount.Difference.IsDirectory,
label);
DrawTreeViewItem.ForItemCell(
rowRect,
rowHeight,
item.depth,
icon,
null,
label,
isSelected,
isFocused,
false,
false);
}
static Texture GetChangeCategoryIcon(ChangeCategory category)
{
switch (category.Type)
{
case ChangeCategoryType.Merged:
return Images.GetImage(Images.Name.IconMerged);
case ChangeCategoryType.Changed:
return Images.GetImage(Images.Name.IconChanged);
case ChangeCategoryType.Moved:
return Images.GetImage(Images.Name.IconMoved);
case ChangeCategoryType.Deleted:
return Images.GetImage(Images.Name.IconDeleted);
case ChangeCategoryType.FSProtection:
return Images.GetImage(Images.Name.IconFsChanged);
case ChangeCategoryType.Added:
return Images.GetImage(Images.Name.IconAdded);
default:
return null;
}
}
static Texture GetClientDiffIcon(bool isDirectory, string path)
{
if (isDirectory)
return Images.GetDirectoryIcon();
return Images.GetFileIconFromCmPath(path);
}
bool mExpandCategories;
TreeViewItemIds<IDiffCategory, ITreeViewNode> mTreeViewItemIds =
new TreeViewItemIds<IDiffCategory, ITreeViewNode>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
UnityDiffTree mDiffTree = new UnityDiffTree();
readonly CooldownWindowDelayer mCooldownFilterAction;
static readonly List<string> ColumnsNames = new List<string> {
PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn)};
readonly DiffTreeViewMenu mMenu;
}
}
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Diff;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class DiffTreeViewMenu
{
internal interface IMetaMenuOperations
{
bool SelectionHasMeta();
void DiffMeta();
void HistoryMeta();
}
internal DiffTreeViewMenu(
IDiffTreeViewMenuOperations operations,
IMetaMenuOperations metaMenuOperations)
{
mOperations = operations;
mMetaMenuOperations = metaMenuOperations;
BuildComponents();
}
internal void Popup()
{
GenericMenu menu = new GenericMenu();
UpdateMenuItems(menu);
menu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
DiffTreeViewMenuOperations operationToExecute = GetMenuOperation(e);
if (operationToExecute == DiffTreeViewMenuOperations.None)
return false;
SelectedDiffsGroupInfo info =
mOperations.GetSelectedDiffsGroupInfo();
DiffTreeViewMenuOperations operations =
DiffTreeViewMenuUpdater.GetAvailableMenuOperations(info);
if (!operations.HasFlag(operationToExecute))
return false;
ProcessMenuOperation(operationToExecute, mOperations);
return true;
}
void DiffMenuItem_Click()
{
mOperations.Diff();
}
void DiffMetaMenuItem_Click()
{
mMetaMenuOperations.DiffMeta();
}
void HistoryMenuItem_Click()
{
mOperations.History();
}
void HistoryMetaMenuItem_Click()
{
mMetaMenuOperations.HistoryMeta();
}
void RevertMenuItem_Click()
{
mOperations.RevertChanges();
}
void UndeleteMenuItem_Click()
{
mOperations.Undelete();
}
void UndeleteToSpecifiedPathMenuItem_Click()
{
mOperations.UndeleteToSpecifiedPaths();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedDiffsGroupInfo groupInfo =
mOperations.GetSelectedDiffsGroupInfo();
DiffTreeViewMenuOperations operations =
DiffTreeViewMenuUpdater.GetAvailableMenuOperations(groupInfo);
if (operations == DiffTreeViewMenuOperations.None)
{
menu.AddDisabledItem(GetNoActionMenuItemContent());
return;
}
bool isMultipleSelection = groupInfo.SelectedItemsCount > 1;
bool selectionHasMeta = mMetaMenuOperations.SelectionHasMeta();
if (operations.HasFlag(DiffTreeViewMenuOperations.Diff))
menu.AddItem(mDiffMenuItemContent, false, DiffMenuItem_Click);
else
menu.AddDisabledItem(mDiffMenuItemContent, false);
if (mMetaMenuOperations.SelectionHasMeta())
{
if (operations.HasFlag(DiffTreeViewMenuOperations.Diff))
menu.AddItem(mDiffMetaMenuItemContent, false, DiffMetaMenuItem_Click);
else
menu.AddDisabledItem(mDiffMetaMenuItemContent);
}
menu.AddSeparator(string.Empty);
if (operations.HasFlag(DiffTreeViewMenuOperations.History))
menu.AddItem(mViewHistoryMenuItemContent, false, HistoryMenuItem_Click);
else
menu.AddDisabledItem(mViewHistoryMenuItemContent, false);
if (mMetaMenuOperations.SelectionHasMeta())
{
if (operations.HasFlag(DiffTreeViewMenuOperations.History))
menu.AddItem(mViewHistoryMetaMenuItemContent, false, HistoryMetaMenuItem_Click);
else
menu.AddDisabledItem(mViewHistoryMetaMenuItemContent, false);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.RevertChanges))
{
menu.AddSeparator(string.Empty);
mRevertMenuItemContent.text = GetRevertMenuItemText(
isMultipleSelection,
selectionHasMeta);
menu.AddItem(mRevertMenuItemContent, false, RevertMenuItem_Click);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.Undelete) ||
operations.HasFlag(DiffTreeViewMenuOperations.UndeleteToSpecifiedPaths))
{
menu.AddSeparator(string.Empty);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.Undelete))
{
mUndeleteMenuItemContent.text = GetUndeleteMenuItemText(
isMultipleSelection,
selectionHasMeta);
menu.AddItem(mUndeleteMenuItemContent, false, UndeleteMenuItem_Click);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.UndeleteToSpecifiedPaths))
{
mUndeleteToSpecifiedPathMenuItemContent.text = GetUndeleteToSpecifiedPathMenuItemText(
isMultipleSelection,
selectionHasMeta);
menu.AddItem(mUndeleteToSpecifiedPathMenuItemContent, false, UndeleteToSpecifiedPathMenuItem_Click);
}
}
GUIContent GetNoActionMenuItemContent()
{
if (mNoActionMenuItemContent == null)
{
mNoActionMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.
Name.NoActionMenuItem));
}
return mNoActionMenuItemContent;
}
static string GetRevertMenuItemText(
bool isMultipleSelection,
bool selectionHasMeta)
{
if (selectionHasMeta && !isMultipleSelection)
return PlasticLocalization.GetString(PlasticLocalization.Name.UndoThisChangePlusMeta);
return isMultipleSelection ?
PlasticLocalization.GetString(PlasticLocalization.Name.UndoSelectedChanges) :
PlasticLocalization.GetString(PlasticLocalization.Name.UndoThisChange);
}
static string GetUndeleteMenuItemText(
bool isMultipleSelection,
bool selectionHasMeta)
{
if (selectionHasMeta && !isMultipleSelection)
return PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteRevisionPlusMeta);
return isMultipleSelection ?
PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteSelectedRevisions) :
PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteRevisions);
}
static string GetUndeleteToSpecifiedPathMenuItemText(
bool isMultipleSelection,
bool selectionHasMeta)
{
if (selectionHasMeta && !isMultipleSelection)
return PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteRevisionPlusMetaPath);
return isMultipleSelection ?
PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteSelectedRevisionsPaths) :
PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteRevisionPath);
}
static void ProcessMenuOperation(
DiffTreeViewMenuOperations operationToExecute,
IDiffTreeViewMenuOperations operations)
{
if (operationToExecute == DiffTreeViewMenuOperations.Diff)
{
operations.Diff();
return;
}
if (operationToExecute == DiffTreeViewMenuOperations.History)
{
operations.History();
return;
}
}
static DiffTreeViewMenuOperations GetMenuOperation(Event e)
{
if (Keyboard.IsControlOrCommandKeyPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.D))
return DiffTreeViewMenuOperations.Diff;
if (Keyboard.IsControlOrCommandKeyPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.H))
return DiffTreeViewMenuOperations.History;
return DiffTreeViewMenuOperations.None;
}
void BuildComponents()
{
mDiffMenuItemContent = new GUIContent(
string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.DiffMenuItem),
GetPlasticShortcut.ForDiff()));
mDiffMetaMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.DiffMetaMenuItem));
mViewHistoryMenuItemContent = new GUIContent(
string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.ViewHistoryMenuItem),
GetPlasticShortcut.ForHistory()));
mViewHistoryMetaMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.ViewHistoryMetaMenuItem));
mRevertMenuItemContent = new GUIContent();
mUndeleteMenuItemContent = new GUIContent();
mUndeleteToSpecifiedPathMenuItemContent = new GUIContent();
}
GUIContent mNoActionMenuItemContent;
GUIContent mDiffMenuItemContent;
GUIContent mDiffMetaMenuItemContent;
GUIContent mViewHistoryMenuItemContent;
GUIContent mViewHistoryMetaMenuItemContent;
GUIContent mRevertMenuItemContent;
GUIContent mUndeleteMenuItemContent;
GUIContent mUndeleteToSpecifiedPathMenuItemContent;
readonly IDiffTreeViewMenuOperations mOperations;
readonly IMetaMenuOperations mMetaMenuOperations;
}
}
using System.Collections.Generic;
using Codice.Utils;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal static class GetClientDiffInfos
{
internal static List<ClientDiffInfo> FromCategories(List<IDiffCategory> categories)
{
List<ClientDiffInfo> result = new List<ClientDiffInfo>();
foreach (ITreeViewNode node in categories)
AddClientDiffInfos(node, result);
return result;
}
static void AddClientDiffInfos(ITreeViewNode node, List<ClientDiffInfo> result)
{
if (node is ClientDiffInfo)
{
result.Add((ClientDiffInfo)node);
return;
}
for (int i = 0; i < node.GetChildrenCount(); i++)
AddClientDiffInfos(node.GetChild(i), result);
}
}
}
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class MergeCategoryTreeViewItem : TreeViewItem
{
internal MergeCategory Category { get; private set; }
internal MergeCategoryTreeViewItem(
int id, int depth, MergeCategory category)
: base(id, depth, category.GetHeaderText())
{
Category = category;
}
}
}
using System.Collections.Generic;
using Codice.Client.Commands;
using Codice.Utils;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class UnityDiffTree
{
internal UnityDiffTree()
{
mInnerTree = new DiffTree();
mMetaCache = new MetaCache();
}
internal void BuildCategories(List<ClientDiff> diffs, bool skipMergeTracking)
{
mInnerTree.BuildCategories(diffs, skipMergeTracking);
mMetaCache.Build(mInnerTree.GetNodes());
}
internal List<IDiffCategory> GetNodes()
{
return mInnerTree.GetNodes();
}
internal bool HasMeta(ClientDiffInfo difference)
{
return mMetaCache.ContainsMeta(difference);
}
internal ClientDiffInfo GetMetaDiff(ClientDiffInfo diff)
{
return mMetaCache.GetExistingMeta(diff);
}
internal void FillWithMeta(List<ClientDiffInfo> diffs)
{
diffs.AddRange(
mMetaCache.GetExistingMeta(diffs));
}
internal void Sort(string key, bool sortAscending)
{
mInnerTree.Sort(key, sortAscending);
}
internal void Filter(Filter filter, List<string> columnNames)
{
mInnerTree.Filter(filter, columnNames);
}
MetaCache mMetaCache = new MetaCache();
DiffTree mInnerTree;
class MetaCache
{
internal void Build(List<IDiffCategory> categories)
{
mCache.Clear();
HashSet<string> indexedKeys = BuildIndexedKeys(
GetClientDiffInfos.FromCategories(categories));
for (int i = 0; i < categories.Count; i++)
{
ExtractToMetaCache(
(ITreeViewNode)categories[i],
i,
mCache,
indexedKeys);
}
}
internal bool ContainsMeta(ClientDiffInfo diff)
{
return mCache.ContainsKey(
BuildKey.ForMetaDiff(diff));
}
internal ClientDiffInfo GetExistingMeta(ClientDiffInfo diff)
{
ClientDiffInfo result;
if (!mCache.TryGetValue(BuildKey.ForMetaDiff(diff), out result))
return null;
return result;
}
internal List<ClientDiffInfo> GetExistingMeta(List<ClientDiffInfo> diffs)
{
List<ClientDiffInfo> result = new List<ClientDiffInfo>();
foreach (ClientDiffInfo diff in diffs)
{
string key = BuildKey.ForMetaDiff(diff);
ClientDiffInfo metaDiff;
if (!mCache.TryGetValue(key, out metaDiff))
continue;
result.Add(metaDiff);
}
return result;
}
static void ExtractToMetaCache(
ITreeViewNode node,
int nodeIndex,
Dictionary<string, ClientDiffInfo> cache,
HashSet<string> indexedKeys)
{
if (node is ClientDiffInfo)
{
ClientDiffInfo diff = (ClientDiffInfo)node;
string path = diff.DiffWithMount.Difference.Path;
if (!MetaPath.IsMetaPath(path))
return;
string realPath = MetaPath.GetPathFromMetaPath(path);
if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
BuildKey.GetMergeCategory(diff),
BuildKey.GetChangeCategory(diff),
realPath)))
return;
// found foo.c and foo.c.meta
// with the same chage types - move .meta to cache
cache.Add(BuildKey.ForDiff(diff), diff);
((ChangeCategory)node.GetParent()).RemoveDiffAt(nodeIndex);
}
for (int i = node.GetChildrenCount() - 1; i >= 0; i--)
{
ExtractToMetaCache(
node.GetChild(i),
i,
cache,
indexedKeys);
}
}
HashSet<string> BuildIndexedKeys(List<ClientDiffInfo> diffs)
{
HashSet<string> result = new HashSet<string>();
foreach (ClientDiffInfo diff in diffs)
{
if (MetaPath.IsMetaPath(diff.DiffWithMount.Difference.Path))
continue;
result.Add(BuildKey.ForDiff(diff));
}
return result;
}
Dictionary<string, ClientDiffInfo> mCache =
new Dictionary<string, ClientDiffInfo>();
static class BuildKey
{
internal static string ForDiff(
ClientDiffInfo diff)
{
return BuildCacheKey(
GetMergeCategory(diff),
GetChangeCategory(diff),
diff.DiffWithMount.Difference.Path);
}
internal static string ForMetaDiff(
ClientDiffInfo diff)
{
return BuildCacheKey(
GetMergeCategory(diff),
GetChangeCategory(diff),
MetaPath.GetMetaPath(diff.DiffWithMount.Difference.Path));
}
internal static string BuildCacheKey(
MergeCategory mergeCategory,
ChangeCategory changeCategory,
string path)
{
string result = string.Concat(changeCategory.Type, ":", path);
if (mergeCategory == null)
return result;
return string.Concat(mergeCategory.GetCategoryNameSingular(), ":", result);
}
internal static ChangeCategory GetChangeCategory(ClientDiffInfo diff)
{
return (ChangeCategory)diff.GetParent();
}
internal static MergeCategory GetMergeCategory(ClientDiffInfo diff)
{
ChangeCategory changeCategory = GetChangeCategory(diff);
ITreeViewNode mergeCategory = changeCategory.GetParent();
if (mergeCategory == null)
return null;
return (MergeCategory)mergeCategory;
}
}
}
}
}
using System;
using System.Collections.Generic;
using UnityEditor;
using Codice.Client.Common.Threading;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Items;
namespace Unity.PlasticSCM.Editor.Views
{
internal static class FileSystemOperation
{
internal static string GetExePath()
{
string title = PlasticLocalization.GetString(
PlasticLocalization.Name.BrowseForExecutableFile);
string directory = Environment.GetFolderPath(
Environment.SpecialFolder.ProgramFiles);
string path = EditorUtility.OpenFilePanel(title, directory, null);
if (path.Length != 0)
return path;
return null;
}
internal static void Open(List<string> files)
{
try
{
foreach (string file in files)
OpenFile(file);
}
catch (Exception ex)
{
ExceptionsHandler.DisplayException(ex);
}
}
internal static void OpenInExplorer(string path)
{
EditorUtility.RevealInFinder(path);
}
static void OpenFile(string path)
{
if (path == null)
return;
string relativePath = GetRelativePath.ToApplication(path);
bool result = AssetDatabase.OpenAsset(
AssetDatabase.LoadMainAssetAtPath(relativePath));
if (result)
return;
OpenOperation.OpenFile(path);
}
}
}
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.History
{
internal enum HistoryListColumn
{
Changeset,
CreationDate,
CreatedBy,
Comment,
Branch,
}
[Serializable]
internal class HistoryListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static HistoryListHeaderState GetDefault()
{
return new HistoryListHeaderState(BuildColumns());
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.BranchColumn));
return result;
}
internal static string GetColumnName(HistoryListColumn column)
{
switch (column)
{
case HistoryListColumn.Changeset:
return PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetColumn);
case HistoryListColumn.CreationDate:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn);
case HistoryListColumn.CreatedBy:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn);
case HistoryListColumn.Comment:
return PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn);
case HistoryListColumn.Branch:
return PlasticLocalization.GetString(PlasticLocalization.Name.BranchColumn);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
if (mColumsAllowedToggleVisibility != null)
TreeHeaderColumns.SetVisibilities(columns, mColumsAllowedToggleVisibility);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 100,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.Changeset)),
minWidth = 50,
},
new Column()
{
width = 250,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.CreationDate)),
minWidth = 100
},
new Column()
{
width = 250,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.CreatedBy)),
minWidth = 100
},
new Column()
{
width = 400,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.Comment)),
minWidth = 100
},
new Column()
{
width = 200,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.Branch)),
minWidth = 100
},
};
}
HistoryListHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
if (mColumsAllowedToggleVisibility == null)
mColumsAllowedToggleVisibility = TreeHeaderColumns.GetVisibilities(columns);
}
[SerializeField]
string[] mHeaderTitles;
[SerializeField]
bool[] mColumsAllowedToggleVisibility;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.History;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Avatar;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal class HistoryListView : TreeView
{
internal HistoryListView(
string wkPath,
RepositorySpec repSpec,
HistoryListHeaderState headerState,
HistoryListViewMenu menu,
List<string> columnNames) :
base(new TreeViewState())
{
mWkPath = wkPath;
mRepSpec = repSpec;
mMenu = menu;
mColumnNames = columnNames;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = true;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
public override void OnGUI(Rect rect)
{
base.OnGUI(rect);
Event e = Event.current;
if (e.type != EventType.KeyDown)
return;
bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e);
if (isProcessed)
e.Use();
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(
TreeViewItem rootItem)
{
if (mRevisionsList == null)
{
ClearRows(rootItem, mRows);
return mRows;
}
RegenerateRows(
mListViewItemIds,
mRevisionsList,
rootItem,
mRows);
return mRows;
}
protected override void SearchChanged(string newSearch)
{
mCooldownFilterAction.Ping();
}
protected override void ContextClickedItem(int id)
{
mMenu.Popup();
Repaint();
}
protected override void RowGUI(RowGUIArgs args)
{
if (args.item is HistoryListViewItem)
{
HistoryListViewItem historyListViewItem = (HistoryListViewItem)args.item;
HistoryListViewItemGUI(
mWkPath,
mRepSpec,
rowHeight,
historyListViewItem,
args,
mLoadedRevisionId == historyListViewItem.Revision.Id,
Repaint);
return;
}
base.RowGUI(args);
}
internal void BuildModel(
HistoryRevisionList historyRevisionList,
long loadedRevisionId)
{
mListViewItemIds.Clear();
mRevisionsList = historyRevisionList;
mLoadedRevisionId = loadedRevisionId;
}
internal void Refilter()
{
if (mRevisionsList == null)
return;
Filter filter = new Filter(searchString);
mRevisionsList.Filter(filter, mColumnNames);
}
internal void Sort()
{
if (mRevisionsList == null)
return;
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mRevisionsList.Sort(
mColumnNames[sortedColumnIdx],
sortAscending);
}
internal long GetLoadedRevisionId()
{
return mLoadedRevisionId;
}
internal List<RepObjectInfo> GetSelectedRepObjectInfos()
{
List<RepObjectInfo> result = new List<RepObjectInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<RepObjectInfo, int> item
in mListViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
result.Add(item.Key);
}
return result;
}
internal List<HistoryRevision> GetSelectedHistoryRevisions()
{
return GetSelectedRepObjectInfos().OfType<HistoryRevision>().ToList();
}
internal void SelectRepObjectInfos(
List<RepObjectInfo> repObjectsToSelect)
{
List<int> idsToSelect = new List<int>();
foreach (RepObjectInfo repObjectInfo in repObjectsToSelect)
{
int repObjectInfoId = GetTreeIdForItem(repObjectInfo);
if (repObjectInfoId == -1)
continue;
idsToSelect.Add(repObjectInfoId);
}
TableViewOperations.SetSelectionAndScroll(this, idsToSelect);
}
int GetTreeIdForItem(RepObjectInfo currentRepObjectInfo)
{
foreach (KeyValuePair<RepObjectInfo, int> item in mListViewItemIds.GetInfoItems())
{
if (!currentRepObjectInfo.Equals(item.Key))
continue;
if (!currentRepObjectInfo.GUID.Equals(item.Key.GUID))
continue;
return item.Value;
}
return -1;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
ListViewItemIds<RepObjectInfo> listViewItemIds,
HistoryRevisionList revisions,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (revisions.GetCount() == 0)
return;
foreach (RepObjectInfo objectInfo in revisions.GetRevisions())
{
int objectId;
if (!listViewItemIds.TryGetInfoItemId(objectInfo, out objectId))
objectId = listViewItemIds.AddInfoItem(objectInfo);
HistoryListViewItem changesetListViewItem =
new HistoryListViewItem(objectId, objectInfo);
rootItem.AddChild(changesetListViewItem);
rows.Add(changesetListViewItem);
}
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void HistoryListViewItemGUI(
string wkPath,
RepositorySpec repSpec,
float rowHeight,
HistoryListViewItem item,
RowGUIArgs args,
bool isBoldText,
Action avatarLoadedAction)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
HistoryListColumn column =
(HistoryListColumn)args.GetColumn(visibleColumnIdx);
HistoryListViewItemCellGUI(
cellRect,
rowHeight,
wkPath,
repSpec,
item,
column,
avatarLoadedAction,
args.selected,
args.focused,
isBoldText);
}
}
static void HistoryListViewItemCellGUI(
Rect rect,
float rowHeight,
string wkPath,
RepositorySpec repSpec,
HistoryListViewItem item,
HistoryListColumn column,
Action avatarLoadedAction,
bool isSelected,
bool isFocused,
bool isBoldText)
{
string columnText = HistoryInfoView.GetColumnText(
wkPath, repSpec, item.Revision,
HistoryListHeaderState.GetColumnName(column));
if (column == HistoryListColumn.Changeset)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
0,
GetRevisionIcon(item.Revision),
null,
columnText,
isSelected,
isFocused,
isBoldText,
false);
return;
}
if (column == HistoryListColumn.CreatedBy)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
-1,
GetAvatar.ForEmail(columnText, avatarLoadedAction),
null,
columnText,
isSelected,
isFocused,
isBoldText,
false);
return;
}
if (column == HistoryListColumn.Branch)
{
DrawTreeViewItem.ForSecondaryLabel(
rect, columnText, isSelected, isFocused, isBoldText);
return;
}
DrawTreeViewItem.ForLabel(
rect, columnText, isSelected, isFocused, isBoldText);
}
static Texture GetRevisionIcon(RepObjectInfo revision)
{
if (revision is MoveRealizationInfo)
return Images.GetImage(Images.Name.IconMoved);
if (revision is RemovedRealizationInfo)
return Images.GetImage(Images.Name.IconDeleted);
return Images.GetFileIcon();
}
ListViewItemIds<RepObjectInfo> mListViewItemIds = new ListViewItemIds<RepObjectInfo>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
HistoryRevisionList mRevisionsList;
long mLoadedRevisionId;
readonly CooldownWindowDelayer mCooldownFilterAction;
readonly HistoryListViewMenu mMenu;
readonly List<string> mColumnNames;
readonly RepositorySpec mRepSpec;
readonly string mWkPath;
}
}

using UnityEditor.IMGUI.Controls;
using Codice.CM.Common;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal class HistoryListViewItem : TreeViewItem
{
internal RepObjectInfo Revision { get; private set; }
internal HistoryListViewItem(int id, RepObjectInfo revision)
: base(id, 1)
{
Revision = revision;
displayName = id.ToString();
}
}
}
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.History;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal class HistoryListViewMenu
{
internal interface IMenuOperations
{
long GetSelectedChangesetId();
}
internal HistoryListViewMenu(
IHistoryViewMenuOperations operations,
IMenuOperations menuOperations)
{
mOperations = operations;
mMenuOperations = menuOperations;
BuildComponents();
}
internal void Popup()
{
GenericMenu menu = new GenericMenu();
UpdateMenuItems(menu);
menu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
HistoryMenuOperations operationToExecute = GetMenuOperation(e);
if (operationToExecute == HistoryMenuOperations.None)
return false;
SelectedHistoryGroupInfo info =
mOperations.GetSelectedHistoryGroupInfo();
HistoryMenuOperations operations =
HistoryMenuUpdater.GetAvailableMenuOperations(info);
if (!operations.HasFlag(operationToExecute))
return false;
ProcessMenuOperation(operationToExecute, mOperations);
return true;
}
void OpenRevisionMenu_Click()
{
mOperations.OpenRevision();
}
void OpenRevisionWithMenu_Click()
{
mOperations.OpenRevisionWith();
}
void SaveRevisionasMenu_Click()
{
mOperations.SaveRevisionAs();
}
void DiffWithPreviousMenuItem_Click()
{
mOperations.DiffWithPrevious();
}
void DiffSelectedRevisionsMenu_Click()
{
mOperations.DiffSelectedRevisions();
}
void DiffChangesetMenu_Click()
{
mOperations.DiffChangeset();
}
void RevertToThisRevisionMenu_Click()
{
mOperations.RevertToThisRevision();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedHistoryGroupInfo info =
mOperations.GetSelectedHistoryGroupInfo();
HistoryMenuOperations operations =
HistoryMenuUpdater.GetAvailableMenuOperations(info);
if (operations == HistoryMenuOperations.None)
{
menu.AddDisabledItem(GetNoActionMenuItemContent(), false);
return;
}
if (operations.HasFlag(HistoryMenuOperations.Open))
menu.AddItem(mOpenRevisionMenuItemContent, false, OpenRevisionMenu_Click);
else
menu.AddDisabledItem(mOpenRevisionMenuItemContent, false);
if (operations.HasFlag(HistoryMenuOperations.OpenWith))
menu.AddItem(mOpenRevisionWithMenuItemContent, false, OpenRevisionWithMenu_Click);
else
menu.AddDisabledItem(mOpenRevisionWithMenuItemContent, false);
if (operations.HasFlag(HistoryMenuOperations.SaveAs))
menu.AddItem(mSaveRevisionAsMenuItemContent, false, SaveRevisionasMenu_Click);
else
menu.AddDisabledItem(mSaveRevisionAsMenuItemContent, false);
menu.AddSeparator(string.Empty);
if (operations.HasFlag(HistoryMenuOperations.DiffWithPrevious))
menu.AddItem(mDiffWithPreviousMenuItemContent, false, DiffWithPreviousMenuItem_Click);
if (operations.HasFlag(HistoryMenuOperations.DiffSelected))
menu.AddItem(mDiffSelectedRevisionsMenuItemContent, false, DiffSelectedRevisionsMenu_Click);
mDiffChangesetMenuItemContent.text =
PlasticLocalization.GetString(PlasticLocalization.Name.HistoryMenuItemDiffChangeset) +
string.Format(" {0}", GetSelectedChangesetName(mMenuOperations));
if (operations.HasFlag(HistoryMenuOperations.DiffChangeset))
menu.AddItem(mDiffChangesetMenuItemContent, false, DiffChangesetMenu_Click);
else
menu.AddDisabledItem(mDiffChangesetMenuItemContent, false);
menu.AddSeparator(string.Empty);
if (operations.HasFlag(HistoryMenuOperations.RevertTo))
menu.AddItem(mRevertToThisRevisionMenuItemContent, false, RevertToThisRevisionMenu_Click);
else
menu.AddDisabledItem(mRevertToThisRevisionMenuItemContent, false);
}
static HistoryMenuOperations GetMenuOperation(Event e)
{
if (Keyboard.IsControlOrCommandKeyPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.D))
return HistoryMenuOperations.DiffWithPrevious;
return HistoryMenuOperations.None;
}
static void ProcessMenuOperation(
HistoryMenuOperations operationToExecute,
IHistoryViewMenuOperations operations)
{
if (operationToExecute == HistoryMenuOperations.DiffWithPrevious)
{
operations.DiffWithPrevious();
return;
}
}
GUIContent GetNoActionMenuItemContent()
{
if (mNoActionMenuItemContent == null)
{
mNoActionMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.
Name.NoActionMenuItem));
}
return mNoActionMenuItemContent;
}
static string GetSelectedChangesetName(IMenuOperations menuOperations)
{
long selectedChangesetId = menuOperations.GetSelectedChangesetId();
if (selectedChangesetId == -1)
return string.Empty;
return selectedChangesetId.ToString();
}
void BuildComponents()
{
mOpenRevisionMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.HistoryMenuItemOpen));
mOpenRevisionWithMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.HistoryMenuItemOpenWith));
mSaveRevisionAsMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.SaveThisRevisionAs));
mDiffWithPreviousMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.HistoryMenuItemDiffWithPrevious),
GetPlasticShortcut.ForDiff()));
mDiffSelectedRevisionsMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.HistoryMenuItemDiffSelectedRevisions));
mDiffChangesetMenuItemContent = new GUIContent();
mRevertToThisRevisionMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.HistoryMenuItemRevertToThisRevision));
}
GUIContent mNoActionMenuItemContent;
GUIContent mOpenRevisionMenuItemContent;
GUIContent mOpenRevisionWithMenuItemContent;
GUIContent mSaveRevisionAsMenuItemContent;
GUIContent mDiffWithPreviousMenuItemContent;
GUIContent mDiffSelectedRevisionsMenuItemContent;
GUIContent mDiffChangesetMenuItemContent;
GUIContent mRevertToThisRevisionMenuItemContent;
readonly IHistoryViewMenuOperations mOperations;
readonly IMenuOperations mMenuOperations;
}
}
using System.Collections.Generic;
using Codice.CM.Common;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal static class HistorySelection
{
internal static void SelectRevisions(
HistoryListView listView,
List<RepObjectInfo> revisionsToSelect)
{
if (revisionsToSelect == null || revisionsToSelect.Count == 0)
{
TableViewOperations.SelectFirstRow(listView);
return;
}
listView.SelectRepObjectInfos(revisionsToSelect);
if (listView.HasSelection())
return;
TableViewOperations.SelectFirstRow(listView);
}
internal static List<RepObjectInfo> GetSelectedRepObjectInfos(
HistoryListView listView)
{
return listView.GetSelectedRepObjectInfos();
}
internal static List<HistoryRevision> GetSelectedHistoryRevisions(
HistoryListView listView)
{
return listView.GetSelectedHistoryRevisions();
}
internal static HistoryRevision GetSelectedHistoryRevision(
HistoryListView listView)
{
List<HistoryRevision> revisions =
listView.GetSelectedHistoryRevisions();
if (revisions.Count == 0)
return null;
return revisions[0];
}
}
}
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.CM.Common;
using Codice.Client.Common;
using GluonGui;
using PlasticGui;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.Diff;
using PlasticGui.WorkspaceWindow.History;
using GluonRevertOperation = GluonGui.WorkspaceWindow.Views.Details.History.RevertOperation;
using HistoryDescriptor = GluonGui.WorkspaceWindow.Views.Details.History.HistoryDescriptor;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.UI.Tree;
using Unity.PlasticSCM.Editor.Views.Changesets;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal class HistoryTab :
IRefreshableView,
HistoryViewLogic.IHistoryView,
HistoryListViewMenu.IMenuOperations,
IHistoryViewMenuOperations
{
internal HistoryTab(
WorkspaceInfo wkInfo,
IWorkspaceWindow workspaceWindow,
RepositorySpec repSpec,
NewIncomingChangesUpdater newIncomingChangesUpdater,
ViewHost viewHost,
EditorWindow parentWindow,
bool isGluonMode)
{
mWkInfo = wkInfo;
mWorkspaceWindow = workspaceWindow;
mRepSpec = repSpec;
mNewIncomingChangesUpdater = newIncomingChangesUpdater;
mViewHost = viewHost;
mParentWindow = parentWindow;
mIsGluonMode = isGluonMode;
mGuiMessage = new UnityPlasticGuiMessage(parentWindow);
BuildComponents(wkInfo, repSpec);
mProgressControls = new ProgressControlsForViews();
mHistoryViewLogic = new HistoryViewLogic(
wkInfo, this, mProgressControls);
}
internal void RefreshForItem(
long itemId,
string path,
bool isDirectory)
{
mItemId = itemId;
mPath = path;
mIsDirectory = isDirectory;
((IRefreshableView)this).Refresh();
}
internal void Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
DoActionsToolbar(
this,
mProgressControls,
mSearchField,
mHistoryListView,
GetViewTitle(mPath));
DoHistoryArea(
mHistoryListView,
mProgressControls.IsOperationRunning());
}
internal void OnDisable()
{
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
TreeHeaderSettings.Save(
mHistoryListView.multiColumnHeader.state,
UnityConstants.HISTORY_TABLE_SETTINGS_NAME);
}
void IRefreshableView.Refresh()
{
mHistoryViewLogic.RefreshForItem(mRepSpec, mItemId);
}
List<RepObjectInfo> HistoryViewLogic.IHistoryView.GetSelectedRevisions()
{
return HistorySelection.GetSelectedRepObjectInfos(mHistoryListView);
}
void HistoryViewLogic.IHistoryView.SelectRevisions(
List<RepObjectInfo> revisionsToSelect)
{
HistorySelection.SelectRevisions(
mHistoryListView, revisionsToSelect);
}
void HistoryViewLogic.IHistoryView.UpdateData(
HistoryRevisionList list, long loadedRevisionId)
{
mHistoryListView.BuildModel(list, loadedRevisionId);
mHistoryListView.Refilter();
mHistoryListView.Sort();
mHistoryListView.Reload();
}
long HistoryListViewMenu.IMenuOperations.GetSelectedChangesetId()
{
HistoryRevision revision = HistorySelection.
GetSelectedHistoryRevision(mHistoryListView);
if (revision == null)
return -1;
return revision.ChangeSet;
}
SelectedHistoryGroupInfo IHistoryViewMenuOperations.GetSelectedHistoryGroupInfo()
{
return SelectedHistoryGroupInfo.BuildFromSelection(
HistorySelection.GetSelectedRepObjectInfos(mHistoryListView),
HistorySelection.GetSelectedHistoryRevisions(mHistoryListView),
mHistoryListView.GetLoadedRevisionId(),
mIsDirectory);
}
void IHistoryViewMenuOperations.OpenRevision()
{
OpenRevisionOperation.Open(
mRepSpec,
Path.GetFileName(mPath),
HistorySelection.GetSelectedHistoryRevisions(
mHistoryListView));
}
void IHistoryViewMenuOperations.OpenRevisionWith()
{
List<HistoryRevision> revisions = HistorySelection.
GetSelectedHistoryRevisions(mHistoryListView);
OpenRevisionOperation.OpenWith(
mRepSpec,
FileSystemOperation.GetExePath(),
Path.GetFileName(mPath),
revisions);
}
void IHistoryViewMenuOperations.SaveRevisionAs()
{
HistoryRevision revision = HistorySelection.
GetSelectedHistoryRevision(mHistoryListView);
string defaultFileName = DefaultRevisionName.Get(
Path.GetFileName(mPath), revision.ChangeSet);
string destinationPath = SaveAction.GetDestinationPath(
mWkInfo.ClientPath, mPath, defaultFileName);
if (string.IsNullOrEmpty(destinationPath))
return;
SaveRevisionOperation.SaveRevision(
mRepSpec,
destinationPath,
revision,
mProgressControls);
}
void IHistoryViewMenuOperations.DiffWithPrevious()
{
HistoryRevision revision = HistorySelection.
GetSelectedHistoryRevision(mHistoryListView);
DiffOperation.DiffWithPrevious(
mWkInfo,
mRepSpec,
Path.GetFileName(mPath),
string.Empty,
revision.Id,
mItemId,
revision.ChangeSet,
mProgressControls,
null,
null);
}
void IHistoryViewMenuOperations.DiffSelectedRevisions()
{
List<HistoryRevision> revisions = HistorySelection.
GetSelectedHistoryRevisions(mHistoryListView);
bool areReversed = revisions[0].Id > revisions[1].Id;
DiffOperation.DiffRevisions(
mWkInfo,
mRepSpec,
Path.GetFileName(mPath),
string.Empty,
mItemId,
revisions[(areReversed) ? 1 : 0],
revisions[(areReversed) ? 0 : 1],
mProgressControls,
null,
null);
}
void IHistoryViewMenuOperations.DiffChangeset()
{
HistoryRevision revision = HistorySelection.
GetSelectedHistoryRevision(mHistoryListView);
LaunchDiffOperations.DiffChangeset(
mRepSpec, revision.ChangeSet, mIsGluonMode);
}
void IHistoryViewMenuOperations.RevertToThisRevision()
{
HistoryRevision revision = HistorySelection.
GetSelectedHistoryRevision(mHistoryListView);
string fullPath = GetFullPath(mWkInfo.ClientPath, mPath);
if (mIsGluonMode)
{
HistoryDescriptor historyDescriptor = new HistoryDescriptor(
mRepSpec, fullPath, mItemId, revision.Id, mIsDirectory);
GluonRevertOperation.RevertToThisRevision(
mWkInfo,
mViewHost,
mProgressControls,
historyDescriptor,
revision,
mGuiMessage,
RefreshAsset.UnityAssetDatabase);
return;
}
RevertOperation.RevertToThisRevision(
mWkInfo,
mProgressControls,
mWorkspaceWindow,
mRepSpec,
revision,
fullPath,
mGuiMessage,
mNewIncomingChangesUpdater,
RefreshAsset.UnityAssetDatabase);
}
void SearchField_OnDownOrUpArrowKeyPressed()
{
mHistoryListView.SetFocusAndEnsureSelectedItem();
}
static string GetFullPath(string wkPath, string path)
{
if (PathHelper.IsContainedOn(path, wkPath))
return path;
return WorkspacePath.GetWorkspacePathFromCmPath(
wkPath, path, Path.DirectorySeparatorChar);
}
static void DoActionsToolbar(
IRefreshableView refreshableView,
ProgressControlsForViews progressControls,
SearchField searchField,
HistoryListView listView,
string viewTitle)
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.Label(
viewTitle,
UnityStyles.HistoryTab.HeaderLabel);
if (progressControls.IsOperationRunning())
{
DrawProgressForViews.ForIndeterminateProgress(
progressControls.ProgressData);
}
GUILayout.FlexibleSpace();
DrawSearchField.For(
searchField,
listView,
UnityConstants.SEARCH_FIELD_WIDTH);
DoRefreshButton(
refreshableView,
progressControls.IsOperationRunning());
EditorGUILayout.EndHorizontal();
}
static void DoRefreshButton(
IRefreshableView refreshableView,
bool isOperationRunning)
{
EditorGUI.BeginDisabledGroup(isOperationRunning);
if (GUILayout.Button(new GUIContent(
Images.GetRefreshIcon()), EditorStyles.toolbarButton))
refreshableView.Refresh();
EditorGUI.EndDisabledGroup();
}
static void DoHistoryArea(
HistoryListView historyListView,
bool isOperationRunning)
{
GUI.enabled = !isOperationRunning;
Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
historyListView.OnGUI(rect);
GUI.enabled = true;
}
static string GetViewTitle(string path)
{
path = PathHelper.RemoveLastSlash(
path, Path.DirectorySeparatorChar);
return PlasticLocalization.GetString(
PlasticLocalization.Name.HistoryViewTitle,
Path.GetFileName(path));
}
void BuildComponents(
WorkspaceInfo wkInfo,
RepositorySpec repSpec)
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
HistoryListHeaderState headerState =
HistoryListHeaderState.GetDefault();
TreeHeaderSettings.Load(headerState,
UnityConstants.HISTORY_TABLE_SETTINGS_NAME,
(int)HistoryListColumn.CreationDate,
false);
mHistoryListView = new HistoryListView(
wkInfo.ClientPath,
repSpec,
headerState,
new HistoryListViewMenu(this, this),
HistoryListHeaderState.GetColumnNames());
mHistoryListView.Reload();
}
SearchField mSearchField;
HistoryListView mHistoryListView;
long mItemId;
string mPath;
bool mIsDirectory;
readonly WorkspaceInfo mWkInfo;
readonly HistoryViewLogic mHistoryViewLogic;
readonly ProgressControlsForViews mProgressControls;
readonly IWorkspaceWindow mWorkspaceWindow;
readonly RepositorySpec mRepSpec;
readonly bool mIsGluonMode;
readonly EditorWindow mParentWindow;
readonly ViewHost mViewHost;
readonly GuiMessage.IGuiMessage mGuiMessage;
readonly NewIncomingChangesUpdater mNewIncomingChangesUpdater;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment