initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

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

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ade7225274b3d4c32a9eb7e64f83c5a1
timeCreated: 1539786107
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,21 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui;
using PlasticGui.WorkspaceWindow.PendingChanges;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal class ChangeTreeViewItem : TreeViewItem
{
internal PendingChangeInfo ChangeInfo { get; private set; }
internal ChangeTreeViewItem(int id, PendingChangeInfo change, int depth)
: base(id, depth)
{
ChangeInfo = change;
displayName = change.GetColumnText(PlasticLocalization.GetString(
PlasticLocalization.Name.ItemColumn));
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a9e847d045a7744b08c7a37912965cdc
timeCreated: 1539688098
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,18 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.PendingChanges;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal class ChangelistTreeViewItem : TreeViewItem
{
internal ChangelistNode Changelist { get; private set; }
internal ChangelistTreeViewItem(int id, ChangelistNode changelist)
: base(id, 0)
{
Changelist = changelist;
}
}
}

View file

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

View file

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

View file

@ -0,0 +1,190 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Changelists
{
internal class ChangelistMenu
{
internal ChangelistMenu(
IChangelistMenuOperations changelistMenuOperations,
bool isGluonMode)
{
mChangelistMenuOperations = changelistMenuOperations;
BuildComponents(isGluonMode);
}
internal void Popup()
{
GenericMenu menu = new GenericMenu();
UpdateMenuItems(menu);
menu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
ChangelistMenuOperations operationToExecute = GetMenuOperations(e);
if (operationToExecute == ChangelistMenuOperations.None)
return false;
ChangelistMenuOperations operations =
ChangelistMenuUpdater.GetAvailableMenuOperations(
mChangelistMenuOperations.GetSelectedChangesGroupInfo(),
mChangelistMenuOperations.GetSelectedChangelistInfos());
if (!operations.HasFlag(operationToExecute))
return false;
ProcessMenuOperation(operationToExecute, mChangelistMenuOperations);
return true;
}
void CheckinChangelistMenuItem_Click()
{
mChangelistMenuOperations.Checkin();
}
void ShelveChangelistMenuItem_Click()
{
mChangelistMenuOperations.Shelve();
}
void UndoChangelistMenuItem_Click()
{
mChangelistMenuOperations.Undo();
}
void CreateNewChangelistMenuItem_Click()
{
mChangelistMenuOperations.CreateNew();
}
void EditChangelistMenuItem_Click()
{
mChangelistMenuOperations.Edit();
}
void DeleteChangelistMenuItem_Click()
{
mChangelistMenuOperations.Delete();
}
void UpdateMenuItems(GenericMenu menu)
{
ChangelistMenuOperations operations = ChangelistMenuUpdater.GetAvailableMenuOperations(
mChangelistMenuOperations.GetSelectedChangesGroupInfo(),
mChangelistMenuOperations.GetSelectedChangelistInfos());
if (operations == ChangelistMenuOperations.None)
{
menu.AddDisabledItem(GetNoActionMenuItemContent());
return;
}
if (operations.HasFlag(ChangelistMenuOperations.Checkin))
menu.AddItem(mCheckinChangelistMenuItemContent, false, CheckinChangelistMenuItem_Click);
else
menu.AddDisabledItem(mCheckinChangelistMenuItemContent);
if (mShelveChangelistMenuItemContent != null)
{
if (operations.HasFlag(ChangelistMenuOperations.Shelve))
menu.AddItem(mShelveChangelistMenuItemContent, false, ShelveChangelistMenuItem_Click);
else
menu.AddDisabledItem(mShelveChangelistMenuItemContent);
}
menu.AddSeparator(string.Empty);
if (operations.HasFlag(ChangelistMenuOperations.Undo))
menu.AddItem(mUndoChangelistMenuItemContent, false, UndoChangelistMenuItem_Click);
else
menu.AddDisabledItem(mUndoChangelistMenuItemContent);
menu.AddSeparator(string.Empty);
if (operations.HasFlag(ChangelistMenuOperations.CreateNew))
menu.AddItem(mCreateNewChangelistMenuItemContent, false, CreateNewChangelistMenuItem_Click);
else
menu.AddDisabledItem(mCreateNewChangelistMenuItemContent);
if (operations.HasFlag(ChangelistMenuOperations.Edit))
menu.AddItem(mEditChangelistMenuItemContent, false, EditChangelistMenuItem_Click);
else
menu.AddDisabledItem(mEditChangelistMenuItemContent);
if (operations.HasFlag(ChangelistMenuOperations.Delete))
menu.AddItem(mDeleteChangelistMenuItemContent, false, DeleteChangelistMenuItem_Click);
else
menu.AddDisabledItem(mDeleteChangelistMenuItemContent);
}
GUIContent GetNoActionMenuItemContent()
{
if (mNoActionMenuItemContent == null)
{
mNoActionMenuItemContent = new GUIContent(PlasticLocalization.GetString(
PlasticLocalization.Name.NoActionMenuItem));
}
return mNoActionMenuItemContent;
}
static ChangelistMenuOperations GetMenuOperations(Event e)
{
if (Keyboard.IsKeyPressed(e, KeyCode.Delete))
return ChangelistMenuOperations.Delete;
return ChangelistMenuOperations.None;
}
static void ProcessMenuOperation(
ChangelistMenuOperations operationToExecute,
IChangelistMenuOperations changelistMenuOperations)
{
if (operationToExecute == ChangelistMenuOperations.Delete)
{
changelistMenuOperations.Delete();
return;
}
}
void BuildComponents(bool isGluonMode)
{
mCheckinChangelistMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.CheckinChangelist));
if (!isGluonMode)
mShelveChangelistMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.ShelveChangelist));
mUndoChangelistMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.UndoChangesChangelist));
mCreateNewChangelistMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.CreateNewChangelist));
mEditChangelistMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.EditChangelist));
mDeleteChangelistMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.DeleteChangelist),
GetPlasticShortcut.ForDelete()));
}
GUIContent mNoActionMenuItemContent;
GUIContent mCheckinChangelistMenuItemContent;
GUIContent mShelveChangelistMenuItemContent;
GUIContent mUndoChangelistMenuItemContent;
GUIContent mCreateNewChangelistMenuItemContent;
GUIContent mEditChangelistMenuItemContent;
GUIContent mDeleteChangelistMenuItemContent;
readonly IChangelistMenuOperations mChangelistMenuOperations;
bool mIsGluonMode;
}
}

View file

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

View file

@ -0,0 +1,90 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Codice.Client.BaseCommands;
using Codice.Client.Commands;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Changelists
{
internal class MoveToChangelistMenuBuilder
{
internal MoveToChangelistMenuBuilder(
WorkspaceInfo wkInfo,
IChangelistMenuOperations operations)
{
mWkInfo = wkInfo;
mOperations = operations;
}
internal void BuildComponents()
{
mMoveToChangelistMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.MoveToChangelist));
mNewChangelistMenuItemContent = new GUIContent(GetSubMenuText(
PlasticLocalization.GetString(PlasticLocalization.Name.New)));
}
internal void UpdateMenuItems(
GenericMenu menu,
ChangelistMenuOperations operations,
List<ChangeInfo> changes,
List<ChangeListInfo> involvedChangelists)
{
if (!operations.HasFlag(ChangelistMenuOperations.MoveToChangelist))
{
menu.AddDisabledItem(mMoveToChangelistMenuItemContent);
return;
}
menu.AddItem(
mNewChangelistMenuItemContent,
false,
() => NewChangelist_Click(changes));
List<string> targetChangelists = GetTargetChangelists.
ForInvolvedChangelists(mWkInfo, involvedChangelists);
if (targetChangelists.Count == 0)
return;
menu.AddSeparator(GetSubMenuText(string.Empty));
foreach (string changelist in targetChangelists)
{
menu.AddItem(
new GUIContent(GetSubMenuText(changelist)),
false,
() => MoveToChangelist_Click(changes, changelist));
}
}
void NewChangelist_Click(List<ChangeInfo> changes)
{
mOperations.MoveToNewChangelist(changes);
}
void MoveToChangelist_Click(List<ChangeInfo> changes, string targetChangelist)
{
mOperations.MoveToChangelist(changes, targetChangelist);
}
static string GetSubMenuText(string subMenuName)
{
return UnityMenuItem.GetText(
PlasticLocalization.GetString(PlasticLocalization.Name.MoveToChangelist),
UnityMenuItem.EscapedText(subMenuName));
}
GUIContent mMoveToChangelistMenuItemContent;
GUIContent mNewChangelistMenuItemContent;
readonly WorkspaceInfo mWkInfo;
readonly IChangelistMenuOperations mOperations;
}
}

View file

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

