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,17 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal class ChangeCategoryTreeViewItem : TreeViewItem
{
internal MergeChangesCategory Category { get; private set; }
internal ChangeCategoryTreeViewItem(int id, MergeChangesCategory category)
: base(id, 0, category.CategoryType.ToString())
{
Category = category;
}
}
}

View File

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

View File

@@ -0,0 +1,19 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal class ChangeTreeViewItem : TreeViewItem
{
internal MergeChangeInfo ChangeInfo { get; private set; }
internal ChangeTreeViewItem(int id, MergeChangeInfo change)
: base(id, 1)
{
ChangeInfo = change;
displayName = id.ToString();
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,39 @@
using Codice.Client.BaseCommands.Merge;
using Codice.CM.Common.Merge;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer.DirectoryConflicts
{
internal class ConflictResolutionState
{
internal DirectoryConflictResolveActions ResolveAction { get; set; }
internal string RenameValue { get; set; }
internal bool IsApplyActionsForNextConflictsChecked { get; set; }
internal static ConflictResolutionState Build(
DirectoryConflict directoryConflict,
DirectoryConflictAction[] conflictActions)
{
bool hasRenameOption = DirectoryConflictResolutionInfo.HasRenameOption(
conflictActions);
ConflictResolutionState result = new ConflictResolutionState()
{
IsApplyActionsForNextConflictsChecked = false,
ResolveAction = (hasRenameOption) ?
DirectoryConflictResolveActions.Rename :
DirectoryConflictResolveActions.KeepSource,
};
if (!hasRenameOption)
return result;
result.RenameValue = DirectoryConflictResolutionInfo.GetProposeNewItemName(
directoryConflict, "dst");
return result;
}
}
}

View File

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

View File

@@ -0,0 +1,256 @@
using System;
using UnityEditor;
using UnityEngine;
using Codice.Client.BaseCommands.Merge;
using Codice.CM.Common.Merge;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer.DirectoryConflicts
{
internal static class DrawDirectoryResolutionPanel
{
internal static void ForConflict(
MergeChangeInfo conflict,
int pendingConflictsCount,
DirectoryConflictUserInfo conflictUserInfo,
DirectoryConflictAction[] actions,
Action<MergeChangeInfo> resolveConflictAction,
ref ConflictResolutionState state)
{
bool isResolveButtonEnabled;
string validationMessage = null;
GetValidationData(
conflict,
state,
out isResolveButtonEnabled,
out validationMessage);
GUILayout.Space(2);
DoHeader(
conflictUserInfo.ConflictTitle,
conflict,
resolveConflictAction,
isResolveButtonEnabled,
ref state);
DoConflictExplanation(conflictUserInfo.ConflictExplanation);
DoSourceAndDestinationLabels(
conflictUserInfo.SourceOperation,
conflictUserInfo.DestinationOperation);
DoResolutionOptions(
actions,
validationMessage,
ref state);
DoApplyActionsForNextConflictsCheck(pendingConflictsCount, ref state);
GUILayout.Space(10);
}
static void DoHeader(
string conflictName,
MergeChangeInfo conflict,
Action<MergeChangeInfo> resolveConflictAction,
bool isResolveButtonEnabled,
ref ConflictResolutionState state)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label(conflictName,
UnityStyles.DirectoryConflicts.TitleLabel);
GUI.enabled = isResolveButtonEnabled;
GUILayout.Space(5);
if (GUILayout.Button(PlasticLocalization.GetString(
PlasticLocalization.Name.ResolveDirectoryConflict)))
{
resolveConflictAction(conflict);
}
GUI.enabled = true;
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
}
static void DoConflictExplanation(string explanation)
{
GUILayout.Space(5);
GUILayout.Label(explanation, EditorStyles.wordWrappedLabel);
}
static void DoSourceAndDestinationLabels(
string sourceOperation,
string destinationOperation)
{
GUILayout.Space(5);
GUIStyle boldLabelStyle = UnityStyles.DirectoryConflicts.BoldLabel;
GUIContent srcLabel = new GUIContent(
PlasticLocalization.GetString(
PlasticLocalization.Name.Source));
GUIContent dstLabel = new GUIContent(
PlasticLocalization.GetString(
PlasticLocalization.Name.Destination));
float maxWidth = GetMaxWidth(srcLabel, dstLabel, boldLabelStyle);
EditorGUILayout.BeginHorizontal();
GUILayout.Space(25);
GUILayout.Label(srcLabel, boldLabelStyle, GUILayout.Width(maxWidth));
GUILayout.Label(sourceOperation, EditorStyles.label);
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Space(25);
GUILayout.Label(dstLabel, boldLabelStyle, GUILayout.Width(maxWidth));
GUILayout.Label(destinationOperation, EditorStyles.label);
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
}
static void DoResolutionOptions(
DirectoryConflictAction[] actions,
string validationMessage,
ref ConflictResolutionState state)
{
GUILayout.Space(10);
GUILayout.Label(PlasticLocalization.GetString(
PlasticLocalization.Name.ResolveDirectoryConflictChooseOption));
foreach (DirectoryConflictAction action in actions)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(25);
if (GUILayout.Toggle(
state.ResolveAction == action.ActionKind,
action.ActionText,
EditorStyles.radioButton))
{
state.ResolveAction = action.ActionKind;
}
if (action.ActionKind == DirectoryConflictResolveActions.Rename)
{
GUI.enabled = state.ResolveAction == DirectoryConflictResolveActions.Rename;
state.RenameValue = GUILayout.TextField(
state.RenameValue,
UnityStyles.DirectoryConflicts.FileNameTextField,
GUILayout.Width(250));
GUI.enabled = true;
if (!string.IsNullOrEmpty(validationMessage))
{
GUILayout.Label(new GUIContent(
validationMessage,
Images.GetWarnIcon()),
UnityStyles.DirectoryConflictResolution.WarningLabel,
GUILayout.Height(UnityConstants.DIR_CONFLICT_VALIDATION_WARNING_LABEL_HEIGHT));
}
}
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
}
}
static void DoApplyActionsForNextConflictsCheck(
int pendingConflictsCount,
ref ConflictResolutionState state)
{
if (pendingConflictsCount == 0)
return;
GUILayout.Space(5);
bool isCheckEnabled = state.ResolveAction != DirectoryConflictResolveActions.Rename;
bool isChecked = state.IsApplyActionsForNextConflictsChecked & isCheckEnabled;
GUI.enabled = isCheckEnabled;
EditorGUILayout.BeginHorizontal();
state.IsApplyActionsForNextConflictsChecked = !GUILayout.Toggle(
isChecked,
GetApplyActionCheckButtonText(pendingConflictsCount));
if (!isCheckEnabled)
state.IsApplyActionsForNextConflictsChecked = false;
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
GUI.enabled = true;
}
static bool IsValidName(
string name,
DirectoryConflict conflict,
out string errorMessage)
{
if (string.IsNullOrEmpty(name))
{
errorMessage = PlasticLocalization.GetString(
PlasticLocalization.Name.InputItemNameMessage);
return false;
}
if (name == DirectoryConflictResolutionInfo.GetOldItemName(conflict))
{
errorMessage = PlasticLocalization.GetString(
PlasticLocalization.Name.ProvideDifferentItemNameForRenameResolution);
return false;
}
errorMessage = null;
return true;
}
static void GetValidationData(
MergeChangeInfo conflict,
ConflictResolutionState state,
out bool isResolveButtonEnabled,
out string renameWarningMessage)
{
if (state.ResolveAction != DirectoryConflictResolveActions.Rename)
{
renameWarningMessage = string.Empty;
isResolveButtonEnabled = true;
return;
}
isResolveButtonEnabled = IsValidName(
state.RenameValue,
conflict.DirectoryConflict,
out renameWarningMessage);
}
static float GetMaxWidth(
GUIContent label1,
GUIContent label2,
GUIStyle style)
{
Vector2 srcLabelSize = style.CalcSize(label1);
Vector2 dstLabelSize = style.CalcSize(label2);
return Math.Max(srcLabelSize.x, dstLabelSize.x);
}
static string GetApplyActionCheckButtonText(int pendingConflictsCount)
{
if (pendingConflictsCount > 1)
return PlasticLocalization.GetString(
PlasticLocalization.Name.ApplyActionForNextConflictsCheckButtonSingular,
pendingConflictsCount);
return PlasticLocalization.GetString(
PlasticLocalization.Name.ApplyActionForNextConflictsCheckButtonPlural,
pendingConflictsCount);
}
}
}

