Created unity project
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 156e16594aa6bd54cb77aa3f8eae5c82
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fdd86a000d1ef04094416eefed53087
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ac250bc549a212428286f328779be0e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,249 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 281456381b1a4c742b0efbe305328c7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,519 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
using Codice.Client.Commands;
|
||||
using Codice.Client.Common;
|
||||
using Codice.Client.Common.EventTracking;
|
||||
using Codice.Client.Common.Threading;
|
||||
using Codice.CM.Common;
|
||||
using Codice.CM.Common.Mount;
|
||||
using PlasticGui;
|
||||
using PlasticGui.WorkspaceWindow;
|
||||
using PlasticGui.WorkspaceWindow.BrowseRepository;
|
||||
using PlasticGui.WorkspaceWindow.Diff;
|
||||
using Unity.PlasticSCM.Editor.AssetUtils;
|
||||
using Unity.PlasticSCM.Editor.UI;
|
||||
using Unity.PlasticSCM.Editor.UI.Progress;
|
||||
using Unity.PlasticSCM.Editor.Tool;
|
||||
using Unity.PlasticSCM.Editor.Views.Diff.Dialogs;
|
||||
using Unity.PlasticSCM.Editor.Views.History;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.Diff
|
||||
{
|
||||
internal class DiffPanel :
|
||||
IDiffTreeViewMenuOperations,
|
||||
DiffTreeViewMenu.IMetaMenuOperations,
|
||||
UndeleteClientDiffsOperation.IGetRestorePathDialog
|
||||
{
|
||||
internal DiffPanel(
|
||||
WorkspaceInfo wkInfo,
|
||||
IWorkspaceWindow workspaceWindow,
|
||||
IRefreshView refreshView,
|
||||
IViewSwitcher viewSwitcher,
|
||||
IHistoryViewLauncher historyViewLauncher,
|
||||
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
|
||||
EditorWindow parentWindow,
|
||||
bool isGluonMode)
|
||||
{
|
||||
mWkInfo = wkInfo;
|
||||
mWorkspaceWindow = workspaceWindow;
|
||||
mRefreshView = refreshView;
|
||||
mViewSwitcher = viewSwitcher;
|
||||
mHistoryViewLauncher = historyViewLauncher;
|
||||
mShowDownloadPlasticExeWindow = showDownloadPlasticExeWindow;
|
||||
mParentWindow = parentWindow;
|
||||
mGuiMessage = new UnityPlasticGuiMessage();
|
||||
mIsGluonMode = isGluonMode;
|
||||
|
||||
BuildComponents();
|
||||
|
||||
mProgressControls = new ProgressControlsForViews();
|
||||
}
|
||||
|
||||
internal void ClearInfo()
|
||||
{
|
||||
ClearData();
|
||||
|
||||
mParentWindow.Repaint();
|
||||
}
|
||||
|
||||
internal void UpdateInfo(
|
||||
MountPointWithPath mountWithPath,
|
||||
ChangesetInfo csetInfo)
|
||||
{
|
||||
FillData(mountWithPath, csetInfo);
|
||||
|
||||
mParentWindow.Repaint();
|
||||
}
|
||||
|
||||
internal void OnEnable()
|
||||
{
|
||||
mSearchField.downOrUpArrowKeyPressed +=
|
||||
SearchField_OnDownOrUpArrowKeyPressed;
|
||||
}
|
||||
|
||||
internal void OnDisable()
|
||||
{
|
||||
mSearchField.downOrUpArrowKeyPressed -=
|
||||
SearchField_OnDownOrUpArrowKeyPressed;
|
||||
}
|
||||
|
||||
internal void Update()
|
||||
{
|
||||
mProgressControls.UpdateProgress(mParentWindow);
|
||||
}
|
||||
|
||||
internal void OnGUI()
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
DoActionsToolbar(
|
||||
mDiffs,
|
||||
mDiffsBranchResolver,
|
||||
mProgressControls,
|
||||
mIsSkipMergeTrackingButtonVisible,
|
||||
mIsSkipMergeTrackingButtonChecked,
|
||||
mSearchField,
|
||||
mDiffTreeView);
|
||||
|
||||
DoDiffTreeViewArea(
|
||||
mDiffTreeView,
|
||||
mProgressControls.IsOperationRunning());
|
||||
|
||||
if (mProgressControls.HasNotification())
|
||||
{
|
||||
DrawProgressForViews.ForNotificationArea(
|
||||
mProgressControls.ProgressData);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
void IDiffTreeViewMenuOperations.SaveRevisionAs()
|
||||
{
|
||||
TrackFeatureUseEvent.For(
|
||||
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
|
||||
TrackFeatureUseEvent.Features.SaveRevisionFromDiff);
|
||||
|
||||
ClientDiffInfo clientDiffInfo =
|
||||
DiffSelection.GetSelectedDiff(mDiffTreeView);
|
||||
RepositorySpec repSpec = clientDiffInfo.DiffWithMount.Mount.RepSpec;
|
||||
RevisionInfo revision = clientDiffInfo.DiffWithMount.Difference.RevInfo;
|
||||
|
||||
string defaultFileName = DefaultRevisionName.Get(
|
||||
Path.GetFileName(clientDiffInfo.DiffWithMount.Difference.Path), revision.Changeset);
|
||||
string destinationPath = SaveAction.GetDestinationPath(
|
||||
mWkInfo.ClientPath,
|
||||
clientDiffInfo.DiffWithMount.Difference.Path,
|
||||
defaultFileName);
|
||||
|
||||
if (string.IsNullOrEmpty(destinationPath))
|
||||
return;
|
||||
|
||||
SaveRevisionOperation.SaveRevision(
|
||||
repSpec,
|
||||
destinationPath,
|
||||
revision,
|
||||
mProgressControls);
|
||||
}
|
||||
|
||||
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,
|
||||
PlasticExeLauncher.BuildForDiffRevision(mWkInfo, mIsGluonMode, mShowDownloadPlasticExeWindow),
|
||||
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),
|
||||
mRefreshView,
|
||||
mProgressControls,
|
||||
this,
|
||||
mGuiMessage,
|
||||
AfterRevertOrUndeleteOperation);
|
||||
}
|
||||
|
||||
void IDiffTreeViewMenuOperations.UndeleteToSpecifiedPaths()
|
||||
{
|
||||
UndeleteClientDiffsOperation.UndeleteToSpecifiedPaths(
|
||||
mWkInfo,
|
||||
DiffSelection.GetSelectedDiffs(mDiffTreeView),
|
||||
mRefreshView,
|
||||
mProgressControls,
|
||||
this,
|
||||
mGuiMessage,
|
||||
AfterRevertOrUndeleteOperation);
|
||||
}
|
||||
|
||||
void IDiffTreeViewMenuOperations.Annotate()
|
||||
{
|
||||
}
|
||||
|
||||
void IDiffTreeViewMenuOperations.CopyFilePath(bool relativePath)
|
||||
{
|
||||
EditorGUIUtility.systemCopyBuffer = GetFilePathList.FromClientDiffInfos(
|
||||
DiffSelection.GetSelectedDiffsWithoutMeta(mDiffTreeView),
|
||||
relativePath,
|
||||
mWkInfo.ClientPath);
|
||||
}
|
||||
|
||||
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,
|
||||
PlasticExeLauncher.BuildForDiffRevision(mWkInfo, mIsGluonMode, mShowDownloadPlasticExeWindow),
|
||||
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 = PlasticGui.Plastic.API.GetChangesetDifferences(
|
||||
mountWithPath, csetInfo);
|
||||
|
||||
mDiffsBranchResolver = BuildBranchResolver.ForDiffs(mDiffs);
|
||||
},
|
||||
/*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(
|
||||
mWkInfo,
|
||||
mDiffs,
|
||||
mDiffsBranchResolver,
|
||||
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(
|
||||
WorkspaceInfo wkInfo,
|
||||
List<ClientDiff> diffs,
|
||||
BranchResolver brResolver,
|
||||
bool skipMergeTracking,
|
||||
DiffTreeView diffTreeView)
|
||||
{
|
||||
diffTreeView.BuildModel(
|
||||
wkInfo, diffs, brResolver, skipMergeTracking);
|
||||
|
||||
diffTreeView.Refilter();
|
||||
|
||||
diffTreeView.Sort();
|
||||
|
||||
diffTreeView.Reload();
|
||||
}
|
||||
|
||||
void DoActionsToolbar(
|
||||
List<ClientDiff> diffs,
|
||||
BranchResolver brResolver,
|
||||
ProgressControlsForViews progressControls,
|
||||
bool isSkipMergeTrackingButtonVisible,
|
||||
bool isSkipMergeTrackingButtonChecked,
|
||||
SearchField searchField,
|
||||
DiffTreeView diffTreeView)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
|
||||
if (progressControls.IsOperationRunning())
|
||||
{
|
||||
DrawProgressForViews.ForIndeterminateProgress(
|
||||
progressControls.ProgressData);
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (isSkipMergeTrackingButtonVisible)
|
||||
{
|
||||
DoSkipMergeTrackingButton(
|
||||
diffs, brResolver,
|
||||
isSkipMergeTrackingButtonChecked,
|
||||
diffTreeView);
|
||||
}
|
||||
|
||||
DrawSearchField.For(
|
||||
searchField,
|
||||
diffTreeView,
|
||||
UnityConstants.SEARCH_FIELD_WIDTH);
|
||||
VerifyIfSearchFieldIsRecentlyFocused(searchField);
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void VerifyIfSearchFieldIsRecentlyFocused(SearchField searchField)
|
||||
{
|
||||
if (searchField.HasFocus() != mIsSearchFieldFocused)
|
||||
{
|
||||
mIsSearchFieldFocused = !mIsSearchFieldFocused;
|
||||
|
||||
if (mIsSearchFieldFocused)
|
||||
{
|
||||
TrackFeatureUseEvent.For(
|
||||
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
|
||||
TrackFeatureUseEvent.Features.ChangesetViewDiffSearchBox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoSkipMergeTrackingButton(
|
||||
List<ClientDiff> diffs,
|
||||
BranchResolver brResolver,
|
||||
bool isSkipMergeTrackingButtonChecked,
|
||||
DiffTreeView diffTreeView)
|
||||
{
|
||||
bool wasChecked = isSkipMergeTrackingButtonChecked;
|
||||
|
||||
GUIContent buttonContent = new GUIContent(
|
||||
PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.SkipDiffMergeTracking));
|
||||
|
||||
GUIStyle buttonStyle = new GUIStyle(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;
|
||||
|
||||
// if user just checked the skip merge tracking button
|
||||
if (isChecked)
|
||||
{
|
||||
TrackFeatureUseEvent.For(
|
||||
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
|
||||
TrackFeatureUseEvent.Features.ChangesetViewSkipMergeTrackingButton);
|
||||
}
|
||||
|
||||
UpdateDiffTreeView(mWkInfo, diffs, brResolver, 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;
|
||||
volatile BranchResolver mDiffsBranchResolver;
|
||||
|
||||
bool mIsSkipMergeTrackingButtonVisible;
|
||||
bool mIsSkipMergeTrackingButtonChecked;
|
||||
|
||||
SearchField mSearchField;
|
||||
bool mIsSearchFieldFocused = false;
|
||||
|
||||
DiffTreeView mDiffTreeView;
|
||||
|
||||
ChangesetInfo mSelectedChangesetInfo;
|
||||
MountPointWithPath mSelectedMountWithPath;
|
||||
|
||||
readonly ProgressControlsForViews mProgressControls;
|
||||
readonly GuiMessage.IGuiMessage mGuiMessage;
|
||||
readonly EditorWindow mParentWindow;
|
||||
readonly IRefreshView mRefreshView;
|
||||
readonly IWorkspaceWindow mWorkspaceWindow;
|
||||
readonly IHistoryViewLauncher mHistoryViewLauncher;
|
||||
readonly IViewSwitcher mViewSwitcher;
|
||||
readonly LaunchTool.IShowDownloadPlasticExeWindow mShowDownloadPlasticExeWindow;
|
||||
readonly WorkspaceInfo mWkInfo;
|
||||
readonly bool mIsGluonMode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ee79162e06c6984a97600b7c0680611
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ef5fb54cd29b40468eaf5a14e9845ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,565 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
using Codice.Client.Commands;
|
||||
using Codice.Client.Common;
|
||||
using Codice.CM.Common;
|
||||
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 = false;
|
||||
|
||||
mCooldownFilterAction = new CooldownWindowDelayer(
|
||||
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
|
||||
|
||||
EnableHorizontalScrollbar();
|
||||
}
|
||||
|
||||
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 BeforeRowsGUI()
|
||||
{
|
||||
int firstRowVisible;
|
||||
int lastRowVisible;
|
||||
GetFirstAndLastVisibleRows(out firstRowVisible, out lastRowVisible);
|
||||
|
||||
GUI.DrawTexture(new Rect(0,
|
||||
firstRowVisible * rowHeight,
|
||||
GetRowRect(0).width + 500,
|
||||
(lastRowVisible * rowHeight) + 1500),
|
||||
Images.GetTreeviewBackgroundTexture());
|
||||
|
||||
DrawTreeViewItem.InitializeStyles();
|
||||
mLargestRowWidth = 0;
|
||||
base.BeforeRowsGUI();
|
||||
}
|
||||
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
float itemWidth;
|
||||
TreeViewItemGUI(
|
||||
args.item, args.rowRect, rowHeight, mDiffTree, args.selected, args.focused, out itemWidth);
|
||||
|
||||
float rowWidth = baseIndent + args.item.depth * depthIndentWidth +
|
||||
itemWidth + UnityConstants.TREEVIEW_ROW_WIDTH_OFFSET;
|
||||
|
||||
if (rowWidth > mLargestRowWidth)
|
||||
mLargestRowWidth = rowWidth;
|
||||
}
|
||||
|
||||
protected override void AfterRowsGUI()
|
||||
{
|
||||
if (mHorizontalColumn != null)
|
||||
mHorizontalColumn.width = mLargestRowWidth;
|
||||
|
||||
base.AfterRowsGUI();
|
||||
}
|
||||
|
||||
internal void ClearModel()
|
||||
{
|
||||
mTreeViewItemIds.Clear();
|
||||
|
||||
mDiffTree = new UnityDiffTree();
|
||||
}
|
||||
|
||||
internal void BuildModel(
|
||||
WorkspaceInfo wkInfo,
|
||||
List<ClientDiff> diffs,
|
||||
BranchResolver brResolver,
|
||||
bool skipMergeTracking)
|
||||
{
|
||||
mTreeViewItemIds.Clear();
|
||||
|
||||
mDiffTree.BuildCategories(wkInfo, diffs, brResolver, 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);
|
||||
}
|
||||
|
||||
void EnableHorizontalScrollbar()
|
||||
{
|
||||
mHorizontalColumn = new MultiColumnHeaderState.Column();
|
||||
mHorizontalColumn.autoResize = false;
|
||||
|
||||
MultiColumnHeaderState.Column[] cols = { mHorizontalColumn };
|
||||
MultiColumnHeaderState headerState = new MultiColumnHeaderState(cols);
|
||||
|
||||
multiColumnHeader = new MultiColumnHeader(headerState);
|
||||
multiColumnHeader.height = 0f;
|
||||
}
|
||||
|
||||
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 CategoryGroup &&
|
||||
((CategoryGroup)category).CategoryType == CategoryGroup.Type.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,
|
||||
(CategoryGroup)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 TreeViewItemGUI(
|
||||
TreeViewItem item,
|
||||
Rect rowRect,
|
||||
float rowHeight,
|
||||
UnityDiffTree diffTree,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
out float itemWidth)
|
||||
{
|
||||
if (item is MergeCategoryTreeViewItem)
|
||||
{
|
||||
MergeCategoryTreeViewItemGUI(
|
||||
rowRect,
|
||||
(MergeCategoryTreeViewItem)item,
|
||||
isSelected,
|
||||
isFocused,
|
||||
out itemWidth);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item is ChangeCategoryTreeViewItem)
|
||||
{
|
||||
ChangeCategoryTreeViewItemGUI(
|
||||
rowRect,
|
||||
(ChangeCategoryTreeViewItem)item,
|
||||
isSelected,
|
||||
isFocused,
|
||||
out itemWidth);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item is ClientDiffTreeViewItem)
|
||||
{
|
||||
ClientDiffTreeViewItemGUI(
|
||||
rowRect,
|
||||
rowHeight,
|
||||
diffTree,
|
||||
(ClientDiffTreeViewItem)item,
|
||||
isSelected,
|
||||
isFocused,
|
||||
out itemWidth);
|
||||
return;
|
||||
}
|
||||
|
||||
itemWidth = 0;
|
||||
}
|
||||
|
||||
static void MergeCategoryTreeViewItemGUI(
|
||||
Rect rowRect,
|
||||
MergeCategoryTreeViewItem item,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
out float itemWidth)
|
||||
{
|
||||
string label = item.Category.CategoryName;
|
||||
string infoLabel = PlasticLocalization.Name.ItemsCount.GetString(
|
||||
item.Category.GetChildrenCount());
|
||||
|
||||
itemWidth = CalculateLabelWidth(label);
|
||||
|
||||
DrawTreeViewItem.ForCategoryItem(
|
||||
rowRect,
|
||||
item.depth,
|
||||
label,
|
||||
infoLabel,
|
||||
isSelected,
|
||||
isFocused);
|
||||
}
|
||||
|
||||
static void ChangeCategoryTreeViewItemGUI(
|
||||
Rect rowRect,
|
||||
ChangeCategoryTreeViewItem item,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
out float itemWidth)
|
||||
{
|
||||
string label = item.Category.CategoryName;
|
||||
string infoLabel = PlasticLocalization.Name.ItemsCount.GetString(
|
||||
item.Category.GetChildrenCount());
|
||||
|
||||
itemWidth = CalculateLabelWidth(label);
|
||||
|
||||
DrawTreeViewItem.ForCategoryItem(
|
||||
rowRect,
|
||||
item.depth,
|
||||
label,
|
||||
infoLabel,
|
||||
isSelected,
|
||||
isFocused);
|
||||
}
|
||||
|
||||
static void ClientDiffTreeViewItemGUI(
|
||||
Rect rowRect,
|
||||
float rowHeight,
|
||||
UnityDiffTree diffTree,
|
||||
ClientDiffTreeViewItem item,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
out float itemWidth)
|
||||
{
|
||||
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);
|
||||
|
||||
itemWidth = CalculateItemWidth(label, icon, rowHeight);
|
||||
|
||||
DrawTreeViewItem.ForItemCell(
|
||||
rowRect,
|
||||
rowHeight,
|
||||
item.depth,
|
||||
icon,
|
||||
null,
|
||||
label,
|
||||
isSelected,
|
||||
isFocused,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
static float CalculateItemWidth(
|
||||
string label,
|
||||
Texture icon,
|
||||
float rowHeight)
|
||||
{
|
||||
float labelWidth = CalculateLabelWidth(label);
|
||||
float iconWidth = rowHeight * ((float)icon.width / icon.height);
|
||||
|
||||
return labelWidth + iconWidth;
|
||||
}
|
||||
|
||||
static float CalculateLabelWidth(string label)
|
||||
{
|
||||
GUIContent content = new GUIContent(label);
|
||||
Vector2 contentSize = DefaultStyles.label.CalcSize(content);
|
||||
|
||||
return contentSize.x;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
MultiColumnHeaderState.Column mHorizontalColumn;
|
||||
float mLargestRowWidth;
|
||||
|
||||
readonly CooldownWindowDelayer mCooldownFilterAction;
|
||||
|
||||
static readonly List<string> ColumnsNames = new List<string> {
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn)};
|
||||
readonly DiffTreeViewMenu mMenu;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba4e6e12f66973142a87299287cb34dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,323 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using Codice.Client.Common.EventTracking;
|
||||
using Codice.CM.Common;
|
||||
using PlasticGui;
|
||||
using PlasticGui.WorkspaceWindow.Diff;
|
||||
using Unity.PlasticSCM.Editor.UI;
|
||||
using Unity.PlasticSCM.Editor.Tool;
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SaveRevisionAsMenuItem_Click()
|
||||
{
|
||||
mOperations.SaveRevisionAs();
|
||||
}
|
||||
|
||||
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 CopyFilePathMenuItem_Click()
|
||||
{
|
||||
mOperations.CopyFilePath(relativePath: false);
|
||||
}
|
||||
|
||||
void CopyRelativeFilePathMenuItem_Click()
|
||||
{
|
||||
mOperations.CopyFilePath(relativePath: true);
|
||||
}
|
||||
|
||||
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.SaveAs))
|
||||
menu.AddItem(mSaveRevisionAsMenuItemContent, false, SaveRevisionAsMenuItem_Click);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (operations.HasFlag(DiffTreeViewMenuOperations.CopyFilePath))
|
||||
{
|
||||
menu.AddSeparator(string.Empty);
|
||||
|
||||
menu.AddItem(
|
||||
mCopyFilePathMenuItemContent, false, CopyFilePathMenuItem_Click);
|
||||
menu.AddItem(
|
||||
mCopyRelativeFilePathMenuItemContent, false, CopyRelativeFilePathMenuItem_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);
|
||||
}
|
||||
|
||||
void ProcessMenuOperation(DiffTreeViewMenuOperations operationToExecute)
|
||||
{
|
||||
if (operationToExecute == DiffTreeViewMenuOperations.SaveAs)
|
||||
{
|
||||
SaveRevisionAsMenuItem_Click();
|
||||
return;
|
||||
}
|
||||
|
||||
if (operationToExecute == DiffTreeViewMenuOperations.Diff)
|
||||
{
|
||||
DiffMenuItem_Click();
|
||||
return;
|
||||
}
|
||||
|
||||
if (operationToExecute == DiffTreeViewMenuOperations.History)
|
||||
{
|
||||
HistoryMenuItem_Click();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
mSaveRevisionAsMenuItemContent = new GUIContent(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.DiffMenuItemSaveRevisionAs));
|
||||
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();
|
||||
mCopyFilePathMenuItemContent = new GUIContent(PlasticLocalization.Name.CopyFilePathMenuItem.GetString());
|
||||
mCopyRelativeFilePathMenuItemContent =
|
||||
new GUIContent(PlasticLocalization.Name.CopyRelativeFilePathMenuItem.GetString());
|
||||
}
|
||||
|
||||
GUIContent mNoActionMenuItemContent;
|
||||
|
||||
GUIContent mSaveRevisionAsMenuItemContent;
|
||||
GUIContent mDiffMenuItemContent;
|
||||
GUIContent mDiffMetaMenuItemContent;
|
||||
GUIContent mViewHistoryMenuItemContent;
|
||||
GUIContent mViewHistoryMetaMenuItemContent;
|
||||
GUIContent mRevertMenuItemContent;
|
||||
GUIContent mUndeleteMenuItemContent;
|
||||
GUIContent mUndeleteToSpecifiedPathMenuItemContent;
|
||||
GUIContent mCopyFilePathMenuItemContent;
|
||||
GUIContent mCopyRelativeFilePathMenuItemContent;
|
||||
|
||||
readonly IDiffTreeViewMenuOperations mOperations;
|
||||
readonly IMetaMenuOperations mMetaMenuOperations;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c9c0041347ae4e4cb794a3da850fa79
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ab43506dddfc244ab5b44585140c5a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
|
||||
using PlasticGui.WorkspaceWindow.Diff;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.Diff
|
||||
{
|
||||
internal class MergeCategoryTreeViewItem : TreeViewItem
|
||||
{
|
||||
internal CategoryGroup Category { get; private set; }
|
||||
|
||||
internal MergeCategoryTreeViewItem(
|
||||
int id, int depth, CategoryGroup categoryGroup)
|
||||
: base(id, depth, categoryGroup.GetHeaderText())
|
||||
{
|
||||
Category = categoryGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 923dacaaac477a941a4a5c7c1657a250
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,233 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Codice.Client.Commands;
|
||||
using Codice.Client.Common;
|
||||
using Codice.CM.Common;
|
||||
using Codice.Utils;
|
||||
using PlasticGui;
|
||||
using PlasticGui.Diff;
|
||||
using PlasticGui.WorkspaceWindow.Diff;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.Diff
|
||||
{
|
||||
internal class UnityDiffTree
|
||||
{
|
||||
internal UnityDiffTree()
|
||||
{
|
||||
mInnerTree = new DiffTree();
|
||||
mMetaCache = new MetaCache();
|
||||
}
|
||||
|
||||
internal void BuildCategories(
|
||||
WorkspaceInfo wkInfo,
|
||||
List<ClientDiff> diffs,
|
||||
BranchResolver brResolver,
|
||||
bool skipMergeTracking)
|
||||
{
|
||||
mInnerTree.BuildCategories(
|
||||
RevisionInfoCodeReviewAdapter.CalculateCodeReviewEntries(
|
||||
wkInfo,
|
||||
diffs,
|
||||
brResolver,
|
||||
skipMergeTracking),
|
||||
brResolver);
|
||||
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.GetCategoryGroup(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(
|
||||
GetCategoryGroup(diff),
|
||||
GetChangeCategory(diff),
|
||||
diff.DiffWithMount.Difference.Path);
|
||||
}
|
||||
|
||||
internal static string ForMetaDiff(
|
||||
ClientDiffInfo diff)
|
||||
{
|
||||
return BuildCacheKey(
|
||||
GetCategoryGroup(diff),
|
||||
GetChangeCategory(diff),
|
||||
MetaPath.GetMetaPath(diff.DiffWithMount.Difference.Path));
|
||||
}
|
||||
|
||||
internal static string BuildCacheKey(
|
||||
CategoryGroup categoryGroup,
|
||||
ChangeCategory changeCategory,
|
||||
string path)
|
||||
{
|
||||
string result = string.Concat(changeCategory.Type, ":", path);
|
||||
|
||||
if (categoryGroup == null)
|
||||
return result;
|
||||
|
||||
return string.Concat(categoryGroup.GetHeaderText(), ":", result);
|
||||
}
|
||||
|
||||
internal static ChangeCategory GetChangeCategory(ClientDiffInfo diff)
|
||||
{
|
||||
return (ChangeCategory)diff.GetParent();
|
||||
}
|
||||
|
||||
internal static CategoryGroup GetCategoryGroup(ClientDiffInfo diff)
|
||||
{
|
||||
ChangeCategory changeCategory = GetChangeCategory(diff);
|
||||
|
||||
ITreeViewNode categoryGroup = changeCategory.GetParent();
|
||||
|
||||
if (categoryGroup == null)
|
||||
return null;
|
||||
|
||||
return (CategoryGroup)categoryGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e89b1e9e9f1060b4f817977507831248
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user