View file

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6e70bba63d1604ffb90a65601cb8abae
folderAsset: yes
timeCreated: 1541005875
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEditor;
using UnityEngine;
using Codice.Client.GameUI.Checkin;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs
{
internal class CheckinConflictsDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 600, 418);
}
}
internal static ResponseType Show(
IList<CheckinConflict> conflicts,
PlasticLocalization.Name dialogTitle,
PlasticLocalization.Name dialogExplanation,
PlasticLocalization.Name okButtonCaption,
EditorWindow parentWindow)
{
CheckinConflictsDialog dialog = Create(
PlasticLocalization.GetString(dialogTitle),
PlasticLocalization.GetString(dialogExplanation),
GetConflictsText(conflicts),
PlasticLocalization.GetString(okButtonCaption));
return dialog.RunModal(parentWindow);
}
protected override void OnModalGUI()
{
Title(mDialogTitle);
Paragraph(mDialogExplanation);
Title(PlasticLocalization.GetString(PlasticLocalization.Name.ItemColumn));
ConflictsArea();
GUILayout.Space(20);
DoButtonsArea();
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinConflictsTitle);
}
void ConflictsArea()
{
mScrollPosition = EditorGUILayout.BeginScrollView(
mScrollPosition, EditorStyles.helpBox, GUILayout.Height(205));
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Space(6);
Paragraph(mConflictsText);
}
EditorGUILayout.EndScrollView();
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(mOkButtonCaption))
return;
OkButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
static string GetConflictsText(IList<CheckinConflict> conflicts)
{
StringBuilder sb = new StringBuilder();
foreach (CheckinConflict conflict in conflicts)
{
sb.AppendFormat(
"{0} {1}{2}",
conflict.Description,
conflict.ActionMessage,
Environment.NewLine);
}
return sb.ToString();
}
static CheckinConflictsDialog Create(
string dialogTitle,
string dialogExplanation,
string conflictsText,
string okButtonCaption)
{
var instance = CreateInstance<CheckinConflictsDialog>();
instance.mDialogTitle = dialogTitle;
instance.mDialogExplanation = dialogExplanation;
instance.mConflictsText = conflictsText;
instance.mOkButtonCaption = okButtonCaption;
instance.mEnterKeyAction = instance.OkButtonAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
return instance;
}
Vector2 mScrollPosition;
string mDialogTitle;
string mDialogExplanation;
string mConflictsText;
string mOkButtonCaption;
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 615fa68a626934ca28141174234fee26
timeCreated: 1542733474
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,231 @@
using UnityEditor;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.PendingChanges;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs
{
internal class CheckinMergeNeededDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 650, 390);
}
}
internal static CheckinMergeNeededData Merge(
WorkspaceInfo wkInfo,
EditorWindow parentWindow)
{
RepositorySpec repSpec = PlasticGui.Plastic.API.GetRepositorySpec(wkInfo);
BranchInfo parentBranchInfo = PlasticGui.Plastic.API.GetWorkingBranch(wkInfo);
CheckinMergeNeededDialog dialog = Create(
repSpec, parentBranchInfo,
new ProgressControlsForDialogs());
ResponseType dialogResult = dialog.RunModal(parentWindow);
CheckinMergeNeededData result = new CheckinMergeNeededData(
repSpec, parentBranchInfo,
dialog.mMergeNow, dialog.mChildBranchName);
result.Result = dialogResult == ResponseType.Ok;
return result;
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeRequest));
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeRequestMessage));
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeRequestQuestion));
DoMergeNowArea();
DoMergeLaterArea();
GUILayout.Space(10);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
GUILayout.Space(10);
DoButtonsArea();
mProgressControls.ForcedUpdateProgress(this);
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeTitle);
}
void DoMergeNowArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Space(20);
EditorGUI.BeginChangeCheck();
bool mergeNowChecked = RadioToggle(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeNow), mMergeNow);
if (EditorGUI.EndChangeCheck() && mergeNowChecked)
{
mMergeNow = mergeNowChecked; // Just check
}
GUILayout.FlexibleSpace();
}
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Space(45);
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeNowMessage));
}
}
void DoMergeLaterArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Space(20);
EditorGUI.BeginChangeCheck();
bool mergeLaterChecked = RadioToggle(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeLater), !mMergeNow);
if (EditorGUI.EndChangeCheck() && mergeLaterChecked)
{
mMergeNow = !mergeLaterChecked; // Just uncheck
}
GUILayout.FlexibleSpace();
}
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Space(45);
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeLaterMessage,
mCurrentBranchInfo.BranchName));
}
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Space(60);
GUILayout.Label(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinMergeBranch), UnityStyles.Paragraph);
GUILayout.Space(-10);
using (new EditorGUILayout.VerticalScope())
{
GUILayout.Space(6);
GUI.enabled = !mMergeNow;
mChildBranchName = EditorGUILayout.TextField(
string.Empty, mChildBranchName);
GUI.enabled = true;
}
}
}
void DoButtonsArea()
{
using (new EditorGUI.DisabledScope(
mProgressControls.ProgressData.IsWaitingAsyncResult))
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoMergeButton();
DoCancelButton();
return;
}
DoCancelButton();
DoMergeButton();
}
}
void DoMergeButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.MergeButton)))
return;
MergeButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void MergeButtonAction()
{
CheckinMergeNeededData data = new CheckinMergeNeededData(
mRepSpec, mCurrentBranchInfo, mMergeNow, mChildBranchName);
CheckinMergeNeededValidation.AsyncValidation(
data, this, mProgressControls);
}
bool RadioToggle(string text, bool isOn)
{
var rect = GUILayoutUtility.GetRect(
new GUIContent(text), UnityStyles.Dialog.RadioToggle);
bool isOnAfter = EditorGUI.Toggle(
rect, isOn, UnityStyles.Dialog.RadioToggle);
GUI.Label(
new Rect(
rect.x + rect.height, rect.y,
rect.xMax - rect.height, rect.height),
text, UnityStyles.Paragraph);
return isOnAfter;
}
static CheckinMergeNeededDialog Create(
RepositorySpec repSpec,
BranchInfo currentBranchInfo,
ProgressControlsForDialogs progressControls)
{
var instance = CreateInstance<CheckinMergeNeededDialog>();
instance.mRepSpec = repSpec;
instance.mCurrentBranchInfo = currentBranchInfo;
instance.mProgressControls = progressControls;
instance.mEnterKeyAction = instance.MergeButtonAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
return instance;
}
[SerializeField]
bool mMergeNow = true;
[SerializeField]
string mChildBranchName = DEFAULT_BRANCH_NAME;
ProgressControlsForDialogs mProgressControls;
BranchInfo mCurrentBranchInfo;
RepositorySpec mRepSpec;
const string DEFAULT_BRANCH_NAME = "task000";
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e618da42af60f4600a4bc48211cbae9f
timeCreated: 1541414834
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,245 @@
using UnityEditor;
using UnityEngine;
using Codice.Client.Commands;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs
{
class CreateChangelistDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 710, 290);
}
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(PlasticLocalization.Name.CreateChangelistTitle);
}
protected override void OnModalGUI()
{
DoTitleArea();
DoFieldsArea();
DoButtonsArea();
}
internal static ChangelistCreationData CreateChangelist(
WorkspaceInfo wkInfo,
EditorWindow parentWindow)
{
CreateChangelistDialog dialog = Create(wkInfo);
ResponseType dialogueResult = dialog.RunModal(parentWindow);
ChangelistCreationData result = dialog.BuildCreationData();
result.Result = dialogueResult == ResponseType.Ok;
return result;
}
internal static ChangelistCreationData EditChangelist(
WorkspaceInfo wkInfo,
ChangeListInfo changelistToEdit,
EditorWindow parentWindow)
{
CreateChangelistDialog dialog = Edit(wkInfo, changelistToEdit);
ResponseType dialogueResult = dialog.RunModal(parentWindow);
ChangelistCreationData result = dialog.BuildCreationData();
result.Result = dialogueResult == ResponseType.Ok;
return result;
}
void DoTitleArea()
{
GUILayout.BeginVertical();
Title(PlasticLocalization.GetString(mIsCreateMode ?
PlasticLocalization.Name.CreateChangelistTitle :
PlasticLocalization.Name.EditChangelistTitle));
GUILayout.Space(5);
Paragraph(PlasticLocalization.GetString(mIsCreateMode ?
PlasticLocalization.Name.CreateChangelistExplanation :
PlasticLocalization.Name.EditChangelistExplanation));
GUILayout.EndVertical();
}
void DoFieldsArea()
{
GUILayout.BeginVertical();
DoNameFieldArea();
GUILayout.Space(5);
DoDescriptionFieldArea();
GUILayout.Space(5);
DoPersistentFieldArea();
GUILayout.Space(5);
GUILayout.EndVertical();
}
void DoNameFieldArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Label(
PlasticLocalization.GetString(PlasticLocalization.Name.ChangelistNameEntry),
GUILayout.Width(100));
GUI.SetNextControlName(NAME_FIELD_CONTROL_NAME);
mChangelistName = GUILayout.TextField(mChangelistName);
if (!mWasNameFieldFocused)
{
EditorGUI.FocusTextInControl(NAME_FIELD_CONTROL_NAME);
mWasNameFieldFocused = true;
}
GUILayout.Space(5);
}
}
void DoDescriptionFieldArea()
{
using (new EditorGUILayout.HorizontalScope())
{
using (new EditorGUILayout.VerticalScope(GUILayout.Width(100)))
{
GUILayout.Space(49);
GUILayout.Label(
PlasticLocalization.GetString(PlasticLocalization.Name.ChangelistDescriptionEntry),
GUILayout.Width(100));
}
mChangelistDescription = GUILayout.TextArea(mChangelistDescription, GUILayout.Height(100));
GUILayout.Space(5);
}
}
void DoPersistentFieldArea()
{
mIsPersistent = GUILayout.Toggle(
mIsPersistent,
PlasticLocalization.GetString(PlasticLocalization.Name.ChangelistPersistentCheckBoxEntry));
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
using (new EditorGUILayout.HorizontalScope(GUILayout.MinWidth(500)))
{
GUILayout.Space(2);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
GUILayout.Space(2);
}
GUILayout.FlexibleSpace();
DoCreateButton();
DoCancelButton();
}
}
void DoCancelButton()
{
if (NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
{
CancelButtonAction();
}
}
void DoCreateButton()
{
if (!NormalButton(PlasticLocalization.GetString(mIsCreateMode ?
PlasticLocalization.Name.CreateButton :
PlasticLocalization.Name.EditButton)))
return;
ChangelistCreationValidation.Validation(
mWkInfo,
mChangelistName,
mIsCreateMode || !mChangelistName.Equals(mChangelistToEdit.Name),
this,
mProgressControls);
}
static CreateChangelistDialog Create(WorkspaceInfo wkInfo)
{
var instance = CreateInstance<CreateChangelistDialog>();
instance.IsResizable = false;
instance.mEscapeKeyAction = instance.CloseButtonAction;
instance.mWkInfo = wkInfo;
instance.mChangelistToEdit = null;
instance.mChangelistName = string.Empty;
instance.mChangelistDescription = string.Empty;
instance.mIsPersistent = false;
instance.mProgressControls = new ProgressControlsForDialogs();
instance.mIsCreateMode = true;
return instance;
}
static CreateChangelistDialog Edit(
WorkspaceInfo wkInfo,
ChangeListInfo changelistToEdit)
{
var instance = CreateInstance<CreateChangelistDialog>();
instance.IsResizable = false;
instance.mEscapeKeyAction = instance.CloseButtonAction;
instance.mWkInfo = wkInfo;
instance.mChangelistToEdit = changelistToEdit;
instance.mChangelistName = changelistToEdit.Name;
instance.mChangelistDescription = changelistToEdit.Description;
instance.mIsPersistent = changelistToEdit.IsPersistent;
instance.mProgressControls = new ProgressControlsForDialogs();
instance.mIsCreateMode = false;
return instance;
}
ChangelistCreationData BuildCreationData()
{
ChangeListInfo changelistInfo = new ChangeListInfo();
changelistInfo.Name = mChangelistName;
changelistInfo.Description = mChangelistDescription;
changelistInfo.IsPersistent = mIsPersistent;
changelistInfo.Type = ChangeListType.UserDefined;
return new ChangelistCreationData(changelistInfo);
}
ProgressControlsForDialogs mProgressControls;
WorkspaceInfo mWkInfo;
ChangeListInfo mChangelistToEdit;
string mChangelistName;
string mChangelistDescription;
bool mIsPersistent;
bool mIsCreateMode;
bool mWasNameFieldFocused;
const string NAME_FIELD_CONTROL_NAME = "CreateChangelistNameField";
}
}

View file

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

View file

@ -0,0 +1,166 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Codice.Client.BaseCommands;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.PendingChanges;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs
{
internal class DependenciesDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 650, 430);
}
}
internal static bool IncludeDependencies(
WorkspaceInfo wkInfo,
IList<ChangeDependencies<ChangeInfo>> changesDependencies,
string operation,
EditorWindow parentWindow)
{
DependenciesDialog dialog = Create(wkInfo, changesDependencies, operation);
return dialog.RunModal(parentWindow) == ResponseType.Ok;
}
protected override void OnModalGUI()
{
using (new EditorGUILayout.HorizontalScope())
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.DependenciesDialogTitle));
}
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.DependenciesExplanation, mOperation));
Title(PlasticLocalization.GetString(PlasticLocalization.Name.ItemColumn));
Rect scrollWidth = GUILayoutUtility.GetRect(0, position.width, 1, 1);
GUI.DrawTexture(
new Rect(scrollWidth.x, scrollWidth.y, scrollWidth.width, 200),
Texture2D.whiteTexture);
DoDependenciesArea();
GUILayout.Space(20);
DoButtonsArea();
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.DependenciesDialogTitle);
}
void DoDependenciesArea()
{
// NOTE(rafa): We cannot use a tree view here because it misbehaves with the way we create the modals
mScrollPosition = EditorGUILayout.BeginScrollView(mScrollPosition, GUILayout.Height(200));
for (int i = 0; i < mChangesDependencies.Count; i++)
{
var dependant = mChangesDependencies[i];
bool isExpanded = mExpandedDependencies[i];
isExpanded = EditorGUILayout.Foldout(
isExpanded,
ChangeInfoView.GetPathDescription(
mWkInfo.ClientPath, dependant.Change),
UnityStyles.Dialog.Foldout);
mExpandedDependencies[i] = isExpanded;
if (isExpanded)
{
for (int j = 0; j < dependant.Dependencies.Count; j++)
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Space(20);
GUILayout.Label(
ChangeInfoView.GetPathDescription(
mWkInfo.ClientPath, dependant.Dependencies[j]),
UnityStyles.Paragraph);
}
}
}
}
EditorGUILayout.EndScrollView();
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(mOperation))
return;
OkButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
static DependenciesDialog Create(
WorkspaceInfo wkInfo,
IList<ChangeDependencies<ChangeInfo>> changesDependencies,
string operation)
{
var instance = CreateInstance<DependenciesDialog>();
instance.mWkInfo = wkInfo;
instance.mChangesDependencies = changesDependencies;
instance.mOperation = operation;
instance.mEnterKeyAction = instance.OkButtonAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mExpandedDependencies = new bool[changesDependencies.Count];
for (int i = 0; i < changesDependencies.Count; i++)
instance.mExpandedDependencies[i] = true;
return instance;
}
bool[] mExpandedDependencies;
Vector2 mScrollPosition;
string mOperation;
IList<ChangeDependencies<ChangeInfo>> mChangesDependencies;
WorkspaceInfo mWkInfo;
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c584c584ba20f4daea226141b9e55bd0
timeCreated: 1541611814
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,184 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
using Codice.CM.Client.Gui;
using Codice.Client.BaseCommands.EventTracking;
using Codice.CM.Common;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs
{
internal class EmptyCheckinMessageDialog : PlasticDialog
{
internal bool UserChoseToNotDisplayWarningAgain { get; private set; }
protected override string GetTitle()
{
return string.Empty;
}
protected override void OnModalGUI()
{
DoMainContentSection();
DoCheckboxSection();
DoButtonsArea();
}
void DoMainContentSection()
{
using (new EditorGUILayout.HorizontalScope())
{
EditorGUI.DrawRect(GUILayoutUtility.GetRect(56f, 56f), Color.white);
var plasticIconRect = GUILayoutUtility.GetRect(36f, 36f);
plasticIconRect.x -= 46f;
plasticIconRect.y += 10f;
GUI.DrawTexture(plasticIconRect, Images.GetPlasticIcon());
using (new EditorGUILayout.VerticalScope())
{
GUILayout.Label(
PlasticLocalization.GetString(
PlasticLocalization.Name.EmptyCommentsDialogTitle),
UnityStyles.Dialog.MessageTitle);
GUILayout.Space(3f);
GUILayout.Label(
PlasticLocalization.GetString(
PlasticLocalization.Name.EmptyCommentsDialogContent),
UnityStyles.Dialog.MessageText);
GUILayout.Space(15f);
}
}
}
void DoCheckboxSection()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Space(95f);
UserChoseToNotDisplayWarningAgain = TitleToggle(
PlasticLocalization.GetString(
PlasticLocalization.Name.DoNotShowMessageAgain),
UserChoseToNotDisplayWarningAgain);
}
}
void DoButtonsArea()
{
using (new EditorGUILayout.VerticalScope())
{
GUILayout.Space(25f);
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoCheckInAnywayButton();
GUILayout.Space(13f);
DoCancelButton();
return;
}
DoCancelButton();
GUILayout.Space(13f);
DoCheckInAnywayButton();
}
}
}
void DoCheckInAnywayButton()
{
if (!AcceptButton(
PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinAnyway),
30))
return;
if (!mSentCheckinAnywayTrackEvent)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
TrackFeatureUseEvent.Features.PendingChangesCheckinDialogCheckinAnyway);
mSentCheckinAnywayTrackEvent = true;
}
if (UserChoseToNotDisplayWarningAgain && !mSentCheckboxTrackEvent)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
TrackFeatureUseEvent.Features.PendingChangesCheckinDialogDoNotShowMessageAgain);
mSentCheckboxTrackEvent = true;
}
ApplyButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
if (!mSentCancelTrackEvent)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
TrackFeatureUseEvent.Features.PendingChangesCheckinDialogCancel);
mSentCancelTrackEvent = true;
}
CancelButtonAction();
}
internal static bool ShouldContinueWithCheckin(
EditorWindow parentWindow,
WorkspaceInfo wkInfo)
{
var dialog = Create(wkInfo);
// using the apply response as the 'Check In Anyway' button click
if (dialog.RunModal(parentWindow) != ResponseType.Apply)
return false;
if (dialog.UserChoseToNotDisplayWarningAgain)
{
var guiClientConfig = GuiClientConfig.Get();
guiClientConfig.Configuration.ShowEmptyCommentWarning = false;
guiClientConfig.Save();
}
return true;
}
static EmptyCheckinMessageDialog Create(WorkspaceInfo wkInfo)
{
var instance = CreateInstance<EmptyCheckinMessageDialog>();
instance.mEnterKeyAction = instance.OkButtonAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mWkInfo = wkInfo;
return instance;
}
WorkspaceInfo mWkInfo;
// IMGUI evaluates every frame, need to make sure feature tracks get sent only once
bool mSentCheckinAnywayTrackEvent = false;
bool mSentCancelTrackEvent = false;
bool mSentCheckboxTrackEvent = false;
}
}

View file

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

View file