View File

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

View File

@@ -0,0 +1,44 @@
using System.Collections.Generic;
using PlasticGui.WorkspaceWindow.IncomingChanges;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal static class IncomingChangesSelection
{
internal static List<string> GetPathsFromSelectedFileConflictsIncludingMeta(
IncomingChangesTreeView treeView)
{
List<string> result = new List<string>();
List<MergeChangeInfo> selection =
treeView.GetSelectedFileConflicts();
treeView.FillWithMeta(selection);
foreach (MergeChangeInfo incomingChange in selection)
{
result.Add(incomingChange.GetPath());
}
return result;
}
internal static SelectedIncomingChangesGroupInfo GetSelectedGroupInfo(
IncomingChangesTreeView treeView)
{
List<MergeChangeInfo> selectedIncomingChanges =
treeView.GetSelectedIncomingChanges();
return GetSelectedIncomingChangesGroupInfo.For(
selectedIncomingChanges);
}
internal static MergeChangeInfo GetSingleSelectedIncomingChange(
IncomingChangesTreeView treeView)
{
return treeView.GetSelectedIncomingChange();
}
}
}

View File

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

View File

@@ -0,0 +1,912 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Codice.Client.BaseCommands;
using Codice.Client.BaseCommands.Merge;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.Client.Common.EventTracking;
using Codice.Client.Common.FsNodeReaders;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using Codice.CM.Common.Merge;
using PlasticGui;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.BranchExplorer;
using PlasticGui.WorkspaceWindow.Diff;
using PlasticGui.WorkspaceWindow.IncomingChanges;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.UI.Tree;
using Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer.DirectoryConflicts;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal class IncomingChangesTab :
IIncomingChangesTab,
IRefreshableView,
MergeViewLogic.IMergeView,
IIncomingChangesViewMenuOperations,
IncomingChangesViewMenu.IMetaMenuOperations
{
internal IncomingChangesTab(
WorkspaceInfo wkInfo,
IWorkspaceWindow workspaceWindow,
IViewSwitcher switcher,
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
NewIncomingChangesUpdater newIncomingChangesUpdater,
EditorWindow parentWindow)
{
mWkInfo = wkInfo;
mWorkspaceWindow = workspaceWindow;
mSwitcher = switcher;
mShowDownloadPlasticExeWindow = showDownloadPlasticExeWindow;
mNewIncomingChangesUpdater = newIncomingChangesUpdater;
mParentWindow = parentWindow;
mGuiMessage = new UnityPlasticGuiMessage();
BuildComponents(mWkInfo);
mProgressControls = new ProgressControlsForViews();
mCooldownClearUpdateSuccessAction = new CooldownWindowDelayer(
DelayedClearUpdateSuccess,
UnityConstants.NOTIFICATION_CLEAR_INTERVAL);
PlasticNotifier plasticNotifier = new PlasticNotifier();
mMergeController = new MergeController(
mWkInfo,
null,
null,
EnumMergeType.IncomingMerge,
true,
plasticNotifier,
null);
mMergeViewLogic = new MergeViewLogic(
mWkInfo,
EnumMergeType.IncomingMerge,
true,
mMergeController,
plasticNotifier,
ShowIncomingChangesFrom.NotificationBar,
null,
mNewIncomingChangesUpdater,
null,
this,
NewChangesInWk.Build(mWkInfo, new BuildWorkspacekIsRelevantNewChange()),
mProgressControls,
null);
((IRefreshableView)this).Refresh();
}
bool IIncomingChangesTab.IsVisible{ get; set; }
void IIncomingChangesTab.OnDisable()
{
TreeHeaderSettings.Save(
mIncomingChangesTreeView.multiColumnHeader.state,
UnityConstants.DEVELOPER_INCOMING_CHANGES_TABLE_SETTINGS_NAME);
mResolveChangeset.Clear();
}
void IIncomingChangesTab.Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
void IIncomingChangesTab.OnGUI()
{
if (Event.current.type == EventType.Layout)
{
mHasPendingDirectoryConflicts = mMergeChangesTree != null &&
MergeChangesTreeParser.GetUnsolvedDirectoryConflictsCount(mMergeChangesTree) > 0;
mIsOperationRunning = mProgressControls.IsOperationRunning();
}
DoConflictsTree(
mIncomingChangesTreeView,
mIsOperationRunning,
mHasNothingToDownload,
mIsUpdateSuccessful);
List<MergeChangeInfo> selectedIncomingChanges =
mIncomingChangesTreeView.GetSelectedIncomingChanges();
if (GetSelectedIncomingChangesGroupInfo.For(
selectedIncomingChanges).IsDirectoryConflictsSelection &&
!Mouse.IsRightMouseButtonPressed(Event.current))
{
DoDirectoryConflictResolutionPanel(
selectedIncomingChanges,
new Action<MergeChangeInfo>(ResolveDirectoryConflict),
mConflictResolutionStates);
}
DrawActionToolbar.Begin(mParentWindow);
if (!mIsOperationRunning)
{
DoActionToolbarMessage(
mIsMessageLabelVisible,
mMessageLabelText,
mHasNothingToDownload,
mIsErrorMessageLabelVisible,
mErrorMessageLabelText,
mDirectoryConflictCount,
mFileConflictCount,
mChangesSummary);
if (mIsProcessMergesButtonVisible)
{
DoProcessMergesButton(
mIsProcessMergesButtonEnabled && !mHasPendingDirectoryConflicts,
mProcessMergesButtonText,
mSwitcher,
mWorkspaceWindow,
mGuiMessage,
mMergeViewLogic,
RefreshAsset.BeforeLongAssetOperation,
() => AfterProcessMerges(RefreshAsset.AfterLongAssetOperation));
}
if (mIsCancelMergesButtonVisible)
{
mIsCancelMergesButtonEnabled = DoCancelMergesButton(
mIsCancelMergesButtonEnabled,
mMergeViewLogic);
}
if (mHasPendingDirectoryConflicts)
{
GUILayout.Space(5);
DoWarningMessage();
}
}
else
{
DrawProgressForViews.ForIndeterminateProgress(
mProgressControls.ProgressData);
}
DrawActionToolbar.End();
if (mProgressControls.HasNotification())
{
DrawProgressForViews.ForNotificationArea(
mProgressControls.ProgressData);
}
}
void IIncomingChangesTab.AutoRefresh()
{
BranchInfo workingBranch = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
workingBranch = OverlappedCalculator.GetWorkingBranch(
mWkInfo.ClientPath);
},
/*afterOperationDelegate*/ delegate
{
if (waiter.Exception != null)
{
ExceptionsHandler.DisplayException(waiter.Exception);
return;
}
// No need for merge info if it's a label
if (workingBranch == null)
return;
mMergeController.UpdateMergeObjectInfoIfNeeded(workingBranch);
mMergeViewLogic.AutoRefresh();
});
}
void IRefreshableView.Refresh()
{
BranchInfo workingBranch = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
workingBranch = OverlappedCalculator.GetWorkingBranch(
mWkInfo.ClientPath);
},
/*afterOperationDelegate*/ delegate
{
if (waiter.Exception != null)
{
ExceptionsHandler.DisplayException(waiter.Exception);
return;
}
// No need for merge info if it's a label
if (workingBranch == null)
return;
mMergeController.UpdateMergeObjectInfoIfNeeded(workingBranch);
mMergeViewLogic.Refresh();
});
}
void MergeViewLogic.IMergeView.UpdateData(
MergeChangesTree mergeChangesTree,
ExplainMergeData explainMergeData,
MergeSolvedFileConflicts solvedFileConflicts,
bool isIncomingMerge,
bool isMergeTo,
bool mergeHasFinished)
{
HideMessage();
ShowProcessMergesButton(
MergeViewTexts.GetProcessMergeButtonText(
MergeChangesTreeParser.HasFileConflicts(mergeChangesTree),
true));
mMergeChangesTree = mergeChangesTree;
mConflictResolutionStates.Clear();
UpdateFileConflictsTree(
mergeChangesTree,
mIncomingChangesTreeView,
mResolveChangeset);
UpdateOverview(mergeChangesTree, solvedFileConflicts);
}
void MergeViewLogic.IMergeView.UpdateSolvedDirectoryConflicts()
{
}
void MergeViewLogic.IMergeView.UpdateSolvedFileConflicts(
MergeSolvedFileConflicts solvedFileConflicts)
{
mIncomingChangesTreeView.UpdateSolvedFileConflicts(
solvedFileConflicts);
}
void MergeViewLogic.IMergeView.ShowMessage(
string title,
string message,
bool isErrorMessage)
{
if (isErrorMessage)
{
mErrorMessageLabelText = message;
mIsErrorMessageLabelVisible = true;
return;
}
mMessageLabelText = message;
mIsMessageLabelVisible = true;
mHasNothingToDownload = message == PlasticLocalization.GetString(
PlasticLocalization.Name.MergeNothingToDownloadForIncomingView);
}
string MergeViewLogic.IMergeView.GetComments(out bool bCancel)
{
bCancel = false;
return string.Empty;
}
void MergeViewLogic.IMergeView.DisableProcessMergesButton()
{
mIsProcessMergesButtonEnabled = false;
}
void MergeViewLogic.IMergeView.ShowCancelButton()
{
mIsCancelMergesButtonEnabled = true;
mIsCancelMergesButtonVisible = true;
}
void MergeViewLogic.IMergeView.HideCancelButton()
{
mIsCancelMergesButtonEnabled = false;
mIsCancelMergesButtonVisible = false;
}
void MergeViewLogic.IMergeView.EnableMergeOptionButton()
{
}
void MergeViewLogic.IMergeView.DisableMergeOptionsButton()
{
}
SelectedIncomingChangesGroupInfo IIncomingChangesViewMenuOperations.GetSelectedIncomingChangesGroupInfo()
{
return IncomingChangesSelection.GetSelectedGroupInfo(mIncomingChangesTreeView);
}
void IIncomingChangesViewMenuOperations.MergeContributors()
{
if (mShowDownloadPlasticExeWindow.Show(
mWkInfo,
false,
TrackFeatureUseEvent.Features.InstallPlasticCloudFromMergeSelectedFiles,
TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromMergeSelectedFiles,
TrackFeatureUseEvent.Features.CancelPlasticInstallationFromMergeSelectedFiles))
return;
List<string> selectedPaths = IncomingChangesSelection.
GetPathsFromSelectedFileConflictsIncludingMeta(
mIncomingChangesTreeView);
mMergeViewLogic.ProcessMerges(
mWorkspaceWindow,
mSwitcher,
mGuiMessage,
selectedPaths,
null,
MergeContributorType.MergeContributors,
RefreshAsset.BeforeLongAssetOperation,
() => AfterProcessMerges(RefreshAsset.AfterLongAssetOperation),
null);
}
void IIncomingChangesViewMenuOperations.MergeKeepingSourceChanges()
{
List<string> selectedPaths = IncomingChangesSelection.
GetPathsFromSelectedFileConflictsIncludingMeta(
mIncomingChangesTreeView);
mMergeViewLogic.ProcessMerges(
mWorkspaceWindow,
mSwitcher,
mGuiMessage,
selectedPaths,
null,
MergeContributorType.KeepSource,
RefreshAsset.BeforeLongAssetOperation,
() => AfterProcessMerges(RefreshAsset.AfterLongAssetOperation),
null);
}
void IIncomingChangesViewMenuOperations.MergeKeepingWorkspaceChanges()
{
List<string> selectedPaths = IncomingChangesSelection.
GetPathsFromSelectedFileConflictsIncludingMeta(
mIncomingChangesTreeView);
mMergeViewLogic.ProcessMerges(
mWorkspaceWindow,
mSwitcher,
mGuiMessage,
selectedPaths,
null,
MergeContributorType.KeepDestination,
RefreshAsset.BeforeLongAssetOperation,
() => AfterProcessMerges(RefreshAsset.AfterLongAssetOperation),
null);
}
void IIncomingChangesViewMenuOperations.DiffYoursWithIncoming()
{
MergeChangeInfo incomingChange = IncomingChangesSelection.
GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
if (incomingChange == null)
return;
DiffYoursWithIncoming(
mShowDownloadPlasticExeWindow,
incomingChange,
mWkInfo);
}
void IIncomingChangesViewMenuOperations.DiffIncomingChanges()
{
MergeChangeInfo incomingChange = IncomingChangesSelection.
GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
if (incomingChange == null)
return;
DiffIncomingChanges(
mShowDownloadPlasticExeWindow,
incomingChange,
mWkInfo);
}
void IncomingChangesViewMenu.IMetaMenuOperations.DiffIncomingChanges()
{
MergeChangeInfo incomingChange = IncomingChangesSelection.
GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
if (incomingChange == null)
return;
DiffIncomingChanges(
mShowDownloadPlasticExeWindow,
mIncomingChangesTreeView.GetMetaChange(incomingChange),
mWkInfo);
}
void IncomingChangesViewMenu.IMetaMenuOperations.DiffYoursWithIncoming()
{
MergeChangeInfo incomingChange = IncomingChangesSelection.
GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
if (incomingChange == null)
return;
DiffYoursWithIncoming(
mShowDownloadPlasticExeWindow,
mIncomingChangesTreeView.GetMetaChange(incomingChange),
mWkInfo);
}
bool IncomingChangesViewMenu.IMetaMenuOperations.SelectionHasMeta()
{
return mIncomingChangesTreeView.SelectionHasMeta();
}
static void DiffYoursWithIncoming(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
MergeChangeInfo incomingChange,
WorkspaceInfo wkInfo)
{
if (showDownloadPlasticExeWindow.Show(
wkInfo,
false,
TrackFeatureUseEvent.Features.InstallPlasticCloudFromDiffYoursWithIncoming,
TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromDiffYoursWithIncoming,
TrackFeatureUseEvent.Features.CancelPlasticInstallationFromDiffYoursWithIncoming))
return;
DiffOperation.DiffYoursWithIncoming(
wkInfo,
incomingChange.GetMount(),
incomingChange.GetRevision(),
incomingChange.GetPath(),
xDiffLauncher: null,
imageDiffLauncher: null);
}
static void DiffIncomingChanges(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
MergeChangeInfo incomingChange,
WorkspaceInfo wkInfo)
{
if (showDownloadPlasticExeWindow.Show(
wkInfo,
false,
TrackFeatureUseEvent.Features.InstallPlasticCloudFromDiffIncomingChanges,
TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromDiffIncomingChanges,
TrackFeatureUseEvent.Features.CancelPlasticInstallationFromDiffIncomingChanges))
return;
DiffOperation.DiffRevisions(
wkInfo,
incomingChange.GetMount().RepSpec,
incomingChange.GetBaseRevision(),
incomingChange.GetRevision(),
incomingChange.GetPath(),
incomingChange.GetPath(),
true,
xDiffLauncher: null,
imageDiffLauncher: null);
}
void ShowProcessMergesButton(string processMergesButtonText)
{
mProcessMergesButtonText = processMergesButtonText;
mIsProcessMergesButtonEnabled = true;
mIsProcessMergesButtonVisible = true;
}
void HideMessage()
{
mMessageLabelText = string.Empty;
mIsMessageLabelVisible = false;
mHasNothingToDownload = false;
mErrorMessageLabelText = string.Empty;
mIsErrorMessageLabelVisible = false;
}
void DelayedClearUpdateSuccess()
{
mIsUpdateSuccessful = false;
}
static void DoDirectoryConflictResolutionPanel(
List<MergeChangeInfo> selectedChangeInfos,
Action<MergeChangeInfo> resolveDirectoryConflictAction,
Dictionary<DirectoryConflict, ConflictResolutionState> conflictResolutionStates)
{
MergeChangeInfo selectedDirectoryConflict = selectedChangeInfos[0];
if (selectedDirectoryConflict.DirectoryConflict.IsResolved())
return;
DirectoryConflictUserInfo conflictUserInfo;
DirectoryConflictAction[] conflictActions;
DirectoryConflictResolutionInfo.FromDirectoryConflict(
selectedDirectoryConflict.GetMount(),
selectedDirectoryConflict.DirectoryConflict,
false,
out conflictUserInfo,
out conflictActions);
ConflictResolutionState conflictResolutionState = GetConflictResolutionState(
selectedDirectoryConflict.DirectoryConflict,
conflictActions,
conflictResolutionStates);
int pendingSelectedConflictsCount = GetPendingConflictsCount(
selectedChangeInfos);
DrawDirectoryResolutionPanel.ForConflict(
selectedDirectoryConflict,
(pendingSelectedConflictsCount <= 1) ? 0 : pendingSelectedConflictsCount - 1,
conflictUserInfo,
conflictActions,
resolveDirectoryConflictAction,
ref conflictResolutionState);
}
void ResolveDirectoryConflict(MergeChangeInfo conflict)
{
ConflictResolutionState state;
if (!mConflictResolutionStates.TryGetValue(conflict.DirectoryConflict, out state))
return;
List<DirectoryConflictResolutionData> conflictResolutions =
new List<DirectoryConflictResolutionData>();
AddConflictResolution(
conflict,
state.ResolveAction,
state.RenameValue,
conflictResolutions);
MergeChangeInfo metaConflict =
mIncomingChangesTreeView.GetMetaChange(conflict);
if (metaConflict != null)
{
AddConflictResolution(
metaConflict,
state.ResolveAction,
MetaPath.GetMetaPath(state.RenameValue),
conflictResolutions);
}
if (state.IsApplyActionsForNextConflictsChecked)
{
foreach (MergeChangeInfo otherConflict in mIncomingChangesTreeView.GetSelectedIncomingChanges())
{
AddConflictResolution(
otherConflict,
state.ResolveAction,
state.RenameValue,
conflictResolutions);
}
}
mMergeViewLogic.ResolveDirectoryConflicts(conflictResolutions);
}
static void AddConflictResolution(
MergeChangeInfo conflict,
DirectoryConflictResolveActions resolveAction,
string renameValue,
List<DirectoryConflictResolutionData> conflictResolutions)
{
conflictResolutions.Add(new DirectoryConflictResolutionData(
conflict.DirectoryConflict,
conflict.Xlink,
conflict.GetMount().Mount,
resolveAction,
renameValue));
}
static void DoConflictsTree(
IncomingChangesTreeView incomingChangesTreeView,
bool isOperationRunning,
bool hasNothingToDownload,
bool isUpdateSuccessful)
{
GUI.enabled = !isOperationRunning;
Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
incomingChangesTreeView.OnGUI(rect);
if (hasNothingToDownload)
DrawEmptyState(rect, isUpdateSuccessful);
GUI.enabled = true;
}
static void DrawEmptyState(
Rect rect,
bool isUpdateSuccessful)
{
if (isUpdateSuccessful)
{
DrawTreeViewEmptyState.For(
rect,
PlasticLocalization.GetString(PlasticLocalization.Name.WorkspaceUpdateCompleted),
Images.GetStepOkIcon());
return;
}
DrawTreeViewEmptyState.For(
rect,
PlasticLocalization.GetString(PlasticLocalization.Name.NoIncomingChanges));
}
static void DoActionToolbarMessage(
bool isMessageLabelVisible,
string messageLabelText,
bool hasNothingToDownload,
bool isErrorMessageLabelVisible,
string errorMessageLabelText,
int directoryConflictCount,
int fileConflictCount,
MergeViewTexts.ChangesToApplySummary changesSummary)
{
if (isMessageLabelVisible)
{
string message = messageLabelText;
if (hasNothingToDownload)
{
message = PlasticLocalization.GetString(
PlasticLocalization.Name.WorkspaceIsUpToDate);
}
DoInfoMessage(message);
}
if (isErrorMessageLabelVisible)
{
DoErrorMessage(errorMessageLabelText);
}
if (!isMessageLabelVisible && !isErrorMessageLabelVisible)
{
DrawIncomingChangesOverview.For(
directoryConflictCount,
fileConflictCount,
changesSummary);
}
}
void AfterProcessMerges(Action afterAssetLongOperation)
{
mIsUpdateSuccessful = true;
mCooldownClearUpdateSuccessAction.Ping();
afterAssetLongOperation();
}
static void DoProcessMergesButton(
bool isEnabled,
string processMergesButtonText,
IViewSwitcher switcher,
IWorkspaceWindow workspaceWindow,
GuiMessage.IGuiMessage guiMessage,
MergeViewLogic mergeViewLogic,
Action beforeProcessMergesAction,
Action afterProcessMergesAction)
{
GUI.enabled = isEnabled;
if (DrawActionButton.For(processMergesButtonText))
{
mergeViewLogic.ProcessMerges(
workspaceWindow,
switcher,
guiMessage,
new List<string>(),
null,
MergeContributorType.MergeContributors,
beforeProcessMergesAction,
afterProcessMergesAction,
null);
}
GUI.enabled = true;
}
static bool DoCancelMergesButton(
bool isEnabled,
MergeViewLogic mergeViewLogic)
{
bool shouldCancelMergesButtonEnabled = true;
GUI.enabled = isEnabled;
if (DrawActionButton.For(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
{
mergeViewLogic.Cancel();
shouldCancelMergesButtonEnabled = false;
}
GUI.enabled = true;
return shouldCancelMergesButtonEnabled;
}
static void DoWarningMessage()
{
string label = PlasticLocalization.GetString(PlasticLocalization.Name.SolveConflictsInLable);
GUILayout.Label(
new GUIContent(label, Images.GetWarnIcon()),
UnityStyles.IncomingChangesTab.HeaderWarningLabel);
}
void UpdateFileConflictsTree(
MergeChangesTree incomingChangesTree,
IncomingChangesTreeView incomingChangesTreeView,
IResolveChangeset resolveChangeset)
{
UnityIncomingChangesTree unityIncomingChangesTree = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
unityIncomingChangesTree = UnityIncomingChangesTree.BuildIncomingChangeCategories(
incomingChangesTree);
incomingChangesTree.ResolveUserNames(
new MergeChangesTree.ResolveUserName());
incomingChangesTree.ResolveComments(resolveChangeset);
},
/*afterOperationDelegate*/ delegate
{
incomingChangesTreeView.BuildModel(unityIncomingChangesTree);
incomingChangesTreeView.Sort();
incomingChangesTreeView.Reload();
incomingChangesTreeView.SelectFirstUnsolvedDirectoryConflict();
});
}
void UpdateOverview(
MergeChangesTree mergeChangesTree,
MergeSolvedFileConflicts solvedFileConflicts)
{
mChangesSummary = MergeChangesTreeParser.
GetChangesToApplySummary(mergeChangesTree);
mFileConflictCount = MergeChangesTreeParser.GetUnsolvedFileConflictsCount(
mergeChangesTree, solvedFileConflicts);
mDirectoryConflictCount = MergeChangesTreeParser.GetUnsolvedDirectoryConflictsCount(
mergeChangesTree);
}
static void DoInfoMessage(string message)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label(message, UnityStyles.IncomingChangesTab.ChangesToApplySummaryLabel);
EditorGUILayout.EndHorizontal();
}
static void DoErrorMessage(string message)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label(message, UnityStyles.IncomingChangesTab.RedPendingConflictsOfTotalLabel);
EditorGUILayout.EndHorizontal();
}
void BuildComponents(WorkspaceInfo wkInfo)
{
IncomingChangesTreeHeaderState incomingChangesHeaderState =
IncomingChangesTreeHeaderState.GetDefault();
TreeHeaderSettings.Load(incomingChangesHeaderState,
UnityConstants.DEVELOPER_INCOMING_CHANGES_TABLE_SETTINGS_NAME,
(int)IncomingChangesTreeColumn.Path, true);
mIncomingChangesTreeView = new IncomingChangesTreeView(
wkInfo, incomingChangesHeaderState,
IncomingChangesTreeHeaderState.GetColumnNames(),
new IncomingChangesViewMenu(this, this));
mIncomingChangesTreeView.Reload();
}
static ConflictResolutionState GetConflictResolutionState(
DirectoryConflict directoryConflict,
DirectoryConflictAction[] conflictActions,
Dictionary<DirectoryConflict, ConflictResolutionState> conflictResoltionStates)
{
ConflictResolutionState result;
if (conflictResoltionStates.TryGetValue(directoryConflict, out result))
return result;
result = ConflictResolutionState.Build(directoryConflict, conflictActions);
conflictResoltionStates.Add(directoryConflict, result);
return result;
}
static int GetPendingConflictsCount(
List<MergeChangeInfo> selectedChangeInfos)
{
int result = 0;
foreach (MergeChangeInfo changeInfo in selectedChangeInfos)
{
if (changeInfo.DirectoryConflict.IsResolved())
continue;
result++;
}
return result;
}
bool mIsProcessMergesButtonVisible;
bool mIsCancelMergesButtonVisible;
bool mIsMessageLabelVisible;
bool mIsErrorMessageLabelVisible;
bool mHasNothingToDownload;
bool mIsProcessMergesButtonEnabled;
bool mIsCancelMergesButtonEnabled;
bool mHasPendingDirectoryConflicts;
bool mIsOperationRunning;
bool mIsUpdateSuccessful;
string mProcessMergesButtonText;
string mMessageLabelText;
string mErrorMessageLabelText;
IncomingChangesTreeView mIncomingChangesTreeView;
MergeChangesTree mMergeChangesTree;
Dictionary<DirectoryConflict, ConflictResolutionState> mConflictResolutionStates =
new Dictionary<DirectoryConflict, ConflictResolutionState>();
int mDirectoryConflictCount;
int mFileConflictCount;
MergeViewTexts.ChangesToApplySummary mChangesSummary;
readonly ProgressControlsForViews mProgressControls;
readonly CooldownWindowDelayer mCooldownClearUpdateSuccessAction;
readonly MergeViewLogic mMergeViewLogic;
readonly MergeController mMergeController;
readonly GuiMessage.IGuiMessage mGuiMessage;
readonly EditorWindow mParentWindow;
readonly NewIncomingChangesUpdater mNewIncomingChangesUpdater;
readonly LaunchTool.IShowDownloadPlasticExeWindow mShowDownloadPlasticExeWindow;
readonly IViewSwitcher mSwitcher;
readonly IWorkspaceWindow mWorkspaceWindow;
readonly WorkspaceInfo mWkInfo;
readonly IResolveChangeset mResolveChangeset = new ResolveChangeset();
}
}

