Created unity project

This commit is contained in:
2024-12-07 20:55:50 +01:00
parent 539250d964
commit 54fe327198
13758 changed files with 865324 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,17 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.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.Merge.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,81 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class AddMoveMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal AddMoveMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffSourceDestination_Click()
{
mMergeViewMenuOperations.DiffSourceWithDestination();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
if (info.SelectedConflict.DirectoryConflict.SourceAndDestinationAreSameType())
menu.AddItem(mDiffSourceDestinationMenuItemContent, false, DiffSourceDestination_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.AddMoveConflictViewSource.GetString());
mViewDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.AddMoveConflictViewDestination.GetString());
mDiffSourceDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationAddMove.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
GUIContent mDiffSourceDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,93 @@
using UnityEditor;
using UnityEngine;
using Codice.CM.Common.Merge;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class ChangeDeleteMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal ChangeDeleteMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffSourcePrevious_Click()
{
mMergeViewMenuOperations.DiffSourceWithAncestor();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
bool isAddedDeleted = IsAddedDeleted(info.SelectedConflict.DirectoryConflict);
if (!isAddedDeleted)
menu.AddItem(mDiffSourcePreviousMenuItemContent, false, DiffSourcePrevious_Click);
mViewSourceAddedMenuItemContent.text = isAddedDeleted ?
PlasticLocalization.Name.ChangeDeleteConflictViewSourceAdded.GetString() :
PlasticLocalization.Name.ChangeDeleteConflictViewSourceChanged.GetString();
menu.AddItem(mViewSourceAddedMenuItemContent, false, ViewSource_Click);
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
}
static bool IsAddedDeleted(DirectoryConflict conflict)
{
return ((ChangeDeleteConflict)conflict).Src.Status == Difference.DiffNodeStatus.Added;
// otherwise is modified - deleted
}
void BuildComponents()
{
mDiffSourcePreviousMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationChangeDelete.GetString());
mViewSourceAddedMenuItemContent = new GUIContent();
mViewDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.ChangeDeleteConflictViewDestination.GetString());
}
GenericMenu mMenu;
GUIContent mDiffSourcePreviousMenuItemContent;
GUIContent mViewSourceAddedMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aba7053d59726d64b86f2c4f98dbb910
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
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.Merge.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,81 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class CycleMoveMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal CycleMoveMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffSourceDestination_Click()
{
mMergeViewMenuOperations.DiffSourceWithDestination();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
if (info.SelectedConflict.DirectoryConflict.SourceAndDestinationAreSameType())
menu.AddItem(mDiffSourceDestinationMenuItemContent, false, DiffSourceDestination_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.CycleMoveConflictViewSource.GetString());
mViewDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.CycleMoveConflictViewDestination.GetString());
mDiffSourceDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationCycleMove.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
GUIContent mDiffSourceDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,93 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
using Codice.CM.Common.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class DeleteChangeMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal DeleteChangeMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffDestinationPrevious_Click()
{
mMergeViewMenuOperations.DiffDestinationWithAncestor();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
bool isDeleteAdded = IsDeletedAdded(info.SelectedConflict.DirectoryConflict);
if (!isDeleteAdded)
menu.AddItem(mDiffDestinationPreviousMenuItemContent, false, DiffDestinationPrevious_Click);
menu.AddItem(mViewSourceAddedMenuItemContent, false, ViewSource_Click);
mViewDestinationMenuItemContent.text = isDeleteAdded ?
PlasticLocalization.Name.DeleteChangeConflictViewDestinationAdded.GetString() :
PlasticLocalization.Name.DeleteChangeConflictViewDestinationChanged.GetString();
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
}
static bool IsDeletedAdded(DirectoryConflict conflict)
{
return ((ChangeDeleteConflict)conflict).Dst.Status == Difference.DiffNodeStatus.Added;
// otherwise is delete - modified
}
void BuildComponents()
{
mDiffDestinationPreviousMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationDeleteChange.GetString());
mViewSourceAddedMenuItemContent = new GUIContent(
PlasticLocalization.Name.DeleteChangeConflictViewSource.GetString());
mViewDestinationMenuItemContent = new GUIContent();
}
GenericMenu mMenu;
GUIContent mDiffDestinationPreviousMenuItemContent;
GUIContent mViewSourceAddedMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,81 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class DeleteMoveMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal DeleteMoveMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffSourceDestination_Click()
{
mMergeViewMenuOperations.DiffSourceWithDestination();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
if (info.SelectedConflict.DirectoryConflict.SourceAndDestinationAreSameType())
menu.AddItem(mDiffSourceDestinationMenuItemContent, false, DiffSourceDestination_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.DeleteMoveConflictViewSource.GetString());
mViewDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.DeleteMoveConflictViewDestination.GetString());
mDiffSourceDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationDeleteMove.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
GUIContent mDiffSourceDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,55 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class DivergentMoveMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal DivergentMoveMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void UpdateMenuItems(GenericMenu menu)
{
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.DivergentMoveViewSource.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,260 @@
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.Merge.Developer.DirectoryConflicts
{
internal static class DrawDirectoryResolutionPanel
{
internal static void ForConflict(
MergeChangeInfo conflict,
int pendingConflictsCount,
DirectoryConflictUserInfo conflictUserInfo,
DirectoryConflictAction[] actions,
Action<MergeChangeInfo> resolveConflictAction,
GUIContent validationLabel,
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,
validationLabel,
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,
GUIContent validationLabel,
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))
{
validationLabel.text = validationMessage;
GUILayout.Label(
validationLabel,
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;
}
internal 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,81 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class EvilTwinMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal EvilTwinMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffSourceDestination_Click()
{
mMergeViewMenuOperations.DiffSourceWithDestination();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
if (info.SelectedConflict.DirectoryConflict.SourceAndDestinationAreSameType())
menu.AddItem(mDiffSourceDestinationMenuItemContent, false, DiffSourceDestination_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.EvilTwinsConflictViewSource.GetString());
mViewDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.EvilTwinsConflictViewDestination.GetString());
mDiffSourceDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationEvilTwin.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
GUIContent mDiffSourceDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,55 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class LoadedTwiceMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal LoadedTwiceMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void UpdateMenuItems(GenericMenu menu)
{
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.LoadedTwiceViewSource.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,190 @@
using UnityEditor;
using Codice.CM.Common.Merge;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class MergeViewDirectoryConflictMenu
{
internal interface IDirectoryConflictMenu
{
GenericMenu Menu { get; }
void Popup();
}
internal GenericMenu Menu { get { return mDirectoryConflictMenu != null ? mDirectoryConflictMenu.Menu : null; } }
internal MergeViewDirectoryConflictMenu(IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
}
internal void Popup()
{
mDirectoryConflictMenu = GetMenu();
if (mDirectoryConflictMenu == null)
return;
mDirectoryConflictMenu.Popup();
}
IDirectoryConflictMenu GetMenu()
{
DirectoryConflict conflict = mMergeViewMenuOperations.
GetSelectedMergeChangesGroupInfo().SelectedConflict.DirectoryConflict;
if (conflict is AddMoveConflict)
{
AddMoveConflict addMove = conflict as AddMoveConflict;
return addMove.IsAddMove ?
GetAddMoveMenu() :
GetMoveAddMenu();
}
if (conflict is ChangeDeleteConflict)
{
ChangeDeleteConflict changeDelete = conflict as ChangeDeleteConflict;
return changeDelete.IsChangeDelete ?
GetChangeDeletetMenu() :
GetDeleteChangeMenu();
}
if (conflict is MoveDeleteConflict)
{
MoveDeleteConflict moveDelete = conflict as MoveDeleteConflict;
return moveDelete.IsMoveDelete ?
GetMoveDeleteMenu() :
GetDeleteMoveMenu();
}
if (conflict is EvilTwinConflict)
{
EvilTwinConflict evilTwin = conflict as EvilTwinConflict;
return evilTwin.IsMovedEvilTwin ?
GetMovedEvilTwinMenu() :
GetEvilTwinMenu();
}
if (conflict is CycleMoveConflict)
return GetCycleMoveMenu();
if (conflict is DivergentMoveConflict)
return GetDivergentMoveMenu();
if (conflict is LoadedTwiceConflict)
return GetLoadedTwiceMenu();
return null;
}
IDirectoryConflictMenu GetAddMoveMenu()
{
if (mAddMoveMenu == null)
mAddMoveMenu = new AddMoveMenu(mMergeViewMenuOperations);
return mAddMoveMenu;
}
IDirectoryConflictMenu GetChangeDeletetMenu()
{
if (mChangeDeleteMenu == null)
mChangeDeleteMenu = new ChangeDeleteMenu(mMergeViewMenuOperations);
return mChangeDeleteMenu;
}
IDirectoryConflictMenu GetCycleMoveMenu()
{
if (mCycleMoveMenu == null)
mCycleMoveMenu = new CycleMoveMenu(mMergeViewMenuOperations);
return mCycleMoveMenu;
}
IDirectoryConflictMenu GetDeleteChangeMenu()
{
if (mDeleteChangeMenu == null)
mDeleteChangeMenu = new DeleteChangeMenu(mMergeViewMenuOperations);
return mDeleteChangeMenu;
}
IDirectoryConflictMenu GetDeleteMoveMenu()
{
if (mDeleteMoveMenu == null)
mDeleteMoveMenu = new DeleteMoveMenu(mMergeViewMenuOperations);
return mDeleteMoveMenu;
}
IDirectoryConflictMenu GetDivergentMoveMenu()
{
if (mDivergentMoveMenu == null)
mDivergentMoveMenu = new DivergentMoveMenu(mMergeViewMenuOperations);
return mDivergentMoveMenu;
}
IDirectoryConflictMenu GetEvilTwinMenu()
{
if (mEvilTwinMenu == null)
mEvilTwinMenu = new EvilTwinMenu(mMergeViewMenuOperations);
return mEvilTwinMenu;
}
IDirectoryConflictMenu GetLoadedTwiceMenu()
{
if (mLoadedTwiceMenu == null)
mLoadedTwiceMenu = new LoadedTwiceMenu(mMergeViewMenuOperations);
return mLoadedTwiceMenu;
}
IDirectoryConflictMenu GetMoveAddMenu()
{
if (mMoveAddMenu == null)
mMoveAddMenu = new MoveAddMenu(mMergeViewMenuOperations);
return mMoveAddMenu;
}
IDirectoryConflictMenu GetMoveDeleteMenu()
{
if (mMoveDeleteMenu == null)
mMoveDeleteMenu = new MoveDeleteMenu(mMergeViewMenuOperations);
return mMoveDeleteMenu;
}
IDirectoryConflictMenu GetMovedEvilTwinMenu()
{
if (mMovedEvilTwinMenu == null)
mMovedEvilTwinMenu = new MovedEvilTwinMenu(mMergeViewMenuOperations);
return mMovedEvilTwinMenu;
}
IDirectoryConflictMenu mDirectoryConflictMenu;
AddMoveMenu mAddMoveMenu;
ChangeDeleteMenu mChangeDeleteMenu;
CycleMoveMenu mCycleMoveMenu;
DeleteChangeMenu mDeleteChangeMenu;
DeleteMoveMenu mDeleteMoveMenu;
DivergentMoveMenu mDivergentMoveMenu;
EvilTwinMenu mEvilTwinMenu;
LoadedTwiceMenu mLoadedTwiceMenu;
MoveAddMenu mMoveAddMenu;
MoveDeleteMenu mMoveDeleteMenu;
MovedEvilTwinMenu mMovedEvilTwinMenu;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,81 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class MoveAddMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal MoveAddMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffSourceDestination_Click()
{
mMergeViewMenuOperations.DiffSourceWithDestination();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
if (info.SelectedConflict.DirectoryConflict.SourceAndDestinationAreSameType())
menu.AddItem(mDiffSourceDestinationMenuItemContent, false, DiffSourceDestination_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.MoveAddConflictViewSource.GetString());
mViewDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.MoveAddConflictViewDestination.GetString());
mDiffSourceDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationMoveAdd.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
GUIContent mDiffSourceDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,81 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class MoveDeleteMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal MoveDeleteMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffSourceDestination_Click()
{
mMergeViewMenuOperations.DiffSourceWithDestination();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
if (info.SelectedConflict.DirectoryConflict.SourceAndDestinationAreSameType())
menu.AddItem(mDiffSourceDestinationMenuItemContent, false, DiffSourceDestination_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.MoveDeleteConflictViewSource.GetString());
mViewDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.MoveDeleteConflictViewDestination.GetString());
mDiffSourceDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationMoveDelete.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
GUIContent mDiffSourceDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,81 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts
{
internal class MovedEvilTwinMenu : MergeViewDirectoryConflictMenu.IDirectoryConflictMenu
{
internal MovedEvilTwinMenu(
IMergeViewMenuOperations mergeViewMenuOperations)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
BuildComponents();
}
GenericMenu MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Menu
{
get { return mMenu; }
}
void MergeViewDirectoryConflictMenu.IDirectoryConflictMenu.Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
void ViewDestination_Click()
{
mMergeViewMenuOperations.OpenDstRevision();
}
void ViewSource_Click()
{
mMergeViewMenuOperations.OpenSrcRevision();
}
void DiffSourceDestination_Click()
{
mMergeViewMenuOperations.DiffSourceWithDestination();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
menu.AddItem(mViewSourceMenuItemContent, false, ViewSource_Click);
menu.AddItem(mViewDestinationMenuItemContent, false, ViewDestination_Click);
if (info.SelectedConflict.DirectoryConflict.SourceAndDestinationAreSameType())
menu.AddItem(mDiffSourceDestinationMenuItemContent, false, DiffSourceDestination_Click);
}
void BuildComponents()
{
mViewSourceMenuItemContent = new GUIContent(
PlasticLocalization.Name.MovedEvilConflictViewSource.GetString());
mViewDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.MovedEvilConflictViewDestination.GetString());
mDiffSourceDestinationMenuItemContent = new GUIContent(
PlasticLocalization.Name.DiffSourceWithDestinationMoveEvilTwin.GetString());
}
GenericMenu mMenu;
GUIContent mViewSourceMenuItemContent;
GUIContent mViewDestinationMenuItemContent;
GUIContent mDiffSourceDestinationMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5deddb7ed7802d41947ef9ac98ccd56
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.Merge.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.Merge.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,457 @@
using System;
using Codice.Client.Commands;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common;
using Codice.CM.Client.Differences.Merge;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer
{
internal class MergeOptionsDialog : PlasticDialog
{
internal bool MergeBothRadioToggleIsChecked { get { return mMergeBothRadioToggle; } }
internal bool MergeFromDestinationRadioToggleIsChecked { get { return mMergeFromDestinationRadioToggle; } }
internal bool MergeFromSourceRadioToggleIsChecked { get { return mMergeFromSourceRadioToggle; } }
internal bool OnlyOneRadioToggleIsChecked { get { return mOnlyOneRadioToggle; } }
internal bool ForcedRadioToggleIsChecked { get { return mForcedRadioToggle; } }
internal bool IgnoreMergeTrackingToggleIsChecked
{
get { return mIgnoreMergeTrackingToggle; }
set { mIgnoreMergeTrackingToggle = value; }
}
internal bool AutomaticAncestorRadioToggleIsChecked { get { return mAutomaticAncestorRadioToggle; } }
internal bool ManualAncestorRadioToggleIsChecked { get { return mManualAncestorRadioToggle; } }
internal string AncestorTextField { set { mAncestorTextField = value; } }
internal static bool MergeOptions(MergeDialogParameters mergeDialogParameters)
{
MergeOptionsDialog dialog = Create(
mergeDialogParameters,
new ProgressControlsForDialogs());
dialog.SetMergeOptions();
return dialog.RunModal(focusedWindow) == ResponseType.Ok;
}
internal static MergeOptionsDialog MergeOptionsForTesting(MergeDialogParameters mergeDialogParameters)
{
MergeOptionsDialog dialog = Create(
mergeDialogParameters,
new ProgressControlsForDialogs());
dialog.SetMergeOptions();
return dialog;
}
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 600, 450);
}
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.MergeOptionsTitle);
}
protected override void OnModalGUI()
{
GUILayout.Label(
PlasticLocalization.Name.MergeOptionsTitle.GetString(),
UnityStyles.Dialog.MessageTitle);
GUILayout.Label(
PlasticLocalization.Name.MergeOptionsExplanation.GetString(),
UnityStyles.Paragraph);
DrawSection(
PlasticLocalization.Name.MergeOptionsContributorsTitle.GetString(),
DoMergeContributorsArea);
DrawSection(
PlasticLocalization.Name.ConflictResolutionTitle.GetString(),
DoMergeConflictResolutionArea);
DrawSection(
PlasticLocalization.Name.MergeOptionSkipMergeTrackingTitle.GetString(),
DoSkipMergeTrackingArea);
DrawSection(
PlasticLocalization.Name.MergeOptionAdvancedTitle.GetString(),
DoAdvancedArea);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
DoButtonsArea();
mProgressControls.ForcedUpdateProgress(this);
}
void DoMergeContributorsArea()
{
if (GUILayout.Toggle(
mMergeBothRadioToggle,
PlasticLocalization.Name.MergeOptionBoth.GetString(),
UnityStyles.Dialog.RadioToggle))
{
CheckMergeBothRadioToggle();
}
GUI.enabled = mParameters.IsRegularMerge();
if (GUILayout.Toggle(
mMergeFromDestinationRadioToggle,
PlasticLocalization.Name.MergeOptionFromDestination.GetString(),
UnityStyles.Dialog.RadioToggle))
{
CheckMergeFromDestinationRadioToggle();
}
if (GUILayout.Toggle(
mMergeFromSourceRadioToggle,
PlasticLocalization.Name.MergeOptionFromSource.GetString(),
UnityStyles.Dialog.RadioToggle))
{
CheckMergeFromSourceRadioToggle();
}
GUI.enabled = true;
}
internal void CheckMergeBothRadioToggle()
{
mMergeBothRadioToggle = true;
mMergeFromDestinationRadioToggle = false;
mMergeFromSourceRadioToggle = false;
}
internal void CheckMergeFromDestinationRadioToggle()
{
mMergeBothRadioToggle = false;
mMergeFromDestinationRadioToggle = true;
mMergeFromSourceRadioToggle = false;
}
internal void CheckMergeFromSourceRadioToggle()
{
mMergeBothRadioToggle = false;
mMergeFromDestinationRadioToggle = false;
mMergeFromSourceRadioToggle = true;
}
void DoMergeConflictResolutionArea()
{
if (GUILayout.Toggle(
mOnlyOneRadioToggle,
Styles.ManualConflictResolution,
UnityStyles.Dialog.RadioToggle))
{
CheckOnlyOneRadioToggle();
}
if (GUILayout.Toggle(
mForcedRadioToggle,
Styles.AutomaticConflictResolution,
UnityStyles.Dialog.RadioToggle))
{
CheckForcedRadioToggle();
}
}
internal void CheckOnlyOneRadioToggle()
{
mOnlyOneRadioToggle = true;
mForcedRadioToggle = false;
}
internal void CheckForcedRadioToggle()
{
mOnlyOneRadioToggle = false;
mForcedRadioToggle = true;
}
void DoSkipMergeTrackingArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUI.enabled = !mParameters.IsRegularMerge();
mIgnoreMergeTrackingToggle = GUILayout.Toggle(
mIgnoreMergeTrackingToggle,
PlasticLocalization.Name.MergeOptionSkipMergeTrackingExplanation.GetString(),
UnityStyles.Dialog.CheckBox);
GUI.enabled = true;
if (GUILayout.Button(Images.GetInfoIcon(), UnityStyles.Dialog.FlatButton))
{
ShowSkipMergeTrackingHelp();
}
GUILayout.FlexibleSpace();
}
}
void ShowSkipMergeTrackingHelp()
{
GuiMessage.ShowInformation(
PlasticLocalization.GetString(
PlasticLocalization.Name.MergeOptionSkipMergeTrackingHelpTitle),
PlasticLocalization.GetString(
PlasticLocalization.Name.MergeOptionSkipMergeTrackingHelp));
}
void DoAdvancedArea()
{
GUI.enabled = mParameters.IsRegularMerge();
if (GUILayout.Toggle(
mAutomaticAncestorRadioToggle,
PlasticLocalization.Name.MergeOptionAutomaticCalculateAncestor.GetString(),
UnityStyles.Dialog.RadioToggle))
{
CheckAutomaticAncestorRadioToggle();
}
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Toggle(
mManualAncestorRadioToggle,
PlasticLocalization.Name.MergeOptionManualSpecifyAncestor.GetString(),
UnityStyles.Dialog.RadioToggle))
{
CheckManualAncestorRadioToggle();
}
GUI.enabled = mParameters.IsRegularMerge() && mManualAncestorRadioToggle;
GUILayout.Space(5);
mAncestorTextField = GUILayout.TextField(mAncestorTextField, GUILayout.Width(90));
if (mManualAncestorRadioToggle)
{
GUILayout.Label(PlasticLocalization.Name.
MergeOptionManualSpecifyAncestorExample.GetString());
}
GUILayout.FlexibleSpace();
}
GUI.enabled = true;
}
internal void CheckAutomaticAncestorRadioToggle()
{
mAutomaticAncestorRadioToggle = true;
mManualAncestorRadioToggle = false;
}
internal void CheckManualAncestorRadioToggle()
{
mAutomaticAncestorRadioToggle = false;
mManualAncestorRadioToggle = true;
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoSaveButton();
DoCancelButton();
return;
}
DoCancelButton();
DoSaveButton();
}
}
void DoSaveButton()
{
if (!AcceptButton(PlasticLocalization.Name.SaveButton.GetString()))
return;
OkButtonWithValidationAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.Name.CancelButton.GetString()))
return;
CancelButtonAction();
}
void SetMergeOptions()
{
if (mParameters.Options == null)
return;
MergeDialogOptions mergeOptions = mParameters.Options;
SetMergeContributorOptions(mergeOptions);
SetSkipMergeTrackingOptions(mergeOptions);
SetConflictResolutionOptions(mergeOptions);
SetResolutionStrategyOptions(mParameters);
}
void SetMergeContributorOptions(MergeDialogOptions mergeOptions)
{
switch (mergeOptions.Contributor)
{
case MergeContributorType.MergeContributors:
{
mMergeBothRadioToggle = true;
break;
}
case MergeContributorType.KeepDestination:
{
mMergeFromDestinationRadioToggle = true;
break;
}
case MergeContributorType.KeepSource:
{
mMergeFromSourceRadioToggle = true;
break;
}
}
}
void SetSkipMergeTrackingOptions(MergeDialogOptions mergeOptions)
{
mIgnoreMergeTrackingToggle = mergeOptions.IgnoreMergeTracking;
}
void SetConflictResolutionOptions(MergeDialogOptions mergeOptions)
{
switch (mergeOptions.ResolutionType)
{
case MergeResolutionType.OnlyOne:
{
mOnlyOneRadioToggle = true;
break;
}
default:
{
mForcedRadioToggle = true;
break;
}
}
}
void SetResolutionStrategyOptions(MergeDialogParameters parameters)
{
if (parameters.Strategy == MergeStrategy.Manual && parameters.AncestorSpec != null)
{
mManualAncestorRadioToggle = true;
mAncestorTextField = parameters.AncestorSpec.csNumber.ToString();
}
else
{
mAutomaticAncestorRadioToggle = true;
}
}
internal void OkButtonWithValidationAction()
{
mParameters.SaveParameters(
mMergeBothRadioToggle,
mMergeFromDestinationRadioToggle,
mMergeFromSourceRadioToggle,
mIgnoreMergeTrackingToggle,
mOnlyOneRadioToggle,
mAutomaticAncestorRadioToggle);
if (mParameters.Strategy != MergeStrategy.Manual)
{
OkButtonAction();
return;
}
MergeDialogValidation.AsyncValidation(
mParameters,
mAncestorTextField,
this,
mProgressControls);
}
static void DrawSection(string title, Action drawContent)
{
EditorGUILayout.Space(10);
GUILayout.Label(
title,
UnityStyles.Dialog.SectionTitle);
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.Space(15);
using (new EditorGUILayout.VerticalScope())
{
drawContent();
}
GUILayout.FlexibleSpace();
}
}
static MergeOptionsDialog Create(
MergeDialogParameters parameters,
ProgressControlsForDialogs progressControls)
{
var instance = CreateInstance<MergeOptionsDialog>();
instance.mParameters = parameters;
instance.mProgressControls = progressControls;
instance.mEscapeKeyAction = instance.CancelButtonAction;
return instance;
}
class Styles
{
internal static GUIContent ManualConflictResolution =
new GUIContent(PlasticLocalization.GetString(
PlasticLocalization.Name.ManualConflictResolution),
PlasticLocalization.GetString(
PlasticLocalization.Name.ManualConflictResolutionTooltip));
internal static GUIContent AutomaticConflictResolution =
new GUIContent(PlasticLocalization.GetString(
PlasticLocalization.Name.AutomaticConflictResolution),
PlasticLocalization.GetString(
PlasticLocalization.Name.AutomaticConflictResolutionTooltip));
}
bool mMergeBothRadioToggle;
bool mMergeFromDestinationRadioToggle;
bool mMergeFromSourceRadioToggle;
bool mOnlyOneRadioToggle;
bool mForcedRadioToggle;
bool mIgnoreMergeTrackingToggle;
bool mAutomaticAncestorRadioToggle;
bool mManualAncestorRadioToggle;
string mAncestorTextField;
ProgressControlsForDialogs mProgressControls;
MergeDialogParameters mParameters;
}
}