@ -0,0 +1,186 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Items;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs
{
internal class FilterRulesConfirmationDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 520, 350);
}
}
internal static FilterRulesConfirmationData AskForConfirmation(
string[] rules,
bool isAddOperation,
bool isApplicableToAllWorkspaces,
EditorWindow parentWindow)
{
string explanation = PlasticLocalization.GetString(isAddOperation ?
PlasticLocalization.Name.FilterRulesConfirmationAddMessage :
PlasticLocalization.Name.FilterRulesConfirmationRemoveMessage);
FilterRulesConfirmationDialog dialog = Create(
explanation, GetRulesText(rules), isApplicableToAllWorkspaces);
ResponseType dialogResult = dialog.RunModal(parentWindow);
FilterRulesConfirmationData result = new FilterRulesConfirmationData(
dialog.mApplyRulesToAllWorkspace, dialog.GetRules());
result.Result = dialogResult == ResponseType.Ok;
return result;
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.FilterRulesConfirmationTitle));
Paragraph(mDialogExplanation);
RulesArea();
GUILayout.Space(20);
DoButtonsArea();
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.FilterRulesConfirmationTitle);
}
void RulesArea()
{
mScrollPosition = EditorGUILayout.BeginScrollView(mScrollPosition);
mRulesText = EditorGUILayout.TextArea(
mRulesText, GUILayout.ExpandHeight(true));
mIsTextAreaFocused = FixTextAreaSelectionIfNeeded(mIsTextAreaFocused);
EditorGUILayout.EndScrollView();
if (!mIsApplicableToAllWorkspaces)
return;
mApplyRulesToAllWorkspace = EditorGUILayout.ToggleLeft(
PlasticLocalization.GetString(PlasticLocalization.Name.ApplyRulesToAllWorkspaceCheckButton),
mApplyRulesToAllWorkspace, GUILayout.Width(200));
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.OkButton)))
return;
OkButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
string[] GetRules()
{
if (string.IsNullOrEmpty(mRulesText))
return new string[0];
return mRulesText.Split(
Environment.NewLine.ToCharArray(),
StringSplitOptions.RemoveEmptyEntries);
}
static bool FixTextAreaSelectionIfNeeded(bool isTextAreaFocused)
{
TextEditor textEditor = typeof(EditorGUI)
.GetField("activeEditor", BindingFlags.Static | BindingFlags.NonPublic)
.GetValue(null) as TextEditor;
// text editor is null when it is not focused
if (textEditor == null)
return false;
// restore the selection the first time that has selected text
// because it is done automatically by Unity
if (isTextAreaFocused)
return true;
if (string.IsNullOrEmpty(textEditor.SelectedText))
return false;
textEditor.SelectNone();
textEditor.MoveTextEnd();
return true;
}
static string GetRulesText(string[] rules)
{
if (rules == null)
return string.Empty;
return string.Join(Environment.NewLine, rules)
+ Environment.NewLine;
}
static FilterRulesConfirmationDialog Create(
string explanation,
string rulesText,
bool isApplicableToAllWorkspaces)
{
var instance = CreateInstance<FilterRulesConfirmationDialog>();
instance.mDialogExplanation = explanation;
instance.mRulesText = rulesText;
instance.mIsApplicableToAllWorkspaces = isApplicableToAllWorkspaces;
instance.mEnterKeyAction = instance.OkButtonAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
return instance;
}
bool mIsTextAreaFocused;
Vector2 mScrollPosition;
bool mApplyRulesToAllWorkspace;
bool mIsApplicableToAllWorkspaces;
string mRulesText;
string mDialogExplanation;
}
}

View file

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

View file

@ -0,0 +1,36 @@
using System.Collections.Generic;
using UnityEditor;
using Codice.Client.GameUI.Checkin;
using GluonGui.Dialog;
using GluonGui.WorkspaceWindow.Views.Checkin.Operations;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs
{
internal class LaunchCheckinConflictsDialog : CheckinUIOperation.ICheckinConflictsDialog
{
internal LaunchCheckinConflictsDialog(EditorWindow window)
{
mWindow = window;
}
Result CheckinUIOperation.ICheckinConflictsDialog.Show(
IList<CheckinConflict> conflicts,
PlasticLocalization.Name dialogTitle,
PlasticLocalization.Name dialogExplanation,
PlasticLocalization.Name okButtonCaption)
{
ResponseType responseType = CheckinConflictsDialog.Show(
conflicts, dialogTitle, dialogExplanation,
okButtonCaption, mWindow);
return responseType == ResponseType.Ok ?
Result.Ok : Result.Cancel;
}
EditorWindow mWindow;
}
}

View file

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

View file

@ -0,0 +1,29 @@
using System.Collections.Generic;
using UnityEditor;
using Codice.Client.BaseCommands;
using Codice.CM.Common;
using GluonGui.WorkspaceWindow.Views.Checkin.Operations;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs
{
internal class LaunchDependenciesDialog : DependenciesHandler.IDependenciesDialog
{
internal LaunchDependenciesDialog(string operation, EditorWindow parentWindow)
{
mOperation = operation;
mParentWindow = parentWindow;
}
bool DependenciesHandler.IDependenciesDialog.IncludeDependencies(
WorkspaceInfo wkInfo, IList<ChangeDependencies<ChangeInfo>> dependencies)
{
return DependenciesDialog.IncludeDependencies(
wkInfo, dependencies, mOperation, mParentWindow);
}
string mOperation;
EditorWindow mParentWindow;
}
}

View file

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

View file

@ -0,0 +1,120 @@
using System.Reflection;
using UnityEditor;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal static class DrawCommentTextArea
{
internal static void For(
PendingChangesTab pendingChangesTab,
float width,
bool isOperationRunning)
{
using (new GuiEnabled(!isOperationRunning))
{
EditorGUILayout.BeginHorizontal();
Rect textAreaRect = BuildTextAreaRect(
pendingChangesTab.CommentText,
width);
EditorGUI.BeginChangeCheck();
pendingChangesTab.CommentText = DoTextArea(
pendingChangesTab.CommentText ?? string.Empty,
pendingChangesTab.ForceToShowComment,
textAreaRect);
pendingChangesTab.ForceToShowComment = false;
if (EditorGUI.EndChangeCheck())
OnTextAreaChanged(pendingChangesTab);
if (string.IsNullOrEmpty(pendingChangesTab.CommentText))
{
DoPlaceholderIfNeeded(PlasticLocalization.GetString(
PlasticLocalization.Name.CheckinComment),
textAreaRect);
}
EditorGUILayout.EndHorizontal();
}
}
static void OnTextAreaChanged(PendingChangesTab pendingChangesTab)
{
pendingChangesTab.ClearIsCommentWarningNeeded();
}
static string DoTextArea(
string text,
bool forceToShowText,
Rect textAreaRect)
{
// while the text area has the focus, the changes to
// the source string will not be picked up by the text editor.
// so, when we want to change the text programmatically
// we have to remove the focus, set the text and then reset the focus.
TextEditor textEditor = typeof(EditorGUI)
.GetField("activeEditor", BindingFlags.Static | BindingFlags.NonPublic)
.GetValue(null) as TextEditor;
bool shouldBeFocusFixed = forceToShowText && textEditor != null;
if (shouldBeFocusFixed)
EditorGUIUtility.keyboardControl = 0;
var modifiedTextAreaStyle = new GUIStyle(EditorStyles.textArea);
modifiedTextAreaStyle.padding.left = 7;
modifiedTextAreaStyle.padding.top = 5;
modifiedTextAreaStyle.stretchWidth = false;
modifiedTextAreaStyle.stretchHeight = false;
text = EditorGUI.TextArea(textAreaRect, text, modifiedTextAreaStyle);
if (shouldBeFocusFixed)
EditorGUIUtility.keyboardControl = textEditor.controlID;
return text;
}
static void DoPlaceholderIfNeeded(string placeholder, Rect textAreaRect)
{
int textAreaControlId = GUIUtility.GetControlID(FocusType.Passive) - 1;
if (EditorGUIUtility.keyboardControl == textAreaControlId)
return;
Rect hintRect = textAreaRect;
hintRect.height = EditorStyles.textArea.lineHeight;
GUI.Label(hintRect, placeholder, UnityStyles.PendingChangesTab.CommentPlaceHolder);
}
static Rect BuildTextAreaRect(string text, float width)
{
GUIStyle commentTextAreaStyle = UnityStyles.PendingChangesTab.CommentTextArea;
commentTextAreaStyle.stretchWidth = false;
// The number here (230) controls how much the right side buttons are pushed off the
// screen when window is at min width
float contentWidth = width - 230f;
Rect result = GUILayoutUtility.GetRect(
contentWidth,
UnityConstants.PLASTIC_WINDOW_COMMENT_SECTION_HEIGHT);
result.width = contentWidth;
result.height = UnityConstants.PLASTIC_WINDOW_COMMENT_SECTION_HEIGHT;
result.xMin = 50f;
return result;
}
}
}

View file

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

View file

@ -0,0 +1,195 @@
using UnityEditor;
using UnityEngine;
using Codice.Client.BaseCommands;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Items;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal interface IFilesFilterPatternsMenuOperations
{
void AddFilesFilterPatterns(
FilterTypes type, FilterActions action, FilterOperationType operation);
}
internal class FilesFilterPatternsMenuBuilder
{
internal FilesFilterPatternsMenuBuilder(IFilesFilterPatternsMenuOperations operations)
{
mOperations = operations;
}
internal void BuildIgnoredSubmenuItem()
{
mIgnoredSubmenuItem = new GUIContent(string.Empty);
mIgnoredByNameMenuItemContent = new GUIContent(string.Empty);
mIgnoredByExtensionMenuItemContent = new GUIContent(string.Empty);
mIgnoredByFullPathMenuItemContent = new GUIContent(string.Empty);
}
internal void BuildHiddenChangesSubmenuItem()
{
mHiddenChangesSubmenuItem = new GUIContent(string.Empty);
mHiddenChangesByNameMenuItemContent = new GUIContent(string.Empty);
mHiddenChangesByExtensionMenuItemContent = new GUIContent(string.Empty);
mHiddenChangesByFullPathMenuItemContent = new GUIContent(string.Empty);
}
internal void UpdateMenuItems(GenericMenu menu, FilterMenuActions actions)
{
if (mIgnoredSubmenuItem != null)
UpdateIgnoredMenuItems(menu, actions.Operations);
if (mHiddenChangesSubmenuItem != null)
UpdateHiddenChangesMenuItems(menu, actions.Operations);
SetFilterMenuItemsLabels(actions);
}
void UpdateIgnoredMenuItems(GenericMenu menu, FilterMenuOperations operations)
{
if (!operations.HasFlag(FilterMenuOperations.Ignore))
{
menu.AddDisabledItem(mIgnoredSubmenuItem);
return;
}
menu.AddItem(mIgnoredByNameMenuItemContent, false, IgnoredByName_Click);
menu.AddItem(mIgnoredByExtensionMenuItemContent, false, IgnoredByExtension_Click);
if (!operations.HasFlag(FilterMenuOperations.IgnoreByExtension))
return;
menu.AddItem(mIgnoredByFullPathMenuItemContent, false, IgnoredByFullPath_Click);
}
void UpdateHiddenChangesMenuItems(GenericMenu menu, FilterMenuOperations operations)
{
if (!operations.HasFlag(FilterMenuOperations.HideChanged))
{
menu.AddDisabledItem(mHiddenChangesSubmenuItem);
return;
}
menu.AddItem(mHiddenChangesByNameMenuItemContent, false, HiddenChangesByName_Click);
menu.AddItem(mHiddenChangesByExtensionMenuItemContent, false, HiddenChangesByExtension_Click);
if (!operations.HasFlag(FilterMenuOperations.HideChangedByExtension))
return;
menu.AddItem(mHiddenChangesByFullPathMenuItemContent, false, HiddenChangesByFullPath_Click);
}
void IgnoredByName_Click()
{
mOperations.AddFilesFilterPatterns(
FilterTypes.Ignored, FilterActions.ByName,
GetIgnoredFilterOperationType());
}
void IgnoredByExtension_Click()
{
mOperations.AddFilesFilterPatterns(
FilterTypes.Ignored, FilterActions.ByExtension,
GetIgnoredFilterOperationType());
}
void IgnoredByFullPath_Click()
{
mOperations.AddFilesFilterPatterns(
FilterTypes.Ignored, FilterActions.ByFullPath,
GetIgnoredFilterOperationType());
}
void HiddenChangesByName_Click()
{
mOperations.AddFilesFilterPatterns(
FilterTypes.HiddenChanges, FilterActions.ByName,
GetHiddenChangesFilterOperationType());
}
void HiddenChangesByExtension_Click()
{
mOperations.AddFilesFilterPatterns(
FilterTypes.HiddenChanges, FilterActions.ByExtension,
GetHiddenChangesFilterOperationType());
}
void HiddenChangesByFullPath_Click()
{
mOperations.AddFilesFilterPatterns(
FilterTypes.HiddenChanges, FilterActions.ByFullPath,
GetHiddenChangesFilterOperationType());
}
FilterOperationType GetIgnoredFilterOperationType()
{
if (mIgnoredByNameMenuItemContent.text.StartsWith(PlasticLocalization.GetString(
PlasticLocalization.Name.MenuAddToIgnoreList)))
{
return FilterOperationType.Add;
}
return FilterOperationType.Remove;
}
FilterOperationType GetHiddenChangesFilterOperationType()
{
if (mHiddenChangesByNameMenuItemContent.text.StartsWith(PlasticLocalization.GetString(
PlasticLocalization.Name.MenuAddToHiddenChangesList)))
{
return FilterOperationType.Add;
}
return FilterOperationType.Remove;
}
void SetFilterMenuItemsLabels(FilterMenuActions actions)
{
if (mIgnoredSubmenuItem != null)
{
mIgnoredSubmenuItem.text = actions.IgnoredTitle;
mIgnoredByNameMenuItemContent.text = GetSubMenuText(
actions.IgnoredTitle, actions.FilterByName);
mIgnoredByExtensionMenuItemContent.text = GetSubMenuText(
actions.IgnoredTitle, actions.FilterByExtension);
mIgnoredByFullPathMenuItemContent.text = GetSubMenuText(
actions.IgnoredTitle, actions.FilterByFullPath);
}
if (mHiddenChangesSubmenuItem != null)
{
mHiddenChangesSubmenuItem.text = actions.HiddenChangesTitle;
mHiddenChangesByNameMenuItemContent.text = GetSubMenuText(
actions.HiddenChangesTitle, actions.FilterByName);
mHiddenChangesByExtensionMenuItemContent.text = GetSubMenuText(
actions.HiddenChangesTitle, actions.FilterByExtension);
mHiddenChangesByFullPathMenuItemContent.text = GetSubMenuText(
actions.HiddenChangesTitle, actions.FilterByFullPath);
}
}
static string GetSubMenuText(string menuName, string subMenuName)
{
return UnityMenuItem.GetText(
menuName,
UnityMenuItem.EscapedText(subMenuName));
}
GUIContent mIgnoredSubmenuItem;
GUIContent mHiddenChangesSubmenuItem;
GUIContent mIgnoredByNameMenuItemContent;
GUIContent mHiddenChangesByNameMenuItemContent;
GUIContent mIgnoredByExtensionMenuItemContent;
GUIContent mHiddenChangesByExtensionMenuItemContent;
GUIContent mIgnoredByFullPathMenuItemContent;
GUIContent mHiddenChangesByFullPathMenuItemContent;
IFilesFilterPatternsMenuOperations mOperations;
}
}