View File

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

View File

@@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal enum IncomingChangesTreeColumn
{
Path,
Size,
Author,
Details,
Resolution,
DateModified,
Comment
}
[Serializable]
internal class IncomingChangesTreeHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static IncomingChangesTreeHeaderState GetDefault()
{
IncomingChangesTreeHeaderState headerState =
new IncomingChangesTreeHeaderState(BuildColumns());
headerState.visibleColumns = GetDefaultVisibleColumns();
return headerState;
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.SizeColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.DetailsColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.ResolutionMethodColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.DateModifiedColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn));
return result;
}
internal static string GetColumnName(IncomingChangesTreeColumn column)
{
switch (column)
{
case IncomingChangesTreeColumn.Path:
return PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn);
case IncomingChangesTreeColumn.Size:
return PlasticLocalization.GetString(PlasticLocalization.Name.SizeColumn);
case IncomingChangesTreeColumn.Author:
return PlasticLocalization.GetString(PlasticLocalization.Name.AuthorColumn);
case IncomingChangesTreeColumn.Details:
return PlasticLocalization.GetString(PlasticLocalization.Name.DetailsColumn);
case IncomingChangesTreeColumn.Resolution:
return PlasticLocalization.GetString(PlasticLocalization.Name.ResolutionMethodColumn);
case IncomingChangesTreeColumn.DateModified:
return PlasticLocalization.GetString(PlasticLocalization.Name.DateModifiedColumn);
case IncomingChangesTreeColumn.Comment:
return PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
if (mColumsAllowedToggleVisibility != null)
TreeHeaderColumns.SetVisibilities(columns, mColumsAllowedToggleVisibility);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static int[] GetDefaultVisibleColumns()
{
List<int> result = new List<int>();
result.Add((int)IncomingChangesTreeColumn.Path);
result.Add((int)IncomingChangesTreeColumn.Size);
result.Add((int)IncomingChangesTreeColumn.Author);
result.Add((int)IncomingChangesTreeColumn.DateModified);
result.Add((int)IncomingChangesTreeColumn.Comment);
return result.ToArray();
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 450,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.Path)),
minWidth = 200,
allowToggleVisibility = false,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 150,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.Size)),
minWidth = 45,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 150,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.Author)),
minWidth = 80,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 200,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.Details)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 250,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.Resolution)),
minWidth = 120,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 330,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.DateModified)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 400,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.Comment)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
}
};
}
IncomingChangesTreeHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
if (mColumsAllowedToggleVisibility == null)
mColumsAllowedToggleVisibility = TreeHeaderColumns.GetVisibilities(columns);
}
[SerializeField]
string[] mHeaderTitles;
[SerializeField]
bool[] mColumsAllowedToggleVisibility;
}
}