View File

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

View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer
{
internal static class MergeSelection
{
internal static List<string> GetPathsFromSelectedFileConflictsIncludingMeta(
MergeTreeView treeView)
{
List<string> result = new List<string>();
List<MergeChangeInfo> selection =
treeView.GetSelectedFileConflicts();
treeView.FillWithMeta(selection);
foreach (MergeChangeInfo mergeChange in selection)
{
result.Add(mergeChange.GetPath());
}
return result;
}
internal static SelectedMergeChangesGroupInfo GetSelectedGroupInfo(
MergeTreeView treeView, bool isIncomingMerge)
{
List<MergeChangeInfo> selectedMergeChanges =
treeView.GetSelectedMergeChanges();
return GetSelectedMergeChangesGroupInfo.For(
selectedMergeChanges, isIncomingMerge);
}
internal static MergeChangeInfo GetSingleSelectedMergeChange(
MergeTreeView treeView)
{
return treeView.GetSelectedMergeChange();
}
}
}

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,11 @@
fileFormatVersion: 2
guid: 4f04b21b06239da4f95a5a9753647440
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,177 @@
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.Merge.Developer
{
internal enum MergeTreeColumn
{
Path,
Size,
Author,
Details,
Resolution,
DateModified,
Comment
}
[Serializable]
internal class MergeTreeHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static MergeTreeHeaderState GetDefault()
{
MergeTreeHeaderState headerState =
new MergeTreeHeaderState(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(MergeTreeColumn column)
{
switch (column)
{
case MergeTreeColumn.Path:
return PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn);
case MergeTreeColumn.Size:
return PlasticLocalization.GetString(PlasticLocalization.Name.SizeColumn);
case MergeTreeColumn.Author:
return PlasticLocalization.GetString(PlasticLocalization.Name.AuthorColumn);
case MergeTreeColumn.Details:
return PlasticLocalization.GetString(PlasticLocalization.Name.DetailsColumn);
case MergeTreeColumn.Resolution:
return PlasticLocalization.GetString(PlasticLocalization.Name.ResolutionMethodColumn);
case MergeTreeColumn.DateModified:
return PlasticLocalization.GetString(PlasticLocalization.Name.DateModifiedColumn);
case MergeTreeColumn.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)MergeTreeColumn.Path);
result.Add((int)MergeTreeColumn.Size);
result.Add((int)MergeTreeColumn.Author);
result.Add((int)MergeTreeColumn.Resolution);
result.Add((int)MergeTreeColumn.DateModified);
result.Add((int)MergeTreeColumn.Comment);
return result.ToArray();
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 450,
headerContent = new GUIContent(
GetColumnName(MergeTreeColumn.Path)),
minWidth = 200,
allowToggleVisibility = false,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 150,
headerContent = new GUIContent(
GetColumnName(MergeTreeColumn.Size)),
minWidth = 45,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 150,
headerContent = new GUIContent(
GetColumnName(MergeTreeColumn.Author)),
minWidth = 80,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 200,
headerContent = new GUIContent(
GetColumnName(MergeTreeColumn.Details)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 250,
headerContent = new GUIContent(
GetColumnName(MergeTreeColumn.Resolution)),
minWidth = 120,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 330,
headerContent = new GUIContent(
GetColumnName(MergeTreeColumn.DateModified)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 400,
headerContent = new GUIContent(
GetColumnName(MergeTreeColumn.Comment)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
}
};
}
MergeTreeHeaderState(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,627 @@
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;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
using UnityEditor;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer
{
internal class MergeTreeView : TreeView
{
internal GenericMenu Menu { get { return mMenu.Menu; } }
internal MergeTreeView(
WorkspaceInfo wkInfo,
MergeTreeHeaderState headerState,
List<string> columnNames,
MergeViewMenu 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;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
}
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(
mMergeTree,
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();
}
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 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,
mMergeTree.GetMetaChange(changeInfo),
mSolvedFileConflicts);
bool isSolvedConflict = IsSolved.Conflict(
changeInfo,
mMergeTree.GetMetaChange(changeInfo),
mSolvedFileConflicts);
MergeTreeViewItemGUI(
mWkInfo.ClientPath,
mMergeTree,
this,
changeTreeViewItem,
args,
isCurrentConflict,
isSolvedConflict);
return;
}
base.RowGUI(args);
}
internal void SelectFirstUnsolvedDirectoryConflict()
{
foreach (MergeChangesCategory category in mMergeTree.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(UnityMergeTree tree)
{
mTreeViewItemIds.Clear();
mMergeTree = tree;
mSolvedFileConflicts = null;
mExpandCategories = true;
}
internal void Refilter()
{
Filter filter = new Filter(searchString);
mMergeTree.Filter(filter, mColumnNames);
mExpandCategories = true;
}
internal void Sort()
{
if (mMergeTree == null)
return;
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mMergeTree.Sort(mColumnNames[sortedColumnIdx], sortAscending);
}
internal void UpdateSolvedFileConflicts(
MergeSolvedFileConflicts solvedFileConflicts)
{
mSolvedFileConflicts = solvedFileConflicts;
}
internal MergeChangeInfo GetMetaChange(MergeChangeInfo change)
{
if (change == null)
return null;
return mMergeTree.GetMetaChange(change);
}
internal void FillWithMeta(List<MergeChangeInfo> changes)
{
mMergeTree.FillWithMeta(changes);
}
internal bool SelectionHasMeta()
{
MergeChangeInfo selectedChangeInfo = GetSelectedMergeChange();
if (selectedChangeInfo == null)
return false;
return mMergeTree.HasMeta(selectedChangeInfo);
}
internal MergeChangeInfo GetSelectedMergeChange()
{
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> GetSelectedMergeChanges()
{
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 DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
UnityMergeTree mergeTree,
TreeViewItemIds<MergeChangesCategory, MergeChangeInfo> treeViewItemIds,
MergeTreeView treeView,
TreeViewItem rootItem,
List<TreeViewItem> rows,
bool expandCategories)
{
if (mergeTree == null)
return;
ClearRows(rootItem, rows);
List<MergeChangesCategory> categories = mergeTree.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 MergeTreeViewItemGUI(
string wkPath,
UnityMergeTree mergeTree,
MergeTreeView treeView,
ChangeTreeViewItem item,
RowGUIArgs args,
bool isCurrentConflict,
bool isSolvedConflict)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
MergeTreeColumn column =
(MergeTreeColumn)args.GetColumn(visibleColumnIdx);
MergeTreeViewItemCellGUI(
wkPath,
cellRect,
treeView.rowHeight,
mergeTree,
treeView,
item,
column,
args.selected,
args.focused,
isCurrentConflict,
isSolvedConflict);
}
}
static void MergeTreeViewItemCellGUI(
string wkPath,
Rect rect,
float rowHeight,
UnityMergeTree mergeTree,
MergeTreeView treeView,
ChangeTreeViewItem item,
MergeTreeColumn column,
bool isSelected,
bool isFocused,
bool isCurrentConflict,
bool isSolvedConflict)
{
MergeChangeInfo mergeChange = item.ChangeInfo;
string label = mergeChange.GetColumnText(
MergeTreeHeaderState.GetColumnName(column));
if (column == MergeTreeColumn.Path)
{
if (mergeTree.HasMeta(item.ChangeInfo))
label = string.Concat(label, UnityConstants.TREEVIEW_META_LABEL);
Texture icon = GetIcon(wkPath, mergeChange);
Texture overlayIcon =
GetChangesOverlayIcon.ForPlasticMergeChange(
mergeChange, isSolvedConflict);
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
item.depth,
icon,
overlayIcon,
label,
isSelected,
isFocused,
isCurrentConflict,
false);
return;
}
if (column == MergeTreeColumn.Size)
{
// If there is a meta file, add the meta file to the file size so that it is consistent
// with the Merge overview
if (mergeTree.HasMeta(item.ChangeInfo))
{
MergeChangeInfo metaFileInfo = mergeTree.GetMetaChange(mergeChange);
long metaFileSize = metaFileInfo.GetSize();
long fileSize = mergeChange.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 mergeChange)
{
RevisionInfo revInfo = mergeChange.GetRevision();
bool isDirectory = revInfo.
Type == EnumRevisionType.enDirectory;
if (isDirectory || mergeChange.IsXLink())
return Images.GetDirectoryIcon();
string fullPath = WorkspacePath.GetWorkspacePathFromCmPath(
wkPath,
mergeChange.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(
MergeTreeView 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;
UnityMergeTree mMergeTree;
CooldownWindowDelayer mCooldownFilterAction;
readonly MergeViewMenu 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,493 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer
{
internal class MergeViewFileConflictMenu
{
internal interface IMetaMenuOperations
{
void DiffSourceWithAncestor();
void DiffDestinationWithAncestor();
void DiffSourceWithDestination();
void ShowHistory();
bool SelectionHasMeta();
}
internal GenericMenu Menu { get { return mMenu; } }
internal MergeViewFileConflictMenu(
IMergeViewMenuOperations mergeViewMenuOperations,
IMetaMenuOperations mergeMetaMenuOperations,
bool isIncomingMerge,
bool isMergeTo)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
mMergeMetaMenuOperations = mergeMetaMenuOperations;
BuildComponents(isIncomingMerge, isMergeTo);
}
internal void Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
MergeMenuOperations operationToExecute = GetMenuOperations(e);
if (operationToExecute == MergeMenuOperations.None)
return false;
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
MergeMenuOperations operations =
UpdateMergeMenu.GetAvailableMenuOperations(info);
if (!operations.HasFlag(operationToExecute))
return false;
ProcessMenuOperation(operationToExecute, mMergeViewMenuOperations);
return true;
}
void MergeSelectedFilesMenuItem_Click()
{
mMergeViewMenuOperations.MergeContributors();
}
void MergeKeepingSourceChangesMenuItem_Click()
{
mMergeViewMenuOperations.MergeKeepingSourceChanges();
}
void MergeKeepingWorkspaceChangesMenuItem_Click()
{
mMergeViewMenuOperations.MergeKeepingWorkspaceChanges();
}
void DiffSourceWithDestinationMenuItem_Click()
{
mMergeViewMenuOperations.DiffSourceWithDestination();
}
void DiffDestinationWithAncestorMenuItem_Click()
{
mMergeViewMenuOperations.DiffDestinationWithAncestor();
}
void DiffSourceWithAncestorMenuItem_Click()
{
mMergeViewMenuOperations.DiffSourceWithAncestor();
}
void DiffMetaSourceWithDestinationMenuItem_Click()
{
mMergeMetaMenuOperations.DiffSourceWithDestination();
}
void DiffMetaDestinationWithAncestorMenuItem_Click()
{
mMergeMetaMenuOperations.DiffDestinationWithAncestor();
}
void DiffMetaSourceWithAncestorMenuItem_Click()
{
mMergeMetaMenuOperations.DiffSourceWithAncestor();
}
void HistoryMetaMenuItem_Click()
{
mMergeMetaMenuOperations.ShowHistory();
}
void CopyFilePathMenuItem_Click()
{
mMergeViewMenuOperations.CopyFilePath(relativePath: false);
}
void CopyRelativeFilePathMenuItem_Click()
{
mMergeViewMenuOperations.CopyFilePath(relativePath: true);
}
void HistoryMenuItem_Click()
{
mMergeViewMenuOperations.ShowHistory();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedMergeChangesGroupInfo info =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
MergeMenuOperations operations =
UpdateMergeMenu.GetAvailableMenuOperations(info);
if (operations == MergeMenuOperations.None)
{
menu.AddDisabledItem(GetNoActionMenuItemContent());
return;
}
AddMergeActions(menu, operations);
menu.AddSeparator(string.Empty);
AddDiffActions(menu, info, operations);
if (mMergeMetaMenuOperations.SelectionHasMeta())
{
menu.AddSeparator(string.Empty);
AddMetaActions(menu, info, operations);
}
menu.AddSeparator(string.Empty);
AddCopyFilePathActions(menu, operations);
menu.AddSeparator(string.Empty);
AddHistoryMenuItem(mHistoryMenuItemContent, menu, operations, HistoryMenuItem_Click);
}
void AddMergeActions(
GenericMenu menu,
MergeMenuOperations operations)
{
AddMergeSelectedFilesMenuItem(
mMergeSelectedFilesMenuItemContent, menu, operations, MergeSelectedFilesMenuItem_Click);
AddMergeKeepingSourceChangesMenuItem(
mMergeKeepingSourceChangesMenuItemContent, menu, operations, MergeKeepingSourceChangesMenuItem_Click);
AddMergeKeepingWorkspaceChangesMenuItem(
mMergeKeepingWorkspaceChangesMenuItemContent, menu, operations, MergeKeepingWorkspaceChangesMenuItem_Click);
}
void AddDiffActions(
GenericMenu menu,
SelectedMergeChangesGroupInfo info,
MergeMenuOperations operations)
{
mDiffSourceWithDestinationMenuItemContent.text =
UnityMenuItem.EscapedText(info.DiffSourceWithDestinationMenuItemText);
AddDiffSourceWithDestinationMenuItem(
mDiffSourceWithDestinationMenuItemContent, menu, operations, DiffSourceWithDestinationMenuItem_Click);
AddDiffDestinationWithAncestorMenuItem(
mDiffDestinationWithAncestorMenuItemContent, menu, operations, DiffDestinationWithAncestorMenuItem_Click);
AddDiffSourceWithAncestorMenuItem(
mDiffSourceWithAncestorMenuItem, menu, operations, DiffSourceWithAncestorMenuItem_Click);
}
void AddMetaActions(
GenericMenu menu,
SelectedMergeChangesGroupInfo info,
MergeMenuOperations operations)
{
mDiffMetaSourceWithDestinationMenuItemContent.text = string.Format(
"{0}/{1}",
MetaPath.META_EXTENSION,
UnityMenuItem.EscapedText(info.DiffSourceWithDestinationMenuItemText));
AddDiffSourceWithDestinationMenuItem(
mDiffMetaSourceWithDestinationMenuItemContent, menu, operations, DiffMetaSourceWithDestinationMenuItem_Click);
AddDiffDestinationWithAncestorMenuItem(
mDiffMetaDestinationWithAncestorMenuItemContent, menu, operations, DiffMetaDestinationWithAncestorMenuItem_Click);
AddDiffSourceWithAncestorMenuItem(
mDiffMetaSourceWithAncestorMenuItemContent, menu, operations, DiffMetaSourceWithAncestorMenuItem_Click);
AddHistoryMenuItem(
mHistoryMetaMenuItemContent, menu, operations, HistoryMetaMenuItem_Click);
}
void AddCopyFilePathActions(
GenericMenu menu,
MergeMenuOperations operations)
{
AddCopyFilePathMenuItem(
mCopyFilePathMenuItemContent, menu, operations, CopyFilePathMenuItem_Click);
AddCopyFilePathMenuItem(
mCopyRelativeFilePathMenuItemContent, menu, operations, CopyRelativeFilePathMenuItem_Click);
}
GUIContent GetNoActionMenuItemContent()
{
if (mNoActionMenuItemContent == null)
{
mNoActionMenuItemContent = new GUIContent(
PlasticLocalization.GetString(
PlasticLocalization.Name.NoActionMenuItem));
}
return mNoActionMenuItemContent;
}
static void AddMergeSelectedFilesMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
MergeMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(MergeMenuOperations.MergeContributors))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddMergeKeepingSourceChangesMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
MergeMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(MergeMenuOperations.MergeKeepingSourceChanges))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddMergeKeepingWorkspaceChangesMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
MergeMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(MergeMenuOperations.MergeKeepingWorkspaceChanges))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddDiffSourceWithDestinationMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
MergeMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(MergeMenuOperations.DiffSourceWithDestination))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddDiffDestinationWithAncestorMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
MergeMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (!operations.HasFlag(MergeMenuOperations.DiffDestinationWithAncestor))
return;
menu.AddItem(
menuItemContent,
false,
menuFunction);
}
static void AddDiffSourceWithAncestorMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
MergeMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(MergeMenuOperations.DiffSourceWithAncestor))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddCopyFilePathMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
MergeMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(MergeMenuOperations.CopyFilePath))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddHistoryMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
MergeMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(MergeMenuOperations.ShowHistory))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static MergeMenuOperations GetMenuOperations(Event e)
{
if (Keyboard.IsControlOrCommandKeyPressed(e) &&
Keyboard.IsKeyPressed(e, KeyCode.H))
return MergeMenuOperations.ShowHistory;
return MergeMenuOperations.None;
}
static void ProcessMenuOperation(
MergeMenuOperations operationToExecute,
IMergeViewMenuOperations mergeViewMenuOperations)
{
if (operationToExecute == MergeMenuOperations.ShowHistory)
{
mergeViewMenuOperations.ShowHistory();
return;
}
}
void BuildComponents(
bool isIncomingMerge,
bool isMergeTo)
{
mMergeSelectedFilesMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.
Name.MergeSelectedFiles));
mMergeKeepingSourceChangesMenuItemContent = new GUIContent(
UnityMenuItem.EscapedText(
MergeViewTexts.GetMergeKeepingSourceChangesMenuItemText(
isIncomingMerge, isMergeTo)));
mMergeKeepingWorkspaceChangesMenuItemContent = new GUIContent(
UnityMenuItem.EscapedText(
MergeViewTexts.GetMergeKeepingWorkspaceChangesMenuItemText(
isIncomingMerge, isMergeTo)));
string diffSourceWithAncestorText = UnityMenuItem.EscapedText(
MergeViewTexts.GetDiffSourceWithAncestorMenuItemText(isIncomingMerge));
mDiffSourceWithDestinationMenuItemContent = new GUIContent(string.Empty);
mDiffDestinationWithAncestorMenuItemContent = new GUIContent(
UnityMenuItem.EscapedText(
PlasticLocalization.GetString(
PlasticLocalization.Name.DiffDestinationWithAncestor)));
mDiffSourceWithAncestorMenuItem = new GUIContent(
diffSourceWithAncestorText);
mDiffMetaSourceWithDestinationMenuItemContent = new GUIContent(string.Empty);
mDiffMetaDestinationWithAncestorMenuItemContent = new GUIContent(
string.Format(
"{0}/{1}",
MetaPath.META_EXTENSION,
UnityMenuItem.EscapedText(
PlasticLocalization.GetString(
PlasticLocalization.Name.DiffDestinationWithAncestor))));
mDiffMetaSourceWithAncestorMenuItemContent = new GUIContent(
string.Format(
"{0}/{1}",
MetaPath.META_EXTENSION,
diffSourceWithAncestorText));
mHistoryMetaMenuItemContent = new GUIContent(
string.Format(
"{0}/{1}",
MetaPath.META_EXTENSION,
PlasticLocalization.Name.ItemsMenuItemHistory.GetString()));
mCopyFilePathMenuItemContent = new GUIContent(PlasticLocalization.Name.CopyFilePathMenuItem.GetString());
mCopyRelativeFilePathMenuItemContent =
new GUIContent(PlasticLocalization.Name.CopyRelativeFilePathMenuItem.GetString());
mHistoryMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.Name.ItemsMenuItemHistory.GetString(),
GetPlasticShortcut.ForHistory()));
}
GenericMenu mMenu;
GUIContent mNoActionMenuItemContent;
GUIContent mMergeSelectedFilesMenuItemContent;
GUIContent mMergeKeepingSourceChangesMenuItemContent;
GUIContent mMergeKeepingWorkspaceChangesMenuItemContent;
GUIContent mDiffSourceWithDestinationMenuItemContent;
GUIContent mDiffDestinationWithAncestorMenuItemContent;
GUIContent mDiffSourceWithAncestorMenuItem;
GUIContent mDiffMetaSourceWithDestinationMenuItemContent;
GUIContent mDiffMetaDestinationWithAncestorMenuItemContent;
GUIContent mDiffMetaSourceWithAncestorMenuItemContent;
GUIContent mHistoryMetaMenuItemContent;
GUIContent mCopyFilePathMenuItemContent;
GUIContent mCopyRelativeFilePathMenuItemContent;
GUIContent mHistoryMenuItemContent;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
readonly IMetaMenuOperations mMergeMetaMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,101 @@
using UnityEditor;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.Views.Merge.Developer.DirectoryConflicts;
using UnityEngine;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer
{
internal class MergeViewMenu
{
internal GenericMenu Menu
{
get
{
return mMergeViewFileConflictMenu != null ?
mMergeViewFileConflictMenu.Menu : mMergeViewDirectoryConflictMenu != null ?
mMergeViewDirectoryConflictMenu.Menu : null;
}
}
internal MergeViewMenu(
IMergeViewMenuOperations mergeViewMenuOperations,
MergeViewFileConflictMenu.IMetaMenuOperations mergeMetaMenuOperations,
bool isIncomingMerge,
bool isMergeTo)
{
mMergeViewMenuOperations = mergeViewMenuOperations;
mMergeMetaMenuOperations = mergeMetaMenuOperations;
mIsIncomingMerge = isIncomingMerge;
mIsMergeTo = isMergeTo;
}
internal void Popup()
{
SelectedMergeChangesGroupInfo selectedGroupInfo =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
if (selectedGroupInfo.SelectedConflict == null)
return;
if (selectedGroupInfo.IsDirectoryConflictsSelection)
{
GetMergeViewDirectoryConflictMenu().Popup();
return;
}
GetMergeViewFileConflictMenu().Popup();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
SelectedMergeChangesGroupInfo selectedGroupInfo =
mMergeViewMenuOperations.GetSelectedMergeChangesGroupInfo();
if (selectedGroupInfo.SelectedConflict == null)
return false;
if (selectedGroupInfo.IsDirectoryConflictsSelection)
return false;
if (mMergeViewFileConflictMenu == null)
return false;
return mMergeViewFileConflictMenu.ProcessKeyActionIfNeeded(e);
}
MergeViewFileConflictMenu GetMergeViewFileConflictMenu()
{
if (mMergeViewFileConflictMenu == null)
{
mMergeViewFileConflictMenu =
new MergeViewFileConflictMenu(
mMergeViewMenuOperations,
mMergeMetaMenuOperations,
mIsIncomingMerge,
mIsMergeTo);
}
return mMergeViewFileConflictMenu;
}
MergeViewDirectoryConflictMenu GetMergeViewDirectoryConflictMenu()
{
if (mMergeViewDirectoryConflictMenu == null)
{
mMergeViewDirectoryConflictMenu =
new MergeViewDirectoryConflictMenu(mMergeViewMenuOperations);
}
return mMergeViewDirectoryConflictMenu;
}
MergeViewFileConflictMenu mMergeViewFileConflictMenu;
MergeViewDirectoryConflictMenu mMergeViewDirectoryConflictMenu;
readonly IMergeViewMenuOperations mMergeViewMenuOperations;
readonly MergeViewFileConflictMenu.IMetaMenuOperations mMergeMetaMenuOperations;
readonly bool mIsIncomingMerge;
readonly bool mIsMergeTo;
}
}

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,188 @@
using System.Collections.Generic;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer
{
internal class UnityMergeTree
{
internal static UnityMergeTree BuildMergeCategories(
MergeChangesTree tree)
{
return new UnityMergeTree(tree);
}
UnityMergeTree(
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 Filter(Filter filter, List<string> columnNames)
{
mInnerTree.Filter(filter, columnNames);
}
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> mergeChangesCategories)
{
mCache.Clear();
foreach (MergeChangesCategory category in mergeChangesCategories)
{
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:

View File

@@ -0,0 +1,89 @@
using UnityEditor;
using UnityEngine;
using Codice.Client.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.Merge
{
internal static class DrawMergeOverview
{
internal static void For(
int directoryConflictCount,
int fileConflictCount,
MergeViewTexts.ChangesToApplySummary changesSummary)
{
DrawItem(
Images.GetConflictedIcon(),
PlasticLocalization.Name.DirectoryConflictsTitleSingular,
PlasticLocalization.Name.DirectoryConflictsTitlePlural,
directoryConflictCount,
0,
false);
DrawItem(
Images.GetConflictedIcon(),
PlasticLocalization.Name.FileConflictsTitleSingular,
PlasticLocalization.Name.FileConflictsTitlePlural,
fileConflictCount,
0,
false);
DrawItem(
Images.GetOutOfSyncIcon(),
PlasticLocalization.Name.MergeChangesMadeInSourceOfMergeOverviewSingular,
PlasticLocalization.Name.MergeChangesMadeInSourceOfMergeOverviewPlural,
changesSummary.FilesToModify,
changesSummary.SizeToModify,
true);
DrawItem(
Images.GetAddedLocalIcon(),
PlasticLocalization.Name.MergeNewItemsToDownloadOverviewSingular,
PlasticLocalization.Name.MergeNewItemsToDownloadOverviewPlural,
changesSummary.FilesToAdd,
changesSummary.SizeToAdd,
true);
DrawItem(
Images.GetDeletedRemoteIcon(),
PlasticLocalization.Name.MergeDeletesToApplyOverviewSingular,
PlasticLocalization.Name.MergeDeletesToApplyOverviewPlural,
changesSummary.FilesToDelete,
changesSummary.SizeToDelete,
true);
}
static void DrawItem(
Texture2D icon,
PlasticLocalization.Name singularLabel,
PlasticLocalization.Name pluralLabel,
int count,
long size,
bool showSize)
{
if (count == 0)
return;
EditorGUILayout.BeginHorizontal();
GUIContent iconContent = new GUIContent(icon);
GUILayout.Label(iconContent, GUILayout.Width(20f), GUILayout.Height(20f));
string label = PlasticLocalization.GetString(count > 1 ? pluralLabel : singularLabel);
if (showSize)
label = string.Format(label, count, SizeConverter.ConvertToSizeString(size));
else
label = string.Format(label, count);
GUIContent content = new GUIContent(label);
GUILayout.Label(content, UnityStyles.MergeTab.ChangesToApplySummaryLabel);
GUILayout.Space(5);
EditorGUILayout.EndHorizontal();
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,17 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui.Gluon.WorkspaceWindow.Views.IncomingChanges;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon
{
internal class ChangeCategoryTreeViewItem : TreeViewItem
{
internal IncomingChangeCategory Category { get; private set; }
internal ChangeCategoryTreeViewItem(int id, IncomingChangeCategory category)
: base(id, 0)
{
Category = category;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: faf2afd8696f4604f82f46b06b357f06
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.Gluon.WorkspaceWindow.Views.IncomingChanges;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon
{
internal class ChangeTreeViewItem : TreeViewItem
{
internal IncomingChangeInfo ChangeInfo { get; private set; }
internal ChangeTreeViewItem(int id, IncomingChangeInfo change)
: base(id, 1)
{
ChangeInfo = change;
displayName = change.GetPathString();
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,19 @@
using UnityEditor.IMGUI.Controls;
using Codice.CM.Common;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon.Errors
{
internal class ErrorListViewItem : TreeViewItem
{
internal ErrorMessage ErrorMessage { get; private set; }
internal ErrorListViewItem(int id, ErrorMessage errorMessage)
: base(id, 0)
{
ErrorMessage = errorMessage;
displayName = errorMessage.Path;
}
}
}

View File

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

View File

@@ -0,0 +1,93 @@
using System;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon.Errors
{
internal enum ErrorsListColumn
{
Path,
Reason
}
[Serializable]
internal class ErrorsListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static ErrorsListHeaderState GetDefault()
{
return new ErrorsListHeaderState(BuildColumns());
}
static string GetColumnName(ErrorsListColumn column)
{
switch (column)
{
case ErrorsListColumn.Path:
return PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn);
case ErrorsListColumn.Reason:
return PlasticLocalization.GetString(PlasticLocalization.Name.Reason);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
if (mColumsAllowedToggleVisibility != null)
TreeHeaderColumns.SetVisibilities(columns, mColumsAllowedToggleVisibility);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 300,
headerContent = new GUIContent(
GetColumnName(ErrorsListColumn.Path)),
minWidth = 200,
allowToggleVisibility = false,
canSort = false,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 600,
headerContent = new GUIContent(
GetColumnName(ErrorsListColumn.Reason)),
minWidth = 200,
canSort = false,
sortingArrowAlignment = TextAlignment.Right
}
};
}
ErrorsListHeaderState(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: 8c069d7fb0d30cf499458f0d9c9fe035
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,180 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.IMGUI.Controls;
using Codice.Client.BaseCommands;
using Codice.CM.Common;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon.Errors
{
internal class ErrorsListView : TreeView
{
internal ErrorsListView(ErrorsListHeaderState headerState)
: base(new TreeViewState())
{
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = false;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = true;
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem rootItem)
{
RegenerateRows(
this, mErrorMessages, rootItem, mRows);
return mRows;
}
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 ErrorListViewItem)
{
ErrorListViewItemGUI((ErrorListViewItem)args.item, args);
return;
}
base.RowGUI(args);
}
internal void BuildModel(List<ErrorMessage> errorMessages)
{
mErrorMessages = errorMessages;
}
internal ErrorMessage GetSelectedError()
{
List<ErrorMessage> selectedErrors = GetSelectedErrors(this);
if (selectedErrors.Count != 1)
return null;
return selectedErrors[0];
}
static List<ErrorMessage> GetSelectedErrors(
ErrorsListView listView)
{
List<ErrorMessage> result = new List<ErrorMessage>();
IList<int> selectedIds = listView.GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (ErrorListViewItem treeViewItem in
listView.FindRows(selectedIds))
{
result.Add(treeViewItem.ErrorMessage);
}
return result;
}
static void RegenerateRows(
ErrorsListView listView,
List<ErrorMessage> errorMessages,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (errorMessages.Count == 0)
return;
for (int i = 0; i < errorMessages.Count; i++)
{
ErrorListViewItem errorListViewItem =
new ErrorListViewItem(i + 1, errorMessages[i]);
rootItem.AddChild(errorListViewItem);
rows.Add(errorListViewItem);
}
listView.SetSelection(new List<int> { 1 });
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void ErrorListViewItemGUI(
ErrorListViewItem item,
RowGUIArgs args)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
ErrorsListColumn column =
(ErrorsListColumn)args.GetColumn(visibleColumnIdx);
ErrorListViewItemCellGUI(
cellRect, item, column, args.selected, args.focused);
}
}
static void ErrorListViewItemCellGUI(
Rect rect,
ErrorListViewItem item,
ErrorsListColumn column,
bool isSelected,
bool isFocused)
{
ErrorMessage errorMessage = item.ErrorMessage;
string label = column == ErrorsListColumn.Path ?
errorMessage.Path : errorMessage.Error;
if (column == ErrorsListColumn.Path)
{
DrawTreeViewItem.ForLabel(
rect, label, isSelected, isFocused, false);
return;
}
DrawTreeViewItem.ForSecondaryLabel(
rect, label, isSelected, isFocused, false);
}
List<TreeViewItem> mRows = new List<TreeViewItem>();
List<ErrorMessage> mErrorMessages = new List<ErrorMessage>();
}
}

View File

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

View File

@@ -0,0 +1,33 @@
using System.Collections.Generic;
using PlasticGui.Gluon.WorkspaceWindow.Views.IncomingChanges;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon
{
internal static class IncomingChangesSelection
{
internal static SelectedIncomingChangesGroupInfo GetSelectedGroupInfo(
IncomingChangesTreeView treeView)
{
List<IncomingChangeInfo> selectedIncomingChanges =
treeView.GetSelectedIncomingChanges();
return GetSelectedIncomingChangesGroupInfo.For(
selectedIncomingChanges);
}
internal static List<IncomingChangeInfo> GetSelectedFileConflictsIncludingMeta(
IncomingChangesTreeView treeView)
{
List<IncomingChangeInfo> result = treeView.GetSelectedFileConflicts();
treeView.FillWithMeta(result);
return result;
}
internal static IncomingChangeInfo GetSingleSelectedIncomingChange(
IncomingChangesTreeView treeView)
{
return treeView.GetSelectedIncomingChange();
}
}
}

View File

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

View File

@@ -0,0 +1,816 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using Codice.Client.BaseCommands;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.Client.Common.FsNodeReaders;
using Codice.CM.Common;
using GluonGui;
using PlasticGui;
using PlasticGui.Gluon.WorkspaceWindow;
using PlasticGui.Gluon.WorkspaceWindow.Views.IncomingChanges;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.Diff;
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.StatusBar;
using Unity.PlasticSCM.Editor.UI.Tree;
using Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon.Errors;
using Unity.PlasticSCM.Editor.Views.Merge;
using UnityEditor.IMGUI.Controls;
using CheckIncomingChanges = PlasticGui.Gluon.WorkspaceWindow.CheckIncomingChanges;
using NewIncomingChangesUpdater = PlasticGui.Gluon.WorkspaceWindow.NewIncomingChangesUpdater;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon
{
internal class IncomingChangesTab :
IIncomingChangesTab,
IRefreshableView,
IncomingChangesViewLogic.IIncomingChangesView,
IIncomingChangesViewMenuOperations,
IncomingChangesViewMenu.IMetaMenuOperations
{
internal IncomingChangesTab(
WorkspaceInfo wkInfo,
ViewHost viewHost,
WorkspaceWindow workspaceWindow,
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
NewIncomingChangesUpdater newIncomingChangesUpdater,
CheckIncomingChanges.IUpdateIncomingChanges updateIncomingChanges,
StatusBar statusBar,
EditorWindow parentWindow)
{
mWkInfo = wkInfo;
mShowDownloadPlasticExeWindow = showDownloadPlasticExeWindow;
mNewIncomingChangesUpdater = newIncomingChangesUpdater;
mParentWindow = parentWindow;
mStatusBar = statusBar;
BuildComponents();
mProgressControls = new ProgressControlsForViews();
mCooldownClearUpdateSuccessAction = new CooldownWindowDelayer(
DelayedClearUpdateSuccess,
UnityConstants.NOTIFICATION_CLEAR_INTERVAL);
mErrorsSplitterState = PlasticSplitterGUILayout.InitSplitterState(
new float[] { 0.75f, 0.25f },
new int[] { 100, 100 },
new int[] { 100000, 100000 }
);
mErrorDetailsSplitterState = PlasticSplitterGUILayout.InitSplitterState(
new float[] { 0.60f, 0.40f },
new int[] { 100, 100 },
new int[] { 100000, 100000 }
);
mIncomingChangesViewLogic = new IncomingChangesViewLogic(
wkInfo, viewHost, this, new UnityPlasticGuiMessage(),
mProgressControls, updateIncomingChanges,
workspaceWindow.GluonProgressOperationHandler, workspaceWindow,
new IncomingChangesViewLogic.ApplyGluonWorkspaceLocalChanges(),
new IncomingChangesViewLogic.OutOfDateItemsOperations(),
new IncomingChangesViewLogic.GetWorkingBranch(),
new IncomingChangesViewLogic.ResolveUserName(),
new ResolveChangeset(),
NewChangesInWk.Build(wkInfo, new BuildWorkspacekIsRelevantNewChange()),
null);
mIncomingChangesViewLogic.Refresh();
}
bool IIncomingChangesTab.IsVisible
{
get { return mIsVisible; }
set { mIsVisible = value; }
}
void IIncomingChangesTab.OnEnable()
{
mSearchField.downOrUpArrowKeyPressed +=
SearchField_OnDownOrUpArrowKeyPressed;
}
void IIncomingChangesTab.OnDisable()
{
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
TreeHeaderSettings.Save(
mIncomingChangesTreeView.multiColumnHeader.state,
UnityConstants.GLUON_INCOMING_CHANGES_TABLE_SETTINGS_NAME);
TreeHeaderSettings.Save(
mErrorsListView.multiColumnHeader.state,
UnityConstants.GLUON_INCOMING_ERRORS_TABLE_SETTINGS_NAME);
}
void IIncomingChangesTab.Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
void IIncomingChangesTab.OnGUI()
{
bool splitterNeeded = mIsErrorsListVisible;
if (splitterNeeded)
PlasticSplitterGUILayout.BeginVerticalSplit(mErrorsSplitterState);
DoIncomingChangesArea(
mIncomingChangesTreeView,
mProgressControls.IsOperationRunning(),
mHasNothingToDownload,
mIsUpdateSuccessful);
DoErrorsArea(
mErrorsListView,
mErrorDetailsSplitterState,
mIsErrorsListVisible);
if (splitterNeeded)
PlasticSplitterGUILayout.EndVerticalSplit();
DrawActionToolbar.Begin(mParentWindow);
if (!mProgressControls.IsOperationRunning())
{
DoActionToolbarMessage(
mIsMessageLabelVisible,
mMessageLabelText,
mHasNothingToDownload,
mIsErrorMessageLabelVisible,
mErrorMessageLabelText,
mFileConflictCount,
mChangesSummary);
if (mIsProcessMergesButtonVisible)
{
DoProcessMergesButton(
mIsProcessMergesButtonEnabled,
mProcessMergesButtonText,
mShowDownloadPlasticExeWindow,
mIncomingChangesViewLogic,
mIncomingChangesTreeView,
mWkInfo,
RefreshAsset.BeforeLongAssetOperation,
(c) => AfterProcessMerges(c));
}
if (mIsCancelMergesButtonVisible)
{
mIsCancelMergesButtonEnabled = DoCancelMergesButton(
mIsCancelMergesButtonEnabled,
mIncomingChangesViewLogic);
}
}
else
{
DrawProgressForViews.ForIndeterminateProgress(
mProgressControls.ProgressData);
}
DrawActionToolbar.End();
if (mProgressControls.HasNotification())
{
DrawProgressForViews.ForNotificationArea(
mProgressControls.ProgressData);
}
}
void IIncomingChangesTab.DrawSearchFieldForTab()
{
// We don't have the filtering implemented at the plasticgui level: IncomingChangesTree.Filter
// When it's implemented, just uncomment this method to show the filter textbox for partial workspaces
// VCS-1006158 [Desktop] gluon: add filter in incoming changes view
/*
DrawSearchField.For(
mSearchField,
mIncomingChangesTreeView,
UnityConstants.SEARCH_FIELD_WIDTH);
*/
}
void IIncomingChangesTab.AutoRefresh()
{
mIncomingChangesViewLogic.AutoRefresh(DateTime.Now);
}
void IRefreshableView.Refresh()
{
if (mNewIncomingChangesUpdater != null)
mNewIncomingChangesUpdater.Update(DateTime.Now);
mIncomingChangesViewLogic.Refresh();
}
void IncomingChangesViewLogic.IIncomingChangesView.UpdateData(
IncomingChangesTree tree,
List<ErrorMessage> errorMessages,
string processMergesButtonText,
PendingConflictsLabelData conflictsLabelData,
string changesToApplySummaryText)
{
ShowProcessMergesButton(processMergesButtonText);
((IncomingChangesViewLogic.IIncomingChangesView)this).
UpdatePendingConflictsLabel(conflictsLabelData);
UpdateIncomingChangesTree(mIncomingChangesTreeView, tree);
UpdateErrorsList(mErrorsListView, errorMessages);
mIsErrorsListVisible = errorMessages.Count > 0;
UpdateOverview(tree, conflictsLabelData);
}
void IncomingChangesViewLogic.IIncomingChangesView.UpdatePendingConflictsLabel(
PendingConflictsLabelData data)
{
}
void IncomingChangesViewLogic.IIncomingChangesView.UpdateSolvedFileConflicts(
List<IncomingChangeInfo> solvedConflicts,
IncomingChangeInfo currentConflict)
{
mIncomingChangesTreeView.UpdateSolvedFileConflicts(
solvedConflicts, currentConflict);
}
void IncomingChangesViewLogic.IIncomingChangesView.ShowMessage(
string message, bool isErrorMessage)
{
if (isErrorMessage)
{
mErrorMessageLabelText = message;
mIsErrorMessageLabelVisible = true;
return;
}
mMessageLabelText = message;
mIsMessageLabelVisible = true;
mHasNothingToDownload = message == PlasticLocalization.GetString(
PlasticLocalization.Name.MergeNothingToDownloadForIncomingView);
}
void IncomingChangesViewLogic.IIncomingChangesView.HideMessage()
{
mMessageLabelText = string.Empty;
mIsMessageLabelVisible = false;
mHasNothingToDownload = false;
mErrorMessageLabelText = string.Empty;
mIsErrorMessageLabelVisible = false;
}
void IncomingChangesViewLogic.IIncomingChangesView.DisableProcessMergesButton()
{
mIsProcessMergesButtonEnabled = false;
}
void IncomingChangesViewLogic.IIncomingChangesView.ShowCancelButton()
{
mIsCancelMergesButtonEnabled = true;
mIsCancelMergesButtonVisible = true;
}
void IncomingChangesViewLogic.IIncomingChangesView.HideCancelButton()
{
mIsCancelMergesButtonEnabled = false;
mIsCancelMergesButtonVisible = false;
}
SelectedIncomingChangesGroupInfo IIncomingChangesViewMenuOperations.GetSelectedIncomingChangesGroupInfo()
{
return IncomingChangesSelection.GetSelectedGroupInfo(mIncomingChangesTreeView);
}
void IIncomingChangesViewMenuOperations.MergeContributors()
{
List<IncomingChangeInfo> fileConflicts = IncomingChangesSelection.
GetSelectedFileConflictsIncludingMeta(mIncomingChangesTreeView);
mIncomingChangesViewLogic.ProcessMergesForConflicts(
MergeContributorType.MergeContributors,
PlasticExeLauncher.BuildForMergeSelectedFiles(mWkInfo, true, mShowDownloadPlasticExeWindow),
fileConflicts,
RefreshAsset.BeforeLongAssetOperation,
AfterProcessMerges);
}
void IIncomingChangesViewMenuOperations.MergeKeepingSourceChanges()
{
List<IncomingChangeInfo> fileConflicts = IncomingChangesSelection.
GetSelectedFileConflictsIncludingMeta(mIncomingChangesTreeView);
mIncomingChangesViewLogic.ProcessMergesForConflicts(
MergeContributorType.KeepSource,
null,
fileConflicts,
RefreshAsset.BeforeLongAssetOperation,
AfterProcessMerges);
}
void IIncomingChangesViewMenuOperations.MergeKeepingWorkspaceChanges()
{
List<IncomingChangeInfo> fileConflicts = IncomingChangesSelection.
GetSelectedFileConflictsIncludingMeta(mIncomingChangesTreeView);
mIncomingChangesViewLogic.ProcessMergesForConflicts(
MergeContributorType.KeepDestination,
null,
fileConflicts,
RefreshAsset.BeforeLongAssetOperation,
AfterProcessMerges);
}
void IIncomingChangesViewMenuOperations.DiffIncomingChanges()
{
IncomingChangeInfo incomingChange = IncomingChangesSelection.
GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
if (incomingChange == null)
return;
DiffIncomingChanges(
mShowDownloadPlasticExeWindow,
incomingChange,
mWkInfo);
}
void IIncomingChangesViewMenuOperations.DiffYoursWithIncoming()
{
IncomingChangeInfo incomingChange = IncomingChangesSelection.
GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
if (incomingChange == null)
return;
DiffYoursWithIncoming(
mShowDownloadPlasticExeWindow,
incomingChange,
mWkInfo);
}
void IIncomingChangesViewMenuOperations.CopyFilePath(bool relativePath)
{
EditorGUIUtility.systemCopyBuffer = GetFilePathList.FromIncomingChangeInfos(
IncomingChangesSelection.GetSelectedFileConflictsIncludingMeta(
mIncomingChangesTreeView),
relativePath,
mWkInfo.ClientPath);
}
void IncomingChangesViewMenu.IMetaMenuOperations.DiffIncomingChanges()
{
IncomingChangeInfo incomingChange = IncomingChangesSelection.
GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
if (incomingChange == null)
return;
DiffIncomingChanges(
mShowDownloadPlasticExeWindow,
mIncomingChangesTreeView.GetMetaChange(incomingChange),
mWkInfo);
}
void IncomingChangesViewMenu.IMetaMenuOperations.DiffYoursWithIncoming()
{
IncomingChangeInfo incomingChange = IncomingChangesSelection.
GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
if (incomingChange == null)
return;
DiffYoursWithIncoming(
mShowDownloadPlasticExeWindow,
mIncomingChangesTreeView.GetMetaChange(incomingChange),
mWkInfo);
}
bool IncomingChangesViewMenu.IMetaMenuOperations.SelectionHasMeta()
{
return mIncomingChangesTreeView.SelectionHasMeta();
}
void SearchField_OnDownOrUpArrowKeyPressed()
{
mIncomingChangesTreeView.SetFocusAndEnsureSelectedItem();
}
static void DiffIncomingChanges(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
IncomingChangeInfo incomingChange,
WorkspaceInfo wkInfo)
{
DiffOperation.DiffRevisions(
wkInfo,
incomingChange.GetMount().RepSpec,
incomingChange.GetBaseRevision(),
incomingChange.GetRevision(),
incomingChange.GetPath(),
incomingChange.GetPath(),
true,
PlasticExeLauncher.BuildForDiffContributors(wkInfo, true, showDownloadPlasticExeWindow),
imageDiffLauncher: null);
}
static void DiffYoursWithIncoming(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
IncomingChangeInfo incomingChange,
WorkspaceInfo wkInfo)
{
DiffOperation.DiffYoursWithIncoming(
wkInfo,
incomingChange.GetMount(),
incomingChange.GetRevision(),
incomingChange.GetPath(),
PlasticExeLauncher.BuildForDiffContributors(wkInfo, true, showDownloadPlasticExeWindow),
imageDiffLauncher: null);
}
static void UpdateErrorsList(
ErrorsListView errorsListView,
List<ErrorMessage> errorMessages)
{
errorsListView.BuildModel(errorMessages);
errorsListView.Reload();
}
void UpdateProcessMergesButtonText()
{
mProcessMergesButtonText =
mIncomingChangesViewLogic.GetProcessMergesButtonText();
}
void ShowProcessMergesButton(string processMergesButtonText)
{
mProcessMergesButtonText = processMergesButtonText;
mIsProcessMergesButtonEnabled = true;
mIsProcessMergesButtonVisible = true;
}
static void DoActionToolbarMessage(
bool isMessageLabelVisible,
string messageLabelText,
bool hasNothingToDownload,
bool isErrorMessageLabelVisible,
string errorMessageLabelText,
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)
{
DrawMergeOverview.For(
0,
fileConflictCount,
changesSummary);
}
}
static void DoInfoMessage(string message)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label(message, UnityStyles.MergeTab.ChangesToApplySummaryLabel);
EditorGUILayout.EndHorizontal();
}
static void DoErrorMessage(string message)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label(message, UnityStyles.MergeTab.RedPendingConflictsOfTotalLabel);
EditorGUILayout.EndHorizontal();
}
static void DoIncomingChangesArea(
IncomingChangesTreeView incomingChangesTreeView,
bool isOperationRunning,
bool hasNothingToDownload,
bool isUpdateSuccessful)
{
EditorGUILayout.BeginVertical();
DoIncomingChangesTreeViewArea(
incomingChangesTreeView,
isOperationRunning,
hasNothingToDownload,
isUpdateSuccessful);
EditorGUILayout.EndVertical();
}
static void DoProcessMergesButton(
bool isEnabled,
string processMergesButtonText,
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
IncomingChangesViewLogic incomingChangesViewLogic,
IncomingChangesTreeView incomingChangesTreeView,
WorkspaceInfo wkInfo,
Action beforeProcessMergesAction,
EndOperationDelegateForUpdatedItems afterProcessMergesAction)
{
GUI.enabled = isEnabled;
if (DrawActionButton.For(processMergesButtonText))
{
List<IncomingChangeInfo> incomingChanges =
incomingChangesViewLogic.GetCheckedChanges();
incomingChangesTreeView.FillWithMeta(incomingChanges);
if (incomingChanges.Count == 0)
return;
incomingChangesViewLogic.ProcessMergesForItems(
incomingChanges,
PlasticExeLauncher.BuildForResolveConflicts(wkInfo, true, showDownloadPlasticExeWindow),
beforeProcessMergesAction,
afterProcessMergesAction);
}
GUI.enabled = true;
}
static bool DoCancelMergesButton(
bool isEnabled,
IncomingChangesViewLogic incomingChangesViewLogic)
{
bool shouldCancelMergesButtonEnabled = true;
GUI.enabled = isEnabled;
if (DrawActionButton.For(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
{
incomingChangesViewLogic.Cancel();
shouldCancelMergesButtonEnabled = false;
}
GUI.enabled = true;
return shouldCancelMergesButtonEnabled;
}
void DoErrorsArea(
ErrorsListView errorsListView,
object splitterState,
bool isErrorsListVisible)
{
EditorGUILayout.BeginVertical();
if (isErrorsListVisible)
{
DrawSplitter.ForHorizontalIndicator();
DoErrorsListArea(errorsListView, splitterState);
}
EditorGUILayout.EndVertical();
}
static void UpdateIncomingChangesTree(
IncomingChangesTreeView incomingChangesTreeView,
IncomingChangesTree tree)
{
incomingChangesTreeView.BuildModel(
UnityIncomingChangesTree.BuildIncomingChangeCategories(tree));
incomingChangesTreeView.Refilter();
incomingChangesTreeView.Sort();
incomingChangesTreeView.Reload();
}
static void DoIncomingChangesTreeViewArea(
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));
}
void DoErrorsListArea(
ErrorsListView errorsListView,
object splitterState)
{
EditorGUILayout.BeginVertical();
GUILayout.Label(
PlasticLocalization.GetString(
PlasticLocalization.Name.IncomingChangesCannotBeApplied),
EditorStyles.boldLabel);
DoErrorsListSplitViewArea(
errorsListView, splitterState);
EditorGUILayout.EndVertical();
}
void DoErrorsListSplitViewArea(
ErrorsListView errorsListView,
object splitterState)
{
EditorGUILayout.BeginHorizontal();
PlasticSplitterGUILayout.BeginHorizontalSplit(splitterState);
DoErrorsListViewArea(errorsListView);
DoErrorDetailsTextArea(errorsListView.GetSelectedError());
PlasticSplitterGUILayout.EndHorizontalSplit();
EditorGUILayout.EndHorizontal();
}
static void DoErrorsListViewArea(
ErrorsListView errorsListView)
{
Rect treeRect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
errorsListView.OnGUI(treeRect);
}
void DoErrorDetailsTextArea(ErrorMessage selectedErrorMessage)
{
string errorDetailsText = selectedErrorMessage == null ?
string.Empty : selectedErrorMessage.Error;
mErrorDetailsScrollPosition = GUILayout.BeginScrollView(
mErrorDetailsScrollPosition);
GUILayout.TextArea(
errorDetailsText, UnityStyles.TextFieldWithWrapping,
GUILayout.ExpandHeight(true));
GUILayout.EndScrollView();
}
void AfterProcessMerges(List<string> changes)
{
RefreshAsset.AfterLongAssetOperation(
ProjectPackages.ShouldBeResolved(changes, mWkInfo, true));
bool isTreeViewEmpty = mIncomingChangesTreeView.GetCheckedItemCount() ==
mIncomingChangesTreeView.GetTotalItemCount();
if (isTreeViewEmpty)
{
mIsUpdateSuccessful = true;
mCooldownClearUpdateSuccessAction.Ping();
return;
}
mStatusBar.Notify(
PlasticLocalization.GetString(PlasticLocalization.Name.WorkspaceUpdateCompleted),
MessageType.None,
Images.GetStepOkIcon());
}
void UpdateOverview(
IncomingChangesTree incomingChangesTree,
PendingConflictsLabelData conflictsLabelData)
{
mChangesSummary = BuildFilesSummaryData.
GetChangesToApplySummary(incomingChangesTree);
mFileConflictCount = conflictsLabelData.PendingConflictsCount;
}
void DelayedClearUpdateSuccess()
{
mIsUpdateSuccessful = false;
}
void BuildComponents()
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed +=
SearchField_OnDownOrUpArrowKeyPressed;
IncomingChangesTreeHeaderState incomingChangesHeaderState =
IncomingChangesTreeHeaderState.GetDefault();
TreeHeaderSettings.Load(incomingChangesHeaderState,
UnityConstants.GLUON_INCOMING_CHANGES_TABLE_SETTINGS_NAME,
(int)IncomingChangesTreeColumn.Path, true);
mIncomingChangesTreeView = new IncomingChangesTreeView(
mWkInfo, incomingChangesHeaderState,
IncomingChangesTreeHeaderState.GetColumnNames(),
new IncomingChangesViewMenu(this, this),
UpdateProcessMergesButtonText);
mIncomingChangesTreeView.Reload();
ErrorsListHeaderState errorsListHeaderState =
ErrorsListHeaderState.GetDefault();
TreeHeaderSettings.Load(errorsListHeaderState,
UnityConstants.GLUON_INCOMING_ERRORS_TABLE_SETTINGS_NAME,
UnityConstants.UNSORT_COLUMN_ID);
mErrorsListView = new ErrorsListView(errorsListHeaderState);
mErrorsListView.Reload();
}
bool mIsVisible;
bool mIsProcessMergesButtonVisible;
bool mIsCancelMergesButtonVisible;
bool mIsMessageLabelVisible;
bool mIsErrorMessageLabelVisible;
bool mIsErrorsListVisible;
bool mIsProcessMergesButtonEnabled;
bool mIsCancelMergesButtonEnabled;
string mProcessMergesButtonText;
string mMessageLabelText;
string mErrorMessageLabelText;
bool mHasNothingToDownload;
bool mIsUpdateSuccessful;
SearchField mSearchField;
IncomingChangesTreeView mIncomingChangesTreeView;
ErrorsListView mErrorsListView;
int mFileConflictCount;
MergeViewTexts.ChangesToApplySummary mChangesSummary;
object mErrorsSplitterState;
object mErrorDetailsSplitterState;
readonly ProgressControlsForViews mProgressControls;
readonly CooldownWindowDelayer mCooldownClearUpdateSuccessAction;
Vector2 mErrorDetailsScrollPosition;
readonly IncomingChangesViewLogic mIncomingChangesViewLogic;
readonly EditorWindow mParentWindow;
readonly StatusBar mStatusBar;
readonly NewIncomingChangesUpdater mNewIncomingChangesUpdater;
readonly LaunchTool.IShowDownloadPlasticExeWindow mShowDownloadPlasticExeWindow;
readonly WorkspaceInfo mWkInfo;
}
}

View File

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

View File

@@ -0,0 +1,136 @@
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.Gluon
{
internal enum IncomingChangesTreeColumn
{
Path,
LastEditedBy,
Size,
DateModififed,
Comment
}
[Serializable]
internal class IncomingChangesTreeHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static IncomingChangesTreeHeaderState GetDefault()
{
return new IncomingChangesTreeHeaderState(BuildColumns());
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.LastEditedByColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.SizeColumn));
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.LastEditedBy:
return PlasticLocalization.GetString(PlasticLocalization.Name.LastEditedByColumn);
case IncomingChangesTreeColumn.Size:
return PlasticLocalization.GetString(PlasticLocalization.Name.SizeColumn);
case IncomingChangesTreeColumn.DateModififed:
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 Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 440,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.Path)),
minWidth = 200,
allowToggleVisibility = false,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 150,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.LastEditedBy)),
minWidth = 80,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 80,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.Size)),
minWidth = 45,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 260,
headerContent = new GUIContent(
GetColumnName(IncomingChangesTreeColumn.DateModififed)),
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: c0821447a35700c4280782d1092cf4c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,667 @@
using System;
using System.IO;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.CM.Common;
using Codice.Client.Common;
using PlasticGui;
using PlasticGui.Gluon.WorkspaceWindow.Views.IncomingChanges;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon
{
internal class IncomingChangesTreeView : TreeView
{
internal IncomingChangesTreeView(
WorkspaceInfo wkInfo,
IncomingChangesTreeHeaderState headerState,
List<string> columnNames,
IncomingChangesViewMenu menu,
Action onCheckedNodeChanged)
: base(new TreeViewState())
{
mWkInfo = wkInfo;
mColumnNames = columnNames;
mMenu = menu;
mOnCheckedNodeChanged = onCheckedNodeChanged;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
customFoldoutYOffset = UnityConstants.TREEVIEW_FOLDOUT_Y_OFFSET;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = false;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
}
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 SearchChanged(string newSearch)
{
mCooldownFilterAction.Ping();
}
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)
{
CategoryTreeViewItemGUI(
args.rowRect, rowHeight,
(ChangeCategoryTreeViewItem)args.item,
mOnCheckedNodeChanged,
mSolvedConflicts.Count,
args.selected, args.focused);
return;
}
if (args.item is ChangeTreeViewItem)
{
ChangeTreeViewItem changeTreeViewItem =
(ChangeTreeViewItem)args.item;
IncomingChangeInfo changeInfo = changeTreeViewItem.ChangeInfo;
IncomingChangeInfo metaChangeInfo = mIncomingChangesTree.GetMetaChange(
changeInfo);
bool isCurrentConflict = IsCurrentConflict(
changeInfo,
metaChangeInfo,
mCurrentConflict);
bool isSolvedConflict = IsSolvedConflict(
changeInfo,
metaChangeInfo,
mSolvedConflicts);
IncomingChangeTreeViewItemGUI(
mWkInfo.ClientPath,
mIncomingChangesTree,
this,
changeTreeViewItem,
mOnCheckedNodeChanged, args,
isCurrentConflict,
isSolvedConflict);
return;
}
base.RowGUI(args);
}
internal void BuildModel(UnityIncomingChangesTree tree)
{
mTreeViewItemIds.Clear();
mIncomingChangesTree = tree;
mSolvedConflicts = new List<IncomingChangeInfo>();
mCurrentConflict = null;
mExpandCategories = true;
}
internal void UpdateSolvedFileConflicts(
List<IncomingChangeInfo> solvedConflicts,
IncomingChangeInfo currentConflict)
{
mSolvedConflicts = solvedConflicts;
mCurrentConflict = currentConflict;
}
internal void Refilter()
{
Filter filter = new Filter(searchString);
mIncomingChangesTree.Filter(filter, mColumnNames);
mExpandCategories = true;
}
internal void Sort()
{
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mIncomingChangesTree.Sort(
mColumnNames[sortedColumnIdx],
sortAscending);
}
internal IncomingChangeInfo GetMetaChange(IncomingChangeInfo change)
{
if (change == null)
return null;
return mIncomingChangesTree.GetMetaChange(change);
}
internal void FillWithMeta(List<IncomingChangeInfo> changes)
{
mIncomingChangesTree.FillWithMeta(changes);
}
internal bool SelectionHasMeta()
{
IncomingChangeInfo selectedChangeInfo = GetSelectedIncomingChange();
if (selectedChangeInfo == null)
return false;
return mIncomingChangesTree.HasMeta(selectedChangeInfo);
}
internal IncomingChangeInfo GetSelectedIncomingChange()
{
IList<int> selectedIds = GetSelection();
if (selectedIds.Count != 1)
return null;
int selectedId = selectedIds[0];
foreach (KeyValuePair<IncomingChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (selectedId == item.Value)
return item.Key;
}
return null;
}
internal List<IncomingChangeInfo> GetSelectedIncomingChanges()
{
List<IncomingChangeInfo> result = new List<IncomingChangeInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<IncomingChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
result.Add(item.Key);
}
return result;
}
internal List<IncomingChangeInfo> GetSelectedFileConflicts()
{
List<IncomingChangeInfo> result = new List<IncomingChangeInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<IncomingChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
if (item.Key.CategoryType != IncomingChangeCategory.Type.Conflicted)
continue;
result.Add(item.Key);
}
return result;
}
internal int GetCheckedItemCount()
{
List<IncomingChangeCategory> categories = mIncomingChangesTree.GetNodes();
if (categories == null)
return 0;
int checkedCount = 0;
foreach (IncomingChangeCategory category in categories)
{
checkedCount += ((ICheckablePlasticTreeCategory)category).GetCheckedChangesCount();
}
return checkedCount;
}
internal int GetTotalItemCount()
{
List<IncomingChangeCategory> categories = mIncomingChangesTree.GetNodes();
if (categories == null)
return 0;
int totalCount = 0;
foreach (IncomingChangeCategory category in categories)
{
totalCount += category.GetChildrenCount();
}
return totalCount;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static bool IsCurrentConflict(
IncomingChangeInfo changeInfo,
IncomingChangeInfo metaChangeInfo,
IncomingChangeInfo currentConflict)
{
if (metaChangeInfo == null)
return currentConflict == changeInfo;
return currentConflict == changeInfo ||
currentConflict == metaChangeInfo;
}
static bool IsSolvedConflict(
IncomingChangeInfo changeInfo,
IncomingChangeInfo metaChangeInfo,
List<IncomingChangeInfo> solvedConflicts)
{
if (metaChangeInfo == null)
return solvedConflicts.Contains(changeInfo);
return solvedConflicts.Contains(changeInfo) &&
solvedConflicts.Contains(metaChangeInfo);
}
static void RegenerateRows(
UnityIncomingChangesTree incomingChangesTree,
TreeViewItemIds<IncomingChangeCategory, IncomingChangeInfo> treeViewItemIds,
IncomingChangesTreeView treeView,
TreeViewItem rootItem,
List<TreeViewItem> rows,
bool expandCategories)
{
if (incomingChangesTree == null)
return;
ClearRows(rootItem, rows);
List<IncomingChangeCategory> categories = incomingChangesTree.GetNodes();
if (categories == null)
return;
List<int> categoriesToExpand = new List<int>();
foreach (IncomingChangeCategory 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,
categories.Count, expandCategories))
continue;
categoriesToExpand.Add(categoryTreeViewItem.id);
foreach (IncomingChangeInfo incomingChange in category.GetChanges())
{
int changeId;
if (!treeViewItemIds.TryGetInfoItemId(incomingChange, out changeId))
changeId = treeViewItemIds.AddInfoItem(incomingChange);
TreeViewItem changeTreeViewItem =
new ChangeTreeViewItem(changeId, incomingChange);
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 UpdateCheckStateForSelection(
IncomingChangesTreeView treeView,
ChangeTreeViewItem senderTreeViewItem)
{
IList<int> selectedIds = treeView.GetSelection();
if (selectedIds.Count <= 1)
return;
if (!selectedIds.Contains(senderTreeViewItem.id))
return;
bool isChecked = ((ICheckablePlasticTreeNode)senderTreeViewItem.ChangeInfo).IsChecked() ?? false;
foreach (TreeViewItem treeViewItem in treeView.FindRows(selectedIds))
{
if (treeViewItem is ChangeCategoryTreeViewItem)
{
((ICheckablePlasticTreeCategory)((ChangeCategoryTreeViewItem)treeViewItem)
.Category).UpdateCheckedState(isChecked);
continue;
}
((ICheckablePlasticTreeNode)((ChangeTreeViewItem)treeViewItem)
.ChangeInfo).UpdateCheckedState(isChecked);
}
}
static void CategoryTreeViewItemGUI(
Rect rowRect,
float rowHeight,
ChangeCategoryTreeViewItem item,
Action onCheckedNodeChanged,
int solvedConflictsCount,
bool isSelected,
bool isFocused)
{
string label = item.Category.CategoryName;
string infoLabel = item.Category.GetCheckedChangesText();
bool wasChecked = CheckableItems.GetIsCheckedValueForCategory(item.Category) ?? false;
bool hadCheckedChildren = ((ICheckablePlasticTreeCategory)item.Category).GetCheckedChangesCount() > 0;
DefaultStyles.label = GetCategoryStyle(
item.Category, solvedConflictsCount, isSelected);
bool isChecked = DrawTreeViewItem.ForCheckableCategoryItem(
rowRect,
rowHeight,
item.depth,
label,
infoLabel,
isSelected,
isFocused,
wasChecked,
hadCheckedChildren,
hadPartiallyCheckedChildren: false);
DefaultStyles.label = UnityStyles.Tree.Label;
if (!wasChecked && isChecked)
{
((ICheckablePlasticTreeCategory)item.Category).UpdateCheckedState(true);
onCheckedNodeChanged();
return;
}
if (wasChecked && !isChecked)
{
((ICheckablePlasticTreeCategory)item.Category).UpdateCheckedState(false);
onCheckedNodeChanged();
return;
}
}
static void IncomingChangeTreeViewItemGUI(
string wkPath,
UnityIncomingChangesTree incomingChangesTree,
IncomingChangesTreeView treeView,
ChangeTreeViewItem item,
Action onCheckedNodeChanged,
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,
onCheckedNodeChanged,
column,
args.selected,
args.focused,
isCurrentConflict,
isSolvedConflict);
}
}
static void IncomingChangeTreeViewItemCellGUI(
string wkPath,
Rect rect,
float rowHeight,
UnityIncomingChangesTree incomingChangesTree,
IncomingChangesTreeView treeView,
ChangeTreeViewItem item,
Action onCheckedNodeChanged,
IncomingChangesTreeColumn column,
bool isSelected,
bool isFocused,
bool isCurrentConflict,
bool isSolvedConflict)
{
IncomingChangeInfo 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.ForGluonIncomingChange(
incomingChange, isSolvedConflict);
bool wasChecked = ((ICheckablePlasticTreeNode)incomingChange).IsChecked() ?? false;
bool isChecked = DrawTreeViewItem.ForCheckableItemCell(
rect, rowHeight, item.depth,
icon, overlayIcon, label,
isSelected, isFocused, isCurrentConflict,
wasChecked);
((ICheckablePlasticTreeNode)incomingChange).UpdateCheckedState(isChecked);
if (wasChecked != isChecked)
{
UpdateCheckStateForSelection(treeView, item);
onCheckedNodeChanged();
}
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))
{
IncomingChangeInfo 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,
IncomingChangeInfo incomingChange)
{
bool isDirectory = incomingChange.GetRevision().
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(
IncomingChangeCategory category,
int solvedConflictsCount,
bool isSelected)
{
if (isSelected)
return UnityStyles.Tree.Label;
if (category.CategoryType != IncomingChangeCategory.Type.Conflicted)
return UnityStyles.Tree.Label;
return category.GetChildrenCount() > solvedConflictsCount ?
UnityStyles.Tree.RedLabel : UnityStyles.Tree.GreenLabel;
}
static bool ShouldExpandCategory(
IncomingChangesTreeView treeView,
ChangeCategoryTreeViewItem categoryTreeViewItem,
int categoriesCount,
bool expandCategories)
{
if (expandCategories)
{
if (categoriesCount == 1)
return true;
if (categoryTreeViewItem.Category.CategoryType
== IncomingChangeCategory.Type.Conflicted)
return true;
if (categoryTreeViewItem.Category.GetChildrenCount()
> NODES_TO_EXPAND_CATEGORY)
return false;
return true;
}
return treeView.IsExpanded(categoryTreeViewItem.id);
}
bool mExpandCategories;
TreeViewItemIds<IncomingChangeCategory, IncomingChangeInfo> mTreeViewItemIds =
new TreeViewItemIds<IncomingChangeCategory, IncomingChangeInfo>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
IncomingChangeInfo mCurrentConflict;
List<IncomingChangeInfo> mSolvedConflicts;
UnityIncomingChangesTree mIncomingChangesTree;
CooldownWindowDelayer mCooldownFilterAction;
readonly Action mOnCheckedNodeChanged;
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: 7f2f2eb277e02054cbc5ccee904b593b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,272 @@
using UnityEngine;
using UnityEditor;
using Codice.CM.Common;
using Codice.Client.Common.EventTracking;
using PlasticGui;
using PlasticGui.Gluon.WorkspaceWindow.Views.IncomingChanges;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon
{
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 CopyFilePathMenuItem_Click()
{
mIncomingChangesViewMenuOperations.CopyFilePath(relativePath: false);
}
void CopyRelativeFilePathMenuItem_Click()
{
mIncomingChangesViewMenuOperations.CopyFilePath(relativePath: true);
}
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())
{
menu.AddSeparator(string.Empty);
AddMetaActions(menu, operations);
}
menu.AddSeparator(string.Empty);
AddCopyFilePathActions(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);
}
void AddCopyFilePathActions(
GenericMenu menu,
IncomingChangesMenuOperations operations)
{
AddCopyFilePathMenuItem(
mCopyFilePathMenuItemContent, menu, operations, CopyFilePathMenuItem_Click);
AddCopyFilePathMenuItem(
mCopyRelativeFilePathMenuItemContent, menu, operations, CopyRelativeFilePathMenuItem_Click);
}
static void AddCopyFilePathMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
IncomingChangesMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(IncomingChangesMenuOperations.CopyFilePath))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
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));
mCopyFilePathMenuItemContent = new GUIContent(PlasticLocalization.Name.CopyFilePathMenuItem.GetString());
mCopyRelativeFilePathMenuItemContent =
new GUIContent(PlasticLocalization.Name.CopyRelativeFilePathMenuItem.GetString());
}
GUIContent mNoActionMenuItemContent;
GUIContent mMergeSelectedFilesMenuItemContent;
GUIContent mMergeKeepingSourceChangesMenuItemContent;
GUIContent mMergeKeepingWorkspaceChangesMenuItemContent;
GUIContent mDiffYoursWithIncomingMenuItemContent;
GUIContent mDiffIncomingChangesMenuItemContent;
GUIContent mDiffMetaYoursWithIncomingMenuItemContent;
GUIContent mDiffMetaIncomingChangesMenuItemContent;
GUIContent mCopyFilePathMenuItemContent;
GUIContent mCopyRelativeFilePathMenuItemContent;
readonly IIncomingChangesViewMenuOperations mIncomingChangesViewMenuOperations;
readonly IMetaMenuOperations mIncomingChangesMetaMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,181 @@
using System.Collections.Generic;
using PlasticGui;
using PlasticGui.Gluon.WorkspaceWindow.Views.IncomingChanges;
namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Gluon
{
internal class UnityIncomingChangesTree
{
internal static UnityIncomingChangesTree BuildIncomingChangeCategories(
IncomingChangesTree tree)
{
return new UnityIncomingChangesTree(tree);
}
UnityIncomingChangesTree(IncomingChangesTree tree)
{
mInnerTree = tree;
mMetaCache.Build(mInnerTree.GetNodes());
}
internal List<IncomingChangeCategory> GetNodes()
{
return mInnerTree.GetNodes();
}
internal bool HasMeta(IncomingChangeInfo changeInfo)
{
return mMetaCache.ContainsMeta(changeInfo);
}
internal IncomingChangeInfo GetMetaChange(IncomingChangeInfo change)
{
return mMetaCache.GetExistingMeta(change);
}
internal void FillWithMeta(List<IncomingChangeInfo> changes)
{
changes.AddRange(
mMetaCache.GetExistingMeta(changes));
}
internal void Filter(Filter filter, List<string> columnNames)
{
mInnerTree.Filter(filter, columnNames);
}
internal void Sort(string key, bool isAscending)
{
mInnerTree.Sort(key, isAscending);
}
MetaCache mMetaCache = new MetaCache();
IncomingChangesTree mInnerTree;
class MetaCache
{
internal bool ContainsMeta(IncomingChangeInfo changeInfo)
{
string key = BuildKey.ForMetaChange(changeInfo);
return mCache.ContainsKey(key);
}
internal IncomingChangeInfo GetExistingMeta(IncomingChangeInfo change)
{
IncomingChangeInfo result;
if (!mCache.TryGetValue(BuildKey.ForMetaChange(change), out result))
return null;
return result;
}
internal List<IncomingChangeInfo> GetExistingMeta(
List<IncomingChangeInfo> changes)
{
List<IncomingChangeInfo> result = new List<IncomingChangeInfo>();
foreach (IncomingChangeInfo change in changes)
{
string key = BuildKey.ForMetaChange(change);
IncomingChangeInfo metaChange;
if (!mCache.TryGetValue(key, out metaChange))
continue;
result.Add(metaChange);
}
return result;
}
internal void Build(List<IncomingChangeCategory> incomingChangesCategories)
{
mCache.Clear();
foreach (IncomingChangeCategory category in incomingChangesCategories)
{
ExtractMetaToCache(category, mCache);
}
}
static void ExtractMetaToCache(
IncomingChangeCategory category,
Dictionary<string, IncomingChangeInfo> cache)
{
List<IncomingChangeInfo> changes = category.GetChanges();
HashSet<string> indexedKeys = BuildIndexedKeys(
changes);
for (int i = changes.Count - 1; i >= 0; i--)
{
IncomingChangeInfo 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<IncomingChangeInfo> changes)
{
HashSet<string> result = new HashSet<string>();
foreach (IncomingChangeInfo change in changes)
{
if (MetaPath.IsMetaPath(change.GetPath()))
continue;
result.Add(BuildKey.ForChange(change));
}
return result;
}
Dictionary<string, IncomingChangeInfo> mCache =
new Dictionary<string, IncomingChangeInfo>();
static class BuildKey
{
internal static string ForChange(
IncomingChangeInfo change)
{
return BuildCacheKey(
change.CategoryType,
change.GetPath());
}
internal static string ForMetaChange(
IncomingChangeInfo change)
{
return BuildCacheKey(
change.CategoryType,
MetaPath.GetMetaPath(change.GetPath()));
}
internal static string BuildCacheKey(
IncomingChangeCategory.Type type,
string path)
{
return string.Concat(type, ":", path);
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,17 @@
namespace Unity.PlasticSCM.Editor.Views.Merge
{
internal interface IIncomingChangesTab
{
bool IsVisible
{
get; set;
}
void OnEnable();
void OnDisable();
void Update();
void OnGUI();
void DrawSearchFieldForTab();
void AutoRefresh();
}
}

View File

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