View file

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

View file

@ -0,0 +1,111 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal class PendingChangesMultiColumnHeader : MultiColumnHeader
{
internal PendingChangesMultiColumnHeader(
PendingChangesTreeView treeView,
MultiColumnHeaderState headerState,
UnityPendingChangesTree tree)
: base(headerState)
{
mPendingChangesTreeView = treeView;
mPendingChangesTree = tree;
}
protected override void ColumnHeaderGUI(MultiColumnHeaderState.Column column, Rect headerRect, int columnIndex)
{
if (columnIndex == 0)
{
bool checkAllWasMixed = IsMixedCheckedState();
bool checkAllWasTrue = IsAllCheckedState();
var checkRect = new Rect(
headerRect.x + UnityConstants.TREEVIEW_BASE_INDENT,
headerRect.y + 3 + UnityConstants.TREEVIEW_HEADER_CHECKBOX_Y_OFFSET, // Custom offset because header labels are not centered
UnityConstants.TREEVIEW_CHECKBOX_SIZE,
headerRect.height);
EditorGUI.showMixedValue = checkAllWasMixed;
bool checkAllIsTrue = EditorGUI.Toggle(
checkRect,
checkAllWasTrue);
EditorGUI.showMixedValue = false;
if (checkAllWasTrue != checkAllIsTrue)
{
UpdateCheckedState(checkAllIsTrue);
((PendingChangesTreeHeaderState)state).UpdateItemColumnHeader(mPendingChangesTreeView);
}
headerRect.x = checkRect.xMax;
headerRect.xMax = column.width;
}
base.ColumnHeaderGUI(column, headerRect, columnIndex);
}
internal bool IsAllCheckedState()
{
List<IPlasticTreeNode> nodes = mPendingChangesTree.GetNodes();
if (nodes == null || nodes.Count == 0)
return false;
foreach (IPlasticTreeNode node in nodes)
{
if (!(CheckedItems.GetIsCheckedValue(node) ?? false))
return false;
}
return true;
}
protected bool IsMixedCheckedState()
{
List<IPlasticTreeNode> nodes = mPendingChangesTree.GetNodes();
if (nodes == null)
return false;
bool hasCheckedNode = false;
bool hasUncheckedNode = false;
foreach (IPlasticTreeNode node in nodes)
{
if (CheckedItems.GetIsPartiallyCheckedValue(node))
return true;
if (CheckedItems.GetIsCheckedValue(node) ?? false)
hasCheckedNode = true;
else
hasUncheckedNode = true;
if (hasCheckedNode && hasUncheckedNode)
return true;
}
return false;
}
internal void UpdateCheckedState(bool isChecked)
{
List<IPlasticTreeNode> nodes = mPendingChangesTree.GetNodes();
if (nodes == null)
return;
foreach (IPlasticTreeNode node in nodes)
CheckedItems.SetCheckedValue(node, isChecked);
}
readonly PendingChangesTreeView mPendingChangesTreeView;
protected UnityPendingChangesTree mPendingChangesTree;
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e7b15873dbe9463cad67af4fac8e41ba
timeCreated: 1589491970

View file

@ -0,0 +1,165 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Codice.Client.BaseCommands;
using Codice.Client.Commands;
using PlasticGui.WorkspaceWindow.PendingChanges;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal static class PendingChangesSelection
{
internal static void SelectChanges(
PendingChangesTreeView treeView,
List<ChangeInfo> changesToSelect)
{
if (changesToSelect == null || changesToSelect.Count == 0)
{
treeView.SelectFirstPendingChangeOnTree();
return;
}
treeView.SelectPreviouslySelectedPendingChanges(changesToSelect);
if (treeView.HasSelection())
return;
treeView.SelectFirstPendingChangeOnTree();
}
internal static List<string> GetSelectedPathsWithoutMeta(
PendingChangesTreeView treeView)
{
return treeView.GetSelectedChanges(false)
.Select(change => change.GetFullPath()).ToList();
}
internal static List<string> GetSelectedPaths(
PendingChangesTreeView treeView)
{
return treeView.GetSelectedChanges(true)
.Select(change => change.GetFullPath()).ToList();
}
internal static List<string> GetSelectedMetaPaths(
PendingChangesTreeView treeView)
{
List<string> result = new List<string>();
foreach (ChangeInfo change in GetSelectedChanges(treeView))
{
string path = change.GetFullPath();
if (!MetaPath.IsMetaPath(path))
continue;
result.Add(path);
}
return result;
}
internal static List<ChangeInfo> GetAllChanges(
PendingChangesTreeView treeView)
{
return treeView.GetAllChanges();
}
internal static List<ChangeInfo> GetChangesToFocus(
PendingChangesTreeView treeView)
{
List<ChangeInfo> selectedChanges = treeView.GetSelectedChanges(true);
if (selectedChanges.Count == 0)
return selectedChanges;
List<ChangeInfo> changesToFocus =
selectedChanges.Where(change => !IsAddedFile(change)).ToList();
if (changesToFocus.Count() == 0)
{
ChangeInfo nearestAddedChange = treeView.GetNearestAddedChange();
if (nearestAddedChange != null)
changesToFocus.Add(nearestAddedChange);
}
return changesToFocus;
}
internal static SelectedChangesGroupInfo GetSelectedChangesGroupInfo(
string wkPath, PendingChangesTreeView treeView)
{
return SelectedChangesGroupInfo.BuildFromChangeInfos(
wkPath,
treeView.GetSelectedChanges(true),
GetInvolvedChangelists(treeView.GetSelectedPendingChangeInfos()));
}
internal static List<ChangeInfo> GetSelectedChanges(
PendingChangesTreeView treeView)
{
return treeView.GetSelectedChanges(true);
}
internal static List<ChangeListInfo> GetSelectedChangeListInfos(
PendingChangesTreeView treeView)
{
List<ChangeListInfo> result = new List<ChangeListInfo>();
List<ChangelistNode> nodes = treeView.GetSelectedChangelistNodes();
foreach (ChangelistNode node in nodes)
result.Add(node.ChangelistInfo);
return result;
}
internal static ChangeListInfo GetSelectedChangeListInfo(
PendingChangesTreeView treeView)
{
List<ChangeListInfo> changeListInfos = GetSelectedChangeListInfos(treeView);
if (changeListInfos.Count == 0)
return null;
return changeListInfos[0];
}
internal static List<ChangelistNode> GetSelectedChangelistNodes(
PendingChangesTreeView treeView)
{
return treeView.GetSelectedChangelistNodes();
}
internal static ChangeInfo GetSelectedChange(
PendingChangesTreeView treeView)
{
return treeView.GetSelectedRow();
}
static List<ChangeListInfo> GetInvolvedChangelists(List<PendingChangeInfo> changes)
{
List<ChangeListInfo> result = new List<ChangeListInfo>();
foreach (PendingChangeInfo pendingChangeInfo in changes)
{
ChangelistNode changelistNode =
(ChangelistNode)pendingChangeInfo.GetParent().GetParent();
if (changelistNode == null)
continue;
result.Add(changelistNode.ChangelistInfo);
}
return result;
}
static bool IsAddedFile(ChangeInfo change)
{
return ChangeTypesClassifier.IsInAddedCategory(change.ChangeTypes)
&& !(Directory.Exists(change.Path) || File.Exists(change.Path));
}
}
}

View file

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

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1b2dfd8c552c2468ca523d8dbb93ea5d
timeCreated: 1539019322
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,358 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Codice.Client.BaseCommands;
using Codice.Client.BaseCommands.EventTracking;
using Codice.Client.Common;
using Codice.CM.Common;
using GluonGui.WorkspaceWindow.Views.Checkin.Operations;
using PlasticGui;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal partial class PendingChangesTab
{
internal void UndoForMode(
WorkspaceInfo wkInfo,
bool isGluonMode)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
isGluonMode ?
TrackFeatureUseEvent.Features.PartialUndo :
TrackFeatureUseEvent.Features.Undo);
if (isGluonMode)
{
PartialUndo();
return;
}
Undo();
}
void UndoChangesForMode(
WorkspaceInfo wkInfo,
bool isGluonMode,
List<ChangeInfo> changesToUndo,
List<ChangeInfo> dependenciesCandidates)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
isGluonMode ?
TrackFeatureUseEvent.Features.PartialUndo :
TrackFeatureUseEvent.Features.Undo);
if (isGluonMode)
{
PartialUndoChanges(
changesToUndo, dependenciesCandidates);
return;
}
UndoChanges(
changesToUndo, dependenciesCandidates);
}
void CheckinForMode(
WorkspaceInfo wkInfo,
bool isGluonMode,
bool keepItemsLocked)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
isGluonMode ?
TrackFeatureUseEvent.Features.PartialCheckin :
TrackFeatureUseEvent.Features.Checkin);
if (isGluonMode)
{
PartialCheckin(keepItemsLocked);
return;
}
Checkin();
}
void CheckinChangesForMode(
List<ChangeInfo> changesToCheckin,
List<ChangeInfo> dependenciesCandidates,
WorkspaceInfo wkInfo,
bool isGluonMode,
bool keepItemsLocked)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
isGluonMode ?
TrackFeatureUseEvent.Features.PartialCheckin :
TrackFeatureUseEvent.Features.Checkin);
if (isGluonMode)
{
PartialCheckinChanges(
changesToCheckin, dependenciesCandidates, keepItemsLocked);
return;
}
CheckinChanges(
changesToCheckin, dependenciesCandidates);
}
void PartialCheckin(bool keepItemsLocked)
{
List<ChangeInfo> changesToCheckin;
List<ChangeInfo> dependenciesCandidates;
mPendingChangesTreeView.GetCheckedChanges(
null,
false,
out changesToCheckin,
out dependenciesCandidates);
PartialCheckinChanges(
changesToCheckin, dependenciesCandidates, keepItemsLocked);
}
void PartialCheckinChanges(
List<ChangeInfo> changesToCheckin,
List<ChangeInfo> dependenciesCandidates,
bool keepItemsLocked)
{
if (CheckEmptyOperation(changesToCheckin))
{
((IProgressControls)mProgressControls).ShowWarning(
PlasticLocalization.GetString(PlasticLocalization.Name.NoItemsAreSelected));
return;
}
bool isCancelled;
SaveAssets.ForChangesWithConfirmation(changesToCheckin, out isCancelled);
if (isCancelled)
return;
CheckinUIOperation ciOperation = new CheckinUIOperation(
mWkInfo, mViewHost, mProgressControls, mGuiMessage,
new LaunchCheckinConflictsDialog(mParentWindow),
new LaunchDependenciesDialog(
PlasticLocalization.GetString(PlasticLocalization.Name.CheckinButton),
mParentWindow),
this,
mWorkspaceWindow.GluonProgressOperationHandler,
null);
ciOperation.Checkin(
changesToCheckin,
dependenciesCandidates,
CommentText,
keepItemsLocked,
false,
EndCheckin);
}
void Checkin()
{
List<ChangeInfo> changesToCheckin;
List<ChangeInfo> dependenciesCandidates;
mPendingChangesTreeView.GetCheckedChanges(
null,
false, out changesToCheckin, out dependenciesCandidates);
CheckinChanges(changesToCheckin, dependenciesCandidates);
}
void CheckinChanges(
List<ChangeInfo> changesToCheckin,
List<ChangeInfo> dependenciesCandidates)
{
if (CheckEmptyOperation(changesToCheckin, HasPendingMergeLinks()))
{
((IProgressControls)mProgressControls).ShowWarning(
PlasticLocalization.GetString(PlasticLocalization.Name.NoItemsAreSelected));
return;
}
bool isCancelled;
SaveAssets.ForChangesWithConfirmation(changesToCheckin, out isCancelled);
if (isCancelled)
return;
mPendingChangesOperations.Checkin(
changesToCheckin,
dependenciesCandidates,
CommentText,
null,
EndCheckin,
null);
}
void ShelveChanges(
List<ChangeInfo> changesToShelve,
List<ChangeInfo> dependenciesCandidates,
WorkspaceInfo wkInfo)
{
ShelveChanges(changesToShelve, dependenciesCandidates);
}
void ShelveChanges(
List<ChangeInfo> changesToShelve,
List<ChangeInfo> dependenciesCandidates)
{
bool hasPendingMergeLinks = HasPendingMergeLinks();
if (hasPendingMergeLinks &&
!UserWantsShelveWithPendingMergeLinks(mGuiMessage))
{
return;
}
if (CheckEmptyOperation(changesToShelve, hasPendingMergeLinks))
{
((IProgressControls)mProgressControls).ShowWarning(
PlasticLocalization.GetString(PlasticLocalization.Name.NoItemsAreSelected));
return;
}
bool isCancelled;
SaveAssets.ForChangesWithConfirmation(changesToShelve, out isCancelled);
if (isCancelled)
return;
mPendingChangesOperations.Shelve(
changesToShelve,
dependenciesCandidates,
CommentText);
}
void PartialUndo()
{
List<ChangeInfo> changesToUndo;
List<ChangeInfo> dependenciesCandidates;
mPendingChangesTreeView.GetCheckedChanges(
null, true,
out changesToUndo, out dependenciesCandidates);
PartialUndoChanges(changesToUndo, dependenciesCandidates);
}
void PartialUndoChanges(
List<ChangeInfo> changesToUndo,
List<ChangeInfo> dependenciesCandidates)
{
if (CheckEmptyOperation(changesToUndo))
{
((IProgressControls)mProgressControls).ShowWarning(
PlasticLocalization.GetString(PlasticLocalization.Name.NoItemsToUndo));
return;
}
SaveAssets.ForChangesWithoutConfirmation(changesToUndo);
UndoUIOperation undoOperation = new UndoUIOperation(
mWkInfo, mViewHost,
new LaunchDependenciesDialog(
PlasticLocalization.GetString(PlasticLocalization.Name.UndoButton),
mParentWindow),
mProgressControls);
undoOperation.Undo(
changesToUndo,
dependenciesCandidates,
RefreshAsset.UnityAssetDatabase);
}
void Undo()
{
List<ChangeInfo> changesToUndo;
List<ChangeInfo> dependenciesCandidates;
mPendingChangesTreeView.GetCheckedChanges(
null, true,
out changesToUndo, out dependenciesCandidates);
UndoChanges(changesToUndo, dependenciesCandidates);
}
void UndoChanges(
List<ChangeInfo> changesToUndo,
List<ChangeInfo> dependenciesCandidates)
{
if (CheckEmptyOperation(changesToUndo, HasPendingMergeLinks()))
{
((IProgressControls)mProgressControls).ShowWarning(
PlasticLocalization.GetString(PlasticLocalization.Name.NoItemsToUndo));
return;
}
SaveAssets.ForChangesWithoutConfirmation(changesToUndo);
mPendingChangesOperations.Undo(
changesToUndo,
dependenciesCandidates,
mPendingMergeLinks.Count,
RefreshAsset.UnityAssetDatabase,
null);
}
void EndCheckin()
{
ShowCheckinSuccess();
RefreshAsset.UnityAssetDatabase();
}
void ShowCheckinSuccess()
{
bool isTreeViewEmpty = mPendingChangesTreeView.GetCheckedItemCount() ==
mPendingChangesTreeView.GetTotalItemCount();
if (isTreeViewEmpty)
{
mIsCheckedInSuccessful = true;
mCooldownClearCheckinSuccessAction.Ping();
return;
}
mStatusBar.Notify(
PlasticLocalization.GetString(PlasticLocalization.Name.CheckinCompleted),
UnityEditor.MessageType.None,
Images.GetStepOkIcon());
}
void DelayedClearCheckinSuccess()
{
mIsCheckedInSuccessful = false;
}
static bool CheckEmptyOperation(List<ChangeInfo> elements)
{
return elements == null || elements.Count == 0;
}
static bool CheckEmptyOperation(List<ChangeInfo> elements, bool bHasPendingMergeLinks)
{
if (bHasPendingMergeLinks)
return false;
if (elements != null && elements.Count > 0)
return false;
return true;
}
static bool UserWantsShelveWithPendingMergeLinks(GuiMessage.IGuiMessage guiMessage)
{
return guiMessage.ShowQuestion(
PlasticLocalization.GetString(PlasticLocalization.Name.ShelveWithPendingMergeLinksRequest),
PlasticLocalization.GetString(PlasticLocalization.Name.ShelveWithPendingMergeLinksRequestMessage),
PlasticLocalization.GetString(PlasticLocalization.Name.ShelveButton));
}
}
}