View File

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

View File

@@ -0,0 +1,576 @@
using System.Collections.Generic;
using System.IO;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.BaseCommands.Merge;
using Codice.Client.Common;
using Codice.CM.Common;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal class IncomingChangesTreeView : TreeView
{
internal IncomingChangesTreeView(
WorkspaceInfo wkInfo,
IncomingChangesTreeHeaderState headerState,
List<string> columnNames,
IncomingChangesViewMenu menu)
: base(new TreeViewState())
{
mWkInfo = wkInfo;
mColumnNames = columnNames;
mMenu = menu;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
customFoldoutYOffset = UnityConstants.TREEVIEW_FOLDOUT_Y_OFFSET;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = false;
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
protected override bool CanChangeExpandedState(TreeViewItem item)
{
return item is ChangeCategoryTreeViewItem;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem rootItem)
{
try
{
RegenerateRows(
mIncomingChangesTree,
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 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,
(lastRowVisible * rowHeight) + 1000),
Images.GetTreeviewBackgroundTexture());
DrawTreeViewItem.InitializeStyles();
base.BeforeRowsGUI();
}
protected override void RowGUI(RowGUIArgs args)
{
if (args.item is ChangeCategoryTreeViewItem)
{
ChangeCategoryTreeViewItem categoryItem =
(ChangeCategoryTreeViewItem)args.item;
CategoryTreeViewItemGUI(
args.rowRect,
categoryItem,
GetSolvedChildrenCount(categoryItem.Category, mSolvedFileConflicts),
args.selected,
args.focused);
return;
}
if (args.item is ChangeTreeViewItem)
{
ChangeTreeViewItem changeTreeViewItem =
(ChangeTreeViewItem)args.item;
MergeChangeInfo changeInfo =
changeTreeViewItem.ChangeInfo;
bool isCurrentConflict = IsCurrent.Conflict(
changeInfo,
mIncomingChangesTree.GetMetaChange(changeInfo),
mSolvedFileConflicts);
bool isSolvedConflict = IsSolved.Conflict(
changeInfo,
mIncomingChangesTree.GetMetaChange(changeInfo),
mSolvedFileConflicts);
IncomingChangeTreeViewItemGUI(
mWkInfo.ClientPath,
mIncomingChangesTree,
this,
changeTreeViewItem,
args,
isCurrentConflict,
isSolvedConflict);
return;
}
base.RowGUI(args);
}
internal void SelectFirstUnsolvedDirectoryConflict()
{
foreach (MergeChangesCategory category in mIncomingChangesTree.GetNodes())
{
if (category.CategoryType != MergeChangesCategory.Type.DirectoryConflicts)
continue;
foreach (MergeChangeInfo changeInfo in category.GetChanges())
{
if (changeInfo.DirectoryConflict.IsResolved())
continue;
int itemId = -1;
if (mTreeViewItemIds.TryGetInfoItemId(changeInfo, out itemId))
{
SetSelection(new List<int>() { itemId });
return;
}
}
}
}
internal void BuildModel(UnityIncomingChangesTree tree)
{
mTreeViewItemIds.Clear();
mIncomingChangesTree = tree;
mSolvedFileConflicts = null;
mExpandCategories = true;
}
internal void Sort()
{
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mIncomingChangesTree.Sort(mColumnNames[sortedColumnIdx], sortAscending);
}
internal void UpdateSolvedFileConflicts(
MergeSolvedFileConflicts solvedFileConflicts)
{
mSolvedFileConflicts = solvedFileConflicts;
}
internal MergeChangeInfo GetMetaChange(MergeChangeInfo change)
{
if (change == null)
return null;
return mIncomingChangesTree.GetMetaChange(change);
}
internal void FillWithMeta(List<MergeChangeInfo> changes)
{
mIncomingChangesTree.FillWithMeta(changes);
}
internal bool SelectionHasMeta()
{
MergeChangeInfo selectedChangeInfo = GetSelectedIncomingChange();
if (selectedChangeInfo == null)
return false;
return mIncomingChangesTree.HasMeta(selectedChangeInfo);
}
internal MergeChangeInfo GetSelectedIncomingChange()
{
IList<int> selectedIds = GetSelection();
if (selectedIds.Count != 1)
return null;
int selectedId = selectedIds[0];
foreach (KeyValuePair<MergeChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (selectedId == item.Value)
return item.Key;
}
return null;
}
internal List<MergeChangeInfo> GetSelectedIncomingChanges()
{
List<MergeChangeInfo> result = new List<MergeChangeInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<MergeChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
result.Add(item.Key);
}
return result;
}
internal List<MergeChangeInfo> GetSelectedFileConflicts()
{
List<MergeChangeInfo> result = new List<MergeChangeInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<MergeChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
if (item.Key.CategoryType !=
MergeChangesCategory.Type.FileConflicts)
continue;
result.Add(item.Key);
}
return result;
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
UnityIncomingChangesTree incomingChangesTree,
TreeViewItemIds<MergeChangesCategory, MergeChangeInfo> treeViewItemIds,
IncomingChangesTreeView treeView,
TreeViewItem rootItem,
List<TreeViewItem> rows,
bool expandCategories)
{
if (incomingChangesTree == null)
return;
ClearRows(rootItem, rows);
List<MergeChangesCategory> categories = incomingChangesTree.GetNodes();
if (categories == null)
return;
List<int> categoriesToExpand = new List<int>();
foreach (MergeChangesCategory category in categories)
{
int categoryId;
if (!treeViewItemIds.TryGetCategoryItemId(category, out categoryId))
categoryId = treeViewItemIds.AddCategoryItem(category);
ChangeCategoryTreeViewItem categoryTreeViewItem =
new ChangeCategoryTreeViewItem(categoryId, category);
rootItem.AddChild(categoryTreeViewItem);
rows.Add(categoryTreeViewItem);
if (!ShouldExpandCategory(
treeView,
categoryTreeViewItem,
expandCategories,
categories.Count))
continue;
categoriesToExpand.Add(categoryTreeViewItem.id);
foreach (MergeChangeInfo changeInfo in category.GetChanges())
{
int differenceId;
if (!treeViewItemIds.TryGetInfoItemId(changeInfo, out differenceId))
differenceId = treeViewItemIds.AddInfoItem(changeInfo);
TreeViewItem changeTreeViewItem =
new ChangeTreeViewItem(differenceId, changeInfo);
categoryTreeViewItem.AddChild(changeTreeViewItem);
rows.Add(changeTreeViewItem);
}
}
treeView.state.expandedIDs = categoriesToExpand;
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void CategoryTreeViewItemGUI(
Rect rowRect,
ChangeCategoryTreeViewItem item,
int solvedChildrenCount,
bool isSelected,
bool isFocused)
{
string label = item.Category.GetCategoryName();
string infoLabel = item.Category.GetChildrenCountText();
DefaultStyles.label = GetCategoryStyle(
item.Category,
solvedChildrenCount,
isSelected);
DrawTreeViewItem.ForCategoryItem(
rowRect,
item.depth,
label,
infoLabel,
isSelected,
isFocused);
DefaultStyles.label = UnityStyles.Tree.Label;
}
static void IncomingChangeTreeViewItemGUI(
string wkPath,
UnityIncomingChangesTree incomingChangesTree,
IncomingChangesTreeView treeView,
ChangeTreeViewItem item,
RowGUIArgs args,
bool isCurrentConflict,
bool isSolvedConflict)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
IncomingChangesTreeColumn column =
(IncomingChangesTreeColumn)args.GetColumn(visibleColumnIdx);
IncomingChangeTreeViewItemCellGUI(
wkPath,
cellRect,
treeView.rowHeight,
incomingChangesTree,
treeView,
item,
column,
args.selected,
args.focused,
isCurrentConflict,
isSolvedConflict);
}
}
static void IncomingChangeTreeViewItemCellGUI(
string wkPath,
Rect rect,
float rowHeight,
UnityIncomingChangesTree incomingChangesTree,
IncomingChangesTreeView treeView,
ChangeTreeViewItem item,
IncomingChangesTreeColumn column,
bool isSelected,
bool isFocused,
bool isCurrentConflict,
bool isSolvedConflict)
{
MergeChangeInfo incomingChange = item.ChangeInfo;
string label = incomingChange.GetColumnText(
IncomingChangesTreeHeaderState.GetColumnName(column));
if (column == IncomingChangesTreeColumn.Path)
{
if (incomingChangesTree.HasMeta(item.ChangeInfo))
label = string.Concat(label, UnityConstants.TREEVIEW_META_LABEL);
Texture icon = GetIcon(wkPath, incomingChange);
Texture overlayIcon =
GetChangesOverlayIcon.ForPlasticIncomingChange(
incomingChange, isSolvedConflict);
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
item.depth,
icon,
overlayIcon,
label,
isSelected,
isFocused,
isCurrentConflict,
false);
return;
}
if (column == IncomingChangesTreeColumn.Size)
{
// If there is a meta file, add the meta file to the file size so that it is consistent
// with the Incoming Changes overview
if (incomingChangesTree.HasMeta(item.ChangeInfo))
{
MergeChangeInfo metaFileInfo = incomingChangesTree.GetMetaChange(incomingChange);
long metaFileSize = metaFileInfo.GetSize();
long fileSize = incomingChange.GetSize();
label = SizeConverter.ConvertToSizeString(fileSize + metaFileSize);
}
DrawTreeViewItem.ForSecondaryLabelRightAligned(
rect, label, isSelected, isFocused, isCurrentConflict);
return;
}
DrawTreeViewItem.ForSecondaryLabel(
rect, label, isSelected, isFocused, isCurrentConflict);
}
static Texture GetIcon(
string wkPath,
MergeChangeInfo incomingChange)
{
RevisionInfo revInfo = incomingChange.GetRevision();
bool isDirectory = revInfo.
Type == EnumRevisionType.enDirectory;
if (isDirectory || incomingChange.IsXLink())
return Images.GetDirectoryIcon();
string fullPath = WorkspacePath.GetWorkspacePathFromCmPath(
wkPath,
incomingChange.GetPath(),
Path.DirectorySeparatorChar);
return Images.GetFileIcon(fullPath);
}
static GUIStyle GetCategoryStyle(
MergeChangesCategory category,
int solvedChildrenCount,
bool isSelected)
{
if (isSelected)
return UnityStyles.Tree.Label;
if (category.CategoryType == MergeChangesCategory.Type.FileConflicts ||
category.CategoryType == MergeChangesCategory.Type.DirectoryConflicts)
{
return category.GetChildrenCount() > solvedChildrenCount ?
UnityStyles.Tree.RedLabel : UnityStyles.Tree.GreenLabel;
}
return UnityStyles.Tree.Label;
}
static bool ShouldExpandCategory(
IncomingChangesTreeView treeView,
ChangeCategoryTreeViewItem categoryTreeViewItem,
bool expandCategories,
int categoriesCount)
{
if (expandCategories)
{
if (categoriesCount == 1)
return true;
if (categoryTreeViewItem.Category.CategoryType ==
MergeChangesCategory.Type.FileConflicts)
return true;
if (categoryTreeViewItem.Category.GetChildrenCount() >
NODES_TO_EXPAND_CATEGORY)
return false;
return true;
}
return treeView.IsExpanded(categoryTreeViewItem.id);
}
static int GetSolvedChildrenCount(
MergeChangesCategory category,
MergeSolvedFileConflicts solvedFileConflicts)
{
int solvedDirConflicts = 0;
if (category.CategoryType == MergeChangesCategory.Type.DirectoryConflicts)
{
foreach (MergeChangeInfo change in category.GetChanges())
{
if (change.DirectoryConflict.IsResolved())
solvedDirConflicts++;
}
return solvedDirConflicts;
}
return (solvedFileConflicts == null) ? 0 :
solvedFileConflicts.GetCount();
}
bool mExpandCategories;
TreeViewItemIds<MergeChangesCategory, MergeChangeInfo> mTreeViewItemIds =
new TreeViewItemIds<MergeChangesCategory, MergeChangeInfo>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
MergeSolvedFileConflicts mSolvedFileConflicts;
UnityIncomingChangesTree mIncomingChangesTree;
readonly IncomingChangesViewMenu mMenu;
readonly List<string> mColumnNames;
readonly WorkspaceInfo mWkInfo;
const int NODES_TO_EXPAND_CATEGORY = 10;
}
}

