This commit is contained in:
2024-09-20 20:30:10 +02:00
commit 4fabf1a6fd
29169 changed files with 1706941 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,531 @@
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 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 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()
{
if (mShowDownloadPlasticExeWindow.Show(
mWkInfo,
mIsGluonMode,
TrackFeatureUseEvent.Features.InstallPlasticCloudFromDiffRevision,
TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromDiffRevision,
TrackFeatureUseEvent.Features.CancelPlasticInstallationFromDiffRevision))
return;
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
DiffOperation.DiffClientDiff(
mWkInfo,
clientDiffInfo.DiffWithMount.Mount.Mount,
clientDiffInfo.DiffWithMount.Difference,
xDiffLauncher: null,
imageDiffLauncher: null);
}
void IDiffTreeViewMenuOperations.History()
{
if (mShowDownloadPlasticExeWindow.Show(
mWkInfo,
mIsGluonMode,
TrackFeatureUseEvent.Features.InstallPlasticCloudFromShowHistory,
TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromShowHistory,
TrackFeatureUseEvent.Features.CancelPlasticInstallationFromShowHistory))
return;
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);
}
bool DiffTreeViewMenu.IMetaMenuOperations.SelectionHasMeta()
{
return mDiffTreeView.SelectionHasMeta();
}
void DiffTreeViewMenu.IMetaMenuOperations.DiffMeta()
{
if (mShowDownloadPlasticExeWindow.Show(
mWkInfo,
mIsGluonMode,
TrackFeatureUseEvent.Features.InstallPlasticCloudFromDiffRevision,
TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromDiffRevision,
TrackFeatureUseEvent.Features.CancelPlasticInstallationFromDiffRevision))
return;
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()
{
if (mShowDownloadPlasticExeWindow.Show(
mWkInfo,
mIsGluonMode,
TrackFeatureUseEvent.Features.InstallPlasticCloudFromShowHistory,
TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromShowHistory,
TrackFeatureUseEvent.Features.CancelPlasticInstallationFromShowHistory))
return;
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;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,298 @@
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 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);
}
}
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();
}
GUIContent mNoActionMenuItemContent;
GUIContent mSaveRevisionAsMenuItemContent;
GUIContent mDiffMenuItemContent;
GUIContent mDiffMetaMenuItemContent;
GUIContent mViewHistoryMenuItemContent;
GUIContent mViewHistoryMetaMenuItemContent;
GUIContent mRevertMenuItemContent;
GUIContent mUndeleteMenuItemContent;
GUIContent mUndeleteToSpecifiedPathMenuItemContent;
readonly IDiffTreeViewMenuOperations mOperations;
readonly IMetaMenuOperations mMetaMenuOperations;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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