View file

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

View file

@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal enum PendingChangesTreeColumn
{
Item,
Status,
Size,
Extension,
Type,
DateModififed,
Repository
}
[Serializable]
internal class PendingChangesTreeHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static PendingChangesTreeHeaderState GetDefault(bool isGluonMode)
{
PendingChangesTreeHeaderState headerState =
new PendingChangesTreeHeaderState(BuildColumns());
headerState.visibleColumns = GetDefaultVisibleColumns();
SetMode(headerState, isGluonMode);
return headerState;
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.ItemColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.StatusColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.SizeColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.ExtensionColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.TypeColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.DateModifiedColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryColumn));
return result;
}
internal static string GetColumnName(PendingChangesTreeColumn column)
{
switch (column)
{
case PendingChangesTreeColumn.Item:
return PlasticLocalization.GetString(PlasticLocalization.Name.ItemColumn);
case PendingChangesTreeColumn.Status:
return PlasticLocalization.GetString(PlasticLocalization.Name.StatusColumn);
case PendingChangesTreeColumn.Size:
return PlasticLocalization.GetString(PlasticLocalization.Name.SizeColumn);
case PendingChangesTreeColumn.Extension:
return PlasticLocalization.GetString(PlasticLocalization.Name.ExtensionColumn);
case PendingChangesTreeColumn.Type:
return PlasticLocalization.GetString(PlasticLocalization.Name.TypeColumn);
case PendingChangesTreeColumn.DateModififed:
return PlasticLocalization.GetString(PlasticLocalization.Name.DateModifiedColumn);
case PendingChangesTreeColumn.Repository:
return PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryColumn);
default:
return null;
}
}
internal static void SetMode(MultiColumnHeaderState state, bool isGluonMode)
{
List<int> result = state.visibleColumns.ToList();
if (!result.Contains((int)PendingChangesTreeColumn.Item))
result.Add((int)PendingChangesTreeColumn.Item);
if (isGluonMode)
result.Remove((int)PendingChangesTreeColumn.Type);
state.columns[(int)PendingChangesTreeColumn.Item].allowToggleVisibility = false;
state.columns[(int)PendingChangesTreeColumn.Type].allowToggleVisibility = !isGluonMode;
state.visibleColumns = result.ToArray();
}
internal void UpdateItemColumnHeader(PendingChangesTreeView treeView)
{
Column itemColumn = columns[(int)PendingChangesTreeColumn.Item];
string columnName = GetColumnName(PendingChangesTreeColumn.Item);
int totalItemCount = treeView.GetTotalItemCount();
if (totalItemCount > 0)
{
string columnStatus = string.Format(
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsSelected),
treeView.GetCheckedItemCount(),
totalItemCount);
itemColumn.headerContent.text = string.Format("{0} {1}", columnName, columnStatus);
}
else
{
itemColumn.headerContent.text = columnName;
}
}
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)PendingChangesTreeColumn.Item);
result.Add((int)PendingChangesTreeColumn.Status);
result.Add((int)PendingChangesTreeColumn.DateModififed);
return result.ToArray();
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 800,
headerContent = new GUIContent(
GetColumnName(PendingChangesTreeColumn.Item)),
minWidth = 200,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 200,
headerContent = new GUIContent(
GetColumnName(PendingChangesTreeColumn.Status)),
minWidth = 80,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 80,
headerContent = new GUIContent(
GetColumnName(PendingChangesTreeColumn.Size)),
minWidth = 45,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 70,
headerContent = new GUIContent(
GetColumnName(PendingChangesTreeColumn.Extension)),
minWidth = 50,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 60,
headerContent = new GUIContent(
GetColumnName(PendingChangesTreeColumn.Type)),
minWidth = 45,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 330,
headerContent = new GUIContent(
GetColumnName(PendingChangesTreeColumn.DateModififed)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 210,
headerContent = new GUIContent(
GetColumnName(PendingChangesTreeColumn.Repository)),
minWidth = 90,
sortingArrowAlignment = TextAlignment.Right
}
};
}
PendingChangesTreeHeaderState(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,12 @@
fileFormatVersion: 2
guid: e57affb3c41ab402e86f99747be972a2
timeCreated: 1539690273
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,998 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.BaseCommands;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.PendingChanges;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
using Unity.PlasticSCM.Editor.AssetsOverlays;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal class PendingChangesTreeView : TreeView
{
internal PendingChangesTreeView(
WorkspaceInfo wkInfo,
bool isGluonMode,
PendingChangesTreeHeaderState headerState,
List<string> columnNames,
PendingChangesViewMenu menu,
IAssetStatusCache assetStatusCache)
: base(new TreeViewState())
{
mWkInfo = wkInfo;
mIsGluonMode = isGluonMode;
mColumnNames = columnNames;
mHeaderState = headerState;
mMenu = menu;
mAssetStatusCache = assetStatusCache;
mPendingChangesTree = new UnityPendingChangesTree();
multiColumnHeader = new PendingChangesMultiColumnHeader(
this,
headerState,
mPendingChangesTree);
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);
}
protected override void SelectionChanged(IList<int> selectedIds)
{
mHeaderState.UpdateItemColumnHeader(this);
if (mIsSelectionChangedEventDisabled)
return;
List<UnityEngine.Object> assets = new List<UnityEngine.Object>();
foreach (ChangeInfo changeInfo in GetSelectedChanges(false))
{
UnityEngine.Object asset = LoadAsset.FromChangeInfo(changeInfo);
if (asset == null)
continue;
assets.Add(asset);
}
UnityEditor.Selection.objects = assets.ToArray();
}
protected void SelectionChanged()
{
SelectionChanged(GetSelection());
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
public override void OnGUI(Rect rect)
{
MultiColumnHeader.DefaultStyles.background =
UnityStyles.Tree.Columns;
try
{
base.OnGUI(rect);
if (!base.HasFocus())
return;
Event e = Event.current;
if (e.type != EventType.KeyDown)
return;
bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e);
if (isProcessed)
e.Use();
}
finally
{
MultiColumnHeader.DefaultStyles.background =
UnityStyles.PendingChangesTab.DefaultMultiColumHeader;
}
}
protected override bool CanChangeExpandedState(TreeViewItem item)
{
return item is ChangeCategoryTreeViewItem || item is ChangelistTreeViewItem;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem rootItem)
{
try
{
RegenerateRows(
mPendingChangesTree, mTreeViewItemIds, this,
rootItem, mRows, mExpandCategories);
}
finally
{
mExpandCategories = false;
}
return mRows;
}
protected override void CommandEventHandling()
{
// NOTE - empty override to prevent crash when pressing ctrl-a in the treeview
}
protected override void SearchChanged(string newSearch)
{
mCooldownFilterAction.Ping();
}
protected override void ContextClickedItem(int id)
{
mMenu.Popup();
Repaint();
}
protected override void BeforeRowsGUI()
{
int firstRowVisible;
int lastRowVisible;
GetFirstAndLastVisibleRows(out firstRowVisible, out lastRowVisible);
GUI.DrawTexture(new Rect(0,
firstRowVisible * rowHeight,
GetRowRect(0).width,
(lastRowVisible * rowHeight) + 1000),
Images.GetTreeviewBackgroundTexture());
DrawTreeViewItem.InitializeStyles();
base.BeforeRowsGUI();
}
protected override void RowGUI(RowGUIArgs args)
{
if (args.item is ChangelistTreeViewItem)
{
ChangelistTreeViewItemGUI(
this,
args.rowRect, rowHeight,
(ChangelistTreeViewItem)args.item,
args.selected, args.focused);
return;
}
if (args.item is ChangeCategoryTreeViewItem)
{
CategoryTreeViewItemGUI(
this,
args.rowRect, rowHeight,
(ChangeCategoryTreeViewItem)args.item,
args.selected, args.focused);
return;
}
if (args.item is ChangeTreeViewItem)
{
ChangeTreeViewItemGUI(
mWkInfo.ClientPath,
mIsGluonMode,
mAssetStatusCache,
this,
mPendingChangesTree,
(ChangeTreeViewItem)args.item,
args);
return;
}
base.RowGUI(args);
}
internal void BuildModel(List<ChangeInfo> changes, CheckedStateManager checkedStateManager)
{
mTreeViewItemIds.Clear();
mPendingChangesTree.BuildChangeCategories(
mWkInfo,
changes,
checkedStateManager);
}
internal ChangeInfo GetChangedForMoved(ChangeInfo moved)
{
return mPendingChangesTree.GetChangedForMoved(moved);
}
internal void Refilter()
{
Filter filter = new Filter(searchString);
mPendingChangesTree.Filter(filter, mColumnNames);
mExpandCategories = true;
}
internal void Sort()
{
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mPendingChangesTree.Sort(
mColumnNames[sortedColumnIdx],
sortAscending);
}
internal bool GetSelectedPathsToDelete(
out List<string> privateDirectories,
out List<string> privateFiles)
{
privateDirectories = new List<string>();
privateFiles = new List<string>();
List<ChangeInfo> dirChanges = new List<ChangeInfo>();
List<ChangeInfo> fileChanges = new List<ChangeInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return false;
foreach (KeyValuePair<PendingChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
ChangeInfo changeInfo = item.Key.ChangeInfo;
if (ChangeInfoType.IsControlled(changeInfo))
continue;
if (changeInfo.IsDirectory)
{
dirChanges.Add(changeInfo);
continue;
}
fileChanges.Add(changeInfo);
}
mPendingChangesTree.FillWithMeta(fileChanges);
mPendingChangesTree.FillWithMeta(dirChanges);
privateDirectories = dirChanges.Select(
d => d.GetFullPath()).ToList();
privateFiles = fileChanges.Select(
f => f.GetFullPath()).ToList();
return true;
}
internal void GetCheckedChanges(
List<ChangelistNode> selectedChangelists,
bool bExcludePrivates,
out List<ChangeInfo> changes,
out List<ChangeInfo> dependenciesCandidates)
{
mPendingChangesTree.GetCheckedChanges(
selectedChangelists,
bExcludePrivates,
out changes,
out dependenciesCandidates);
}
internal List<ChangeInfo> GetAllChanges()
{
return mPendingChangesTree.GetAllChanges();
}
internal ChangeInfo GetMetaChange(ChangeInfo change)
{
if (change == null)
return null;
return mPendingChangesTree.GetMetaChange(change);
}
internal List<ChangeInfo> GetDependenciesCandidates(
List<ChangeInfo> selectedChanges, bool bExcludePrivates)
{
return mPendingChangesTree.GetDependenciesCandidates(
selectedChanges, bExcludePrivates);
}
internal List<IPlasticTreeNode> GetSelectedNodes()
{
List<IPlasticTreeNode> result = new List<IPlasticTreeNode>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<IPlasticTreeNode, int> item
in mTreeViewItemIds.GetCategoryItems())
{
if (!selectedIds.Contains(item.Value))
continue;
result.Add(item.Key);
}
foreach (KeyValuePair<PendingChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
result.Add(item.Key);
}
return result;
}
internal List<ChangeInfo> GetSelectedChanges(bool includeMetaFiles)
{
List<ChangeInfo> result = new List<ChangeInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<PendingChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
result.Add(item.Key.ChangeInfo);
}
if (includeMetaFiles)
mPendingChangesTree.FillWithMeta(result);
return result;
}
internal List<PendingChangeInfo> GetSelectedPendingChangeInfos()
{
List<PendingChangeInfo> result = new List<PendingChangeInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<PendingChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
result.Add(item.Key);
}
return result;
}
internal List<ChangelistNode> GetSelectedChangelistNodes()
{
List<ChangelistNode> result = new List<ChangelistNode>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<IPlasticTreeNode, int> item
in mTreeViewItemIds.GetCategoryItems())
{
if (!selectedIds.Contains(item.Value))
continue;
if (item.Key is ChangelistNode)
result.Add((ChangelistNode)item.Key);
}
return result;
}
internal bool SelectionHasMeta()
{
ChangeInfo selectedChangeInfo = GetSelectedRow();
if (selectedChangeInfo == null)
return false;
return mPendingChangesTree.HasMeta(selectedChangeInfo);
}
internal ChangeInfo GetSelectedRow()
{
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return null;
int selectedId = selectedIds[0];
foreach (KeyValuePair<PendingChangeInfo, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (selectedId == item.Value)
return item.Key.ChangeInfo;
}
return null;
}
internal ChangeInfo GetNearestAddedChange()
{
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return null;
int id = selectedIds[0];
IList<TreeViewItem> treeViewItems =
FindRows(new List<int>() { id });
if (treeViewItems.Count == 0)
return null;
PendingChangeInfo changeInfo =
((ChangeTreeViewItem)treeViewItems[0]).ChangeInfo;
PendingChangeCategory category =
(PendingChangeCategory)changeInfo.GetParent();
int itemIndex = category.GetChildPosition(changeInfo);
ChangeInfo result = GetNextExistingAddedItem(category, itemIndex);
if (result != null)
return result;
return GetPreviousExistingAddedItem(category, itemIndex);
}
internal void SelectFirstPendingChangeOnTree()
{
int treeIdFirstItem = GetTreeIdFirstItem();
if (treeIdFirstItem == -1)
return;
mIsSelectionChangedEventDisabled = true;
try
{
TableViewOperations.SetSelectionAndScroll(
this, new List<int> { treeIdFirstItem });
}
finally
{
mIsSelectionChangedEventDisabled = false;
}
}
internal void SelectPreviouslySelectedPendingChanges(
List<ChangeInfo> changesToSelect)
{
List<int> idsToSelect = new List<int>();
foreach (ChangeInfo change in changesToSelect)
{
int changeId = GetTreeIdForItem(change);
if (changeId == -1)
continue;
idsToSelect.Add(changeId);
}
mIsSelectionChangedEventDisabled = true;
try
{
TableViewOperations.SetSelectionAndScroll(
this, idsToSelect);
}
finally
{
mIsSelectionChangedEventDisabled = false;
}
}
internal int GetCheckedItemCount()
{
return CheckedItems.GetCheckedChildNodeCount(mPendingChangesTree.GetNodes());
}
internal int GetTotalItemCount()
{
return CheckedItems.GetTotalChildNodeCount(mPendingChangesTree.GetNodes());
}
ChangeInfo GetNextExistingAddedItem(
PendingChangeCategory addedCategory, int targetAddedItemIndex)
{
int addedItemsCount = addedCategory.GetChildrenCount();
for (int i = targetAddedItemIndex + 1; i < addedItemsCount; i++)
{
ChangeInfo currentChangeInfo = GetExistingAddedItem(addedCategory, i);
if (currentChangeInfo != null)
return currentChangeInfo;
}
return null;
}
ChangeInfo GetPreviousExistingAddedItem(
PendingChangeCategory addedCategory, int targetAddedItemIndex)
{
for (int i = targetAddedItemIndex - 1; i >= 0; i--)
{
ChangeInfo currentChangeInfo = GetExistingAddedItem(addedCategory, i);
if (currentChangeInfo != null)
return currentChangeInfo;
}
return null;
}
ChangeInfo GetExistingAddedItem(
PendingChangeCategory addedCategory, int addedItemIndex)
{
ChangeInfo currentChangeInfo = ((PendingChangeInfo)addedCategory.
GetChild(addedItemIndex)).ChangeInfo;
if (Directory.Exists(currentChangeInfo.Path) ||
File.Exists(currentChangeInfo.Path))
return currentChangeInfo;
return null;
}
int GetTreeIdFirstItem()
{
PendingChangeInfo firstChange = mPendingChangesTree.GetFirstPendingChange();
if (firstChange == null)
return -1;
int changeId;
if (mTreeViewItemIds.TryGetInfoItemId(firstChange, out changeId))
return changeId;
return -1;
}
int GetTreeIdForItem(ChangeInfo change)
{
foreach (KeyValuePair<PendingChangeInfo, int> item in mTreeViewItemIds.GetInfoItems())
{
ChangeInfo changeInfo = item.Key.ChangeInfo;
if (changeInfo.ChangeTypes != change.ChangeTypes)
continue;
if (changeInfo.GetFullPath() != change.GetFullPath())
continue;
return item.Value;
}
return -1;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void ChangelistTreeViewItemGUI(
PendingChangesTreeView treeView,
Rect rowRect,
float rowHeight,
ChangelistTreeViewItem item,
bool isSelected,
bool isFocused)
{
string label = item.Changelist.ChangelistInfo.Name;
string secondaryLabel = item.Changelist.ChangelistInfo.Description;
bool wasChecked = CheckedItems.GetIsCheckedValue(item.Changelist) ?? false;
bool hadCheckedChildren =
((ICheckablePlasticTreeCategoryGroup)item.Changelist).GetCheckedCategoriesCount() > 0;
bool hadPartiallyCheckedChildren =
((ICheckablePlasticTreeCategoryGroup)item.Changelist).GetPartiallyCheckedCategoriesCount() > 0;
bool isChecked = DrawTreeViewItem.ForCheckableCategoryItem(
rowRect,
rowHeight,
item.depth,
label,
secondaryLabel,
isSelected,
isFocused,
wasChecked,
hadCheckedChildren,
hadPartiallyCheckedChildren);
if (wasChecked != isChecked)
{
CheckedItems.SetCheckedValue(item.Changelist, isChecked);
treeView.SelectionChanged();
}
}
static void CategoryTreeViewItemGUI(
PendingChangesTreeView treeView,
Rect rowRect,
float rowHeight,
ChangeCategoryTreeViewItem item,
bool isSelected,
bool isFocused)
{
string label = item.Category.CategoryName;
string secondaryLabel = item.Category.GetCheckedChangesText();
bool wasChecked = item.Category.IsChecked();
bool hadCheckedChildren =
((ICheckablePlasticTreeCategory)item.Category).GetCheckedChangesCount() > 0;
bool isChecked = DrawTreeViewItem.ForCheckableCategoryItem(
rowRect,
rowHeight,
item.depth,
label,
secondaryLabel,
isSelected,
isFocused,
wasChecked,
hadCheckedChildren,
false);
if (wasChecked != isChecked)
{
CheckedItems.SetCheckedValue(item.Category, isChecked);
treeView.SelectionChanged();
}
}
static void ChangeTreeViewItemGUI(
string wkPath,
bool isGluonMode,
IAssetStatusCache assetStatusCache,
PendingChangesTreeView treeView,
UnityPendingChangesTree pendingChangesTree,
ChangeTreeViewItem item,
RowGUIArgs args)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
PendingChangesTreeColumn column =
(PendingChangesTreeColumn)args.GetColumn(visibleColumnIdx);
ChangeTreeViewItemCellGUI(
isGluonMode,
assetStatusCache,
cellRect,
treeView.rowHeight,
treeView,
pendingChangesTree,
item,
column,
args.selected,
args.focused);
}
}
static void ChangeTreeViewItemCellGUI(
bool isGluonMode,
IAssetStatusCache assetStatusCache,
Rect rect,
float rowHeight,
PendingChangesTreeView treeView,
UnityPendingChangesTree pendingChangesTree,
ChangeTreeViewItem item,
PendingChangesTreeColumn column,
bool isSelected,
bool isFocused)
{
PendingChangeInfo changeInfo = item.ChangeInfo;
string label = changeInfo.GetColumnText(
PendingChangesTreeHeaderState.GetColumnName(column));
DefaultStyles.label.fontSize = UnityConstants.PENDING_CHANGES_FONT_SIZE;
if (column == PendingChangesTreeColumn.Item)
{
if (pendingChangesTree.HasMeta(changeInfo.ChangeInfo))
label = string.Concat(label, UnityConstants.TREEVIEW_META_LABEL);
Texture icon = GetIcon(changeInfo);
bool isConflicted = IsConflicted(
isGluonMode, assetStatusCache,
changeInfo.ChangeInfo.GetFullPath());
Texture overlayIcon =
GetChangesOverlayIcon.ForPendingChange(
changeInfo.ChangeInfo, isConflicted);
bool wasChecked = ((ICheckablePlasticTreeNode)changeInfo).IsChecked();
bool isChecked = DrawTreeViewItem.ForCheckableItemCell(
rect, rowHeight, item.depth,
icon, overlayIcon, label,
isSelected, isFocused, false,
wasChecked);
((ICheckablePlasticTreeNode)changeInfo).UpdateCheckedState(isChecked);
if (wasChecked != isChecked)
{
UpdateCheckStateForSelection(treeView, item);
treeView.SelectionChanged();
}
return;
}
if (column == PendingChangesTreeColumn.Size)
{
DrawTreeViewItem.ForSecondaryLabelRightAligned(
rect, label, isSelected, isFocused, false);
return;
}
DrawTreeViewItem.ForSecondaryLabel(
rect, label, isSelected, isFocused, false);
}
static void UpdateCheckStateForSelection(
PendingChangesTreeView 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();
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 RegenerateRows(
UnityPendingChangesTree pendingChangesTree,
TreeViewItemIds<IPlasticTreeNode, PendingChangeInfo> treeViewItemIds,
PendingChangesTreeView treeView,
TreeViewItem rootItem,
List<TreeViewItem> rows,
bool expandCategories)
{
ClearRows(rootItem, rows);
List<IPlasticTreeNode> nodes = pendingChangesTree.GetNodes();
if (nodes == null)
return;
foreach (IPlasticTreeNode node in nodes)
{
if (node is ChangelistNode)
{
AddChangelistNode(
(ChangelistNode)node,
treeViewItemIds,
treeView,
rootItem,
rows,
expandCategories);
continue;
}
if (node is PendingChangeCategory)
AddPendingChangeCategory(
(PendingChangeCategory)node,
treeViewItemIds,
treeView,
rootItem,
rows,
expandCategories,
0);
}
if (!expandCategories)
return;
treeView.state.expandedIDs = treeViewItemIds.GetCategoryIds();
}
static void AddChangelistNode(
ChangelistNode changelist,
TreeViewItemIds<IPlasticTreeNode, PendingChangeInfo> treeViewItemIds,
PendingChangesTreeView treeView,
TreeViewItem rootItem,
List<TreeViewItem> rows,
bool expandCategories)
{
int changelistCategoryId;
if (!treeViewItemIds.TryGetCategoryItemId(changelist, out changelistCategoryId))
changelistCategoryId = treeViewItemIds.AddCategoryItem(changelist);
ChangelistTreeViewItem changelistTreeViewItem =
new ChangelistTreeViewItem(changelistCategoryId, changelist);
rootItem.AddChild(changelistTreeViewItem);
rows.Add(changelistTreeViewItem);
if (!expandCategories &&
!treeView.IsExpanded(changelistTreeViewItem.id))
return;
IList<IPlasticTreeNode> categories = ((IPlasticTreeNode)changelist).GetChildren();
foreach (IPlasticTreeNode category in categories)
{
AddPendingChangeCategory(
(PendingChangeCategory)category,
treeViewItemIds,
treeView,
changelistTreeViewItem,
rows,
expandCategories,
1);
}
}
static void AddPendingChangeCategory(
PendingChangeCategory category,
TreeViewItemIds<IPlasticTreeNode, PendingChangeInfo> treeViewItemIds,
PendingChangesTreeView treeView,
TreeViewItem rootItem,
List<TreeViewItem> rows,
bool expandCategories,
int depth)
{
int categoryId;
if (!treeViewItemIds.TryGetCategoryItemId(category, out categoryId))
categoryId = treeViewItemIds.AddCategoryItem(category);
ChangeCategoryTreeViewItem categoryTreeViewItem =
new ChangeCategoryTreeViewItem(categoryId, category, depth);
rootItem.AddChild(categoryTreeViewItem);
rows.Add(categoryTreeViewItem);
if (!expandCategories &&
!treeView.IsExpanded(categoryTreeViewItem.id))
return;
foreach (PendingChangeInfo change in category.GetCurrentChanges())
{
int changeId;
if (!treeViewItemIds.TryGetInfoItemId(change, out changeId))
changeId = treeViewItemIds.AddInfoItem(change);
TreeViewItem changeTreeViewItem =
new ChangeTreeViewItem(changeId, change, depth + 1);
categoryTreeViewItem.AddChild(changeTreeViewItem);
rows.Add(changeTreeViewItem);
}
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static Texture GetIcon(PendingChangeInfo change)
{
if (change.ChangeInfo.IsDirectory)
return Images.GetDirectoryIcon();
string fullPath = change.ChangeInfo.GetFullPath();
return Images.GetFileIcon(fullPath);
}
static bool IsConflicted(
bool isGluonMode,
IAssetStatusCache assetStatusCache,
string fullPath)
{
if (!isGluonMode)
return false;
return ClassifyAssetStatus.IsConflicted(
assetStatusCache.GetStatus(fullPath));
}
bool mExpandCategories;
bool mIsSelectionChangedEventDisabled;
TreeViewItemIds<IPlasticTreeNode, PendingChangeInfo> mTreeViewItemIds =
new TreeViewItemIds<IPlasticTreeNode, PendingChangeInfo>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
UnityPendingChangesTree mPendingChangesTree;
CooldownWindowDelayer mCooldownFilterAction;
readonly PendingChangesTreeHeaderState mHeaderState;
readonly PendingChangesViewMenu mMenu;
readonly IAssetStatusCache mAssetStatusCache;
readonly List<string> mColumnNames;
readonly bool mIsGluonMode;
readonly WorkspaceInfo mWkInfo;
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 594dcd9e9e4804aa281a66d024d30752
timeCreated: 1539617947
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,133 @@
using System.Collections.Generic;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Open;
using PlasticGui.WorkspaceWindow.PendingChanges;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
using Unity.PlasticSCM.Editor.Views.PendingChanges.Changelists;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal class PendingChangesViewMenu
{
internal interface IGetSelectedNodes
{
List<IPlasticTreeNode> GetSelectedNodes();
}
internal PendingChangesViewMenu(
WorkspaceInfo wkInfo,
IPendingChangesMenuOperations pendingChangesViewOperations,
IFilesFilterPatternsMenuOperations filterMenuOperations,
IOpenMenuOperations openMenuOperations,
PendingChangesViewPendingChangeMenu.IMetaMenuOperations metaMenuOperations,
IChangelistMenuOperations changelistMenuOperations,
IGetSelectedNodes getSelectedNodes,
bool isGluonMode)
{
mWkInfo = wkInfo;
mPendingChangesViewOperations = pendingChangesViewOperations;
mFilterMenuOperations = filterMenuOperations;
mOpenMenuOperations = openMenuOperations;
mMetaMenuOperations = metaMenuOperations;
mChangelistMenuOperations = changelistMenuOperations;
mGetSelectedNodes = getSelectedNodes;
mIsGluonMode = isGluonMode;
}
internal void Popup()
{
List<IPlasticTreeNode> selectedNodes = mGetSelectedNodes.GetSelectedNodes();
if (AreAllChangelists(selectedNodes))
{
GetChangelistMenu().Popup();
return;
}
if (AreAllPendingChanges(selectedNodes))
{
GetPendingChangeMenu().Popup();
return;
}
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
List<IPlasticTreeNode> selectedNodes = mGetSelectedNodes.GetSelectedNodes();
if (AreAllChangelists(selectedNodes))
{
return GetChangelistMenu().ProcessKeyActionIfNeeded(e);
}
if (AreAllPendingChanges(selectedNodes))
{
return GetPendingChangeMenu().ProcessKeyActionIfNeeded(e);
}
return false;
}
PendingChangesViewPendingChangeMenu GetPendingChangeMenu()
{
if (mPendingChangeMenu == null)
{
mPendingChangeMenu = new PendingChangesViewPendingChangeMenu(
mWkInfo,
mPendingChangesViewOperations,
mChangelistMenuOperations,
mOpenMenuOperations,
mMetaMenuOperations,
mFilterMenuOperations);
}
return mPendingChangeMenu;
}
ChangelistMenu GetChangelistMenu()
{
if (mChangelistMenu == null)
mChangelistMenu = new ChangelistMenu(
mChangelistMenuOperations,
mIsGluonMode);
return mChangelistMenu;
}
static bool AreAllChangelists(List<IPlasticTreeNode> selectedNodes)
{
foreach (IPlasticTreeNode node in selectedNodes)
{
if (!(node is ChangelistNode))
return false;
}
return true;
}
static bool AreAllPendingChanges(List<IPlasticTreeNode> selectedNodes)
{
foreach (IPlasticTreeNode node in selectedNodes)
{
if (!(node is PendingChangeInfo))
return false;
}
return true;
}
PendingChangesViewPendingChangeMenu mPendingChangeMenu;
ChangelistMenu mChangelistMenu;
readonly WorkspaceInfo mWkInfo;
readonly IPendingChangesMenuOperations mPendingChangesViewOperations;
readonly IFilesFilterPatternsMenuOperations mFilterMenuOperations;
readonly IOpenMenuOperations mOpenMenuOperations;
readonly PendingChangesViewPendingChangeMenu.IMetaMenuOperations mMetaMenuOperations;
readonly IChangelistMenuOperations mChangelistMenuOperations;
readonly IGetSelectedNodes mGetSelectedNodes;
readonly bool mIsGluonMode;
}
}

View file

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

View file

@ -0,0 +1,477 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Codice.Client.Commands;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Items;
using PlasticGui.WorkspaceWindow.Open;
using PlasticGui.WorkspaceWindow.PendingChanges;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.Views.PendingChanges.Changelists;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal class PendingChangesViewPendingChangeMenu
{
internal interface IMetaMenuOperations
{
void DiffMeta();
void OpenMeta();
void OpenMetaWith();
void OpenMetaInExplorer();
void HistoryMeta();
bool SelectionHasMeta();
}
internal PendingChangesViewPendingChangeMenu(
WorkspaceInfo wkInfo,
IPendingChangesMenuOperations pendingChangesMenuOperations,
IChangelistMenuOperations changelistMenuOperations,
IOpenMenuOperations openMenuOperations,
IMetaMenuOperations metaMenuOperations,
IFilesFilterPatternsMenuOperations filterMenuOperations)
{
mPendingChangesMenuOperations = pendingChangesMenuOperations;
mChangelistMenuOperations = changelistMenuOperations;
mOpenMenuOperations = openMenuOperations;
mMetaMenuOperations = metaMenuOperations;
mFilterMenuBuilder = new FilesFilterPatternsMenuBuilder(filterMenuOperations);
mMoveToChangelistMenuBuilder = new MoveToChangelistMenuBuilder(
wkInfo,
changelistMenuOperations);
BuildComponents();
}
internal void Popup()
{
GenericMenu menu = new GenericMenu();
UpdateMenuItems(menu);
menu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
PendingChangesMenuOperations operationToExecute =
GetPendingChangesMenuOperation(e);
OpenMenuOperations openOperationToExecute =
GetOpenMenuOperation(e);
if (operationToExecute == PendingChangesMenuOperations.None &&
openOperationToExecute == OpenMenuOperations.None)
return false;
SelectedChangesGroupInfo info =
mPendingChangesMenuOperations.GetSelectedChangesGroupInfo();
if (operationToExecute != PendingChangesMenuOperations.None)
return ProcessKeyActionForPendingChangesMenu(
operationToExecute, mPendingChangesMenuOperations, info);
return ProcessKeyActionForOpenMenu(
openOperationToExecute, mOpenMenuOperations, info);
}
void OpenMenuItem_Click()
{
mOpenMenuOperations.Open();
}
void OpenWithMenuItem_Click()
{
mOpenMenuOperations.OpenWith();
}
void OpenInExplorerMenuItem_Click()
{
mOpenMenuOperations.OpenInExplorer();
}
void OpenMetaMenuItem_Click()
{
mMetaMenuOperations.OpenMeta();
}
void OpenMetaWithMenuItem_Click()
{
mMetaMenuOperations.OpenMetaWith();
}
void OpenMetaInExplorerMenuItem_Click()
{
mMetaMenuOperations.OpenMetaInExplorer();
}
void DiffMenuItem_Click()
{
mPendingChangesMenuOperations.Diff();
}
void DiffMetaMenuItem_Click()
{
mMetaMenuOperations.DiffMeta();
}
void UndoChangesMenuItem_Click()
{
mPendingChangesMenuOperations.UndoChanges();
}
void CheckoutMenuItem_Click()
{
mPendingChangesMenuOperations.ApplyLocalChanges();
}
void DeleteMenuItem_Click()
{
mPendingChangesMenuOperations.Delete();
}
void HistoryMenuItem_Click()
{
mPendingChangesMenuOperations.History();
}
void HistoryMetaMenuItem_Click()
{
mMetaMenuOperations.HistoryMeta();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedChangesGroupInfo info =
mPendingChangesMenuOperations.GetSelectedChangesGroupInfo();
PendingChangesMenuOperations operations =
PendingChangesMenuUpdater.GetAvailableMenuOperations(info);
ChangelistMenuOperations changelistOperations =
ChangelistMenuOperations.None;
OpenMenuOperations openOperations =
GetOpenMenuOperations.ForPendingChangesView(info);
bool useChangelists = PlasticGuiConfig.Get().
Configuration.CommitUseChangeLists;
if (useChangelists)
{
List<ChangeListInfo> selectedChangelists =
mChangelistMenuOperations.GetSelectedChangelistInfos();
changelistOperations = ChangelistMenuUpdater.
GetAvailableMenuOperations(info, selectedChangelists);
}
if (operations == PendingChangesMenuOperations.None &&
changelistOperations == ChangelistMenuOperations.None &&
openOperations == OpenMenuOperations.None)
{
menu.AddDisabledItem(GetNoActionMenuItemContent());
return;
}
UpdateOpenMenuItems(menu, openOperations);
menu.AddSeparator(string.Empty);
if (operations.HasFlag(PendingChangesMenuOperations.DiffWorkspaceContent))
menu.AddItem(mDiffMenuItemContent, false, DiffMenuItem_Click);
else
menu.AddDisabledItem(mDiffMenuItemContent);
if (mMetaMenuOperations.SelectionHasMeta())
{
if (operations.HasFlag(PendingChangesMenuOperations.DiffWorkspaceContent))
menu.AddItem(mDiffMetaMenuItemContent, false, DiffMetaMenuItem_Click);
else
menu.AddDisabledItem(mDiffMetaMenuItemContent);
}
menu.AddSeparator(string.Empty);
if (operations.HasFlag(PendingChangesMenuOperations.UndoChanges))
menu.AddItem(mUndoChangesMenuItemContent, false, UndoChangesMenuItem_Click);
else
menu.AddDisabledItem(mUndoChangesMenuItemContent);
menu.AddSeparator(string.Empty);
if (operations.HasFlag(PendingChangesMenuOperations.ApplyLocalChanges))
menu.AddItem(mCheckoutMenuItemContent, false, CheckoutMenuItem_Click);
else
menu.AddDisabledItem(mCheckoutMenuItemContent);
if (operations.HasFlag(PendingChangesMenuOperations.Delete))
menu.AddItem(mDeleteMenuItemContent, false, DeleteMenuItem_Click);
else
menu.AddDisabledItem(mDeleteMenuItemContent);
if (useChangelists)
{
menu.AddSeparator(string.Empty);
mMoveToChangelistMenuBuilder.UpdateMenuItems(
menu,
changelistOperations,
info.SelectedChanges,
info.ChangelistsWithSelectedChanges);
}
menu.AddSeparator(string.Empty);
mFilterMenuBuilder.UpdateMenuItems(
menu, FilterMenuUpdater.GetMenuActions(info));
menu.AddSeparator(string.Empty);
if (operations.HasFlag(PendingChangesMenuOperations.History))
menu.AddItem(mViewHistoryMenuItemContent, false, HistoryMenuItem_Click);
else
menu.AddDisabledItem(mViewHistoryMenuItemContent, false);
if (mMetaMenuOperations.SelectionHasMeta())
{
if (operations.HasFlag(PendingChangesMenuOperations.History))
menu.AddItem(mViewHistoryMetaMenuItemContent, false, HistoryMetaMenuItem_Click);
else
menu.AddDisabledItem(mViewHistoryMetaMenuItemContent);
}
}
void UpdateOpenMenuItems(GenericMenu menu, OpenMenuOperations operations)
{
if (!operations.HasFlag(OpenMenuOperations.Open) &&
!operations.HasFlag(OpenMenuOperations.OpenWith) &&
!operations.HasFlag(OpenMenuOperations.OpenInExplorer))
{
menu.AddDisabledItem(mOpenSubmenuItemContent);
return;
}
if (operations.HasFlag(OpenMenuOperations.Open))
menu.AddItem(mOpenMenuItemContent, false, OpenMenuItem_Click);
else
menu.AddDisabledItem(mOpenMenuItemContent);
if (operations.HasFlag(OpenMenuOperations.OpenWith))
menu.AddItem(mOpenWithMenuItemContent, false, OpenWithMenuItem_Click);
else
menu.AddDisabledItem(mOpenWithMenuItemContent);
if (operations.HasFlag(OpenMenuOperations.OpenInExplorer))
menu.AddItem(mOpenInExplorerMenuItemContent, false, OpenInExplorerMenuItem_Click);
else
menu.AddDisabledItem(mOpenInExplorerMenuItemContent);
if (!mMetaMenuOperations.SelectionHasMeta())
return;
menu.AddSeparator(PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen) + "/");
if (operations.HasFlag(OpenMenuOperations.Open))
menu.AddItem(mOpenMetaMenuItemContent, false, OpenMetaMenuItem_Click);
else
menu.AddDisabledItem(mOpenMetaMenuItemContent);
if (operations.HasFlag(OpenMenuOperations.OpenWith))
menu.AddItem(mOpenMetaWithMenuItemContent, false, OpenMetaWithMenuItem_Click);
else
menu.AddDisabledItem(mOpenMetaWithMenuItemContent);
if (operations.HasFlag(OpenMenuOperations.OpenInExplorer))
menu.AddItem(mOpenMetaInExplorerMenuItemContent, false, OpenMetaInExplorerMenuItem_Click);
else
menu.AddDisabledItem(mOpenMetaInExplorerMenuItemContent);
}
GUIContent GetNoActionMenuItemContent()
{
if (mNoActionMenuItemContent == null)
{
mNoActionMenuItemContent = new GUIContent(PlasticLocalization.GetString(
PlasticLocalization.Name.NoActionMenuItem));
}
return mNoActionMenuItemContent;
}
void BuildComponents()
{
mOpenSubmenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen));
mOpenMenuItemContent = new GUIContent(
UnityMenuItem.GetText(
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen),
string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen),
GetPlasticShortcut.ForOpen())));
mOpenWithMenuItemContent = new GUIContent(
UnityMenuItem.GetText(
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen),
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpenWith)));
mOpenInExplorerMenuItemContent = new GUIContent(
UnityMenuItem.GetText(
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen),
PlasticLocalization.GetString(PlasticLocalization.Name.OpenInExplorerMenuItem)));
mOpenMetaMenuItemContent = new GUIContent(
UnityMenuItem.GetText(
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen),
PlasticLocalization.GetString(PlasticLocalization.Name.OpenMeta)));
mOpenMetaWithMenuItemContent = new GUIContent(
UnityMenuItem.GetText(
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen),
PlasticLocalization.GetString(PlasticLocalization.Name.OpenMetaWith)));
mOpenMetaInExplorerMenuItemContent = new GUIContent(
UnityMenuItem.GetText(
PlasticLocalization.GetString(PlasticLocalization.Name.ItemsMenuItemOpen),
PlasticLocalization.GetString(PlasticLocalization.Name.OpenMetaInExplorer)));
mDiffMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.DiffMenuItem),
GetPlasticShortcut.ForDiff()));
mDiffMetaMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.DiffMetaMenuItem));
mUndoChangesMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.PendingChangesMenuItemUndoChanges));
mCheckoutMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.PendingChangesMenuItemCheckout));
mDeleteMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.PendingChangesMenuItemDelete),
GetPlasticShortcut.ForDelete()));
mViewHistoryMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.ViewHistoryMenuItem),
GetPlasticShortcut.ForHistory()));
mViewHistoryMetaMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.ViewHistoryMetaMenuItem));
mFilterMenuBuilder.BuildIgnoredSubmenuItem();
mFilterMenuBuilder.BuildHiddenChangesSubmenuItem();
mMoveToChangelistMenuBuilder.BuildComponents();
}
static bool ProcessKeyActionForPendingChangesMenu(
PendingChangesMenuOperations operationToExecute,
IPendingChangesMenuOperations pendingChangesMenuOperations,
SelectedChangesGroupInfo info)
{
PendingChangesMenuOperations operations =
PendingChangesMenuUpdater.GetAvailableMenuOperations(info);
if (!operations.HasFlag(operationToExecute))
return false;
ProcessPendingChangesMenuOperation(
operationToExecute, pendingChangesMenuOperations);
return true;
}
static bool ProcessKeyActionForOpenMenu(
OpenMenuOperations openOperationToExecute,
IOpenMenuOperations openMenuOperations,
SelectedChangesGroupInfo info)
{
OpenMenuOperations openOperations =
GetOpenMenuOperations.ForPendingChangesView(info);
if (!openOperations.HasFlag(openOperationToExecute))
return false;
ProcessOpenMenuOperation(
openOperationToExecute, openMenuOperations);
return true;
}
static void ProcessPendingChangesMenuOperation(
PendingChangesMenuOperations operationToExecute,
IPendingChangesMenuOperations pendingChangesMenuOperations)
{
if (operationToExecute == PendingChangesMenuOperations.DiffWorkspaceContent)
{
pendingChangesMenuOperations.Diff();
return;
}
if (operationToExecute == PendingChangesMenuOperations.Delete)
{
pendingChangesMenuOperations.Delete();
return;
}
if (operationToExecute == PendingChangesMenuOperations.History)
{
pendingChangesMenuOperations.History();
return;
}
}
static void ProcessOpenMenuOperation(
OpenMenuOperations openOperationToExecute,
IOpenMenuOperations openMenuOperations)
{
if (openOperationToExecute == OpenMenuOperations.Open)
{
openMenuOperations.Open();
return;
}
}
static PendingChangesMenuOperations GetPendingChangesMenuOperation(Event e)
{
if (Keyboard.IsControlOrCommandKeyPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.D))
return PendingChangesMenuOperations.DiffWorkspaceContent;
if (Keyboard.IsKeyPressed(e, KeyCode.Delete))
return PendingChangesMenuOperations.Delete;
if (Keyboard.IsControlOrCommandKeyPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.H))
return PendingChangesMenuOperations.History;
return PendingChangesMenuOperations.None;
}
static OpenMenuOperations GetOpenMenuOperation(Event e)
{
if (Keyboard.IsShiftPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.O))
return OpenMenuOperations.Open;
return OpenMenuOperations.None;
}
GUIContent mNoActionMenuItemContent;
GUIContent mOpenSubmenuItemContent;
GUIContent mOpenMenuItemContent;
GUIContent mOpenWithMenuItemContent;
GUIContent mOpenInExplorerMenuItemContent;
GUIContent mOpenMetaMenuItemContent;
GUIContent mOpenMetaWithMenuItemContent;
GUIContent mOpenMetaInExplorerMenuItemContent;
GUIContent mDiffMenuItemContent;
GUIContent mDiffMetaMenuItemContent;
GUIContent mUndoChangesMenuItemContent;
GUIContent mCheckoutMenuItemContent;
GUIContent mDeleteMenuItemContent;
GUIContent mViewHistoryMenuItemContent;
GUIContent mViewHistoryMetaMenuItemContent;
readonly WorkspaceInfo mWkInfo;
readonly IMetaMenuOperations mMetaMenuOperations;
readonly IOpenMenuOperations mOpenMenuOperations;
readonly IChangelistMenuOperations mChangelistMenuOperations;
readonly IPendingChangesMenuOperations mPendingChangesMenuOperations;
readonly FilesFilterPatternsMenuBuilder mFilterMenuBuilder;
readonly MoveToChangelistMenuBuilder mMoveToChangelistMenuBuilder;
readonly bool mIsGluonMode;
}
}