View File

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

View File

@@ -0,0 +1,223 @@
using UnityEditor;
using UnityEngine;
using Codice.Client.Common.EventTracking;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.IncomingChanges;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal class IncomingChangesViewMenu
{
internal interface IMetaMenuOperations
{
void DiffIncomingChanges();
void DiffYoursWithIncoming();
bool SelectionHasMeta();
}
internal IncomingChangesViewMenu(
IIncomingChangesViewMenuOperations incomingChangesViewMenuOperations,
IMetaMenuOperations incomingChangesMetaMenuOperations)
{
mIncomingChangesViewMenuOperations = incomingChangesViewMenuOperations;
mIncomingChangesMetaMenuOperations = incomingChangesMetaMenuOperations;
BuildComponents();
}
internal void Popup()
{
GenericMenu menu = new GenericMenu();
UpdateMenuItems(menu);
menu.ShowAsContext();
}
void MergeSelectedFilesMenuItem_Click()
{
mIncomingChangesViewMenuOperations.MergeContributors();
}
void MergeKeepingSourceChangesMenuItem_Click()
{
mIncomingChangesViewMenuOperations.MergeKeepingSourceChanges();
}
void MergeKeepingWorkspaceChangesMenuItem_Click()
{
mIncomingChangesViewMenuOperations.MergeKeepingWorkspaceChanges();
}
void DiffYoursWithIncomingMenuItem_Click()
{
mIncomingChangesViewMenuOperations.DiffYoursWithIncoming();
}
void DiffIncomingChangesMenuItem_Click()
{
mIncomingChangesViewMenuOperations.DiffIncomingChanges();
}
void DiffMetaYoursWithIncomingMenuItem_Click()
{
mIncomingChangesMetaMenuOperations.DiffYoursWithIncoming();
}
void DiffMetaIncomingChangesMenuItem_Click()
{
mIncomingChangesMetaMenuOperations.DiffIncomingChanges();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedIncomingChangesGroupInfo info =
mIncomingChangesViewMenuOperations.GetSelectedIncomingChangesGroupInfo();
IncomingChangesMenuOperations operations =
UpdateIncomingChangesMenu.GetAvailableMenuOperations(info);
if (operations == IncomingChangesMenuOperations.None)
{
menu.AddDisabledItem(GetNoActionMenuItemContent());
return;
}
AddMergeActions(menu, operations);
menu.AddSeparator(string.Empty);
AddDiffActions(menu, operations);
if (!mIncomingChangesMetaMenuOperations.SelectionHasMeta())
return;
menu.AddSeparator(string.Empty);
AddMetaActions(menu, operations);
}
void AddMergeActions(
GenericMenu menu,
IncomingChangesMenuOperations operations)
{
if (operations.HasFlag(IncomingChangesMenuOperations.MergeContributors))
menu.AddItem(mMergeSelectedFilesMenuItemContent, false,
MergeSelectedFilesMenuItem_Click);
else
menu.AddDisabledItem(mMergeSelectedFilesMenuItemContent);
if (operations.HasFlag(IncomingChangesMenuOperations.MergeKeepingSourceChanges))
menu.AddItem(mMergeKeepingSourceChangesMenuItemContent, false,
MergeKeepingSourceChangesMenuItem_Click);
else
menu.AddDisabledItem(mMergeKeepingSourceChangesMenuItemContent);
if (operations.HasFlag(IncomingChangesMenuOperations.MergeKeepingWorkspaceChanges))
menu.AddItem(mMergeKeepingWorkspaceChangesMenuItemContent, false,
MergeKeepingWorkspaceChangesMenuItem_Click);
else
menu.AddDisabledItem(mMergeKeepingWorkspaceChangesMenuItemContent);
}
void AddDiffActions(GenericMenu menu, IncomingChangesMenuOperations operations)
{
if (operations.HasFlag(IncomingChangesMenuOperations.DiffYoursWithIncoming))
menu.AddItem(mDiffYoursWithIncomingMenuItemContent, false,
DiffYoursWithIncomingMenuItem_Click);
else
menu.AddDisabledItem(mDiffYoursWithIncomingMenuItemContent);
if (operations.HasFlag(IncomingChangesMenuOperations.DiffIncomingChanges))
menu.AddItem(mDiffIncomingChangesMenuItemContent, false,
DiffIncomingChangesMenuItem_Click);
else
menu.AddDisabledItem(mDiffIncomingChangesMenuItemContent);
}
void AddMetaActions(GenericMenu menu, IncomingChangesMenuOperations operations)
{
if (operations.HasFlag(IncomingChangesMenuOperations.DiffYoursWithIncoming))
menu.AddItem(mDiffMetaYoursWithIncomingMenuItemContent, false,
DiffMetaYoursWithIncomingMenuItem_Click);
else
menu.AddDisabledItem(mDiffMetaYoursWithIncomingMenuItemContent);
if (operations.HasFlag(IncomingChangesMenuOperations.DiffIncomingChanges))
menu.AddItem(mDiffMetaIncomingChangesMenuItemContent, false,
DiffMetaIncomingChangesMenuItem_Click);
else
menu.AddDisabledItem(mDiffMetaIncomingChangesMenuItemContent);
}
GUIContent GetNoActionMenuItemContent()
{
if (mNoActionMenuItemContent == null)
{
mNoActionMenuItemContent = new GUIContent(
PlasticLocalization.GetString(
PlasticLocalization.Name.NoActionMenuItem));
}
return mNoActionMenuItemContent;
}
void BuildComponents()
{
mMergeSelectedFilesMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.
Name.MergeSelectedFiles));
mMergeKeepingSourceChangesMenuItemContent = new GUIContent(
UnityMenuItem.EscapedText(
PlasticLocalization.GetString(PlasticLocalization.
Name.IncomingChangesMenuItemMergeKeepingSourceChanges)));
mMergeKeepingWorkspaceChangesMenuItemContent = new GUIContent(
UnityMenuItem.EscapedText(
PlasticLocalization.GetString(PlasticLocalization.
Name.IncomingChangesMenuItemMergeKeepingWorkspaceChanges)));
string diffYoursWithIncomingText = UnityMenuItem.EscapedText(
PlasticLocalization.GetString(PlasticLocalization.
Name.IncomingChangesMenuItemDiffYoursWithIncoming));
string diffIncomingChangesText = UnityMenuItem.EscapedText(
PlasticLocalization.GetString(PlasticLocalization.
Name.IncomingChangesMenuItemDiffIncomingChanges));
mDiffYoursWithIncomingMenuItemContent = new GUIContent(
diffYoursWithIncomingText);
mDiffIncomingChangesMenuItemContent = new GUIContent(
diffIncomingChangesText);
mDiffMetaYoursWithIncomingMenuItemContent = new GUIContent(
string.Format(
"{0}/{1}",
MetaPath.META_EXTENSION,
diffYoursWithIncomingText));
mDiffMetaIncomingChangesMenuItemContent = new GUIContent(
string.Format(
"{0}/{1}",
MetaPath.META_EXTENSION,
diffIncomingChangesText));
}
GUIContent mNoActionMenuItemContent;
GUIContent mMergeSelectedFilesMenuItemContent;
GUIContent mMergeKeepingSourceChangesMenuItemContent;
GUIContent mMergeKeepingWorkspaceChangesMenuItemContent;
GUIContent mDiffYoursWithIncomingMenuItemContent;
GUIContent mDiffIncomingChangesMenuItemContent;
GUIContent mDiffMetaYoursWithIncomingMenuItemContent;
GUIContent mDiffMetaIncomingChangesMenuItemContent;
readonly IIncomingChangesViewMenuOperations mIncomingChangesViewMenuOperations;
readonly IMetaMenuOperations mIncomingChangesMetaMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,37 @@
using Codice.Client.BaseCommands.Merge;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
// internal for testing purpuses
internal static class IsCurrent
{
internal static bool Conflict(
MergeChangeInfo changeInfo,
MergeChangeInfo metaChangeInfo,
MergeSolvedFileConflicts solvedFileConflicts)
{
if (solvedFileConflicts == null)
return false;
MergeSolvedFileConflicts.CurrentConflict currentConflict;
if (!solvedFileConflicts.TryGetCurrentConflict(out currentConflict))
return false;
return IsSameConflict(currentConflict, changeInfo) ||
IsSameConflict(currentConflict, metaChangeInfo);
}
static bool IsSameConflict(
MergeSolvedFileConflicts.CurrentConflict currentConflict,
MergeChangeInfo changeInfo)
{
if (changeInfo == null)
return false;
return currentConflict.MountId.Equals(changeInfo.GetMount().Id)
&& currentConflict.ItemId == changeInfo.GetRevision().ItemId;
}
}
}

View File

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

View File

@@ -0,0 +1,54 @@
using Codice.Client.BaseCommands.Merge;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal static class IsSolved
{
internal static bool Conflict(
MergeChangeInfo changeInfo,
MergeChangeInfo metaChangeInfo,
MergeSolvedFileConflicts solvedFileConflicts)
{
if (IsDirectoryConflict(changeInfo))
{
if (metaChangeInfo == null)
return IsDirectoryConflictResolved(changeInfo);
return IsDirectoryConflictResolved(changeInfo) &&
IsDirectoryConflictResolved(metaChangeInfo);
}
if (metaChangeInfo == null)
{
return IsFileConflictResolved(
changeInfo, solvedFileConflicts);
}
return IsFileConflictResolved(changeInfo, solvedFileConflicts) &&
IsFileConflictResolved(metaChangeInfo, solvedFileConflicts);
}
static bool IsFileConflictResolved(
MergeChangeInfo changeInfo,
MergeSolvedFileConflicts solvedFileConflicts)
{
if (solvedFileConflicts == null)
return false;
return solvedFileConflicts.IsResolved(
changeInfo.GetMount().Id,
changeInfo.GetRevision().ItemId);
}
static bool IsDirectoryConflictResolved(MergeChangeInfo changeInfo)
{
return changeInfo.DirectoryConflict.IsResolved();
}
static bool IsDirectoryConflict(MergeChangeInfo changeInfo)
{
return (changeInfo.DirectoryConflict != null);
}
}
}