View file

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

View file

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

View file

@ -0,0 +1,22 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.PendingChanges;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.PendingMergeLinks
{
internal class MergeLinkListViewItem : TreeViewItem
{
internal MountPendingMergeLink MergeLink { get; private set; }
internal MergeLinkListViewItem(int id, MountPendingMergeLink mergeLink)
: base(id, 0)
{
MergeLink = mergeLink;
displayName = mergeLink.GetPendingMergeLinkText();
icon = Images.GetMergeLinkIcon();
}
}
}

View file

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

View file

@ -0,0 +1,137 @@
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.CM.Common;
using Codice.CM.Common.Merge;
using PlasticGui.WorkspaceWindow.PendingChanges;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges.PendingMergeLinks
{
internal class MergeLinksListView : TreeView
{
internal float DesiredHeight
{
get
{
return rowHeight * (mMergeLinks.Count + 1);
}
}
internal MergeLinksListView()
: base(new TreeViewState())
{
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = false;
}
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(mMergeLinks, rootItem, mRows);
return mRows;
}
internal void BuildModel(
IDictionary<MountPoint, IList<PendingMergeLink>> pendingMergeLinks)
{
mMergeLinks = BuildMountPendingMergeLink(pendingMergeLinks);
}
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) + 500),
Images.GetTreeviewBackgroundTexture());
DrawTreeViewItem.InitializeStyles();
base.BeforeRowsGUI();
}
static void RegenerateRows(
List<MountPendingMergeLink> mergeLinks,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (mergeLinks.Count == 0)
return;
for (int i = 0; i < mergeLinks.Count; i++)
{
MergeLinkListViewItem mergeLinkListViewItem =
new MergeLinkListViewItem(i + 1, mergeLinks[i]);
rootItem.AddChild(mergeLinkListViewItem);
rows.Add(mergeLinkListViewItem);
}
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static List<MountPendingMergeLink> BuildMountPendingMergeLink(
IDictionary<MountPoint, IList<PendingMergeLink>> pendingMergeLinks)
{
List<MountPendingMergeLink> result = new List<MountPendingMergeLink>();
if (pendingMergeLinks == null)
return result;
foreach (KeyValuePair<MountPoint, IList<PendingMergeLink>> mountLink
in pendingMergeLinks)
{
result.AddRange(BuildMountPendingMergeLinks(
mountLink.Key, mountLink.Value));
}
return result;
}
static List<MountPendingMergeLink> BuildMountPendingMergeLinks(
MountPoint mount, IList<PendingMergeLink> links)
{
List<MountPendingMergeLink> result = new List<MountPendingMergeLink>();
RepositoryInfo repInfo = RepositorySpecResolverProvider.Get().
GetRepInfo(mount.RepSpec);
foreach (PendingMergeLink link in links)
result.Add(new MountPendingMergeLink(repInfo.GetRepSpec(), link));
return result;
}
List<TreeViewItem> mRows = new List<TreeViewItem>();
List<MountPendingMergeLink> mMergeLinks = new List<MountPendingMergeLink>();
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3ee6978573f6f410a9b799889ea0ad13
timeCreated: 1541785757
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,229 @@
using System.Collections.Generic;
using Codice.Client.BaseCommands;
using Codice.Client.Commands;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.PendingChanges;
using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
namespace Unity.PlasticSCM.Editor.Views.PendingChanges
{
internal class UnityPendingChangesTree
{
internal UnityPendingChangesTree()
{
mInnerTree = new PendingChangesTree();
mMetaCache = new MetaCache();
}
internal List<IPlasticTreeNode> GetNodes()
{
return ((IPlasticTree)mInnerTree).GetNodes();
}
internal bool HasMeta(ChangeInfo changeInfo)
{
return mMetaCache.ContainsMeta(changeInfo);
}
internal ChangeInfo GetMetaChange(ChangeInfo change)
{
return mMetaCache.GetExistingMeta(change);
}
internal void FillWithMeta(List<ChangeInfo> changes)
{
changes.AddRange(
mMetaCache.GetExistingMeta(changes));
}
internal PendingChangeInfo GetFirstPendingChange()
{
List<PendingChangeInfo> changes = mInnerTree.GetAllPendingChanges();
if (changes == null || changes.Count == 0)
return null;
return changes[0];
}
internal List<ChangeInfo> GetAllChanges()
{
List<ChangeInfo> changes = mInnerTree.GetAllChanges();
FillWithMeta(changes);
return changes;
}
internal void GetCheckedChanges(
List<ChangelistNode> selectedChangelists,
bool bExcludePrivates,
out List<ChangeInfo> changes,
out List<ChangeInfo> dependenciesCandidates)
{
mInnerTree.GetCheckedChanges(
selectedChangelists,
bExcludePrivates,
out changes,
out dependenciesCandidates);
changes.AddRange(
mMetaCache.GetExistingMeta(changes));
dependenciesCandidates.AddRange(
mMetaCache.GetExistingMeta(dependenciesCandidates));
}
internal List<ChangeInfo> GetDependenciesCandidates(
List<ChangeInfo> selectedChanges,
bool bExcludePrivates)
{
return mInnerTree.GetDependenciesCandidates(
selectedChanges, bExcludePrivates);
}
internal void BuildChangeCategories(
WorkspaceInfo wkInfo,
List<ChangeInfo> changes,
CheckedStateManager checkedStateManager)
{
mMetaCache.Build(changes);
mInnerTree = BuildPendingChangesTree.FromChanges(
wkInfo,
changes,
checkedStateManager);
}
internal ChangeInfo GetChangedForMoved(ChangeInfo moved)
{
return mInnerTree.GetChangedForMoved(moved);
}
internal void Filter(Filter filter, List<string> columnNames)
{
mInnerTree.Filter(filter, columnNames);
}
internal void Sort(string key, bool ascending)
{
mInnerTree.Sort(key, ascending);
}
MetaCache mMetaCache;
PendingChangesTree mInnerTree;
class MetaCache
{
internal bool ContainsMeta(ChangeInfo changeInfo)
{
string key = BuildKey.ForMetaChange(changeInfo);
return mCache.ContainsKey(key);
}
internal ChangeInfo GetExistingMeta(ChangeInfo change)
{
ChangeInfo result;
if (!mCache.TryGetValue(BuildKey.ForMetaChange(change), out result))
return null;
return result;
}
internal List<ChangeInfo> GetExistingMeta(
List<ChangeInfo> changes)
{
List<ChangeInfo> result = new List<ChangeInfo>();
foreach (ChangeInfo change in changes)
{
string key = BuildKey.ForMetaChange(change);
ChangeInfo metaChange;
if (!mCache.TryGetValue(key, out metaChange))
continue;
result.Add(metaChange);
}
return result;
}
internal void Build(List<ChangeInfo> changes)
{
mCache.Clear();
ExtractMetaToCache(changes, mCache);
}
static void ExtractMetaToCache(
List<ChangeInfo> changes,
Dictionary<string, ChangeInfo> cache)
{
HashSet<string> indexedKeys = BuildIndexedKeys(changes);
for (int i = changes.Count - 1; i >= 0; i--)
{
ChangeInfo currentChange = changes[i];
if (!MetaPath.IsMetaPath(currentChange.Path))
continue;
string realPath = MetaPath.GetPathFromMetaPath(currentChange.Path);
if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
currentChange.ChangeTypes, realPath)))
continue;
// found foo.c and foo.c.meta
// with the same chage types - move .meta to cache
cache.Add(BuildKey.ForChange(currentChange), currentChange);
changes.RemoveAt(i);
}
}
static HashSet<string> BuildIndexedKeys(
List<ChangeInfo> changes)
{
HashSet<string> result = new HashSet<string>();
foreach (ChangeInfo change in changes)
{
if (MetaPath.IsMetaPath(change.Path))
continue;
result.Add(BuildKey.ForChange(change));
}
return result;
}
Dictionary<string, ChangeInfo> mCache =
new Dictionary<string, ChangeInfo>();
static class BuildKey
{
internal static string ForChange(ChangeInfo change)
{
return BuildCacheKey(
change.ChangeTypes,
change.Path);
}
internal static string ForMetaChange(ChangeInfo change)
{
return BuildCacheKey(
change.ChangeTypes,
MetaPath.GetMetaPath(change.Path));
}
internal static string BuildCacheKey(ChangeTypes changeTypes, string path)
{
return string.Concat(changeTypes, ":", path);
}
}
}
}
}

View file

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