View File

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

View File

@@ -0,0 +1,182 @@
using System.Collections.Generic;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
{
internal class UnityIncomingChangesTree
{
internal static UnityIncomingChangesTree BuildIncomingChangeCategories(
MergeChangesTree tree)
{
return new UnityIncomingChangesTree(tree);
}
UnityIncomingChangesTree(
MergeChangesTree tree)
{
mInnerTree = tree;
mMetaCache.Build(mInnerTree.GetNodes());
}
internal List<MergeChangesCategory> GetNodes()
{
return mInnerTree.GetNodes();
}
internal bool HasMeta(MergeChangeInfo changeInfo)
{
return mMetaCache.ContainsMeta(changeInfo);
}
internal MergeChangeInfo GetMetaChange(MergeChangeInfo change)
{
return mMetaCache.GetExistingMeta(change);
}
internal void FillWithMeta(List<MergeChangeInfo> changes)
{
changes.AddRange(
mMetaCache.GetExistingMeta(changes));
}
internal void Sort(string key, bool isAscending)
{
mInnerTree.Sort(key, isAscending);
}
internal void ResolveUserNames(
MergeChangesTree.ResolveUserName resolveUserName)
{
mInnerTree.ResolveUserNames(resolveUserName);
}
MetaCache mMetaCache = new MetaCache();
MergeChangesTree mInnerTree;
class MetaCache
{
internal bool ContainsMeta(MergeChangeInfo changeInfo)
{
string key = BuildKey.ForMetaChange(changeInfo);
return mCache.ContainsKey(key);
}
internal MergeChangeInfo GetExistingMeta(MergeChangeInfo change)
{
MergeChangeInfo result;
if (!mCache.TryGetValue(BuildKey.ForMetaChange(change), out result))
return null;
return result;
}
internal List<MergeChangeInfo> GetExistingMeta(
List<MergeChangeInfo> changes)
{
List<MergeChangeInfo> result = new List<MergeChangeInfo>();
foreach (MergeChangeInfo change in changes)
{
string key = BuildKey.ForMetaChange(change);
MergeChangeInfo metaChange;
if (!mCache.TryGetValue(key, out metaChange))
continue;
result.Add(metaChange);
}
return result;
}
internal void Build(List<MergeChangesCategory> incomingChangesCategories)
{
mCache.Clear();
foreach (MergeChangesCategory category in incomingChangesCategories)
{
ExtractMetaToCache(category, mCache);
}
}
static void ExtractMetaToCache(
MergeChangesCategory category,
Dictionary<string, MergeChangeInfo> cache)
{
List<MergeChangeInfo> changes = category.GetChanges();
HashSet<string> indexedKeys = BuildIndexedKeys(
changes);
for (int i = changes.Count - 1; i >= 0; i--)
{
MergeChangeInfo currentChange = changes[i];
string path = currentChange.GetPath();
if (!MetaPath.IsMetaPath(path))
continue;
string realPath = MetaPath.GetPathFromMetaPath(path);
if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
currentChange.CategoryType, realPath)))
continue;
// found foo.c and foo.c.meta - move .meta to cache
cache.Add(BuildKey.ForChange(currentChange), currentChange);
changes.RemoveAt(i);
}
}
static HashSet<string> BuildIndexedKeys(
List<MergeChangeInfo> changes)
{
HashSet<string> result = new HashSet<string>();
foreach (MergeChangeInfo change in changes)
{
if (MetaPath.IsMetaPath(change.GetPath()))
continue;
result.Add(BuildKey.ForChange(change));
}
return result;
}
Dictionary<string, MergeChangeInfo> mCache =
new Dictionary<string, MergeChangeInfo>();
static class BuildKey
{
internal static string ForChange(
MergeChangeInfo change)
{
return BuildCacheKey(
change.CategoryType,
change.GetPath());
}
internal static string ForMetaChange(
MergeChangeInfo change)
{
return BuildCacheKey(
change.CategoryType,
MetaPath.GetMetaPath(change.GetPath()));
}
internal static string BuildCacheKey(
MergeChangesCategory.Type type,
string path)
{
return string.Concat(type, ":", path);
}
}
}
}
}

View File

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