Created unity project

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

View File

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

View File

@@ -0,0 +1,17 @@
using UnityEditor.IMGUI.Controls;
namespace Unity.PlasticSCM.Editor.Views.Branches
{
class BranchListViewItem : TreeViewItem
{
internal object ObjectInfo { get; private set; }
internal BranchListViewItem(int id, object objectInfo)
: base(id, 1)
{
ObjectInfo = objectInfo;
displayName = id.ToString();
}
}
}

View File

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

View File

@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Branches
{
internal enum BranchesListColumn
{
Name,
Repository,
CreatedBy,
CreationDate,
Comment,
Branch,
Guid
}
[Serializable]
internal class BranchesListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static BranchesListHeaderState GetDefault()
{
return new BranchesListHeaderState(BuildColumns());
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn));
return result;
}
internal static string GetColumnName(BranchesListColumn column)
{
switch (column)
{
case BranchesListColumn.Name:
return PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn);
case BranchesListColumn.Repository:
return PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryColumn);
case BranchesListColumn.CreatedBy:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn);
case BranchesListColumn.CreationDate:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn);
case BranchesListColumn.Comment:
return PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
if (mColumsAllowedToggleVisibility != null)
TreeHeaderColumns.SetVisibilities(columns, mColumsAllowedToggleVisibility);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = UnityConstants.BranchesColumns.BRANCHES_NAME_WIDTH,
minWidth = UnityConstants.BranchesColumns.BRANCHES_NAME_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(BranchesListColumn.Name)),
allowToggleVisibility = false,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = UnityConstants.BranchesColumns.REPOSITORY_WIDTH,
minWidth = UnityConstants.BranchesColumns.REPOSITORY_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(BranchesListColumn.Repository)),
allowToggleVisibility = true,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = UnityConstants.BranchesColumns.CREATEDBY_WIDTH,
minWidth = UnityConstants.BranchesColumns.CREATEDBY_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(BranchesListColumn.CreatedBy)),
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = UnityConstants.BranchesColumns.CREATION_DATE_WIDTH,
minWidth = UnityConstants.BranchesColumns.CREATION_DATE_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(BranchesListColumn.CreationDate)),
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = UnityConstants.BranchesColumns.COMMENT_WIDTH,
minWidth = UnityConstants.BranchesColumns.COMMENT_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(BranchesListColumn.Comment)),
sortingArrowAlignment = TextAlignment.Right
}
};
}
BranchesListHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
if (mColumsAllowedToggleVisibility == null)
mColumsAllowedToggleVisibility = TreeHeaderColumns.GetVisibilities(columns);
}
[SerializeField]
string[] mHeaderTitles;
[SerializeField]
bool[] mColumsAllowedToggleVisibility;
}
}

View File

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

View File

@@ -0,0 +1,418 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.QueryViews;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Avatar;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Branches
{
internal class BranchesListView : TreeView
{
internal GenericMenu Menu { get { return mMenu.Menu; } }
internal BranchesListView(
BranchesListHeaderState headerState,
List<string> columnNames,
BranchesViewMenu menu,
Action sizeChangedAction)
: base(new TreeViewState())
{
mColumnNames = columnNames;
mMenu = menu;
mSizeChangedAction = sizeChangedAction;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = false;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
internal void SetLoadedBranchId(long loadedBranchId)
{
mLoadedBranchId = loadedBranchId;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(
TreeViewItem rootItem)
{
if (mQueryResult == null)
{
ClearRows(rootItem, mRows);
return mRows;
}
RegenerateRows(
mListViewItemIds,
mQueryResult.GetObjects(),
rootItem, mRows);
return mRows;
}
protected override void SearchChanged(string newSearch)
{
mCooldownFilterAction.Ping();
}
protected override void ContextClickedItem(int id)
{
mMenu.Popup();
Repaint();
}
public override void OnGUI(Rect rect)
{
if (Event.current.type == EventType.Layout)
{
if (IsSizeChanged(treeViewRect, mLastRect))
mSizeChangedAction();
}
mLastRect = treeViewRect;
base.OnGUI(rect);
Event e = Event.current;
if (e.type != EventType.KeyDown)
return;
bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e);
if (isProcessed)
e.Use();
}
protected override void BeforeRowsGUI()
{
int firstRowVisible;
int lastRowVisible;
GetFirstAndLastVisibleRows(out firstRowVisible, out lastRowVisible);
GUI.DrawTexture(new Rect(0,
firstRowVisible * rowHeight,
GetRowRect(0).width,
(lastRowVisible * rowHeight) + 1000),
Images.GetTreeviewBackgroundTexture());
DrawTreeViewItem.InitializeStyles();
base.BeforeRowsGUI();
}
protected override void RowGUI(RowGUIArgs args)
{
if (args.item is BranchListViewItem)
{
BranchListViewItem branchListViewItem = (BranchListViewItem)args.item;
BranchInfo branchInfo = (BranchInfo)branchListViewItem.ObjectInfo;
BranchesListViewItemGUI(
mQueryResult,
rowHeight,
branchListViewItem,
args,
branchInfo.BranchId == mLoadedBranchId,
Repaint);
return;
}
base.RowGUI(args);
}
internal void BuildModel(
ViewQueryResult queryResult,
long loadedBranchId)
{
mListViewItemIds.Clear();
mQueryResult = queryResult;
mLoadedBranchId = loadedBranchId;
}
internal void Refilter()
{
if (mQueryResult == null)
return;
Filter filter = new Filter(searchString);
mQueryResult.ApplyFilter(filter, mColumnNames);
}
internal void Sort()
{
if (mQueryResult == null)
return;
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mQueryResult.Sort(
mColumnNames[sortedColumnIdx],
sortAscending);
}
internal List<RepositorySpec> GetSelectedRepositories()
{
List<RepositorySpec> result = new List<RepositorySpec>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<object, int> item
in mListViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
RepositorySpec repSpec =
mQueryResult.GetRepositorySpec(item.Key);
result.Add(repSpec);
}
return result;
}
internal List<RepObjectInfo> GetSelectedRepObjectInfos()
{
List<RepObjectInfo> result = new List<RepObjectInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<object, int> item
in mListViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
RepObjectInfo repObjectInfo =
mQueryResult.GetRepObjectInfo(item.Key);
result.Add(repObjectInfo);
}
return result;
}
internal void SelectRepObjectInfos(
List<RepObjectInfo> repObjectsToSelect)
{
List<int> idsToSelect = new List<int>();
foreach (RepObjectInfo repObjectInfo in repObjectsToSelect)
{
int repObjectInfoId = GetTreeIdForItem(repObjectInfo);
if (repObjectInfoId == -1)
continue;
idsToSelect.Add(repObjectInfoId);
}
TableViewOperations.SetSelectionAndScroll(this, idsToSelect);
}
int GetTreeIdForItem(RepObjectInfo repObjectInfo)
{
foreach (KeyValuePair<object, int> item in mListViewItemIds.GetInfoItems())
{
RepObjectInfo currentRepObjectInfo =
mQueryResult.GetRepObjectInfo(item.Key);
if (!currentRepObjectInfo.Equals(repObjectInfo))
continue;
if (!currentRepObjectInfo.GUID.Equals(repObjectInfo.GUID))
continue;
return item.Value;
}
return -1;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
ListViewItemIds<object> listViewItemIds,
List<object> objectInfos,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (objectInfos.Count == 0)
return;
foreach (object objectInfo in objectInfos)
{
int objectId;
if (!listViewItemIds.TryGetInfoItemId(objectInfo, out objectId))
objectId = listViewItemIds.AddInfoItem(objectInfo);
BranchListViewItem branchListViewItem =
new BranchListViewItem(objectId, objectInfo);
rootItem.AddChild(branchListViewItem);
rows.Add(branchListViewItem);
}
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void BranchesListViewItemGUI(
ViewQueryResult queryResult,
float rowHeight,
BranchListViewItem item,
RowGUIArgs args,
bool isBoldText,
Action avatarLoadedAction)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
if (visibleColumnIdx == 0)
{
cellRect.x += UnityConstants.FIRST_COLUMN_WITHOUT_ICON_INDENT;
cellRect.width -= UnityConstants.FIRST_COLUMN_WITHOUT_ICON_INDENT;
}
BranchesListColumn column =
(BranchesListColumn)args.GetColumn(visibleColumnIdx);
BranchesListViewItemCellGUI(
cellRect,
rowHeight,
queryResult,
item,
column,
avatarLoadedAction,
args.selected,
args.focused,
isBoldText);
}
}
static void BranchesListViewItemCellGUI(
Rect rect,
float rowHeight,
ViewQueryResult queryResult,
BranchListViewItem item,
BranchesListColumn column,
Action avatarLoadedAction,
bool isSelected,
bool isFocused,
bool isBoldText)
{
string columnText = RepObjectInfoView.GetColumnText(
queryResult.GetRepositorySpec(item.ObjectInfo),
queryResult.GetRepObjectInfo(item.ObjectInfo),
BranchesListHeaderState.GetColumnName(column));
if (column == BranchesListColumn.CreatedBy)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
-1,
GetAvatar.ForEmail(columnText, avatarLoadedAction),
null,
columnText,
isSelected,
isFocused,
isBoldText,
false);
return;
}
if (column == BranchesListColumn.Branch ||
column == BranchesListColumn.Repository ||
column == BranchesListColumn.Guid)
{
DrawTreeViewItem.ForSecondaryLabel(
rect, columnText, isSelected, isFocused, isBoldText);
return;
}
DrawTreeViewItem.ForLabel(
rect, columnText, isSelected, isFocused, isBoldText);
}
static bool IsSizeChanged(
Rect currentRect, Rect lastRect)
{
if (currentRect.width != lastRect.width)
return true;
if (currentRect.height != lastRect.height)
return true;
return false;
}
Rect mLastRect;
ListViewItemIds<object> mListViewItemIds = new ListViewItemIds<object>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
ViewQueryResult mQueryResult;
long mLoadedBranchId;
readonly CooldownWindowDelayer mCooldownFilterAction;
readonly Action mSizeChangedAction;
readonly BranchesViewMenu mMenu;
readonly List<string> mColumnNames;
}
}

View File

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

View File

@@ -0,0 +1,81 @@
using System.Collections.Generic;
using System.Linq;
using Codice.CM.Common;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Branches
{
internal static class BranchesSelection
{
internal static void SelectBranches(
BranchesListView listView,
List<RepObjectInfo> branchesToSelect,
int defaultRow)
{
if (branchesToSelect == null || branchesToSelect.Count == 0)
{
TableViewOperations.SelectFirstRow(listView);
return;
}
listView.SelectRepObjectInfos(branchesToSelect);
if (listView.HasSelection())
return;
TableViewOperations.SelectDefaultRow(listView, defaultRow);
if (listView.HasSelection())
return;
TableViewOperations.SelectFirstRow(listView);
}
internal static List<RepObjectInfo> GetSelectedRepObjectInfos(
BranchesListView listView)
{
return listView.GetSelectedRepObjectInfos();
}
internal static int GetSelectedBranchesCount(
BranchesListView listView)
{
return listView.GetSelection().Count;
}
internal static BranchInfo GetSelectedBranch(
BranchesListView listView)
{
List<RepObjectInfo> selectedRepObjectsInfos = listView.GetSelectedRepObjectInfos();
if (selectedRepObjectsInfos.Count == 0)
return null;
return (BranchInfo)selectedRepObjectsInfos[0];
}
internal static List<BranchInfo> GetSelectedBranches(
BranchesListView listView)
{
return listView.GetSelectedRepObjectInfos().Cast<BranchInfo>().ToList();
}
internal static RepositorySpec GetSelectedRepository(
BranchesListView listView)
{
List<RepositorySpec> selectedRepositories = listView.GetSelectedRepositories();
if (selectedRepositories.Count == 0)
return null;
return selectedRepositories[0];
}
internal static List<RepositorySpec> GetSelectedRepositories(
BranchesListView listView)
{
return listView.GetSelectedRepositories();
}
}
}

View File

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

View File

@@ -0,0 +1,485 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using GluonGui;
using PlasticGui;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.QueryViews;
using PlasticGui.WorkspaceWindow.QueryViews.Branches;
using PlasticGui.WorkspaceWindow.Update;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.UI.Tree;
using Unity.PlasticSCM.Editor.Views.Branches.Dialogs;
using Unity.PlasticSCM.Editor.Views.Changesets;
using GluonNewIncomingChangesUpdater = PlasticGui.Gluon.WorkspaceWindow.NewIncomingChangesUpdater;
using IGluonUpdateReport = PlasticGui.Gluon.IUpdateReport;
namespace Unity.PlasticSCM.Editor.Views.Branches
{
internal partial class BranchesTab :
IRefreshableView,
IQueryRefreshableView,
IBranchMenuOperations
{
internal BranchesListView Table { get { return mBranchesListView; } }
internal IBranchMenuOperations Operations { get { return this; } }
internal BranchesTab(
WorkspaceInfo wkInfo,
WorkspaceWindow workspaceWindow,
IViewSwitcher viewSwitcher,
IMergeViewLauncher mergeViewLauncher,
ViewHost viewHost,
IUpdateReport updateReport,
IGluonUpdateReport gluonUpdateReport,
NewIncomingChangesUpdater developerNewIncomingChangesUpdater,
GluonNewIncomingChangesUpdater gluonNewIncomingChangesUpdater,
EditorWindow parentWindow,
bool isGluonMode)
{
mWkInfo = wkInfo;
mParentWindow = parentWindow;
mGluonUpdateReport = gluonUpdateReport;
mViewHost = viewHost;
mWorkspaceWindow = workspaceWindow;
mIsGluonMode = isGluonMode;
mProgressControls = new ProgressControlsForViews();
mDeveloperNewIncomingChangesUpdater = developerNewIncomingChangesUpdater;
mGluonNewIncomingChangesUpdater = gluonNewIncomingChangesUpdater;
BuildComponents(
wkInfo,
workspaceWindow,
viewSwitcher,
mergeViewLauncher,
updateReport,
developerNewIncomingChangesUpdater,
parentWindow);
((IRefreshableView)this).Refresh();
}
internal void OnEnable()
{
mSearchField.downOrUpArrowKeyPressed +=
SearchField_OnDownOrUpArrowKeyPressed;
}
internal void OnDisable()
{
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
TreeHeaderSettings.Save(
mBranchesListView.multiColumnHeader.state,
UnityConstants.BRANCHES_TABLE_SETTINGS_NAME);
}
internal void Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
DoActionsToolbar(mProgressControls);
DoBranchesArea(
mBranchesListView,
mProgressControls.IsOperationRunning());
}
internal void DrawSearchFieldForTab()
{
DrawSearchField.For(
mSearchField,
mBranchesListView,
UnityConstants.SEARCH_FIELD_WIDTH);
}
internal void DrawDateFilter()
{
GUI.enabled = !mProgressControls.IsOperationRunning();
EditorGUI.BeginChangeCheck();
mDateFilter.FilterType = (DateFilter.Type)
EditorGUILayout.EnumPopup(
mDateFilter.FilterType,
EditorStyles.toolbarDropDown,
GUILayout.Width(100));
if (EditorGUI.EndChangeCheck())
{
EnumPopupSetting<DateFilter.Type>.Save(
mDateFilter.FilterType,
UnityConstants.BRANCHES_DATE_FILTER_SETTING_NAME);
((IRefreshableView)this).Refresh();
}
GUI.enabled = true;
}
internal void SetWorkingObjectInfo(WorkingObjectInfo homeInfo)
{
lock (mLock)
{
mLoadedBranchId = homeInfo.BranchInfo.BranchId;
}
mBranchesListView.SetLoadedBranchId(mLoadedBranchId);
}
void IRefreshableView.Refresh()
{
// VCS-1005209 - There are scenarios where the list of branches need to check for incoming changes.
// For example, deleting the active branch will automatically switch your workspace to the parent changeset,
// which might have incoming changes.
if (mDeveloperNewIncomingChangesUpdater != null)
mDeveloperNewIncomingChangesUpdater.Update(DateTime.Now);
if (mGluonNewIncomingChangesUpdater != null)
mGluonNewIncomingChangesUpdater.Update(DateTime.Now);
string query = GetBranchesQuery(mDateFilter);
FillBranches(mWkInfo, query, BranchesSelection.
GetSelectedRepObjectInfos(mBranchesListView));
}
//IQueryRefreshableView
public void RefreshAndSelect(RepObjectInfo repObj)
{
string query = GetBranchesQuery(mDateFilter);
FillBranches(mWkInfo, query, new List<RepObjectInfo> { repObj });
}
int IBranchMenuOperations.GetSelectedBranchesCount()
{
return BranchesSelection.GetSelectedBranchesCount(mBranchesListView);
}
void IBranchMenuOperations.CreateBranch()
{
RepositorySpec repSpec = BranchesSelection.GetSelectedRepository(mBranchesListView);
BranchInfo branchInfo = BranchesSelection.GetSelectedBranch(mBranchesListView);
BranchCreationData branchCreationData = CreateBranchDialog.CreateBranchFromLastParentBranchChangeset(
mParentWindow,
repSpec,
branchInfo);
mBranchOperations.CreateBranch(
branchCreationData,
RefreshAsset.BeforeLongAssetOperation,
items => RefreshAsset.AfterLongAssetOperation(
ProjectPackages.ShouldBeResolved(items, mWkInfo, false)));
}
void IBranchMenuOperations.CreateTopLevelBranch() { }
void IBranchMenuOperations.SwitchToBranch()
{
SwitchToBranchForMode();
}
void IBranchMenuOperations.MergeBranch()
{
mBranchOperations.MergeBranch(
BranchesSelection.GetSelectedRepository(mBranchesListView),
BranchesSelection.GetSelectedBranch(mBranchesListView));
}
void IBranchMenuOperations.CherrypickBranch() { }
void IBranchMenuOperations.MergeToBranch() { }
void IBranchMenuOperations.PullBranch() { }
void IBranchMenuOperations.PullRemoteBranch() { }
void IBranchMenuOperations.SyncWithGit() { }
void IBranchMenuOperations.PushBranch() { }
void IBranchMenuOperations.DiffBranch() { }
void IBranchMenuOperations.DiffWithAnotherBranch() { }
void IBranchMenuOperations.ViewChangesets() { }
void IBranchMenuOperations.RenameBranch()
{
RepositorySpec repSpec = BranchesSelection.GetSelectedRepository(mBranchesListView);
BranchInfo branchInfo = BranchesSelection.GetSelectedBranch(mBranchesListView);
BranchRenameData branchRenameData = RenameBranchDialog.GetBranchRenameData(
repSpec,
branchInfo,
mParentWindow);
mBranchOperations.RenameBranch(branchRenameData);
}
void IBranchMenuOperations.DeleteBranch()
{
var branchesToDelete = BranchesSelection.GetSelectedBranches(mBranchesListView);
if (!DeleteBranchDialog.ConfirmDelete(branchesToDelete))
return;
mBranchOperations.DeleteBranch(
BranchesSelection.GetSelectedRepositories(mBranchesListView),
branchesToDelete,
DeleteBranchOptions.IncludeChangesets);
}
void IBranchMenuOperations.CreateCodeReview() { }
void IBranchMenuOperations.ViewPermissions() { }
void SearchField_OnDownOrUpArrowKeyPressed()
{
mBranchesListView.SetFocusAndEnsureSelectedItem();
}
void OnBranchesListViewSizeChanged()
{
if (!mShouldScrollToSelection)
return;
mShouldScrollToSelection = false;
TableViewOperations.ScrollToSelection(mBranchesListView);
}
void FillBranches(
WorkspaceInfo wkInfo,
string query,
List<RepObjectInfo> branchesToSelect)
{
if (mIsRefreshing)
return;
mIsRefreshing = true;
int defaultRow = TableViewOperations.
GetFirstSelectedRow(mBranchesListView);
((IProgressControls)mProgressControls).ShowProgress(
PlasticLocalization.GetString(
PlasticLocalization.Name.LoadingBranches));
ViewQueryResult queryResult = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
long loadedBranchId = GetLoadedBranchId(wkInfo);
lock(mLock)
{
mLoadedBranchId = loadedBranchId;
}
queryResult = new ViewQueryResult(
PlasticGui.Plastic.API.FindQuery(wkInfo, query));
},
/*afterOperationDelegate*/ delegate
{
try
{
if (waiter.Exception != null)
{
ExceptionsHandler.DisplayException(waiter.Exception);
return;
}
UpdateBranchesList(
mBranchesListView,
queryResult,
mLoadedBranchId);
int branchesCount = GetBranchesCount(queryResult);
if (branchesCount == 0)
{
return;
}
BranchesSelection.SelectBranches(
mBranchesListView, branchesToSelect, defaultRow);
}
finally
{
((IProgressControls)mProgressControls).HideProgress();
mIsRefreshing = false;
}
});
}
static void UpdateBranchesList(
BranchesListView branchesListView,
ViewQueryResult queryResult,
long loadedBranchId)
{
branchesListView.BuildModel(
queryResult, loadedBranchId);
branchesListView.Refilter();
branchesListView.Sort();
branchesListView.Reload();
}
static long GetLoadedBranchId(WorkspaceInfo wkInfo)
{
BranchInfo brInfo = PlasticGui.Plastic.API.GetWorkingBranch(wkInfo);
if (brInfo != null)
return brInfo.BranchId;
return -1;
}
static int GetBranchesCount(
ViewQueryResult queryResult)
{
if (queryResult == null)
return 0;
return queryResult.Count();
}
static string GetBranchesQuery(DateFilter dateFilter)
{
if (dateFilter.FilterType == DateFilter.Type.AllTime)
return QueryConstants.BranchesBeginningQuery;
string whereClause = QueryConstants.GetDateWhereClause(
dateFilter.GetTimeAgo());
return string.Format("{0} {1}",
QueryConstants.BranchesBeginningQuery,
whereClause);
}
static void DoActionsToolbar(ProgressControlsForViews progressControls)
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
if (progressControls.IsOperationRunning())
{
DrawProgressForViews.ForIndeterminateProgress(
progressControls.ProgressData);
}
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
}
static void DoBranchesArea(
BranchesListView branchesListView,
bool isOperationRunning)
{
EditorGUILayout.BeginVertical();
GUI.enabled = !isOperationRunning;
Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
branchesListView.OnGUI(rect);
GUI.enabled = true;
EditorGUILayout.EndVertical();
}
void BuildComponents(
WorkspaceInfo wkInfo,
IWorkspaceWindow workspaceWindow,
IViewSwitcher viewSwitcher,
IMergeViewLauncher mergeViewLauncher,
IUpdateReport updateReport,
NewIncomingChangesUpdater developerNewIncomingChangesUpdater,
EditorWindow parentWindow)
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
DateFilter.Type dateFilterType =
EnumPopupSetting<DateFilter.Type>.Load(
UnityConstants.BRANCHES_DATE_FILTER_SETTING_NAME,
DateFilter.Type.LastMonth);
mDateFilter = new DateFilter(dateFilterType);
BranchesListHeaderState headerState =
BranchesListHeaderState.GetDefault();
TreeHeaderSettings.Load(headerState,
UnityConstants.BRANCHES_TABLE_SETTINGS_NAME,
(int)BranchesListColumn.CreationDate, false);
mBranchesListView = new BranchesListView(
headerState,
BranchesListHeaderState.GetColumnNames(),
new BranchesViewMenu(this, mGluonNewIncomingChangesUpdater != null),
sizeChangedAction: OnBranchesListViewSizeChanged);
mBranchesListView.Reload();
mBranchOperations = new BranchOperations(
wkInfo,
workspaceWindow,
null,
viewSwitcher,
mergeViewLauncher,
this,
ViewType.BranchesView,
mProgressControls,
updateReport,
new ContinueWithPendingChangesQuestionerBuilder(viewSwitcher, parentWindow),
null,
null,
developerNewIncomingChangesUpdater,
null,
null,
null);
}
SearchField mSearchField;
bool mIsRefreshing;
DateFilter mDateFilter;
bool mShouldScrollToSelection;
BranchesListView mBranchesListView;
BranchOperations mBranchOperations;
long mLoadedBranchId = -1;
object mLock = new object();
readonly bool mIsGluonMode;
readonly ViewHost mViewHost;
readonly IGluonUpdateReport mGluonUpdateReport;
readonly WorkspaceWindow mWorkspaceWindow;
readonly WorkspaceInfo mWkInfo;
readonly ProgressControlsForViews mProgressControls;
readonly EditorWindow mParentWindow;
readonly NewIncomingChangesUpdater mDeveloperNewIncomingChangesUpdater;
readonly GluonNewIncomingChangesUpdater mGluonNewIncomingChangesUpdater;
}
}

View File

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

View File

@@ -0,0 +1,57 @@
using Codice.CM.Common;
using GluonGui.WorkspaceWindow.Views.WorkspaceExplorer.Explorer;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.Branches
{
internal partial class BranchesTab
{
private void SwitchToBranchForMode()
{
if (mIsGluonMode)
{
SwitchToBranchForGluon();
return;
}
SwitchToBranchForDeveloper();
}
private void SwitchToBranchForDeveloper()
{
RepositorySpec repSpec = BranchesSelection.GetSelectedRepository(mBranchesListView);
BranchInfo branchInfo = BranchesSelection.GetSelectedBranch(mBranchesListView);
mBranchOperations.SwitchToBranch(
repSpec,
branchInfo,
RefreshAsset.BeforeLongAssetOperation,
items => RefreshAsset.AfterLongAssetOperation(
ProjectPackages.ShouldBeResolved(items, mWkInfo, false)));
}
private void SwitchToBranchForGluon()
{
BranchInfo branchInfo = BranchesSelection.GetSelectedBranch(mBranchesListView);
new SwitchToUIOperation().SwitchToBranch(
mWkInfo,
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
branchInfo,
mViewHost,
null,
new UnityPlasticGuiMessage(),
mProgressControls,
mWorkspaceWindow.GluonProgressOperationHandler,
mGluonUpdateReport,
mWorkspaceWindow,
null,
null,
null,
RefreshAsset.BeforeLongAssetOperation,
items => RefreshAsset.AfterLongAssetOperation(
ProjectPackages.ShouldBeResolved(items, mWkInfo, true)));
}
}
}

View File

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

View File

@@ -0,0 +1,201 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.QueryViews.Branches;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.Branches
{
internal class BranchesViewMenu
{
internal GenericMenu Menu { get { return mMenu; } }
internal BranchesViewMenu(
IBranchMenuOperations branchMenuOperations,
bool isGluonMode)
{
mBranchMenuOperations = branchMenuOperations;
mIsGluonMode = isGluonMode;
BuildComponents();
}
internal void Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
BranchMenuOperations operationToExecute = GetMenuOperations(e);
if (operationToExecute == BranchMenuOperations.None)
return false;
BranchMenuOperations operations =
BranchMenuUpdater.GetAvailableMenuOperations(
mBranchMenuOperations.GetSelectedBranchesCount(),
mIsGluonMode,
false);
if (!operations.HasFlag(operationToExecute))
return false;
ProcessMenuOperation(operationToExecute, mBranchMenuOperations);
return true;
}
void CreateBranchMenuItem_Click()
{
mBranchMenuOperations.CreateBranch();
}
void SwitchToBranchMenuItem_Click()
{
mBranchMenuOperations.SwitchToBranch();
}
void RenameBranchMenuItem_Click()
{
mBranchMenuOperations.RenameBranch();
}
void DeleteBranchMenuItem_Click()
{
mBranchMenuOperations.DeleteBranch();
}
void MergeBranchMenuItem_Click()
{
mBranchMenuOperations.MergeBranch();
}
void UpdateMenuItems(GenericMenu menu)
{
BranchMenuOperations operations = BranchMenuUpdater.GetAvailableMenuOperations(
mBranchMenuOperations.GetSelectedBranchesCount(), mIsGluonMode, false);
AddBranchMenuItem(
mCreateBranchMenuItemContent,
menu,
operations,
BranchMenuOperations.CreateBranch,
CreateBranchMenuItem_Click);
AddBranchMenuItem(
mSwitchToBranchMenuItemContent,
menu,
operations,
BranchMenuOperations.SwitchToBranch,
SwitchToBranchMenuItem_Click);
if (!mIsGluonMode)
{
menu.AddSeparator(string.Empty);
AddBranchMenuItem(
mMergeBranchMenuItemContent,
menu,
operations,
BranchMenuOperations.MergeBranch,
MergeBranchMenuItem_Click);
}
menu.AddSeparator(string.Empty);
AddBranchMenuItem(
mRenameBranchMenuItemContent,
menu,
operations,
BranchMenuOperations.Rename,
RenameBranchMenuItem_Click);
AddBranchMenuItem(
mDeleteBranchMenuItemContent,
menu,
operations,
BranchMenuOperations.Delete,
DeleteBranchMenuItem_Click);
}
static void AddBranchMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
BranchMenuOperations operations,
BranchMenuOperations operationsToCheck,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(operationsToCheck))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void ProcessMenuOperation(
BranchMenuOperations operationToExecute,
IBranchMenuOperations branchMenuOperations)
{
if (operationToExecute == BranchMenuOperations.Delete)
{
branchMenuOperations.DeleteBranch();
return;
}
if (operationToExecute == BranchMenuOperations.MergeBranch)
{
branchMenuOperations.MergeBranch();
return;
}
}
static BranchMenuOperations GetMenuOperations(Event e)
{
if (Keyboard.IsKeyPressed(e, KeyCode.Delete))
return BranchMenuOperations.Delete;
if (Keyboard.IsControlOrCommandKeyPressed(e) &&
Keyboard.IsKeyPressed(e, KeyCode.M))
return BranchMenuOperations.MergeBranch;
return BranchMenuOperations.None;
}
void BuildComponents()
{
mCreateBranchMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.BranchMenuItemCreateBranch));
mSwitchToBranchMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.BranchMenuItemSwitchToBranch));
mMergeBranchMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.BranchMenuItemMergeFromBranch),
GetPlasticShortcut.ForMerge()));
mRenameBranchMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.BranchMenuItemRenameBranch));
mDeleteBranchMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.BranchMenuItemDeleteBranch),
GetPlasticShortcut.ForDelete()));
}
GenericMenu mMenu;
GUIContent mCreateBranchMenuItemContent;
GUIContent mSwitchToBranchMenuItemContent;
GUIContent mMergeBranchMenuItemContent;
GUIContent mRenameBranchMenuItemContent;
GUIContent mDeleteBranchMenuItemContent;
readonly IBranchMenuOperations mBranchMenuOperations;
readonly bool mIsGluonMode;
}
}

View File

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

View File

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

View File

@@ -0,0 +1,194 @@
using UnityEditor;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.QueryViews.Branches;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.Branches.Dialogs
{
class CreateBranchDialog : 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.Name.CreateChildBranchTitle.GetString();
}
protected override void OnModalGUI()
{
DoTitleArea();
DoFieldsArea();
DoButtonsArea();
}
internal static BranchCreationData CreateBranchFromLastParentBranchChangeset(
EditorWindow parentWindow,
RepositorySpec repSpec,
BranchInfo parentBranchInfo)
{
string changesetStr = PlasticLocalization.Name.LastChangeset.GetString();
string explanation = BranchCreationUserInfo.GetFromObjectString(
repSpec, parentBranchInfo, changesetStr);
CreateBranchDialog dialog = Create(repSpec, parentBranchInfo, -1 , explanation);
ResponseType dialogueResult = dialog.RunModal(parentWindow);
BranchCreationData result = dialog.BuildCreationData();
result.Result = dialogueResult == ResponseType.Ok;
return result;
}
void DoTitleArea()
{
GUILayout.BeginVertical();
Title(PlasticLocalization.Name.CreateChildBranchTitle.GetString());
GUILayout.Space(5);
Paragraph(string.Format("{0} {1}",
PlasticLocalization.Name.CreateChildBranchExplanation.GetString(), mExplanation));
GUILayout.EndVertical();
}
void DoFieldsArea()
{
GUILayout.BeginVertical();
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Label(
PlasticLocalization.Name.BranchNameEntry.GetString(),
GUILayout.Width(100));
GUI.SetNextControlName(NAME_FIELD_CONTROL_NAME);
mNewBranchName = GUILayout.TextField(mNewBranchName);
if (!mWasNameFieldFocused)
{
EditorGUI.FocusTextInControl(NAME_FIELD_CONTROL_NAME);
mWasNameFieldFocused = true;
}
GUILayout.Space(5);
}
GUILayout.Space(5);
using (new EditorGUILayout.HorizontalScope())
{
using (new EditorGUILayout.VerticalScope(GUILayout.Width(100)))
{
GUILayout.Space(49);
GUILayout.Label(
PlasticLocalization.Name.CommentsEntry.GetString(),
GUILayout.Width(100));
}
mComment = GUILayout.TextArea(mComment, GUILayout.Height(100));
GUILayout.Space(5);
}
GUILayout.Space(5);
mSwitchToBranch = GUILayout.Toggle(mSwitchToBranch, PlasticLocalization.Name.SwitchToBranchCheckButton.GetString());
GUILayout.Space(5);
GUILayout.EndVertical();
}
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.Name.CancelButton.GetString()))
return;
CancelButtonAction();
}
void DoCreateButton()
{
if (!NormalButton(PlasticLocalization.Name.CreateButton.GetString()))
return;
BranchCreationValidation.AsyncValidation(
BuildCreationData(), this, mProgressControls);
}
static CreateBranchDialog Create(
RepositorySpec repSpec, BranchInfo parentBranchInfo, long changesetId, string explanation)
{
var instance = CreateInstance<CreateBranchDialog>();
instance.IsResizable = false;
instance.mEscapeKeyAction = instance.CloseButtonAction;
instance.mRepositorySpec = repSpec;
instance.mParentBranchInfo = parentBranchInfo;
instance.mNewBranchName = "";
instance.mComment = "";
instance.mSwitchToBranch = true;
instance.mProgressControls = new ProgressControlsForDialogs();
instance.mExplanation = explanation;
instance.mChangesetId = changesetId;
return instance;
}
BranchCreationData BuildCreationData()
{
return new BranchCreationData(
mRepositorySpec,
mParentBranchInfo,
mChangesetId,
mNewBranchName,
mComment,
null,
mSwitchToBranch);
}
ProgressControlsForDialogs mProgressControls;
RepositorySpec mRepositorySpec;
BranchInfo mParentBranchInfo;
long mChangesetId;
string mNewBranchName;
string mComment;
bool mSwitchToBranch;
string mExplanation;
bool mWasNameFieldFocused;
const string NAME_FIELD_CONTROL_NAME = "CreateBranchNameField";
}
}

View File

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

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Codice.CM.Common;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
using UnityEditor;
using UnityEngine;
namespace Unity.PlasticSCM.Editor.Views.Branches.Dialogs
{
internal class DeleteBranchDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
var increaseFactor = mNumberOfBranches <= MAX_ITEMS_TO_SHOW ?
TEXT_LINE_HEIGHT * mNumberOfBranches :
TEXT_LINE_HEIGHT * (MAX_ITEMS_TO_SHOW + 1);
return new Rect(baseRect.x, baseRect.y, baseRect.width, baseRect.height + increaseFactor);
}
}
internal static bool ConfirmDelete(IList<BranchInfo> branches)
{
DeleteBranchDialog dialog = Create(branches);
return dialog.RunModal(null) == ResponseType.Ok;
}
protected override string GetTitle()
{
return mTitle;
}
protected override void OnModalGUI()
{
Paragraph(mMessage);
GUILayout.Space(5);
DoButtonsArea();
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
mConfirmDelete = ToggleEntry(
PlasticLocalization.Name.ConfirmationCheckBox.GetString(),
mConfirmDelete);
GUILayout.Space(10);
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoDeleteButton();
DoCancelButton();
return;
}
DoCancelButton();
DoDeleteButton();
}
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.Name.NoButton.GetString()))
return;
CancelButtonAction();
}
void DoDeleteButton()
{
GUI.enabled = mConfirmDelete;
if (NormalButton(PlasticLocalization.Name.DeleteButton.GetString()))
{
OkButtonAction();
}
GUI.enabled = true;
}
static DeleteBranchDialog Create(IList<BranchInfo> branches)
{
var instance = CreateInstance<DeleteBranchDialog>();
instance.mMessage = BuildDeleteBranchesConfirmationMessage(branches);
instance.mNumberOfBranches = branches.Count;
instance.mTitle = PlasticLocalization.Name.ConfirmDeleteTitle.GetString();
return instance;
}
static string BuildDeleteBranchesConfirmationMessage(IList<BranchInfo> branchToDelete)
{
string[] itemNames = branchToDelete.Select(x => x.Name).ToArray();
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine(PlasticLocalization.Name.DeleteBranchesExplanation.GetString());
stringBuilder.AppendLine();
int num = Math.Min(itemNames.Length, MAX_ITEMS_TO_SHOW);
for (int i = 0; i < num; i++)
{
stringBuilder.AppendLine(" " + (i + 1) + ". " + itemNames[i]);
}
if (itemNames.Length > MAX_ITEMS_TO_SHOW)
{
stringBuilder.AppendLine(PlasticLocalization.Name.DeleteOthersMessage.GetString(itemNames.Length - MAX_ITEMS_TO_SHOW));
}
stringBuilder.AppendLine();
stringBuilder.AppendLine(PlasticLocalization.Name.DeleteBranchesConfirmation.GetString());
return stringBuilder.ToString();
}
const int TEXT_LINE_HEIGHT = 15;
const int MAX_ITEMS_TO_SHOW = 10;
string mMessage;
string mTitle;
int mNumberOfBranches;
bool mConfirmDelete;
}
}

View File

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

View File

@@ -0,0 +1,164 @@
using UnityEditor;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.QueryViews.Branches;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.Branches.Dialogs
{
internal class RenameBranchDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 500, 200);
}
}
internal static BranchRenameData GetBranchRenameData(
RepositorySpec repSpec,
BranchInfo branchInfo,
EditorWindow parentWindow)
{
RenameBranchDialog dialog = Create(
repSpec,
branchInfo,
new ProgressControlsForDialogs());
ResponseType dialogResult = dialog.RunModal(parentWindow);
BranchRenameData result = dialog.BuildRenameData();
result.Result = dialogResult == ResponseType.Ok;
return result;
}
static RenameBranchDialog Create(
RepositorySpec repSpec,
BranchInfo branchInfo,
ProgressControlsForDialogs progressControls)
{
var instance = CreateInstance<RenameBranchDialog>();
instance.mRepSpec = repSpec;
instance.mBranchInfo = branchInfo;
instance.mBranchName = BranchRenameUserInfo.GetShortBranchName(branchInfo.BranchName);
instance.mTitle = PlasticLocalization.GetString(
PlasticLocalization.Name.RenameBranchTitle);
instance.mProgressControls = progressControls;
return instance;
}
protected override string GetTitle()
{
return mTitle;
}
protected override void OnModalGUI()
{
Title(mTitle);
GUILayout.Space(10f);
DoInputArea();
GUILayout.Space(10f);
DrawProgressForDialogs.For(mProgressControls.ProgressData);
GUILayout.Space(10f);
DoButtonsArea();
}
void DoInputArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.Label(
PlasticLocalization.GetString(PlasticLocalization.Name.NewName),
GUILayout.ExpandWidth(false));
GUILayout.Space(10f);
GUI.SetNextControlName(RENAME_BRANCH_TEXTAREA_NAME);
mBranchName = GUILayout.TextField(
mBranchName,
GUILayout.ExpandWidth(true));
if (!mTextAreaFocused)
{
EditorGUI.FocusTextInControl(RENAME_BRANCH_TEXTAREA_NAME);
mTextAreaFocused = true;
}
}
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.RenameButton)))
return;
OkButtonWithValidationAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void OkButtonWithValidationAction()
{
BranchRenameValidation.AsyncValidation(
BuildRenameData(),
this,
mProgressControls);
}
BranchRenameData BuildRenameData()
{
return new BranchRenameData(mRepSpec, mBranchInfo, mBranchName);
}
string mTitle;
string mBranchName;
bool mTextAreaFocused;
RepositorySpec mRepSpec;
BranchInfo mBranchInfo;
ProgressControlsForDialogs mProgressControls;
const string RENAME_BRANCH_TEXTAREA_NAME = "rename_branch_textarea";
}
}

View File

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

View File

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

View File

@@ -0,0 +1,17 @@
using UnityEditor.IMGUI.Controls;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
class ChangesetListViewItem : TreeViewItem
{
internal object ObjectInfo { get; private set; }
internal ChangesetListViewItem(int id, object objectInfo)
: base(id, 1)
{
ObjectInfo = objectInfo;
displayName = id.ToString();
}
}
}

View File

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

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal enum ChangesetsListColumn
{
Name,
CreationDate,
CreatedBy,
Comment,
Branch,
Repository,
Guid
}
[Serializable]
internal class ChangesetsListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static ChangesetsListHeaderState GetDefault()
{
return new ChangesetsListHeaderState(BuildColumns());
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.BranchColumn));
return result;
}
internal static string GetColumnName(ChangesetsListColumn column)
{
switch (column)
{
case ChangesetsListColumn.Name:
return PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn);
case ChangesetsListColumn.CreationDate:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn);
case ChangesetsListColumn.CreatedBy:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn);
case ChangesetsListColumn.Comment:
return PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn);
case ChangesetsListColumn.Branch:
return PlasticLocalization.GetString(PlasticLocalization.Name.BranchColumn);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
if (mColumsAllowedToggleVisibility != null)
TreeHeaderColumns.SetVisibilities(columns, mColumsAllowedToggleVisibility);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = UnityConstants.ChangesetsColumns.CHANGESET_NUMBER_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.CHANGESET_NUMBER_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.Name)),
allowToggleVisibility = false,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = UnityConstants.ChangesetsColumns.CREATION_DATE_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.CREATION_DATE_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.CreationDate)),
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = UnityConstants.ChangesetsColumns.CREATED_BY_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.CREATED_BY_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.CreatedBy)),
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = UnityConstants.ChangesetsColumns.COMMENT_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.COMMENT_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.Comment)),
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = UnityConstants.ChangesetsColumns.BRANCH_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.BRANCH_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.Branch)),
sortingArrowAlignment = TextAlignment.Right
}
};
}
ChangesetsListHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
if (mColumsAllowedToggleVisibility == null)
mColumsAllowedToggleVisibility = TreeHeaderColumns.GetVisibilities(columns);
}
[SerializeField]
string[] mHeaderTitles;
[SerializeField]
bool[] mColumsAllowedToggleVisibility;
}
}

View File

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

View File

@@ -0,0 +1,450 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.QueryViews;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Avatar;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal class ChangesetsListView : TreeView
{
internal GenericMenu Menu { get { return mMenu.Menu; } }
internal ChangesetsListView(
ChangesetsListHeaderState headerState,
List<string> columnNames,
ChangesetsViewMenu menu,
Action sizeChangedAction,
Action selectionChangedAction,
Action doubleClickAction)
: base(new TreeViewState())
{
mColumnNames = columnNames;
mMenu = menu;
mSizeChangedAction = sizeChangedAction;
mSelectionChangedAction = selectionChangedAction;
mDoubleClickAction = doubleClickAction;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = false;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
mCooldownSelectionAction = new CooldownWindowDelayer(
DelayedSelectionChanged, UnityConstants.SELECTION_DELAYED_INPUT_ACTION_INTERVAL);
}
protected override void SelectionChanged(IList<int> selectedIds)
{
mCooldownSelectionAction.Ping();
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
internal void SetLoadedChangesetId(long loadedChangesetId)
{
mLoadedChangesetId = loadedChangesetId;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(
TreeViewItem rootItem)
{
if (mQueryResult == null)
{
ClearRows(rootItem, mRows);
return mRows;
}
RegenerateRows(
mListViewItemIds,
mQueryResult.GetObjects(),
rootItem, mRows);
return mRows;
}
protected override void SearchChanged(string newSearch)
{
mCooldownFilterAction.Ping();
}
protected override void ContextClickedItem(int id)
{
mMenu.Popup();
Repaint();
}
public override void OnGUI(Rect rect)
{
if (Event.current.type == EventType.Layout)
{
if (IsSizeChanged(treeViewRect, mLastRect))
mSizeChangedAction();
}
mLastRect = treeViewRect;
base.OnGUI(rect);
Event e = Event.current;
if (e.type != EventType.KeyDown)
return;
bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e);
if (isProcessed)
e.Use();
}
protected override void BeforeRowsGUI()
{
int firstRowVisible;
int lastRowVisible;
GetFirstAndLastVisibleRows(out firstRowVisible, out lastRowVisible);
GUI.DrawTexture(new Rect(0,
firstRowVisible * rowHeight,
GetRowRect(0).width,
(lastRowVisible * rowHeight) + 1000),
Images.GetTreeviewBackgroundTexture());
DrawTreeViewItem.InitializeStyles();
base.BeforeRowsGUI();
}
protected override void RowGUI(RowGUIArgs args)
{
if (args.item is ChangesetListViewItem)
{
ChangesetListViewItem changesetListViewItem = (ChangesetListViewItem)args.item;
ChangesetInfo changesetInfo = (ChangesetInfo)changesetListViewItem.ObjectInfo;
ChangesetsListViewItemGUI(
mQueryResult,
rowHeight,
changesetListViewItem,
args,
changesetInfo.ChangesetId == mLoadedChangesetId,
Repaint);
return;
}
base.RowGUI(args);
}
protected override void DoubleClickedItem(int id)
{
if (!HasSelection())
return;
mDoubleClickAction();
}
internal void BuildModel(
ViewQueryResult queryResult,
long loadedChangesetId)
{
mListViewItemIds.Clear();
mQueryResult = queryResult;
mLoadedChangesetId = loadedChangesetId;
}
internal void Refilter()
{
if (mQueryResult == null)
return;
Filter filter = new Filter(searchString);
mQueryResult.ApplyFilter(filter, mColumnNames);
}
internal void Sort()
{
if (mQueryResult == null)
return;
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mQueryResult.Sort(
mColumnNames[sortedColumnIdx],
sortAscending);
}
internal List<RepositorySpec> GetSelectedRepositories()
{
List<RepositorySpec> result = new List<RepositorySpec>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<object, int> item
in mListViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
RepositorySpec repSpec =
mQueryResult.GetRepositorySpec(item.Key);
result.Add(repSpec);
}
return result;
}
internal List<RepObjectInfo> GetSelectedRepObjectInfos()
{
List<RepObjectInfo> result = new List<RepObjectInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<object, int> item
in mListViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
RepObjectInfo repObjectInfo =
mQueryResult.GetRepObjectInfo(item.Key);
result.Add(repObjectInfo);
}
return result;
}
internal void SelectRepObjectInfos(
List<RepObjectInfo> repObjectsToSelect)
{
List<int> idsToSelect = new List<int>();
foreach (RepObjectInfo repObjectInfo in repObjectsToSelect)
{
int repObjectInfoId = GetTreeIdForItem(repObjectInfo);
if (repObjectInfoId == -1)
continue;
idsToSelect.Add(repObjectInfoId);
}
TableViewOperations.SetSelectionAndScroll(this, idsToSelect);
}
int GetTreeIdForItem(RepObjectInfo repObjectInfo)
{
foreach (KeyValuePair<object, int> item in mListViewItemIds.GetInfoItems())
{
RepObjectInfo currentRepObjectInfo =
mQueryResult.GetRepObjectInfo(item.Key);
if (!currentRepObjectInfo.Equals(repObjectInfo))
continue;
if (!currentRepObjectInfo.GUID.Equals(repObjectInfo.GUID))
continue;
return item.Value;
}
return -1;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void DelayedSelectionChanged()
{
if (!HasSelection())
return;
mSelectionChangedAction();
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
ListViewItemIds<object> listViewItemIds,
List<object> objectInfos,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (objectInfos.Count == 0)
return;
foreach (object objectInfo in objectInfos)
{
int objectId;
if (!listViewItemIds.TryGetInfoItemId(objectInfo, out objectId))
objectId = listViewItemIds.AddInfoItem(objectInfo);
ChangesetListViewItem changesetListViewItem =
new ChangesetListViewItem(objectId, objectInfo);
rootItem.AddChild(changesetListViewItem);
rows.Add(changesetListViewItem);
}
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void ChangesetsListViewItemGUI(
ViewQueryResult queryResult,
float rowHeight,
ChangesetListViewItem item,
RowGUIArgs args,
bool isBoldText,
Action avatarLoadedAction)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
if (visibleColumnIdx == 0)
{
cellRect.x += UnityConstants.FIRST_COLUMN_WITHOUT_ICON_INDENT;
cellRect.width -= UnityConstants.FIRST_COLUMN_WITHOUT_ICON_INDENT;
}
ChangesetsListColumn column =
(ChangesetsListColumn)args.GetColumn(visibleColumnIdx);
ChangesetsListViewItemCellGUI(
cellRect,
rowHeight,
queryResult,
item,
column,
avatarLoadedAction,
args.selected,
args.focused,
isBoldText);
}
}
static void ChangesetsListViewItemCellGUI(
Rect rect,
float rowHeight,
ViewQueryResult queryResult,
ChangesetListViewItem item,
ChangesetsListColumn column,
Action avatarLoadedAction,
bool isSelected,
bool isFocused,
bool isBoldText)
{
string columnText = RepObjectInfoView.GetColumnText(
queryResult.GetRepositorySpec(item.ObjectInfo),
queryResult.GetRepObjectInfo(item.ObjectInfo),
ChangesetsListHeaderState.GetColumnName(column));
if (column == ChangesetsListColumn.CreatedBy)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
-1,
GetAvatar.ForEmail(columnText, avatarLoadedAction),
null,
columnText,
isSelected,
isFocused,
isBoldText,
false);
return;
}
if (column == ChangesetsListColumn.Branch ||
column == ChangesetsListColumn.Repository ||
column == ChangesetsListColumn.Guid)
{
DrawTreeViewItem.ForSecondaryLabel(
rect, columnText, isSelected, isFocused, isBoldText);
return;
}
DrawTreeViewItem.ForLabel(
rect, columnText, isSelected, isFocused, isBoldText);
}
static bool IsSizeChanged(
Rect currentRect, Rect lastRect)
{
if (currentRect.width != lastRect.width)
return true;
if (currentRect.height != lastRect.height)
return true;
return false;
}
Rect mLastRect;
ListViewItemIds<object> mListViewItemIds = new ListViewItemIds<object>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
ViewQueryResult mQueryResult;
long mLoadedChangesetId;
readonly CooldownWindowDelayer mCooldownFilterAction;
readonly CooldownWindowDelayer mCooldownSelectionAction;
readonly Action mDoubleClickAction;
readonly Action mSelectionChangedAction;
readonly Action mSizeChangedAction;
readonly ChangesetsViewMenu mMenu;
readonly List<string> mColumnNames;
}
}

View File

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

View File

@@ -0,0 +1,68 @@
using System.Collections.Generic;
using Codice.CM.Common;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal static class ChangesetsSelection
{
internal static void SelectChangesets(
ChangesetsListView listView,
List<RepObjectInfo> csetsToSelect,
int defaultRow)
{
if (csetsToSelect == null || csetsToSelect.Count == 0)
{
TableViewOperations.SelectFirstRow(listView);
return;
}
listView.SelectRepObjectInfos(csetsToSelect);
if (listView.HasSelection())
return;
TableViewOperations.SelectDefaultRow(listView, defaultRow);
if (listView.HasSelection())
return;
TableViewOperations.SelectFirstRow(listView);
}
internal static List<RepObjectInfo> GetSelectedRepObjectInfos(
ChangesetsListView listView)
{
return listView.GetSelectedRepObjectInfos();
}
internal static int GetSelectedChangesetsCount(
ChangesetsListView listView)
{
return listView.GetSelection().Count;
}
internal static ChangesetExtendedInfo GetSelectedChangeset(
ChangesetsListView listView)
{
List<RepObjectInfo> selectedRepObjectsInfos = listView.GetSelectedRepObjectInfos();
if (selectedRepObjectsInfos.Count == 0)
return null;
return (ChangesetExtendedInfo)selectedRepObjectsInfos[0];
}
internal static RepositorySpec GetSelectedRepository(
ChangesetsListView listView)
{
List<RepositorySpec> selectedRepositories = listView.GetSelectedRepositories();
if (selectedRepositories.Count == 0)
return null;
return selectedRepositories[0];
}
}
}

View File

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

View File

@@ -0,0 +1,676 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.Client.Common.EventTracking;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using Codice.CM.Common.Mount;
using PlasticGui;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.Update;
using PlasticGui.WorkspaceWindow.QueryViews;
using PlasticGui.WorkspaceWindow.QueryViews.Changesets;
using GluonGui;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.UI.Tree;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.Views.Diff;
using IGluonUpdateReport = PlasticGui.Gluon.IUpdateReport;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal partial class ChangesetsTab :
IRefreshableView,
IQueryRefreshableView,
IChangesetMenuOperations,
ChangesetsViewMenu.IMenuOperations
{
internal ChangesetsListView Table { get { return mChangesetsListView; } }
internal IChangesetMenuOperations Operations { get { return this; } }
internal interface IRevertToChangesetListener
{
void OnSuccessOperation();
}
internal ChangesetsTab(
WorkspaceInfo wkInfo,
WorkspaceWindow workspaceWindow,
IViewSwitcher viewSwitcher,
IMergeViewLauncher mergeViewLauncher,
IHistoryViewLauncher historyViewLauncher,
ViewHost viewHost,
IUpdateReport updateReport,
IGluonUpdateReport gluonUpdateReport,
NewIncomingChangesUpdater newIncomingChangesUpdater,
IRevertToChangesetListener revertToChangesetListener,
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
LaunchTool.IProcessExecutor processExecutor,
EditorWindow parentWindow,
bool isGluonMode)
{
mWkInfo = wkInfo;
mViewHost = viewHost;
mWorkspaceWindow = workspaceWindow;
mViewSwitcher = viewSwitcher;
mRevertToChangesetListener = revertToChangesetListener;
mShowDownloadPlasticExeWindow = showDownloadPlasticExeWindow;
mProcessExecutor = processExecutor;
mParentWindow = parentWindow;
mIsGluonMode = isGluonMode;
mGluonUpdateReport = gluonUpdateReport;
BuildComponents(
wkInfo,
workspaceWindow,
workspaceWindow,
viewSwitcher,
historyViewLauncher,
parentWindow);
mProgressControls = new ProgressControlsForViews();
mSplitterState = PlasticSplitterGUILayout.InitSplitterState(
new float[] { 0.50f, 0.50f },
new int[] { 100, (int)UnityConstants.DIFF_PANEL_MIN_WIDTH },
new int[] { 100000, 100000 }
);
mBorderColor = EditorGUIUtility.isProSkin
? (Color)new Color32(35, 35, 35, 255)
: (Color)new Color32(153, 153, 153, 255);
mChangesetOperations = new ChangesetOperations(
wkInfo,
workspaceWindow,
null,
viewSwitcher,
mergeViewLauncher,
this,
ViewType.ChangesetsView,
mProgressControls,
updateReport,
new ContinueWithPendingChangesQuestionerBuilder(viewSwitcher, parentWindow),
null,
null,
newIncomingChangesUpdater,
null,
null,
null,
null,
null);
((IRefreshableView)this).Refresh();
}
internal void OnEnable()
{
mDiffPanel.OnEnable();
mSearchField.downOrUpArrowKeyPressed +=
SearchField_OnDownOrUpArrowKeyPressed;
}
internal void OnDisable()
{
mDiffPanel.OnDisable();
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
TreeHeaderSettings.Save(
mChangesetsListView.multiColumnHeader.state,
UnityConstants.CHANGESETS_TABLE_SETTINGS_NAME);
}
internal void Update()
{
mDiffPanel.Update();
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
InitializeShowChangesButtonWidth();
DoActionsToolbar(mProgressControls);
PlasticSplitterGUILayout.BeginHorizontalSplit(mSplitterState);
DoChangesetsArea(
mChangesetsListView,
mProgressControls.IsOperationRunning());
EditorGUILayout.BeginHorizontal();
Rect border = GUILayoutUtility.GetRect(1, 0, 1, 100000);
EditorGUI.DrawRect(border, mBorderColor);
DoChangesArea(mDiffPanel);
EditorGUILayout.EndHorizontal();
PlasticSplitterGUILayout.EndHorizontalSplit();
}
internal void DrawSearchFieldForTab()
{
DrawSearchField.For(
mSearchField,
mChangesetsListView,
UnityConstants.SEARCH_FIELD_WIDTH);
VerifyIfSearchFieldIsRecentlyFocused(mSearchField);
}
internal void DrawDateFilter()
{
GUI.enabled = !mProgressControls.IsOperationRunning();
EditorGUI.BeginChangeCheck();
mDateFilter.FilterType = (DateFilter.Type)
EditorGUILayout.EnumPopup(
mDateFilter.FilterType,
EditorStyles.toolbarDropDown,
GUILayout.Width(100));
if (EditorGUI.EndChangeCheck())
{
EnumPopupSetting<DateFilter.Type>.Save(
mDateFilter.FilterType,
UnityConstants.CHANGESETS_DATE_FILTER_SETTING_NAME);
((IRefreshableView)this).Refresh();
}
GUI.enabled = true;
}
internal void SetWorkingObjectInfo(WorkingObjectInfo homeInfo)
{
if (mIsGluonMode)
return;
lock (mLock)
{
mLoadedChangesetId = homeInfo.GetChangesetId();
}
mChangesetsListView.SetLoadedChangesetId(mLoadedChangesetId);
mChangesetsViewMenu.SetLoadedBranchId(homeInfo.BranchInfo.BranchId);
}
internal void SetRevertToChangesetOperationInterfacesForTesting(
RevertToChangesetOperation.IGetStatusForWorkspace getStatusForWorkspace,
RevertToChangesetOperation.IUndoCheckoutOperation undoCheckoutOperation,
RevertToChangesetOperation.IRevertToChangesetMergeController revertToChangesetMergeController)
{
mGetStatusForWorkspace = getStatusForWorkspace;
mUndoCheckoutOperation = undoCheckoutOperation;
mRevertToChangesetMergeController = revertToChangesetMergeController;
}
internal void SetLaunchToolForTesting(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
LaunchTool.IProcessExecutor processExecutor)
{
mShowDownloadPlasticExeWindow = showDownloadPlasticExeWindow;
mProcessExecutor = processExecutor;
}
void IRefreshableView.Refresh()
{
string query = GetChangesetsQuery(mDateFilter);
FillChangesets(
mWkInfo,
query,
ChangesetsSelection.GetSelectedRepObjectInfos(mChangesetsListView));
}
void IQueryRefreshableView.RefreshAndSelect(RepObjectInfo repObj)
{
string query = GetChangesetsQuery(mDateFilter);
FillChangesets(
mWkInfo,
query,
new List<RepObjectInfo> { repObj });
}
int IChangesetMenuOperations.GetSelectedChangesetsCount()
{
return ChangesetsSelection.GetSelectedChangesetsCount(mChangesetsListView);
}
void IChangesetMenuOperations.DiffChangeset()
{
LaunchDiffOperations.DiffChangeset(
mShowDownloadPlasticExeWindow,
mProcessExecutor,
ChangesetsSelection.GetSelectedRepository(mChangesetsListView),
ChangesetsSelection.GetSelectedChangeset(mChangesetsListView),
mIsGluonMode);
}
void IChangesetMenuOperations.DiffSelectedChangesets()
{
List<RepObjectInfo> selectedChangesets = ChangesetsSelection.
GetSelectedRepObjectInfos(mChangesetsListView);
if (selectedChangesets.Count < 2)
return;
LaunchDiffOperations.DiffSelectedChangesets(
mShowDownloadPlasticExeWindow,
mProcessExecutor,
ChangesetsSelection.GetSelectedRepository(mChangesetsListView),
(ChangesetExtendedInfo)selectedChangesets[0],
(ChangesetExtendedInfo)selectedChangesets[1],
mIsGluonMode);
}
void IChangesetMenuOperations.SwitchToChangeset()
{
SwitchToChangesetForMode();
}
void IChangesetMenuOperations.DiffWithAnotherChangeset() { }
void IChangesetMenuOperations.CreateBranch() { }
void IChangesetMenuOperations.LabelChangeset() { }
void IChangesetMenuOperations.MergeChangeset()
{
mChangesetOperations.MergeChangeset(
ChangesetsSelection.GetSelectedRepository(mChangesetsListView),
ChangesetsSelection.GetSelectedChangeset(mChangesetsListView));
}
void IChangesetMenuOperations.CherryPickChangeset() { }
void IChangesetMenuOperations.SubtractiveChangeset() { }
void IChangesetMenuOperations.SubtractiveChangesetInterval() { }
void IChangesetMenuOperations.CherryPickChangesetInterval() { }
void IChangesetMenuOperations.MergeToChangeset() { }
void IChangesetMenuOperations.MoveChangeset() { }
void IChangesetMenuOperations.DeleteChangeset() { }
void IChangesetMenuOperations.BrowseRepositoryOnChangeset() { }
void IChangesetMenuOperations.CreateCodeReview() { }
void IChangesetMenuOperations.RevertToChangeset()
{
if (((IChangesetMenuOperations)this).GetSelectedChangesetsCount() != 1)
return;
ChangesetExtendedInfo targetChangesetInfo = ((ChangesetsViewMenu.IMenuOperations)this).GetSelectedChangeset();
RevertToChangesetOperation.RevertTo(
mWkInfo,
mViewSwitcher,
mWorkspaceWindow,
mProgressControls,
mGetStatusForWorkspace,
mUndoCheckoutOperation,
mRevertToChangesetMergeController,
GuiMessage.Get(),
targetChangesetInfo,
RefreshAsset.BeforeLongAssetOperation,
RefreshAsset.AfterLongAssetOperation,
mRevertToChangesetListener.OnSuccessOperation);
}
void ChangesetsViewMenu.IMenuOperations.DiffBranch()
{
LaunchDiffOperations.DiffBranch(
mShowDownloadPlasticExeWindow,
mProcessExecutor,
ChangesetsSelection.GetSelectedRepository(mChangesetsListView),
ChangesetsSelection.GetSelectedChangeset(mChangesetsListView),
mIsGluonMode);
}
ChangesetExtendedInfo ChangesetsViewMenu.IMenuOperations.GetSelectedChangeset()
{
return ChangesetsSelection.GetSelectedChangeset(
mChangesetsListView);
}
void SearchField_OnDownOrUpArrowKeyPressed()
{
mChangesetsListView.SetFocusAndEnsureSelectedItem();
}
void OnChangesetsListViewSizeChanged()
{
if (!mShouldScrollToSelection)
return;
mShouldScrollToSelection = false;
TableViewOperations.ScrollToSelection(mChangesetsListView);
}
void OnSelectionChanged()
{
List<RepObjectInfo> selectedChangesets = ChangesetsSelection.
GetSelectedRepObjectInfos(mChangesetsListView);
if (selectedChangesets.Count != 1)
return;
mDiffPanel.UpdateInfo(
MountPointWithPath.BuildWorkspaceRootMountPoint(
ChangesetsSelection.GetSelectedRepository(mChangesetsListView)),
(ChangesetExtendedInfo)selectedChangesets[0]);
}
void FillChangesets(
WorkspaceInfo wkInfo,
string query,
List<RepObjectInfo> changesetsToSelect)
{
if (mIsRefreshing)
return;
mIsRefreshing = true;
int defaultRow = TableViewOperations.
GetFirstSelectedRow(mChangesetsListView);
((IProgressControls)mProgressControls).ShowProgress(
PlasticLocalization.GetString(
PlasticLocalization.Name.LoadingChangesets));
ViewQueryResult queryResult = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
long loadedChangesetId = GetLoadedChangesetId(
wkInfo, mIsGluonMode);
long loadedBranchId = GetLoadedBranchId(
wkInfo, loadedChangesetId, mIsGluonMode);
lock (mLock)
{
mLoadedChangesetId = loadedChangesetId;
}
mChangesetsViewMenu.SetLoadedBranchId(loadedBranchId);
queryResult = new ViewQueryResult(
PlasticGui.Plastic.API.FindQuery(wkInfo, query));
},
/*afterOperationDelegate*/ delegate
{
try
{
if (waiter.Exception != null)
{
ExceptionsHandler.DisplayException(waiter.Exception);
return;
}
UpdateChangesetsList(
mChangesetsListView,
queryResult,
mLoadedChangesetId);
int changesetsCount = GetChangesetsCount(queryResult);
if (changesetsCount == 0)
{
mDiffPanel.ClearInfo();
return;
}
ChangesetsSelection.SelectChangesets(
mChangesetsListView, changesetsToSelect, defaultRow);
}
finally
{
((IProgressControls)mProgressControls).HideProgress();
mIsRefreshing = false;
}
});
}
void InitializeShowChangesButtonWidth()
{
if (mShowChangesButtonWidth != -1)
return;
mShowChangesButtonWidth = MeasureMaxWidth.ForTexts(
EditorStyles.toolbarButton,
PlasticLocalization.GetString(PlasticLocalization.Name.HideChanges),
PlasticLocalization.GetString(PlasticLocalization.Name.ShowChanges));
}
void VerifyIfSearchFieldIsRecentlyFocused(SearchField searchField)
{
if (searchField.HasFocus() != mIsSearchFieldFocused)
{
mIsSearchFieldFocused = !mIsSearchFieldFocused;
if (mIsSearchFieldFocused)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
TrackFeatureUseEvent.Features.ChangesetsViewChangesetsSearchBox);
}
}
}
static void UpdateChangesetsList(
ChangesetsListView changesetsListView,
ViewQueryResult queryResult,
long loadedChangesetId)
{
changesetsListView.BuildModel(
queryResult,
loadedChangesetId);
changesetsListView.Refilter();
changesetsListView.Sort();
changesetsListView.Reload();
}
static long GetLoadedChangesetId(
WorkspaceInfo wkInfo,
bool isGluonMode)
{
if (isGluonMode)
return -1;
return PlasticGui.Plastic.API.GetLoadedChangeset(wkInfo);
}
static long GetLoadedBranchId(
WorkspaceInfo wkInfo,
long loadedChangesetId,
bool isGluonMode)
{
if (isGluonMode)
return -1;
return PlasticGui.Plastic.API.GetChangesetInfoFromId(
wkInfo, loadedChangesetId).BranchId;
}
static int GetChangesetsCount(
ViewQueryResult queryResult)
{
if (queryResult == null)
return 0;
return queryResult.Count();
}
static string GetChangesetsQuery(DateFilter dateFilter)
{
if (dateFilter.FilterType == DateFilter.Type.AllTime)
return QueryConstants.ChangesetsBeginningQuery;
string whereClause = QueryConstants.GetDateWhereClause(
dateFilter.GetTimeAgo());
return string.Format("{0} {1}",
QueryConstants.ChangesetsBeginningQuery,
whereClause);
}
void DoActionsToolbar(ProgressControlsForViews progressControls)
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
if (progressControls.IsOperationRunning())
{
DrawProgressForViews.ForIndeterminateProgress(
progressControls.ProgressData);
}
GUILayout.FlexibleSpace();
GUILayout.Space(2);
EditorGUILayout.EndHorizontal();
}
static void DoChangesetsArea(
ChangesetsListView changesetsListView,
bool isOperationRunning)
{
EditorGUILayout.BeginVertical();
GUI.enabled = !isOperationRunning;
Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
changesetsListView.OnGUI(rect);
GUI.enabled = true;
EditorGUILayout.EndVertical();
}
static void DoChangesArea(DiffPanel diffPanel)
{
EditorGUILayout.BeginVertical();
diffPanel.OnGUI();
EditorGUILayout.EndVertical();
}
void BuildComponents(
WorkspaceInfo wkInfo,
IWorkspaceWindow workspaceWindow,
IRefreshView refreshView,
IViewSwitcher viewSwitcher,
IHistoryViewLauncher historyViewLauncher,
EditorWindow parentWindow)
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
DateFilter.Type dateFilterType =
EnumPopupSetting<DateFilter.Type>.Load(
UnityConstants.CHANGESETS_DATE_FILTER_SETTING_NAME,
DateFilter.Type.LastMonth);
mDateFilter = new DateFilter(dateFilterType);
ChangesetsListHeaderState headerState =
ChangesetsListHeaderState.GetDefault();
TreeHeaderSettings.Load(headerState,
UnityConstants.CHANGESETS_TABLE_SETTINGS_NAME,
(int)ChangesetsListColumn.CreationDate, false);
mChangesetsViewMenu = new ChangesetsViewMenu(
wkInfo,
this,
this,
mShowDownloadPlasticExeWindow,
mIsGluonMode);
mChangesetsListView = new ChangesetsListView(
headerState,
ChangesetsListHeaderState.GetColumnNames(),
mChangesetsViewMenu,
sizeChangedAction: OnChangesetsListViewSizeChanged,
selectionChangedAction: OnSelectionChanged,
doubleClickAction: ((IChangesetMenuOperations)this).DiffChangeset);
mChangesetsListView.Reload();
mDiffPanel = new DiffPanel(
wkInfo, workspaceWindow, refreshView, viewSwitcher,
historyViewLauncher, mShowDownloadPlasticExeWindow,
parentWindow, mIsGluonMode);
}
bool mIsRefreshing;
bool mShouldScrollToSelection;
float mShowChangesButtonWidth = -1;
object mSplitterState;
Color mBorderColor;
DateFilter mDateFilter;
SearchField mSearchField;
bool mIsSearchFieldFocused = false;
ChangesetsListView mChangesetsListView;
ChangesetOperations mChangesetOperations;
DiffPanel mDiffPanel;
ChangesetsViewMenu mChangesetsViewMenu;
RevertToChangesetOperation.IGetStatusForWorkspace mGetStatusForWorkspace =
new RevertToChangesetOperation.GetStatusFromWorkspace();
RevertToChangesetOperation.IUndoCheckoutOperation mUndoCheckoutOperation =
new RevertToChangesetOperation.UndoCheckout();
RevertToChangesetOperation.IRevertToChangesetMergeController mRevertToChangesetMergeController =
new RevertToChangesetOperation.RevertToChangesetMergeController();
long mLoadedChangesetId = -1;
object mLock = new object();
LaunchTool.IProcessExecutor mProcessExecutor;
LaunchTool.IShowDownloadPlasticExeWindow mShowDownloadPlasticExeWindow;
readonly bool mIsGluonMode;
readonly ViewHost mViewHost;
readonly IGluonUpdateReport mGluonUpdateReport;
readonly WorkspaceWindow mWorkspaceWindow;
readonly IViewSwitcher mViewSwitcher;
readonly ProgressControlsForViews mProgressControls;
readonly IRevertToChangesetListener mRevertToChangesetListener;
readonly EditorWindow mParentWindow;
readonly WorkspaceInfo mWkInfo;
}
}

View File

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

View File

@@ -0,0 +1,55 @@
using Codice.CM.Common;
using GluonGui.WorkspaceWindow.Views.WorkspaceExplorer.Explorer;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal partial class ChangesetsTab
{
void SwitchToChangesetForMode()
{
if (mIsGluonMode)
{
SwitchToChangesetForGluon();
return;
}
SwitchToChangesetForDeveloper();
}
void SwitchToChangesetForDeveloper()
{
mChangesetOperations.SwitchToChangeset(
ChangesetsSelection.GetSelectedRepository(mChangesetsListView),
ChangesetsSelection.GetSelectedChangeset(mChangesetsListView),
RefreshAsset.BeforeLongAssetOperation,
items => RefreshAsset.AfterLongAssetOperation(
ProjectPackages.ShouldBeResolved(items, mWkInfo, false)));
}
void SwitchToChangesetForGluon()
{
ChangesetExtendedInfo csetInfo = ChangesetsSelection.GetSelectedChangeset(mChangesetsListView);
new SwitchToUIOperation().SwitchToChangeset(
mWkInfo,
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
csetInfo.BranchName,
csetInfo.ChangesetId,
mViewHost,
null,
new UnityPlasticGuiMessage(),
mProgressControls,
mWorkspaceWindow.GluonProgressOperationHandler,
mGluonUpdateReport,
mWorkspaceWindow,
null,
null,
null,
RefreshAsset.BeforeLongAssetOperation,
items => RefreshAsset.AfterLongAssetOperation(
ProjectPackages.ShouldBeResolved(items, mWkInfo, true)));
}
}
}

View File

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

View File

@@ -0,0 +1,398 @@
using UnityEditor;
using UnityEngine;
using Codice.Client.Common.EventTracking;
using Codice.CM.Common;
using PlasticGui.WorkspaceWindow.QueryViews.Changesets;
using PlasticGui;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal class ChangesetsViewMenu
{
internal GenericMenu Menu { get { return mMenu; } }
public interface IMenuOperations
{
void DiffBranch();
ChangesetExtendedInfo GetSelectedChangeset();
}
internal ChangesetsViewMenu(
WorkspaceInfo wkInfo,
IChangesetMenuOperations changesetMenuOperations,
IMenuOperations menuOperations,
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
bool isGluonMode)
{
mWkInfo = wkInfo;
mChangesetMenuOperations = changesetMenuOperations;
mMenuOperations = menuOperations;
mShowDownloadPlasticExeWindow = showDownloadPlasticExeWindow;
mIsGluonMode = isGluonMode;
BuildComponents();
}
internal void Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
int selectedChangesetsCount = mChangesetMenuOperations.GetSelectedChangesetsCount();
ChangesetMenuOperations operationToExecute = GetMenuOperations(
e, selectedChangesetsCount > 1);
if (operationToExecute == ChangesetMenuOperations.None)
return false;
ChangesetMenuOperations operations = ChangesetMenuUpdater.GetAvailableMenuOperations(
selectedChangesetsCount,
mIsGluonMode,
mMenuOperations.GetSelectedChangeset().BranchId,
mLoadedBranchId,
false);
if (!operations.HasFlag(operationToExecute))
return false;
ProcessMenuOperation(operationToExecute);
return true;
}
internal void SetLoadedBranchId(long loadedBranchId)
{
mLoadedBranchId = loadedBranchId;
}
void DiffChangesetMenuItem_Click()
{
mChangesetMenuOperations.DiffChangeset();
}
void DiffSelectedChangesetsMenuItem_Click()
{
mChangesetMenuOperations.DiffSelectedChangesets();
}
void RevertToChangesetMenuItem_Click()
{
mChangesetMenuOperations.RevertToChangeset();
}
void DiffBranchMenuItem_Click()
{
mMenuOperations.DiffBranch();
}
void SwitchToChangesetMenuItem_Click()
{
mChangesetMenuOperations.SwitchToChangeset();
}
void MergeChangesetMenuItem_Click()
{
mChangesetMenuOperations.MergeChangeset();
}
void UpdateMenuItems(GenericMenu menu)
{
ChangesetExtendedInfo singleSelectedChangeset = mMenuOperations.GetSelectedChangeset();
ChangesetMenuOperations operations = ChangesetMenuUpdater.GetAvailableMenuOperations(
mChangesetMenuOperations.GetSelectedChangesetsCount(),
mIsGluonMode,
singleSelectedChangeset.BranchId,
mLoadedBranchId,
false);
AddDiffChangesetMenuItem(
mDiffChangesetMenuItemContent,
menu,
singleSelectedChangeset,
operations,
DiffChangesetMenuItem_Click);
AddDiffSelectedChangesetsMenuItem(
mDiffSelectedChangesetsMenuItemContent,
menu,
operations,
DiffSelectedChangesetsMenuItem_Click);
if (!IsOnMainBranch(singleSelectedChangeset))
{
menu.AddSeparator(string.Empty);
AddDiffBranchMenuItem(
mDiffBranchMenuItemContent,
menu,
singleSelectedChangeset,
operations,
DiffBranchMenuItem_Click);
}
menu.AddSeparator(string.Empty);
AddSwitchToChangesetMenuItem(
mSwitchToChangesetMenuItemContent,
menu,
operations,
SwitchToChangesetMenuItem_Click);
if (mIsGluonMode)
return;
AddBackToMenuItem(
mRevertToChangesetMenuItemContent,
menu,
operations,
RevertToChangesetMenuItem_Click);
menu.AddSeparator(string.Empty);
AddMergeChangesetMenuItem(
mMergeChangesetMenuItemContent,
menu,
operations,
MergeChangesetMenuItem_Click);
}
void ProcessMenuOperation(
ChangesetMenuOperations operationToExecute)
{
if (operationToExecute == ChangesetMenuOperations.DiffChangeset)
{
DiffChangesetMenuItem_Click();
return;
}
if (operationToExecute == ChangesetMenuOperations.DiffSelectedChangesets)
{
DiffSelectedChangesetsMenuItem_Click();
return;
}
if (operationToExecute == ChangesetMenuOperations.MergeChangeset)
{
MergeChangesetMenuItem_Click();
return;
}
}
static void AddDiffChangesetMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetExtendedInfo changeset,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
string changesetName =
changeset != null ?
changeset.ChangesetId.ToString() :
string.Empty;
menuItemContent.text = string.Format("{0} {1}",
PlasticLocalization.GetString(
PlasticLocalization.Name.AnnotateDiffChangesetMenuItem,
changesetName),
GetPlasticShortcut.ForDiff());
if (operations.HasFlag(ChangesetMenuOperations.DiffChangeset))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(
menuItemContent);
}
static void AddDiffSelectedChangesetsMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(ChangesetMenuOperations.DiffSelectedChangesets))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddBackToMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(ChangesetMenuOperations.RevertToChangeset))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddDiffBranchMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetExtendedInfo changeset,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
string branchName = GetBranchName(changeset);
menuItemContent.text =
PlasticLocalization.GetString(PlasticLocalization.Name.AnnotateDiffBranchMenuItem,
branchName);
if (operations.HasFlag(ChangesetMenuOperations.DiffChangeset))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(
menuItemContent);
}
static void AddSwitchToChangesetMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(ChangesetMenuOperations.SwitchToChangeset))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddMergeChangesetMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(ChangesetMenuOperations.MergeChangeset))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static string GetBranchName(ChangesetExtendedInfo changesetInfo)
{
if (changesetInfo == null)
return string.Empty;
string branchName = changesetInfo.BranchName;
int lastIndex = changesetInfo.BranchName.LastIndexOf("/");
if (lastIndex == -1)
return branchName;
return branchName.Substring(lastIndex + 1);
}
static bool IsOnMainBranch(ChangesetExtendedInfo singleSeletedChangeset)
{
if (singleSeletedChangeset == null)
return false;
return singleSeletedChangeset.BranchName == MAIN_BRANCH_NAME;
}
static ChangesetMenuOperations GetMenuOperations(
Event e, bool isMultipleSelection)
{
if (Keyboard.IsControlOrCommandKeyPressed(e) &&
Keyboard.IsKeyPressed(e, KeyCode.D))
return isMultipleSelection ?
ChangesetMenuOperations.DiffSelectedChangesets :
ChangesetMenuOperations.DiffChangeset;
if (Keyboard.IsControlOrCommandKeyPressed(e) &&
Keyboard.IsKeyPressed(e, KeyCode.M))
return ChangesetMenuOperations.MergeChangeset;
return ChangesetMenuOperations.None;
}
void BuildComponents()
{
mDiffChangesetMenuItemContent = new GUIContent(string.Empty);
mDiffSelectedChangesetsMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetMenuItemDiffSelected),
GetPlasticShortcut.ForDiff()));
mDiffBranchMenuItemContent = new GUIContent();
mSwitchToChangesetMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetMenuItemSwitchToChangeset));
mRevertToChangesetMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetMenuItemRevertToChangeset));
mMergeChangesetMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetMenuItemMergeFromChangeset),
GetPlasticShortcut.ForMerge()));
}
GenericMenu mMenu;
GUIContent mDiffChangesetMenuItemContent;
GUIContent mDiffSelectedChangesetsMenuItemContent;
GUIContent mDiffBranchMenuItemContent;
GUIContent mSwitchToChangesetMenuItemContent;
GUIContent mRevertToChangesetMenuItemContent;
GUIContent mMergeChangesetMenuItemContent;
readonly WorkspaceInfo mWkInfo;
readonly IChangesetMenuOperations mChangesetMenuOperations;
readonly IMenuOperations mMenuOperations;
readonly LaunchTool.IShowDownloadPlasticExeWindow mShowDownloadPlasticExeWindow;
readonly bool mIsGluonMode;
long mLoadedBranchId = -1;
const string MAIN_BRANCH_NAME = "/main";
}
}

View File

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

View File

@@ -0,0 +1,44 @@
using System;
using PlasticGui.WorkspaceWindow.QueryViews;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal class DateFilter
{
internal enum Type
{
LastWeek,
Last15Days,
LastMonth,
Last3Months,
LastYear,
AllTime
}
internal Type FilterType;
internal DateFilter(Type filterType)
{
FilterType = filterType;
}
internal string GetTimeAgo()
{
switch (FilterType)
{
case DateFilter.Type.LastWeek:
return QueryConstants.OneWeekAgo;
case DateFilter.Type.Last15Days:
return QueryConstants.HalfMonthAgo;
case DateFilter.Type.LastMonth:
return QueryConstants.OneMonthAgo;
case DateFilter.Type.Last3Months:
return QueryConstants.ThreeMonthsAgo;
case DateFilter.Type.LastYear:
return QueryConstants.OneYearAgo;
}
return string.Empty;
}
}
}

View File

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

View File

@@ -0,0 +1,137 @@
using Codice.CM.Common;
using Unity.PlasticSCM.Editor.Tool;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
static class LaunchDiffOperations
{
internal static void DiffChangeset(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
LaunchTool.IProcessExecutor processExecutor,
RepositorySpec repSpec,
long changesetId,
bool isGluonMode)
{
if (changesetId == -1)
return;
string changesetFullSpec = GetChangesetFullSpec(
repSpec, changesetId);
LaunchTool.OpenChangesetDiffs(
showDownloadPlasticExeWindow,
processExecutor,
repSpec,
changesetFullSpec,
isGluonMode);
}
internal static void DiffChangeset(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
LaunchTool.IProcessExecutor processExecutor,
RepositorySpec repSpec,
ChangesetInfo changesetInfo,
bool isGluonMode)
{
if (changesetInfo == null)
return;
string changesetFullSpec = GetChangesetFullSpec(
repSpec, changesetInfo.ChangesetId);
LaunchTool.OpenChangesetDiffs(
showDownloadPlasticExeWindow,
processExecutor,
repSpec,
changesetFullSpec,
isGluonMode);
}
internal static void DiffSelectedChangesets(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
LaunchTool.IProcessExecutor processExecutor,
RepositorySpec repSpec,
ChangesetInfo cset1,
ChangesetInfo cset2,
bool isGluonMode)
{
ChangesetInfo srcChangesetInfo;
ChangesetInfo dstChangesetInfo;
GetSrcAndDstCangesets(
cset1,
cset2,
out srcChangesetInfo,
out dstChangesetInfo);
string srcChangesetFullSpec = GetChangesetFullSpec(
repSpec, srcChangesetInfo.ChangesetId);
string dstChangesetFullSpec = GetChangesetFullSpec(
repSpec, dstChangesetInfo.ChangesetId);
LaunchTool.OpenSelectedChangesetsDiffs(
showDownloadPlasticExeWindow,
processExecutor,
repSpec,
srcChangesetFullSpec,
dstChangesetFullSpec,
isGluonMode);
}
internal static void DiffBranch(
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
LaunchTool.IProcessExecutor processExecutor,
RepositorySpec repSpec,
ChangesetExtendedInfo changesetExtendedInfo,
bool isGluonMode)
{
if (changesetExtendedInfo == null)
return;
string branchFullSpec = GetBranchFullSpec(
repSpec, changesetExtendedInfo);
LaunchTool.OpenBranchDiffs(
showDownloadPlasticExeWindow,
processExecutor,
repSpec,
branchFullSpec,
isGluonMode);
}
static void GetSrcAndDstCangesets(
ChangesetInfo cset1,
ChangesetInfo cset2,
out ChangesetInfo srcChangesetInfo,
out ChangesetInfo dstChangesetInfo)
{
if (cset1.LocalTimeStamp < cset2.LocalTimeStamp)
{
srcChangesetInfo = cset1;
dstChangesetInfo = cset2;
return;
}
srcChangesetInfo = cset2;
dstChangesetInfo = cset1;
}
static string GetChangesetFullSpec(
RepositorySpec repSpec,
long changesetId)
{
return string.Format("cs:{0}@{1}",
changesetId, repSpec.ToString());
}
static string GetBranchFullSpec(
RepositorySpec repSpec,
ChangesetExtendedInfo changesetExtendedInfo)
{
return string.Format("br:{0}@{1}",
changesetExtendedInfo.BranchName,
repSpec.ToString());
}
}
}

View File

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

View File

@@ -0,0 +1,208 @@
using UnityEditor;
using UnityEngine;
using Codice.Client.Common;
using Codice.Client.Commands;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Update;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views
{
internal class ContinueWithPendingChangesQuestionerBuilder :
SwitchController.IContinueWithPendingChangesQuestionerBuilder
{
internal ContinueWithPendingChangesQuestionerBuilder(
IViewSwitcher viewSwitcher,
EditorWindow parentWindow)
{
mViewSwitcher = viewSwitcher;
mParentWindow = parentWindow;
}
public IContinueWithPendingChangesQuestioner Get(string title, string explanation)
{
return new ContinueWithPendingChangesQuestioner(
title,
explanation,
mViewSwitcher,
mParentWindow);
}
IViewSwitcher mViewSwitcher;
EditorWindow mParentWindow;
}
internal class ContinueWithPendingChangesQuestioner : IContinueWithPendingChangesQuestioner
{
internal ContinueWithPendingChangesQuestioner(
string title,
string explanation,
IViewSwitcher viewSwitcher,
EditorWindow parentWindow)
{
mTitle = title;
mExplanation = explanation;
mViewSwitcher = viewSwitcher;
mParentWindow = parentWindow;
}
public bool ContinueWithPendingChanges()
{
bool result = false;
GUIActionRunner.RunGUIAction(() =>
{
result = ConfirmContinueWithPendingChangesDialog.ConfirmContinue(
mTitle,
mExplanation,
mViewSwitcher,
mParentWindow);
});
return result;
}
string mTitle;
string mExplanation;
IViewSwitcher mViewSwitcher;
EditorWindow mParentWindow;
}
internal class ConfirmContinueWithPendingChangesDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 500, 287);
}
}
internal static bool ConfirmContinue(
string title,
string explanation,
IViewSwitcher viewSwitcher,
EditorWindow parentWindow)
{
ConfirmContinueWithPendingChangesDialog dialog = Create(
title,
explanation,
viewSwitcher);
if (dialog.RunModal(parentWindow) != ResponseType.Ok)
return false;
if (dialog.mIsSwitchToConfirmationChecked)
SavePreference();
return true;
}
static ConfirmContinueWithPendingChangesDialog Create(
string title,
string explanation,
IViewSwitcher viewSwitcher)
{
var instance = CreateInstance<ConfirmContinueWithPendingChangesDialog>();
instance.mTitle = title;
instance.mExplanation = explanation;
instance.mViewSwitcher = viewSwitcher;
return instance;
}
static void SavePreference()
{
ClientConfigData data = ClientConfig.Get().GetClientConfigData();
data.SetPendingChangesOnSwitchAction(UserAction.None);
ClientConfig.Get().Save(data);
}
protected override string GetTitle()
{
return mTitle;
}
protected override void OnModalGUI()
{
Title(mTitle);
Paragraph(mExplanation);
DoSwitchToConfirmationCheckButton();
GUILayout.Space(10);
DoButtonsArea();
}
void DoSwitchToConfirmationCheckButton()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
mIsSwitchToConfirmationChecked = TitleToggle(
PlasticLocalization.GetString(
PlasticLocalization.Name.SwitchToConfirmationCheckButton),
mIsSwitchToConfirmationChecked);
}
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoContinueButton();
DoCancelAndViewPendingChangesButton();
DoCancelButton();
return;
}
DoCancelButton();
DoCancelAndViewPendingChangesButton();
DoContinueButton();
}
}
void DoContinueButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.SwitchToConfirmationContinueButton)))
return;
OkButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void DoCancelAndViewPendingChangesButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.SwitchToConfirmationCancelViewChangesButton)))
return;
mViewSwitcher.ShowPendingChanges();
CancelButtonAction();
}
string mTitle;
string mExplanation;
IViewSwitcher mViewSwitcher;
bool mIsSwitchToConfirmationChecked;
}
}

View File

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

View File

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

View File

@@ -0,0 +1,336 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Codice.Client.Common;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.Configuration.CloudEdition;
using PlasticGui.WorkspaceWindow.Home.Repositories;
using PlasticGui.WorkspaceWindow.Home.Workspaces;
using PlasticGui.WebApi;
using Unity.PlasticSCM.Editor.AssetUtils.Processor;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
{
internal class CreateWorkspaceView :
IPlasticDialogCloser,
IWorkspacesRefreshableView
{
internal interface ICreateWorkspaceListener
{
void OnWorkspaceCreated(WorkspaceInfo wkInfo, bool isGluonMode);
}
internal CreateWorkspaceView(
PlasticWindow parentWindow,
ICreateWorkspaceListener listener,
IPlasticAPI plasticApi,
IPlasticWebRestApi plasticWebRestApi,
string workspacePath)
{
mParentWindow = parentWindow;
mCreateWorkspaceListener = listener;
mWorkspacePath = workspacePath;
mPlasticWebRestApi = plasticWebRestApi;
mProgressControls = new ProgressControlsForViews();
mWorkspaceOperations = new WorkspaceOperations(this, mProgressControls, null);
mCreateWorkspaceState = CreateWorkspaceViewState.BuildForProjectDefaults();
Initialize(plasticApi, plasticWebRestApi);
}
internal void Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
if (Event.current.type == EventType.Layout)
{
mProgressControls.ProgressData.CopyInto(
mCreateWorkspaceState.ProgressData);
}
string repository = mCreateWorkspaceState.Repository;
DrawCreateWorkspace.ForState(
SelectRepository,
CreateRepository,
ValidateAndCreateWorkspace,
mParentWindow,
mPlasticWebRestApi,
mDefaultServer,
ref mCreateWorkspaceState);
if (repository == mCreateWorkspaceState.Repository)
return;
SynchronizeRepositoryAndWorkspace();
}
void Initialize(IPlasticAPI plasticApi, IPlasticWebRestApi plasticWebRestApi)
{
((IProgressControls)mProgressControls).ShowProgress(string.Empty);
WorkspaceInfo[] allWorkspaces = null;
IList allRepositories = null;
string repositoryProject = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
mDefaultServer = GetDefaultServer.ToCreateWorkspace(plasticWebRestApi);
allWorkspaces = plasticApi.GetAllWorkspacesArray();
allRepositories = plasticApi.GetAllRepositories(mDefaultServer, true);
if (OrganizationsInformation.IsUnityOrganization(mDefaultServer))
{
List<string> serverProjects = OrganizationsInformation.GetOrganizationProjects(mDefaultServer);
if (serverProjects.Count > 0)
{
repositoryProject = serverProjects.First();
}
}
},
/*afterOperationDelegate*/ delegate
{
((IProgressControls) mProgressControls).HideProgress();
if (waiter.Exception != null)
{
DisplayException(mProgressControls, waiter.Exception);
return;
}
string serverSpecPart = string.Format("@{0}", ResolveServer.ToDisplayString(mDefaultServer));
mCreateWorkspaceState.Repository = ValidRepositoryName.Get(
string.Format("{0}{1}", mCreateWorkspaceState.Repository, serverSpecPart),
allRepositories);
if (repositoryProject != null)
{
mCreateWorkspaceState.Repository = string.Format("{0}/{1}", repositoryProject, mCreateWorkspaceState.Repository);
}
string proposedWorkspaceName = mCreateWorkspaceState.Repository.Replace(serverSpecPart, string.Empty);
mCreateWorkspaceState.WorkspaceName = CreateWorkspaceDialogUserAssistant.GetNonExistingWkNameForName(
proposedWorkspaceName, allWorkspaces);
mDialogUserAssistant = CreateWorkspaceDialogUserAssistant.ForWkPathAndName(
mWorkspacePath,
allWorkspaces);
SynchronizeRepositoryAndWorkspace();
});
}
void SynchronizeRepositoryAndWorkspace()
{
if (mDialogUserAssistant == null)
{
return;
}
mDialogUserAssistant.RepositoryChanged(
mCreateWorkspaceState.Repository,
mCreateWorkspaceState.WorkspaceName,
mWorkspacePath);
mCreateWorkspaceState.WorkspaceName = mDialogUserAssistant.GetProposedWorkspaceName();
}
void SelectRepository(string repository)
{
mCreateWorkspaceState.Repository = repository;
SynchronizeRepositoryAndWorkspace();
}
void CreateRepository(RepositoryCreationData data)
{
if (!data.Result)
return;
((IProgressControls)mProgressControls).ShowProgress(
PlasticLocalization.GetString(
PlasticLocalization.Name.CreatingRepository,
data.RepName));
RepositoryInfo createdRepository = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
createdRepository = PlasticGui.Plastic.API.CreateRepository(
data.ServerName, data.RepName);
},
/*afterOperationDelegate*/ delegate
{
((IProgressControls)mProgressControls).HideProgress();
if (waiter.Exception != null)
{
DisplayException(mProgressControls, waiter.Exception);
return;
}
if (createdRepository == null)
return;
mCreateWorkspaceState.Repository = createdRepository.GetRepSpec().ToDisplayString();
SynchronizeRepositoryAndWorkspace();
});
}
void ValidateAndCreateWorkspace(CreateWorkspaceViewState state)
{
// We need a conversion here because the actual repSpec is used during the AsyncValidation
// to call UpdateLastUsedRepositoryPreference. Also, it is the one to be used during wk creation
RepositorySpec repSpec = OrganizationsInformation.TryResolveRepositorySpecFromInput(state.Repository);
if (repSpec == null)
{
((IProgressControls) mProgressControls).ShowError(
PlasticLocalization.Name.UnresolvedRepository.GetString(state.Repository));
return;
}
mWkCreationData = BuildCreationDataFromState(state, mWorkspacePath, repSpec);
// AsyncValidation calls IPlasticDialogCloser.CloseDialog() when the validation is ok
WorkspaceCreationValidation.AsyncValidation(mWkCreationData, this, mProgressControls);
}
void IPlasticDialogCloser.CloseDialog()
{
((IProgressControls) mProgressControls).ShowProgress(string.Empty);
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
RepositorySpec repSpec = new SpecGenerator().GenRepositorySpec(
false, mWkCreationData.Repository, CmConnection.Get().UnityOrgResolver);
bool repositoryExist = PlasticGui.Plastic.API.CheckRepositoryExists(
repSpec.Server, repSpec.Name);
if (!repositoryExist)
PlasticGui.Plastic.API.CreateRepository(repSpec.Server, repSpec.Name);
},
/*afterOperationDelegate*/ delegate
{
((IProgressControls)mProgressControls).HideProgress();
if (waiter.Exception != null)
{
DisplayException(mProgressControls, waiter.Exception);
return;
}
mWkCreationData.Result = true;
mWorkspaceOperations.CreateWorkspace(mWkCreationData);
// the operation calls IWorkspacesRefreshableView.RefreshAndSelect
// when the workspace is created
});
}
void IWorkspacesRefreshableView.RefreshAndSelect(WorkspaceInfo wkInfo)
{
UnityCloudProjectLinkMonitor.CheckCloudProjectAlignmentAsync(wkInfo);
PerformInitialCheckin.IfRepositoryIsEmpty(
wkInfo,
mWkCreationData.Repository,
mWkCreationData.IsGluonWorkspace,
PlasticGui.Plastic.API,
mProgressControls,
mCreateWorkspaceListener,
mParentWindow);
}
static WorkspaceCreationData BuildCreationDataFromState(
CreateWorkspaceViewState state,
string workspacePath,
RepositorySpec repSpec)
{
return new WorkspaceCreationData(
state.WorkspaceName,
workspacePath,
repSpec.ToString(),
state.WorkspaceMode == CreateWorkspaceViewState.WorkspaceModes.Gluon,
false);
}
static void DisplayException(
IProgressControls progressControls,
Exception ex)
{
ExceptionsHandler.LogException(
"CreateWorkspaceView", ex);
progressControls.ShowError(
ExceptionsHandler.GetCorrectExceptionMessage(ex));
}
class GetDefaultServer
{
internal static string ToCreateWorkspace(IPlasticWebRestApi plasticWebRestApi)
{
string clientConfServer = PlasticGui.Plastic.ConfigAPI.GetClientConfServer();
if (!EditionToken.IsCloudEdition())
return clientConfServer;
string cloudServer = PlasticGuiConfig.Get().
Configuration.DefaultCloudServer;
if (!string.IsNullOrEmpty(cloudServer))
return cloudServer;
CloudEditionCreds.Data config =
CloudEditionCreds.GetFromClientConf();
cloudServer = GetFirstCloudServer.
GetCloudServer(plasticWebRestApi, config.Email, config.Password);
if (string.IsNullOrEmpty(cloudServer))
return clientConfServer;
SaveCloudServer.ToPlasticGuiConfig(cloudServer);
return cloudServer;
}
}
WorkspaceCreationData mWkCreationData;
CreateWorkspaceViewState mCreateWorkspaceState;
CreateWorkspaceDialogUserAssistant mDialogUserAssistant;
string mDefaultServer;
readonly WorkspaceOperations mWorkspaceOperations;
readonly ProgressControlsForViews mProgressControls;
readonly string mWorkspacePath;
readonly ICreateWorkspaceListener mCreateWorkspaceListener;
readonly PlasticWindow mParentWindow;
readonly IPlasticWebRestApi mPlasticWebRestApi;
}
}

View File

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

View File

@@ -0,0 +1,33 @@
using UnityEngine;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
{
internal class CreateWorkspaceViewState
{
internal enum WorkspaceModes
{
Developer,
Gluon
}
internal string Repository { get; set; }
internal string WorkspaceName { get; set; }
internal WorkspaceModes WorkspaceMode { get; set; }
internal ProgressControlsForViews.Data ProgressData { get; set; }
internal static CreateWorkspaceViewState BuildForProjectDefaults()
{
string projectName = Application.productName;
return new CreateWorkspaceViewState()
{
Repository = projectName,
WorkspaceName = projectName,
WorkspaceMode = WorkspaceModes.Developer,
ProgressData = new ProgressControlsForViews.Data()
};
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,430 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Home.Repositories;
using PlasticGui.WebApi;
using PlasticGui.WorkspaceWindow.Servers;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal class CreateRepositoryDialog :
PlasticDialog,
KnownServersListOperations.IKnownServersList
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 600, 340);
}
}
internal static RepositoryCreationData CreateRepository(
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string proposedRepositoryName,
string proposedServer,
string lastUsedRepServer,
string clientConfServer)
{
string server = CreateRepositoryDialogUserAssistant.GetProposedServer(
proposedServer, lastUsedRepServer, clientConfServer);
CreateRepositoryDialog dialog = Create(
plasticWebRestApi,
new ProgressControlsForDialogs(),
proposedRepositoryName,
server);
ResponseType dialogResult = dialog.RunModal(parentWindow);
bool dialogResultOk = dialogResult == ResponseType.Ok;
RepositoryCreationData result = dialogResultOk ? dialog.BuildCreationData() : new RepositoryCreationData();
result.Result = dialogResultOk;
return result;
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.Name.NewRepositoryTitle.GetString());
Paragraph(PlasticLocalization.Name.NewRepositoryExplanation.GetString());
Paragraph(PlasticLocalization.Name.CreateRepositoryDialogDetailedExplanation.GetString());
if (Event.current.type == EventType.Layout)
{
mProgressControls.ProgressData.CopyInto(mProgressData);
}
GUILayout.Space(5);
DoEntriesArea();
DrawProgressForDialogs.For(mProgressControls.ProgressData);
GUILayout.FlexibleSpace();
DoButtonsArea();
mProgressControls.ForcedUpdateProgress(this);
}
protected override string GetTitle()
{
return PlasticLocalization.Name.NewRepositoryTitle.GetString();
}
void KnownServersListOperations.IKnownServersList.FillValues(List<string> knownServers)
{
// Filter out local server if there is no local installation
// TODO Remove if a unified solution is applied to the unityplastic library
if (knownServers.Contains(LocalOnlyServer.Alias) && !IsExeAvailable.ForLocalServer())
{
knownServers.Remove(LocalOnlyServer.Alias);
}
mKnownServers = knownServers.Select(ResolveServer.ToDisplayString).ToList();
mKnownServers.Sort();
OnServerSelected(mSelectedServer);
}
void DoEntriesArea()
{
mRepositoryName = TextEntry(
PlasticLocalization.Name.RepositoryNameShortLabel.GetString(),
mRepositoryName,
REPONAME_CONTROL_NAME,
ENTRY_WIDTH,
ENTRY_X);
if (!mFocusIsAreadySet)
{
mFocusIsAreadySet = true;
GUI.FocusControl(REPONAME_CONTROL_NAME);
}
GUILayout.Space(5);
mSelectedServer = ComboBox(
PlasticLocalization.Name.RepositoryServerOrOrganizationLabel.GetString(),
mSelectedServer,
mKnownServers,
OnServerSelected,
ENTRY_WIDTH,
ENTRY_X);
if (OrganizationsInformation.IsUnityOrganization(mSelectedServer) && mKnownServers.Contains(mSelectedServer))
{
GUILayout.Space(5);
DoOrganizationProjectsDropdown();
DoCreateOrganizationProjectLink();
}
else
{
mSelectedProject = null;
mCurrentServerProjects = null;
}
}
void DoOrganizationProjectsDropdown()
{
if (mIsLoadingProjects || mSelectedProject == null)
{
GUI.enabled = false;
}
ComboBox(
PlasticLocalization.Name.OrganizationProjectLabel.GetString(),
mSelectedProject,
mCurrentServerProjects,
OnProjectSelected,
ENTRY_WIDTH,
ENTRY_X);
GUI.enabled = true;
}
void DoCreateOrganizationProjectLink()
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button(
PlasticLocalization.Name.CreateOrganizationProjectLabel.GetString(),
UnityStyles.LinkLabel,
GUILayout.Height(20)))
{
string resolvedServer = OrganizationsInformation.TryResolveServerFromInput(mSelectedServer);
if (!string.IsNullOrEmpty(resolvedServer))
{
string organizationName = ServerOrganizationParser.GetOrganizationFromServer(resolvedServer);
Application.OpenURL(UnityUrl.UnityDashboard.UnityOrganizations.GetProjectsUrl(organizationName));
}
}
GUILayout.EndHorizontal();
}
void OnServerSelected(object server)
{
((IProgressControls) mProgressControls).HideProgress();
mProgressControls.ProgressData.StatusMessage = string.Empty;
mProgressControls.ProgressData.StatusType = MessageType.None;
mIsLoadingProjects = false;
if (server == null || string.IsNullOrEmpty(server.ToString()))
{
mSelectedServer = null;
mSelectedProject = null;
mCurrentServerProjects = null;
return;
}
mSelectedServer = server.ToString();
// We need to ensure it is a known server because the dropdown is editable
if (OrganizationsInformation.IsUnityOrganization(mSelectedServer) && mKnownServers.Contains(mSelectedServer))
{
LoadServerProjects(mSelectedServer);
}
else
{
mSelectedProject = null;
}
Repaint();
}
void OnFocus()
{
OnServerSelected(mSelectedServer);
}
void OnProjectSelected(object project)
{
mSelectedProject = project.ToString();
Repaint();
}
void LoadServerProjects(string server)
{
mIsLoadingProjects = true;
mCurrentServerProjects = null;
((IProgressControls) mProgressControls).ShowProgress(
PlasticLocalization.Name.RetrievingServerProjects.GetString());
List<string> serverProjects = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
string serverName = ResolveServer.FromUserInput(server, CmConnection.Get().UnityOrgResolver);
serverProjects = OrganizationsInformation.GetOrganizationProjects(serverName);
},
/*afterOperationDelegate*/ delegate
{
mIsLoadingProjects = false;
if (waiter.Exception != null)
{
((IProgressControls) mProgressControls).ShowError(
PlasticLocalization.Name.ErrorRetrievingServerProjects.GetString());
}
mCurrentServerProjects = serverProjects;
if (mCurrentServerProjects == null || mCurrentServerProjects.Count == 0)
{
mSelectedProject = null;
((IProgressControls) mProgressControls).ShowError(
PlasticLocalization.Name.NoServerProjectsFound.GetString());
}
else
{
if (string.IsNullOrEmpty(mSelectedProject) || !mCurrentServerProjects.Contains(mSelectedProject))
{
mSelectedProject = mCurrentServerProjects.First();
}
((IProgressControls) mProgressControls).HideProgress();
}
});
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (mIsLoadingProjects ||
(OrganizationsInformation.IsUnityOrganization(mSelectedServer) && string.IsNullOrEmpty(mSelectedProject)))
{
GUI.enabled = false;
}
if (AcceptButton(PlasticLocalization.Name.OkButton.GetString()))
{
OkButtonWithValidationAction();
}
GUI.enabled = true;
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.Name.CancelButton.GetString()))
return;
CancelButtonAction();
}
void OkButtonWithValidationAction()
{
// If the validation goes OK, this method closes the dialog
RepositoryCreationValidation.AsyncValidation(
BuildCreationData(),
this,
mProgressControls);
}
void OnEnterKeyAction()
{
if (!OrganizationsInformation.IsUnityOrganization(mSelectedServer))
{
OkButtonWithValidationAction();
return;
}
if (mKnownServers.Contains(mSelectedServer))
{
if (string.IsNullOrEmpty(mSelectedProject))
{
OnServerSelected(mSelectedServer);
}
else
{
OkButtonWithValidationAction();
}
}
}
RepositoryCreationData BuildCreationData()
{
string resolvedServer = OrganizationsInformation.TryResolveServerFromInput(mSelectedServer);
string repositoryName = mSelectedProject != null
? string.Format("{0}/{1}", mSelectedProject, mRepositoryName)
: mRepositoryName;
return new RepositoryCreationData(
repositoryName,
resolvedServer != null ? resolvedServer : mSelectedServer);
}
static CreateRepositoryDialog Create(
IPlasticWebRestApi plasticWebRestApi,
ProgressControlsForDialogs progressControls,
string proposedRepositoryName,
string proposedServer)
{
var instance = CreateInstance<CreateRepositoryDialog>();
instance.mEnterKeyAction = instance.OnEnterKeyAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mPlasticWebRestApi = plasticWebRestApi;
instance.mProgressControls = progressControls;
instance.BuildComponents(proposedRepositoryName, proposedServer);
return instance;
}
void BuildComponents(string proposedRepositoryName, string proposedServer)
{
mSelectedServer = ResolveServer.ToDisplayString(proposedServer);
mRepositoryName = proposedRepositoryName;
if (OrganizationsInformation.IsUnityOrganization(proposedServer))
{
string[] repositoryNameParts = proposedRepositoryName.Split('/');
if (repositoryNameParts.Length > 1)
{
mRepositoryName = repositoryNameParts[repositoryNameParts.Length - 1].Trim();
}
}
KnownServersListOperations.GetCombinedServers(
true,
GetExtraServers(proposedServer),
mProgressControls,
this,
mPlasticWebRestApi,
CmConnection.Get().GetProfileManager());
}
static List<string> GetExtraServers(string proposedServer)
{
List<string> result = new List<string>();
if (!string.IsNullOrEmpty(proposedServer))
result.Add(proposedServer);
return result;
}
IPlasticWebRestApi mPlasticWebRestApi;
bool mFocusIsAreadySet;
string mRepositoryName;
string mSelectedServer;
string mSelectedProject;
bool mIsLoadingProjects;
List<string> mCurrentServerProjects;
List<string> mKnownServers = new List<string>();
ProgressControlsForDialogs.Data mProgressData = new ProgressControlsForDialogs.Data();
ProgressControlsForDialogs mProgressControls;
const float ENTRY_WIDTH = 400;
const float ENTRY_X = 175f;
const string REPONAME_CONTROL_NAME = "CreateRepositoryDialog.RepositoryName";
}
}

View File

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

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal enum RepositoriesListColumn
{
Name,
Server
}
[Serializable]
internal class RepositoriesListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static RepositoriesListHeaderState GetDefault()
{
return new RepositoriesListHeaderState(BuildColumns());
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.ServerColumn));
return result;
}
static string GetColumnName(RepositoriesListColumn column)
{
switch (column)
{
case RepositoriesListColumn.Name:
return PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn);
case RepositoriesListColumn.Server:
return PlasticLocalization.GetString(PlasticLocalization.Name.ServerColumn);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 320,
headerContent = new GUIContent(
GetColumnName(RepositoriesListColumn.Name)),
minWidth = 200,
allowToggleVisibility = false,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 200,
headerContent = new GUIContent(
GetColumnName(RepositoriesListColumn.Server)),
minWidth = 200,
allowToggleVisibility = false,
sortingArrowAlignment = TextAlignment.Right
}
};
}
RepositoriesListHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
}
[SerializeField]
string[] mHeaderTitles;
}
}

View File

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

View File

@@ -0,0 +1,252 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Codice.Client.Common;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Home.Repositories;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal class RepositoriesListView :
TreeView,
IPlasticTable<RepositoryInfo>
{
internal RepositoriesListView(
RepositoriesListHeaderState headerState,
List<string> columnNames,
Action doubleClickAction)
: base(new TreeViewState())
{
mColumnNames = columnNames;
mDoubleClickAction = doubleClickAction;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
mColumnComparers = RepositoriesTableDefinition.BuildColumnComparers();
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(
this, mRepositories, rootItem, mRows);
return mRows;
}
protected override void SearchChanged(string newSearch)
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
protected override void DoubleClickedItem(int id)
{
mDoubleClickAction();
}
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 RepositoryListViewItem)
{
RepositoryListViewItemGUI(
(RepositoryListViewItem)args.item,
args,
rowHeight);
return;
}
base.RowGUI(args);
}
internal string GetSelectedRepository()
{
IList<TreeViewItem> selectedItems = FindRows(GetSelection());
if (selectedItems.Count == 0)
return null;
return ((RepositoryListViewItem) selectedItems[0])
.Repository.GetRepSpec().ToDisplayString();
}
void IPlasticTable<RepositoryInfo>.FillEntriesAndSelectRows(
IList<RepositoryInfo> entries,
List<RepositoryInfo> entriesToSelect,
string currentFilter)
{
mUnfilteredRepositories = entries;
Refilter();
Sort();
Reload();
}
void Refilter()
{
mRepositories = RepositoriesTableDefinition.TableFilter.Filter(
searchString,
mUnfilteredRepositories);
}
void Sort()
{
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
IComparer<RepositoryInfo> comparer = mColumnComparers[
mColumnNames[sortedColumnIdx]];
((List<RepositoryInfo>)mRepositories).Sort(new SortOrderComparer<RepositoryInfo>(
comparer, sortAscending));
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
RepositoriesListView listView,
IList<RepositoryInfo> repositories,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (repositories.Count == 0)
return;
for (int i = 0; i < repositories.Count; i++)
{
RepositoryListViewItem repositoryListViewItem =
new RepositoryListViewItem(i + 1, (RepositoryInfo)repositories[i]);
rootItem.AddChild(repositoryListViewItem);
rows.Add(repositoryListViewItem);
}
listView.SetSelection(new List<int> { 1 });
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void RepositoryListViewItemGUI(
RepositoryListViewItem item,
RowGUIArgs args,
float rowHeight)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
RepositoriesListColumn column =
(RepositoriesListColumn)args.GetColumn(visibleColumnIdx);
RepositoryListViewItemCellGUI(
cellRect,
item,
column,
rowHeight,
args.selected,
args.focused);
}
}
static void RepositoryListViewItemCellGUI(
Rect rect,
RepositoryListViewItem item,
RepositoriesListColumn column,
float rowHeight,
bool isSelected,
bool isFocused)
{
if (column == RepositoriesListColumn.Name)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
0,
Images.GetRepositoryIcon(),
null,
item.Repository.Name,
isSelected,
isFocused,
false,
false);
return;
}
DrawTreeViewItem.ForSecondaryLabel(
rect,
item.ServerDisplayName,
isSelected,
isFocused,
false);
}
List<TreeViewItem> mRows = new List<TreeViewItem>();
IList<RepositoryInfo> mUnfilteredRepositories = new List<RepositoryInfo>();
IList<RepositoryInfo> mRepositories = new List<RepositoryInfo>();
readonly Dictionary<string, IComparer<RepositoryInfo>> mColumnComparers;
readonly List<string> mColumnNames;
readonly Action mDoubleClickAction;
}
}

View File

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

View File

@@ -0,0 +1,347 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Common;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Home.Repositories;
using PlasticGui.WebApi;
using PlasticGui.WorkspaceWindow.Servers;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal class RepositoryExplorerDialog :
PlasticDialog,
KnownServersListOperations.IKnownServersList,
FillRepositoriesTable.IGetFilterText
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 750, 450);
}
}
internal static string BrowseRepository(
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer)
{
RepositoryExplorerDialog dialog = Create(
plasticWebRestApi,
new ProgressControlsForDialogs(),
defaultServer,
new UnityPlasticGuiMessage());
ResponseType dialogResult = dialog.RunModal(parentWindow);
if (dialogResult != ResponseType.Ok)
return null;
return dialog.mRepositoriesListView.GetSelectedRepository();
}
void OnDisable()
{
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
}
protected override void SaveSettings()
{
TreeHeaderSettings.Save(
mRepositoriesListView.multiColumnHeader.state,
UnityConstants.REPOSITORIES_TABLE_SETTINGS_NAME);
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(PlasticLocalization.Name.ChooseRepositoryTitle));
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.SelectRepositoryBelow));
if (Event.current.type == EventType.Layout)
{
mProgressControls.ProgressData.CopyInto(
mState.ProgressData);
}
bool isEnabled = !mProgressControls.ProgressData.IsWaitingAsyncResult;
DoToolbarArea(
mSearchField,
mRepositoriesListView,
isEnabled,
Refresh,
OnServerSelected,
ref mState);
GUILayout.Space(10);
DoListArea(
mRepositoriesListView,
isEnabled);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
DoButtonsArea();
mProgressControls.ForcedUpdateProgress(this);
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(PlasticLocalization.Name.ExploreRepositories);
}
void SearchField_OnDownOrUpArrowKeyPressed()
{
mRepositoriesListView.SetFocusAndEnsureSelectedItem();
}
void Refresh()
{
string resolvedServer = OrganizationsInformation.TryResolveServerFromInput(mState.SelectedServer);
// Even if the server input cannot be resolved, we still want to fill the table so it gets reset
mFillRepositoriesTable.FillTable(
mRepositoriesListView,
null,
mProgressControls,
null,
new FillRepositoriesTable.SaveLastUsedServer(true),
mGuiMessage,
null,
null,
this,
resolvedServer != null ? resolvedServer : mState.SelectedServer,
false,
false,
true);
}
void KnownServersListOperations.IKnownServersList.FillValues(List<string> knownServers)
{
// Filter out local server if there is no local installation
// TODO Remove if a unified solution is applied to the unityplastic library
if (knownServers.Contains(LocalOnlyServer.Alias) && !IsExeAvailable.ForLocalServer())
{
knownServers.Remove(LocalOnlyServer.Alias);
}
mState.AvailableServers = knownServers.Select(ResolveServer.ToDisplayString).ToList();
mState.AvailableServers.Sort();
Refresh();
}
string FillRepositoriesTable.IGetFilterText.Get()
{
return mRepositoriesListView.searchString;
}
void OnServerSelected(object server)
{
mState.SelectedServer = server.ToString();
Repaint();
Refresh();
}
static void DoToolbarArea(
SearchField searchField,
RepositoriesListView listView,
bool isEnabled,
Action refreshAction,
GenericMenu.MenuFunction2 selectServerAction,
ref State state)
{
GUILayout.BeginHorizontal();
GUILayout.Label(
PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryExplorerServerLabel));
GUI.enabled = isEnabled;
state.SelectedServer = DoDropDownTextField(
state.SelectedServer,
state.AvailableServers,
selectServerAction,
refreshAction);
var refreshText = PlasticLocalization.GetString(PlasticLocalization.Name.RefreshButton);
if (GUILayout.Button(refreshText, EditorStyles.miniButton))
refreshAction();
GUILayout.FlexibleSpace();
DrawSearchField.For(searchField, listView, SEARCH_FIELD_WIDTH);
GUI.enabled = true;
GUILayout.EndHorizontal();
}
static void DoListArea(
RepositoriesListView listView,
bool isEnabled)
{
GUI.enabled = isEnabled;
Rect treeRect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
listView.OnGUI(treeRect);
GUI.enabled = true;
}
static string DoDropDownTextField(
string text,
List<string> options,
GenericMenu.MenuFunction2 selectServerAction,
Action enterKeyAction)
{
bool isEnterKeyPressed = false;
Event e = Event.current;
if (Keyboard.IsReturnOrEnterKeyPressed(e))
{
isEnterKeyPressed = true;
}
string result = DropDownTextField.DoDropDownTextField(
text,
DROPDOWN_CONTROL_NAME,
options,
selectServerAction,
GUILayout.Width(DROPDOWN_WIDTH));
if (isEnterKeyPressed && GUI.GetNameOfFocusedControl() == DROPDOWN_CONTROL_NAME)
{
e.Use();
enterKeyAction();
}
return result;
}
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();
}
static RepositoryExplorerDialog Create(
IPlasticWebRestApi plasticWebRestApi,
ProgressControlsForDialogs progressControls,
string defaultServer,
GuiMessage.IGuiMessage guiMessage)
{
var instance = CreateInstance<RepositoryExplorerDialog>();
instance.mGuiMessage = guiMessage;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mProgressControls = progressControls;
instance.BuildComponents(defaultServer, plasticWebRestApi);
return instance;
}
void BuildComponents(
string defaultServer,
IPlasticWebRestApi plasticWebRestApi)
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
RepositoriesListHeaderState headerState =
RepositoriesListHeaderState.GetDefault();
TreeHeaderSettings.Load(headerState,
UnityConstants.REPOSITORIES_TABLE_SETTINGS_NAME,
(int)RepositoriesListColumn.Name);
mRepositoriesListView = new RepositoriesListView(
headerState,
RepositoriesListHeaderState.GetColumnNames(),
OkButtonAction);
mRepositoriesListView.Reload();
mFillRepositoriesTable = new FillRepositoriesTable(
new LocalRepositoriesProvider());
mState = new State()
{
SelectedServer = ResolveServer.ToDisplayString(defaultServer),
ProgressData = new ProgressControlsForDialogs.Data()
};
KnownServersListOperations.GetCombinedServers(
true,
new List<string>(),
mProgressControls,
this,
plasticWebRestApi,
CmConnection.Get().GetProfileManager());
}
SearchField mSearchField;
RepositoriesListView mRepositoriesListView;
ProgressControlsForDialogs mProgressControls;
FillRepositoriesTable mFillRepositoriesTable;
State mState;
GuiMessage.IGuiMessage mGuiMessage;
const string DROPDOWN_CONTROL_NAME = "RepositoryExplorerDialog.ServerDropdown";
const float DROPDOWN_WIDTH = 250;
const float SEARCH_FIELD_WIDTH = 450;
class State
{
internal List<string> AvailableServers { get; set; }
internal string SelectedServer { get; set; }
internal ProgressControlsForDialogs.Data ProgressData { get; set; }
}
}
}

View File

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

View File

@@ -0,0 +1,23 @@
using Codice.Client.Common;
using UnityEditor.IMGUI.Controls;
using Codice.CM.Common;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal class RepositoryListViewItem : TreeViewItem
{
internal RepositoryInfo Repository { get; private set; }
internal string ServerDisplayName { get; private set; }
internal RepositoryListViewItem(int id, RepositoryInfo repository)
: base(id, 0)
{
Repository = repository;
ServerDisplayName = ResolveServer.ToDisplayString(repository.Server);
displayName = repository.Name;
}
}
}

View File

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

View File

@@ -0,0 +1,507 @@
using System;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WebApi;
using PlasticGui.WorkspaceWindow.Home.Repositories;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
{
internal static class DrawCreateWorkspace
{
internal static void ForState(
Action<string> selectRepositoryAction,
Action<RepositoryCreationData> createRepositoryAction,
Action<CreateWorkspaceViewState> createWorkspaceAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer,
ref CreateWorkspaceViewState state)
{
DoTitle();
GUILayout.Space(15);
DoFieldsArea(
selectRepositoryAction,
createRepositoryAction,
parentWindow,
plasticWebRestApi,
defaultServer,
ref state);
GUILayout.Space(10);
DoRadioButtonsArea(ref state);
GUILayout.Space(3);
DoHelpLabel();
GUILayout.Space(10);
DoCreateWorkspaceButton(
createWorkspaceAction,
ref state);
GUILayout.Space(5);
DoNotificationArea(state.ProgressData);
}
static void DoTitle()
{
GUILayout.Label(
PlasticLocalization.GetString(
PlasticLocalization.Name.NewWorkspace),
UnityStyles.Dialog.MessageTitle);
GUILayout.Label(
PlasticLocalization.GetString(PlasticLocalization.Name.WorkspacesExplanationLabel),
EditorStyles.wordWrappedLabel);
}
static void DoFieldsArea(
Action<string> selectRepositoryAction,
Action<RepositoryCreationData> createRepositoryAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer,
ref CreateWorkspaceViewState state)
{
DoRepositoryField(
selectRepositoryAction,
createRepositoryAction,
parentWindow,
plasticWebRestApi,
defaultServer,
ref state);
DoWorkspaceField(ref state);
}
static void DoRepositoryField(
Action<string> selectRepositoryAction,
Action<RepositoryCreationData> createRepositoryAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer,
ref CreateWorkspaceViewState state)
{
EditorGUILayout.BeginHorizontal();
DoLabel(PlasticLocalization.GetString(PlasticLocalization.Name.Repository));
state.Repository = DoTextField(
state.Repository,
!state.ProgressData.IsOperationRunning,
LABEL_WIDTH,
TEXTBOX_WIDTH - BROWSE_BUTTON_WIDTH);
float browseButtonX =
LABEL_WIDTH + TEXTBOX_WIDTH + BUTTON_MARGIN -
BROWSE_BUTTON_WIDTH;
float browseButtonWidth =
BROWSE_BUTTON_WIDTH - BUTTON_MARGIN;
if (DoButton(
"...",
!state.ProgressData.IsOperationRunning,
browseButtonX,
browseButtonWidth))
{
DoBrowseRepositoryButton(
selectRepositoryAction,
parentWindow,
plasticWebRestApi,
defaultServer);
EditorGUIUtility.ExitGUI();
}
float newButtonX =
LABEL_WIDTH + TEXTBOX_WIDTH + BUTTON_MARGIN;
float newButtonWidth =
NEW_BUTTON_WIDTH - BUTTON_MARGIN;
if (DoButton(
PlasticLocalization.GetString(PlasticLocalization.Name.NewButton),
!state.ProgressData.IsOperationRunning,
newButtonX, newButtonWidth))
{
DoNewRepositoryButton(
createRepositoryAction,
parentWindow,
plasticWebRestApi,
state.Repository,
defaultServer);
EditorGUIUtility.ExitGUI();
}
ValidationResult validationResult = ValidateRepository(state.Repository);
if (!validationResult.IsValid)
DoWarningLabel(validationResult.ErrorMessage,
LABEL_WIDTH + TEXTBOX_WIDTH + NEW_BUTTON_WIDTH + LABEL_MARGIN);
EditorGUILayout.EndHorizontal();
}
static void DoWorkspaceField(
ref CreateWorkspaceViewState state)
{
EditorGUILayout.BeginHorizontal();
DoLabel(
PlasticLocalization.GetString(PlasticLocalization.Name.WorkspaceName));
state.WorkspaceName = DoTextField(
state.WorkspaceName,
!state.ProgressData.IsOperationRunning,
LABEL_WIDTH,
TEXTBOX_WIDTH - BROWSE_BUTTON_WIDTH);
ValidationResult validationResult = ValidateWorkspaceName(
state.WorkspaceName);
if (!validationResult.IsValid)
DoWarningLabel(validationResult.ErrorMessage,
LABEL_WIDTH + TEXTBOX_WIDTH - BROWSE_BUTTON_WIDTH + LABEL_MARGIN);
EditorGUILayout.EndHorizontal();
}
static void DoRadioButtonsArea(
ref CreateWorkspaceViewState state)
{
EditorGUILayout.BeginVertical();
DoLabel(
PlasticLocalization.GetString(PlasticLocalization.Name.WorkPreferenceQuestion));
if (DoRadioButton(
PlasticLocalization.GetString(PlasticLocalization.Name.WorkPreferenceAnswerUnityVCS),
state.WorkspaceMode == CreateWorkspaceViewState.WorkspaceModes.Developer,
!state.ProgressData.IsOperationRunning,
RADIO_BUTTON_MARGIN))
state.WorkspaceMode = CreateWorkspaceViewState.WorkspaceModes.Developer;
if (DoRadioButton(
PlasticLocalization.GetString(PlasticLocalization.Name.WorkPreferenceAnswerGluon),
state.WorkspaceMode == CreateWorkspaceViewState.WorkspaceModes.Gluon,
!state.ProgressData.IsOperationRunning,
RADIO_BUTTON_MARGIN))
state.WorkspaceMode = CreateWorkspaceViewState.WorkspaceModes.Gluon;
EditorGUILayout.EndVertical();
}
static void DoCreateWorkspaceButton(
Action<CreateWorkspaceViewState> createWorkspaceAction,
ref CreateWorkspaceViewState state)
{
EditorGUILayout.BeginHorizontal();
bool isButtonEnabled =
IsValidState(state) &&
!state.ProgressData.IsOperationRunning;
string buttonText = PlasticLocalization.GetString(
PlasticLocalization.Name.CreateWorkspace);
bool isButtonClicked = DoButton(buttonText, isButtonEnabled,
CREATE_WORKSPACE_BUTTON_MARGIN, CREATE_WORKSPACE_BUTTON_WIDTH);
GUI.enabled = true;
if (state.ProgressData.IsOperationRunning)
{
DoProgress(state.ProgressData,
CREATE_WORKSPACE_BUTTON_MARGIN +
PROGRESS_MARGIN +
CREATE_WORKSPACE_BUTTON_WIDTH);
}
EditorGUILayout.EndHorizontal();
if (isButtonClicked)
createWorkspaceAction(state);
}
static void DoBrowseRepositoryButton(
Action<string> selectRepositoryAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer)
{
string selectedRepository = RepositoryExplorerDialog.BrowseRepository(
parentWindow,
plasticWebRestApi,
defaultServer);
if (string.IsNullOrEmpty(selectedRepository))
return;
selectRepositoryAction(selectedRepository);
}
static void DoNewRepositoryButton(
Action<RepositoryCreationData> createRepositoryAction,
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string repositorySpecInput,
string defaultServer)
{
string proposedRepositoryName;
string proposedServer;
RepositorySpec repSpec = OrganizationsInformation.TryResolveRepositorySpecFromInput(repositorySpecInput);
if (repSpec != null)
{
proposedRepositoryName = repSpec.Name;
proposedServer = repSpec.Server;
}
else
{
proposedRepositoryName = ExtractRepositoryName(repositorySpecInput);
proposedServer = defaultServer;
}
RepositoryCreationData creationData = CreateRepositoryDialog.CreateRepository(
parentWindow,
plasticWebRestApi,
proposedRepositoryName,
proposedServer,
defaultServer,
ClientConfig.Get().GetWorkspaceServer());
createRepositoryAction(creationData);
}
static string ExtractRepositoryName(string repositorySpec)
{
string[] repositoryParts = repositorySpec.Split('@');
return repositoryParts.Length > 0 ? repositoryParts[0] : string.Empty;
}
static void DoHelpLabel()
{
string linkText =PlasticLocalization.Name.HereLink.GetString();
string labelText = PlasticLocalization.Name.LearnMoreDifferencesUnityVCS.GetString();
EditorGUILayout.BeginHorizontal();
GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel);
labelStyle.richText = true;
labelStyle.stretchWidth = false;
labelStyle.margin = new RectOffset();
labelStyle.padding.left = LEARN_MORE_LABEL_LEFT_PADDING;
GUILayout.Label(labelText, labelStyle);
GUIStyle linkStyle = new GUIStyle(UnityStyles.LinkLabel);
linkStyle.fontSize = EditorStyles.miniLabel.fontSize;
linkStyle.stretchWidth = false;
linkStyle.margin = new RectOffset();
if (GUILayout.Button(linkText, linkStyle))
{
Application.OpenURL(PlasticLocalization.Name.PlasticSCMFullVsPartialWorkspaceLink.GetString());
}
EditorGUIUtility.AddCursorRect(
GUILayoutUtility.GetLastRect(), MouseCursor.Link);
EditorGUILayout.EndHorizontal();
}
static void DoNotificationArea(ProgressControlsForViews.Data progressData)
{
if (string.IsNullOrEmpty(progressData.NotificationMessage))
return;
DrawProgressForViews.ForNotificationArea(progressData);
}
static void DoLabel(string labelText)
{
GUIStyle labelStyle = new GUIStyle(EditorStyles.label);
Rect rect = GUILayoutUtility.GetRect(
new GUIContent(labelText),
labelStyle);
GUI.Label(rect, labelText, labelStyle);
}
static string DoTextField(
string entryValue,
bool enabled,
float textBoxLeft,
float textBoxWidth)
{
GUI.enabled = enabled;
var rect = GUILayoutUtility.GetRect(
new GUIContent(entryValue),
UnityStyles.Dialog.EntryLabel);
rect.width = textBoxWidth;
rect.x = textBoxLeft;
string result = GUI.TextField(rect, entryValue);
GUI.enabled = true;
return result;
}
static bool DoButton(
string text,
bool isEnabled,
float buttonLeft,
float buttonWidth)
{
GUI.enabled = isEnabled;
var rect = GUILayoutUtility.GetRect(
new GUIContent(text),
UnityStyles.Dialog.EntryLabel);
rect.width = buttonWidth;
rect.x = buttonLeft;
bool result = GUI.Button(rect, text);
GUI.enabled = true;
return result;
}
static bool DoRadioButton(
string text,
bool isChecked,
bool isEnabled,
float buttonLeft)
{
GUI.enabled = isEnabled;
GUIStyle radioButtonStyle = new GUIStyle(EditorStyles.radioButton);
radioButtonStyle.padding.left = RADIO_BUTTON_LEFT_PADDING;
var rect = GUILayoutUtility.GetRect(
new GUIContent(text),
radioButtonStyle);
rect.x = buttonLeft;
bool result = GUI.Toggle(
rect,
isChecked,
text,
radioButtonStyle);
GUI.enabled = true;
return result;
}
static void DoWarningLabel(
string labelText,
float labelLeft)
{
Rect rect = GUILayoutUtility.GetRect(
new GUIContent(labelText),
EditorStyles.label);
rect.x = labelLeft;
GUI.Label(rect,
new GUIContent(labelText, Images.GetWarnIcon()),
UnityStyles.HeaderWarningLabel);
}
static void DoProgress(
ProgressControlsForViews.Data data,
float progressLeft)
{
if (string.IsNullOrEmpty(data.ProgressMessage))
return;
var rect = GUILayoutUtility.GetRect(
new GUIContent(data.ProgressMessage),
UnityStyles.Dialog.EntryLabel);
rect.x = progressLeft;
GUI.Label(rect, data.ProgressMessage);
}
static bool IsValidState(
CreateWorkspaceViewState state)
{
if (!ValidateRepository(state.Repository).IsValid)
return false;
if (!ValidateWorkspaceName(state.WorkspaceName).IsValid)
return false;
return true;
}
static ValidationResult ValidateRepository(string repository)
{
ValidationResult result = new ValidationResult();
if (string.IsNullOrEmpty(repository))
{
result.ErrorMessage = PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryNameEmpty);
result.IsValid = false;
return result;
}
result.IsValid = true;
return result;
}
static ValidationResult ValidateWorkspaceName(string workspaceName)
{
ValidationResult result = new ValidationResult();
if (string.IsNullOrEmpty(workspaceName))
{
result.ErrorMessage = PlasticLocalization.GetString(PlasticLocalization.Name.WorkspaceNameEmpty);
result.IsValid = false;
return result;
}
result.IsValid = true;
return result;
}
class ValidationResult
{
internal string ErrorMessage;
internal bool IsValid;
}
const float LABEL_WIDTH = 150;
const float TEXTBOX_WIDTH = 400;
const float BROWSE_BUTTON_WIDTH = 25;
const float NEW_BUTTON_WIDTH = 60;
const float BUTTON_MARGIN = 2;
const float LABEL_MARGIN = 2;
const float RADIO_BUTTON_MARGIN = 38;
const int RADIO_BUTTON_LEFT_PADDING = 20;
const float PROGRESS_MARGIN = 5;
const float CREATE_WORKSPACE_BUTTON_MARGIN = 32;
const float CREATE_WORKSPACE_BUTTON_WIDTH = 160;
const int LEARN_MORE_LABEL_LEFT_PADDING = 10;
}
}

View File

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

View File

@@ -0,0 +1,179 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Codice.Client.BaseCommands;
using Codice.Client.Commands;
using Codice.Client.Commands.CheckIn;
using Codice.Client.Common;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using Codice.CM.Common.Checkin.Partial;
using Codice.Client.GameUI.Checkin;
using PlasticGui;
using PlasticGui.Help.Conditions;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
{
internal static class PerformInitialCheckin
{
internal static void IfRepositoryIsEmpty(
WorkspaceInfo wkInfo,
string repository,
bool isGluonWorkspace,
IPlasticAPI plasticApi,
IProgressControls progressControls,
CreateWorkspaceView.ICreateWorkspaceListener createWorkspaceListener,
PlasticWindow plasticWindow)
{
RepositoryInfo repInfo = null;
bool isEmptyRepository = false;
progressControls.ShowProgress(string.Empty);
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
RepositorySpec repSpec = new SpecGenerator().
GenRepositorySpec(false, repository, CmConnection.Get().UnityOrgResolver);
repInfo = plasticApi.GetRepositoryInfo(repSpec);
isEmptyRepository = IsEmptyRepositoryCondition.
Evaluate(wkInfo, repSpec, plasticApi);
},
/*afterOperationDelegate*/ delegate
{
progressControls.HideProgress();
if (waiter.Exception != null)
{
DisplayException(progressControls, waiter.Exception);
return;
}
if (!isEmptyRepository)
{
plasticWindow.RefreshWorkspaceUI();
return;
}
CheckinPackagesAndProjectSettingsFolders(
wkInfo, isGluonWorkspace, plasticApi,
progressControls, createWorkspaceListener);
});
}
static void CheckinPackagesAndProjectSettingsFolders(
WorkspaceInfo wkInfo,
bool isGluonWorkspace,
IPlasticAPI plasticApi,
IProgressControls progressControls,
CreateWorkspaceView.ICreateWorkspaceListener createWorkspaceListener)
{
progressControls.ShowProgress(PlasticLocalization.GetString(
PlasticLocalization.Name.UnityInitialCheckinProgress));
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
PerformCheckinPackagesAndProjectSettingsFolders(
wkInfo, isGluonWorkspace, plasticApi);
},
/*afterOperationDelegate*/ delegate
{
progressControls.HideProgress();
if (waiter.Exception != null &&
!IsMergeNeededException(waiter.Exception))
{
DisplayException(progressControls, waiter.Exception);
return;
}
createWorkspaceListener.OnWorkspaceCreated(wkInfo, isGluonWorkspace);
});
}
internal static void PerformCheckinPackagesAndProjectSettingsFolders(
WorkspaceInfo wkInfo,
bool isGluonWorkspace,
IPlasticAPI plasticApi)
{
List<string> paths = new List<string> {
Path.Combine(wkInfo.ClientPath, "Packages"),
Path.Combine(wkInfo.ClientPath, "ProjectSettings")
};
string comment = PlasticLocalization.GetString(
PlasticLocalization.Name.UnityInitialCheckinComment);
PerformAdd(paths, plasticApi);
PerformCheckinForMode(wkInfo, paths, comment, isGluonWorkspace);
}
static void PerformAdd(
List<string> paths,
IPlasticAPI plasticApi)
{
AddOptions options = new AddOptions();
options.AddPrivateParents = true;
options.CheckoutParent = true;
options.Recurse = true;
options.SearchForPrivatePaths = true;
options.SkipIgnored = true;
IList checkouts;
plasticApi.Add(paths.ToArray(), options, out checkouts);
}
static void PerformCheckinForMode(
WorkspaceInfo wkInfo,
List<string> paths,
string comment,
bool isGluonWorkspace)
{
if (isGluonWorkspace)
{
new BaseCommandsImpl().PartialCheckin(wkInfo, paths, comment);
return;
}
CheckinParams ciParams = new CheckinParams();
ciParams.paths = paths.ToArray();
ciParams.comment = comment;
ciParams.time = DateTime.MinValue;
ciParams.flags = CheckinFlags.Recurse | CheckinFlags.ProcessSymlinks;
new BaseCommandsImpl().CheckIn(ciParams);
}
static bool IsMergeNeededException(Exception exception)
{
if (exception == null)
return false;
// Check the check-in exception for gluon
if (exception is CheckinConflictsException)
return true;
// Check the check-in exceptions for plastic
return exception is CmClientMergeNeededException;
}
static void DisplayException(
IProgressControls progressControls,
Exception ex)
{
ExceptionsHandler.LogException(
"PerformInitialCheckin", ex);
progressControls.ShowError(
ExceptionsHandler.GetCorrectExceptionMessage(ex));
}
}
}

View File

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

View File

@@ -0,0 +1,49 @@
using System.Collections;
using Codice.CM.Common;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
{
internal static class ValidRepositoryName
{
internal static string Get(string repositoryName, IList repositories)
{
string validRepositoryName = GetValidRepositoryName(repositoryName);
string result = validRepositoryName;
int i = 2;
while (RepositoryExists(result, repositories))
{
result = validRepositoryName + "_" + i.ToString();
i++;
}
return result;
}
static bool RepositoryExists(string repositoryName, IList repositories)
{
if (repositories == null)
return false;
foreach (RepositoryInfo repInfo in repositories)
{
if (repInfo.Name.Equals(repositoryName))
return true;
}
return false;
}
static string GetValidRepositoryName(string newRepository)
{
string result = newRepository.Replace(SUBMODULE_SEPARATOR, '-');
result = result.Replace(PIPE_CHARACTER, '-');
return result;
}
const char SUBMODULE_SEPARATOR = '/';
const char PIPE_CHARACTER = '|';
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,20 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class ClientDiffTreeViewItem : TreeViewItem
{
internal ClientDiffInfo Difference { get; private set; }
internal ClientDiffTreeViewItem(
int id, int depth, ClientDiffInfo diff)
: base(id, depth)
{
Difference = diff;
displayName = diff.PathString;
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,249 @@
using System.IO;
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.Diff;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.Diff.Dialogs
{
internal class GetRestorePathDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 600, 205);
}
}
internal static GetRestorePathData GetRestorePath(
string wkPath,
string restorePath,
string explanation,
bool isDirectory,
bool showSkipButton,
EditorWindow parentWindow)
{
GetRestorePathDialog dialog = Create(
new ProgressControlsForDialogs(),
wkPath,
GetProposedRestorePath.For(restorePath),
explanation,
isDirectory,
showSkipButton);
ResponseType dialogResult = dialog.RunModal(parentWindow);
GetRestorePathData result = dialog.BuildGetRestorePathResult();
result.Result = GetRestorePathResultType(dialogResult);
return result;
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.EnterRestorePathFormTitle));
Paragraph(mExplanation);
DoEntryArea();
GUILayout.Space(10);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
DoButtonsArea();
mProgressControls.ForcedUpdateProgress(this);
}
void DoEntryArea()
{
GUILayout.Label(PlasticLocalization.GetString(
PlasticLocalization.Name.EnterRestorePathFormTextBoxExplanation),
EditorStyles.label);
GUILayout.BeginHorizontal();
mRestorePath = GUILayout.TextField(
mRestorePath, GUILayout.Width(TEXTBOX_WIDTH));
if (GUILayout.Button("...", EditorStyles.miniButton))
{
mRestorePath = (mIsDirectory) ?
DoOpenFolderPanel(mRestorePath) :
DoOpenFilePanel(mRestorePath);
}
GUILayout.EndHorizontal();
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.EnterRestorePathFormTitle);
}
static string DoOpenFolderPanel(string actualPath)
{
string parentDirectory = null;
string directoryName = null;
if (!string.IsNullOrEmpty(actualPath))
{
parentDirectory = Path.GetDirectoryName(actualPath);
directoryName = Path.GetFileName(actualPath);
}
string result = EditorUtility.SaveFolderPanel(
PlasticLocalization.GetString(PlasticLocalization.Name.SelectPathToRestore),
parentDirectory,
directoryName);
if (string.IsNullOrEmpty(result))
return actualPath;
return Path.GetFullPath(result);
}
static string DoOpenFilePanel(string actualPath)
{
string parentDirectory = null;
string fileName = null;
string extension = null;
if (!string.IsNullOrEmpty(actualPath))
{
parentDirectory = Path.GetDirectoryName(actualPath);
fileName = Path.GetFileName(actualPath);
extension = Path.GetExtension(actualPath);
}
string result = EditorUtility.SaveFilePanel(
PlasticLocalization.GetString(PlasticLocalization.Name.SelectPathToRestore),
parentDirectory,
fileName,
extension);
if (string.IsNullOrEmpty(result))
return actualPath;
return Path.GetFullPath(result);
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoSkipButton(mShowSkipButton);
DoCancelButton();
return;
}
DoCancelButton();
DoSkipButton(mShowSkipButton);
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.OkButton)))
return;
OkButtonWithValidationAction();
}
void DoSkipButton(bool showSkipButton)
{
if (!showSkipButton)
return;
if (!NormalButton(PlasticLocalization.GetString(PlasticLocalization.Name.SkipRestoreButton)))
return;
CloseButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void OkButtonWithValidationAction()
{
GetRestorePathValidation.Validation(
mWkPath, BuildGetRestorePathResult(),
this, mProgressControls);
}
GetRestorePathData BuildGetRestorePathResult()
{
return new GetRestorePathData(mRestorePath);
}
static GetRestorePathData.ResultType GetRestorePathResultType(
ResponseType dialogResult)
{
switch (dialogResult)
{
case ResponseType.None:
return GetRestorePathData.ResultType.Skip;
case ResponseType.Ok:
return GetRestorePathData.ResultType.OK;
case ResponseType.Cancel:
return GetRestorePathData.ResultType.Cancel;
}
return GetRestorePathData.ResultType.Cancel;
}
static GetRestorePathDialog Create(
ProgressControlsForDialogs progressControls,
string wkPath,
string restorePath,
string explanation,
bool isDirectory,
bool showSkipButton)
{
var instance = CreateInstance<GetRestorePathDialog>();
instance.mWkPath = wkPath;
instance.mRestorePath = restorePath;
instance.mExplanation = explanation;
instance.mIsDirectory = isDirectory;
instance.mShowSkipButton = showSkipButton;
instance.mEnterKeyAction = instance.OkButtonWithValidationAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mProgressControls = progressControls;
return instance;
}
bool mIsDirectory;
bool mShowSkipButton;
string mExplanation = string.Empty;
string mRestorePath = string.Empty;
string mWkPath = string.Empty;
ProgressControlsForDialogs mProgressControls;
const float TEXTBOX_WIDTH = 520;
}
}

View File

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

View File

@@ -0,0 +1,519 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.Client.Common.EventTracking;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using Codice.CM.Common.Mount;
using PlasticGui;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.BrowseRepository;
using PlasticGui.WorkspaceWindow.Diff;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.Views.Diff.Dialogs;
using Unity.PlasticSCM.Editor.Views.History;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class DiffPanel :
IDiffTreeViewMenuOperations,
DiffTreeViewMenu.IMetaMenuOperations,
UndeleteClientDiffsOperation.IGetRestorePathDialog
{
internal DiffPanel(
WorkspaceInfo wkInfo,
IWorkspaceWindow workspaceWindow,
IRefreshView refreshView,
IViewSwitcher viewSwitcher,
IHistoryViewLauncher historyViewLauncher,
LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
EditorWindow parentWindow,
bool isGluonMode)
{
mWkInfo = wkInfo;
mWorkspaceWindow = workspaceWindow;
mRefreshView = refreshView;
mViewSwitcher = viewSwitcher;
mHistoryViewLauncher = historyViewLauncher;
mShowDownloadPlasticExeWindow = showDownloadPlasticExeWindow;
mParentWindow = parentWindow;
mGuiMessage = new UnityPlasticGuiMessage();
mIsGluonMode = isGluonMode;
BuildComponents();
mProgressControls = new ProgressControlsForViews();
}
internal void ClearInfo()
{
ClearData();
mParentWindow.Repaint();
}
internal void UpdateInfo(
MountPointWithPath mountWithPath,
ChangesetInfo csetInfo)
{
FillData(mountWithPath, csetInfo);
mParentWindow.Repaint();
}
internal void OnEnable()
{
mSearchField.downOrUpArrowKeyPressed +=
SearchField_OnDownOrUpArrowKeyPressed;
}
internal void OnDisable()
{
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
}
internal void Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
EditorGUILayout.BeginVertical();
DoActionsToolbar(
mDiffs,
mDiffsBranchResolver,
mProgressControls,
mIsSkipMergeTrackingButtonVisible,
mIsSkipMergeTrackingButtonChecked,
mSearchField,
mDiffTreeView);
DoDiffTreeViewArea(
mDiffTreeView,
mProgressControls.IsOperationRunning());
if (mProgressControls.HasNotification())
{
DrawProgressForViews.ForNotificationArea(
mProgressControls.ProgressData);
}
EditorGUILayout.EndVertical();
}
void IDiffTreeViewMenuOperations.SaveRevisionAs()
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
TrackFeatureUseEvent.Features.SaveRevisionFromDiff);
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
RepositorySpec repSpec = clientDiffInfo.DiffWithMount.Mount.RepSpec;
RevisionInfo revision = clientDiffInfo.DiffWithMount.Difference.RevInfo;
string defaultFileName = DefaultRevisionName.Get(
Path.GetFileName(clientDiffInfo.DiffWithMount.Difference.Path), revision.Changeset);
string destinationPath = SaveAction.GetDestinationPath(
mWkInfo.ClientPath,
clientDiffInfo.DiffWithMount.Difference.Path,
defaultFileName);
if (string.IsNullOrEmpty(destinationPath))
return;
SaveRevisionOperation.SaveRevision(
repSpec,
destinationPath,
revision,
mProgressControls);
}
SelectedDiffsGroupInfo IDiffTreeViewMenuOperations.GetSelectedDiffsGroupInfo()
{
return SelectedDiffsGroupInfo.BuildFromSelectedNodes(
DiffSelection.GetSelectedDiffsWithoutMeta(mDiffTreeView));
}
void IDiffTreeViewMenuOperations.Diff()
{
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
DiffOperation.DiffClientDiff(
mWkInfo,
clientDiffInfo.DiffWithMount.Mount.Mount,
clientDiffInfo.DiffWithMount.Difference,
PlasticExeLauncher.BuildForDiffRevision(mWkInfo, mIsGluonMode, mShowDownloadPlasticExeWindow),
imageDiffLauncher: null);
}
void IDiffTreeViewMenuOperations.History()
{
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
mHistoryViewLauncher.ShowHistoryView(
clientDiffInfo.DiffWithMount.Mount.RepSpec,
clientDiffInfo.DiffWithMount.Difference.RevInfo.ItemId,
clientDiffInfo.DiffWithMount.Difference.Path,
clientDiffInfo.DiffWithMount.Difference.IsDirectory);
}
void IDiffTreeViewMenuOperations.RevertChanges()
{
RevertClientDiffsOperation.RevertChanges(
mWkInfo,
DiffSelection.GetSelectedDiffs(mDiffTreeView),
mWorkspaceWindow,
mProgressControls,
mGuiMessage,
AfterRevertOrUndeleteOperation);
}
void IDiffTreeViewMenuOperations.Undelete()
{
UndeleteClientDiffsOperation.Undelete(
mWkInfo,
DiffSelection.GetSelectedDiffs(mDiffTreeView),
mRefreshView,
mProgressControls,
this,
mGuiMessage,
AfterRevertOrUndeleteOperation);
}
void IDiffTreeViewMenuOperations.UndeleteToSpecifiedPaths()
{
UndeleteClientDiffsOperation.UndeleteToSpecifiedPaths(
mWkInfo,
DiffSelection.GetSelectedDiffs(mDiffTreeView),
mRefreshView,
mProgressControls,
this,
mGuiMessage,
AfterRevertOrUndeleteOperation);
}
void IDiffTreeViewMenuOperations.Annotate()
{
}
void IDiffTreeViewMenuOperations.CopyFilePath(bool relativePath)
{
EditorGUIUtility.systemCopyBuffer = GetFilePathList.FromClientDiffInfos(
DiffSelection.GetSelectedDiffsWithoutMeta(mDiffTreeView),
relativePath,
mWkInfo.ClientPath);
}
bool DiffTreeViewMenu.IMetaMenuOperations.SelectionHasMeta()
{
return mDiffTreeView.SelectionHasMeta();
}
void DiffTreeViewMenu.IMetaMenuOperations.DiffMeta()
{
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
ClientDiffInfo clientDiffInfoMeta =
mDiffTreeView.GetMetaDiff(clientDiffInfo);
DiffOperation.DiffClientDiff(
mWkInfo,
clientDiffInfoMeta.DiffWithMount.Mount.Mount,
clientDiffInfoMeta.DiffWithMount.Difference,
PlasticExeLauncher.BuildForDiffRevision(mWkInfo, mIsGluonMode, mShowDownloadPlasticExeWindow),
imageDiffLauncher: null);
}
GetRestorePathData
UndeleteClientDiffsOperation.IGetRestorePathDialog.GetRestorePath(
string wkPath, string restorePath, string explanation,
bool isDirectory, bool showSkipButton)
{
return GetRestorePathDialog.GetRestorePath(
wkPath, restorePath, explanation, isDirectory,
showSkipButton, mParentWindow);
}
void DiffTreeViewMenu.IMetaMenuOperations.HistoryMeta()
{
ClientDiffInfo clientDiffInfo =
DiffSelection.GetSelectedDiff(mDiffTreeView);
ClientDiffInfo clientDiffInfoMeta =
mDiffTreeView.GetMetaDiff(clientDiffInfo);
mHistoryViewLauncher.ShowHistoryView(
clientDiffInfoMeta.DiffWithMount.Mount.RepSpec,
clientDiffInfoMeta.DiffWithMount.Difference.RevInfo.ItemId,
clientDiffInfoMeta.DiffWithMount.Difference.Path,
clientDiffInfoMeta.DiffWithMount.Difference.IsDirectory);
}
void SearchField_OnDownOrUpArrowKeyPressed()
{
mDiffTreeView.SetFocusAndEnsureSelectedItem();
}
void AfterRevertOrUndeleteOperation()
{
RefreshAsset.UnityAssetDatabase();
mViewSwitcher.ShowPendingChanges();
}
void ClearData()
{
mSelectedMountWithPath = null;
mSelectedChangesetInfo = null;
mDiffs = null;
ClearDiffs();
}
void FillData(
MountPointWithPath mountWithPath,
ChangesetInfo csetInfo)
{
mSelectedMountWithPath = mountWithPath;
mSelectedChangesetInfo = csetInfo;
((IProgressControls)mProgressControls).ShowProgress(
PlasticLocalization.GetString(PlasticLocalization.Name.Loading));
mIsSkipMergeTrackingButtonVisible = false;
IThreadWaiter waiter = ThreadWaiter.GetWaiter(100);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
mDiffs = PlasticGui.Plastic.API.GetChangesetDifferences(
mountWithPath, csetInfo);
mDiffsBranchResolver = BuildBranchResolver.ForDiffs(mDiffs);
},
/*afterOperationDelegate*/ delegate
{
((IProgressControls)mProgressControls).HideProgress();
if (waiter.Exception != null)
{
ExceptionsHandler.DisplayException(waiter.Exception);
return;
}
if (mSelectedMountWithPath != mountWithPath ||
mSelectedChangesetInfo != csetInfo)
return;
if (mDiffs == null || mDiffs.Count == 0)
{
ClearDiffs();
return;
}
mIsSkipMergeTrackingButtonVisible =
ClientDiffList.HasMerges(mDiffs);
bool skipMergeTracking =
mIsSkipMergeTrackingButtonVisible &&
mIsSkipMergeTrackingButtonChecked;
UpdateDiffTreeView(
mWkInfo,
mDiffs,
mDiffsBranchResolver,
skipMergeTracking,
mDiffTreeView);
});
}
void ClearDiffs()
{
mIsSkipMergeTrackingButtonVisible = false;
ClearDiffTreeView(mDiffTreeView);
((IProgressControls)mProgressControls).ShowNotification(
PlasticLocalization.GetString(PlasticLocalization.Name.NoContentToCompare));
}
static void ClearDiffTreeView(
DiffTreeView diffTreeView)
{
diffTreeView.ClearModel();
diffTreeView.Reload();
}
static void UpdateDiffTreeView(
WorkspaceInfo wkInfo,
List<ClientDiff> diffs,
BranchResolver brResolver,
bool skipMergeTracking,
DiffTreeView diffTreeView)
{
diffTreeView.BuildModel(
wkInfo, diffs, brResolver, skipMergeTracking);
diffTreeView.Refilter();
diffTreeView.Sort();
diffTreeView.Reload();
}
void DoActionsToolbar(
List<ClientDiff> diffs,
BranchResolver brResolver,
ProgressControlsForViews progressControls,
bool isSkipMergeTrackingButtonVisible,
bool isSkipMergeTrackingButtonChecked,
SearchField searchField,
DiffTreeView diffTreeView)
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
if (progressControls.IsOperationRunning())
{
DrawProgressForViews.ForIndeterminateProgress(
progressControls.ProgressData);
}
GUILayout.FlexibleSpace();
if (isSkipMergeTrackingButtonVisible)
{
DoSkipMergeTrackingButton(
diffs, brResolver,
isSkipMergeTrackingButtonChecked,
diffTreeView);
}
DrawSearchField.For(
searchField,
diffTreeView,
UnityConstants.SEARCH_FIELD_WIDTH);
VerifyIfSearchFieldIsRecentlyFocused(searchField);
EditorGUILayout.EndHorizontal();
}
void VerifyIfSearchFieldIsRecentlyFocused(SearchField searchField)
{
if (searchField.HasFocus() != mIsSearchFieldFocused)
{
mIsSearchFieldFocused = !mIsSearchFieldFocused;
if (mIsSearchFieldFocused)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
TrackFeatureUseEvent.Features.ChangesetViewDiffSearchBox);
}
}
}
void DoSkipMergeTrackingButton(
List<ClientDiff> diffs,
BranchResolver brResolver,
bool isSkipMergeTrackingButtonChecked,
DiffTreeView diffTreeView)
{
bool wasChecked = isSkipMergeTrackingButtonChecked;
GUIContent buttonContent = new GUIContent(
PlasticLocalization.GetString(
PlasticLocalization.Name.SkipDiffMergeTracking));
GUIStyle buttonStyle = new GUIStyle(EditorStyles.toolbarButton);
float buttonWidth = buttonStyle.CalcSize(buttonContent).x + 10;
Rect toggleRect = GUILayoutUtility.GetRect(
buttonContent, buttonStyle, GUILayout.Width(buttonWidth));
bool isChecked = GUI.Toggle(
toggleRect, wasChecked, buttonContent, buttonStyle);
if (wasChecked == isChecked)
return;
// if user just checked the skip merge tracking button
if (isChecked)
{
TrackFeatureUseEvent.For(
PlasticGui.Plastic.API.GetRepositorySpec(mWkInfo),
TrackFeatureUseEvent.Features.ChangesetViewSkipMergeTrackingButton);
}
UpdateDiffTreeView(mWkInfo, diffs, brResolver, isChecked, diffTreeView);
mIsSkipMergeTrackingButtonChecked = isChecked;
}
static void DoDiffTreeViewArea(
DiffTreeView diffTreeView,
bool isOperationRunning)
{
GUI.enabled = !isOperationRunning;
Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
diffTreeView.OnGUI(rect);
GUI.enabled = true;
}
void BuildComponents()
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
mDiffTreeView = new DiffTreeView(new DiffTreeViewMenu(this, this));
mDiffTreeView.Reload();
}
volatile List<ClientDiff> mDiffs;
volatile BranchResolver mDiffsBranchResolver;
bool mIsSkipMergeTrackingButtonVisible;
bool mIsSkipMergeTrackingButtonChecked;
SearchField mSearchField;
bool mIsSearchFieldFocused = false;
DiffTreeView mDiffTreeView;
ChangesetInfo mSelectedChangesetInfo;
MountPointWithPath mSelectedMountWithPath;
readonly ProgressControlsForViews mProgressControls;
readonly GuiMessage.IGuiMessage mGuiMessage;
readonly EditorWindow mParentWindow;
readonly IRefreshView mRefreshView;
readonly IWorkspaceWindow mWorkspaceWindow;
readonly IHistoryViewLauncher mHistoryViewLauncher;
readonly IViewSwitcher mViewSwitcher;
readonly LaunchTool.IShowDownloadPlasticExeWindow mShowDownloadPlasticExeWindow;
readonly WorkspaceInfo mWkInfo;
readonly bool mIsGluonMode;
}
}

View File

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

View File

@@ -0,0 +1,30 @@
using System.Collections.Generic;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal static class DiffSelection
{
internal static List<ClientDiffInfo> GetSelectedDiffs(
DiffTreeView treeView)
{
return treeView.GetSelectedDiffs(true);
}
internal static List<ClientDiffInfo> GetSelectedDiffsWithoutMeta(
DiffTreeView treeView)
{
return treeView.GetSelectedDiffs(false);
}
internal static ClientDiffInfo GetSelectedDiff(
DiffTreeView treeView)
{
if (!treeView.HasSelection())
return null;
return treeView.GetSelectedDiffs(false)[0];
}
}
}

View File

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

View File

@@ -0,0 +1,565 @@
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.CM.Common;
using Codice.Utils;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Diff;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class DiffTreeView : TreeView
{
internal DiffTreeView(DiffTreeViewMenu menu)
: base(new TreeViewState())
{
mMenu = menu;
customFoldoutYOffset = UnityConstants.TREEVIEW_FOLDOUT_Y_OFFSET;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = false;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
EnableHorizontalScrollbar();
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
public override void OnGUI(Rect rect)
{
base.OnGUI(rect);
Event e = Event.current;
if (e.type != EventType.KeyDown)
return;
bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e);
if (isProcessed)
e.Use();
}
protected override bool CanChangeExpandedState(TreeViewItem item)
{
return item is ChangeCategoryTreeViewItem
|| item is MergeCategoryTreeViewItem;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem rootItem)
{
try
{
RegenerateRows(
mDiffTree,
mTreeViewItemIds,
this,
rootItem,
mRows,
mExpandCategories);
}
finally
{
mExpandCategories = false;
}
return mRows;
}
protected override void CommandEventHandling()
{
// NOTE - empty override to prevent crash when pressing ctrl-a in the treeview
}
protected override void SearchChanged(string newSearch)
{
mCooldownFilterAction.Ping();
}
protected override void ContextClickedItem(int id)
{
mMenu.Popup();
Repaint();
}
protected override void BeforeRowsGUI()
{
int firstRowVisible;
int lastRowVisible;
GetFirstAndLastVisibleRows(out firstRowVisible, out lastRowVisible);
GUI.DrawTexture(new Rect(0,
firstRowVisible * rowHeight,
GetRowRect(0).width + 500,
(lastRowVisible * rowHeight) + 1500),
Images.GetTreeviewBackgroundTexture());
DrawTreeViewItem.InitializeStyles();
mLargestRowWidth = 0;
base.BeforeRowsGUI();
}
protected override void RowGUI(RowGUIArgs args)
{
float itemWidth;
TreeViewItemGUI(
args.item, args.rowRect, rowHeight, mDiffTree, args.selected, args.focused, out itemWidth);
float rowWidth = baseIndent + args.item.depth * depthIndentWidth +
itemWidth + UnityConstants.TREEVIEW_ROW_WIDTH_OFFSET;
if (rowWidth > mLargestRowWidth)
mLargestRowWidth = rowWidth;
}
protected override void AfterRowsGUI()
{
if (mHorizontalColumn != null)
mHorizontalColumn.width = mLargestRowWidth;
base.AfterRowsGUI();
}
internal void ClearModel()
{
mTreeViewItemIds.Clear();
mDiffTree = new UnityDiffTree();
}
internal void BuildModel(
WorkspaceInfo wkInfo,
List<ClientDiff> diffs,
BranchResolver brResolver,
bool skipMergeTracking)
{
mTreeViewItemIds.Clear();
mDiffTree.BuildCategories(wkInfo, diffs, brResolver, skipMergeTracking);
}
internal void Refilter()
{
Filter filter = new Filter(searchString);
mDiffTree.Filter(filter, ColumnsNames);
mExpandCategories = true;
}
internal void Sort()
{
mDiffTree.Sort(
PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn),
sortAscending: true);
}
internal ClientDiffInfo GetMetaDiff(ClientDiffInfo diff)
{
return mDiffTree.GetMetaDiff(diff);
}
internal bool SelectionHasMeta()
{
if (!HasSelection())
return false;
ClientDiffInfo selectedDiff = GetSelectedDiffs(false)[0];
if (selectedDiff == null)
return false;
return mDiffTree.HasMeta(selectedDiff);
}
internal List<ClientDiffInfo> GetSelectedDiffs(bool includeMetaFiles)
{
List<ClientDiffInfo> result = new List<ClientDiffInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<ITreeViewNode, int> item
in mTreeViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
if (!(item.Key is ClientDiffInfo))
continue;
result.Add((ClientDiffInfo)item.Key);
}
if (includeMetaFiles)
mDiffTree.FillWithMeta(result);
return result;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void EnableHorizontalScrollbar()
{
mHorizontalColumn = new MultiColumnHeaderState.Column();
mHorizontalColumn.autoResize = false;
MultiColumnHeaderState.Column[] cols = { mHorizontalColumn };
MultiColumnHeaderState headerState = new MultiColumnHeaderState(cols);
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.height = 0f;
}
static void RegenerateRows(
UnityDiffTree diffTree,
TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds,
TreeView treeView,
TreeViewItem rootItem,
List<TreeViewItem> rows,
bool expandCategories)
{
ClearRows(rootItem, rows);
List<IDiffCategory> categories = diffTree.GetNodes();
if (categories == null)
return;
foreach (IDiffCategory category in categories)
{
if (category is CategoryGroup &&
((CategoryGroup)category).CategoryType == CategoryGroup.Type.MergeCategory)
{
AddMergeCategory(
rootItem,
category,
rows,
treeViewItemIds,
treeView,
expandCategories);
}
if (category is ChangeCategory)
{
AddChangeCategory(
rootItem,
category,
rows,
treeViewItemIds,
treeView,
expandCategories);
}
}
if (!expandCategories)
return;
treeView.state.expandedIDs = treeViewItemIds.GetCategoryIds();
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void AddMergeCategory(
TreeViewItem rootItem,
IDiffCategory category,
List<TreeViewItem> rows,
TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds,
TreeView treeView,
bool expandCategories)
{
int categoryId;
if (!treeViewItemIds.TryGetCategoryItemId(category, out categoryId))
categoryId = treeViewItemIds.AddCategoryItem(category);
MergeCategoryTreeViewItem mergeCategoryTreeViewItem =
new MergeCategoryTreeViewItem(
categoryId,
rootItem.depth + 1,
(CategoryGroup)category);
rootItem.AddChild(mergeCategoryTreeViewItem);
rows.Add(mergeCategoryTreeViewItem);
if (!expandCategories &&
!treeView.IsExpanded(mergeCategoryTreeViewItem.id))
return;
for (int i = 0; i < category.GetChildrenCount(); i++)
{
IDiffCategory child = (IDiffCategory)((ITreeViewNode)category)
.GetChild(i);
AddChangeCategory(
mergeCategoryTreeViewItem,
child,
rows,
treeViewItemIds,
treeView,
expandCategories);
}
}
static void AddChangeCategory(
TreeViewItem parentItem,
IDiffCategory category,
List<TreeViewItem> rows,
TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds,
TreeView treeView,
bool expandCategories)
{
int categoryId;
if (!treeViewItemIds.TryGetCategoryItemId(category, out categoryId))
categoryId = treeViewItemIds.AddCategoryItem(category);
ChangeCategoryTreeViewItem changeCategoryTreeViewItem =
new ChangeCategoryTreeViewItem(
categoryId,
parentItem.depth + 1,
(ChangeCategory)category);
parentItem.AddChild(changeCategoryTreeViewItem);
rows.Add(changeCategoryTreeViewItem);
if (!expandCategories &&
!treeView.IsExpanded(changeCategoryTreeViewItem.id))
return;
AddClientDiffs(
changeCategoryTreeViewItem,
(ITreeViewNode)category,
rows,
treeViewItemIds);
}
static void AddClientDiffs(
TreeViewItem parentItem,
ITreeViewNode parentNode,
List<TreeViewItem> rows,
TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds)
{
for (int i = 0; i < parentNode.GetChildrenCount(); i++)
{
ITreeViewNode child = parentNode.GetChild(i);
int nodeId;
if (!treeViewItemIds.TryGetInfoItemId(child, out nodeId))
nodeId = treeViewItemIds.AddInfoItem(child);
TreeViewItem changeTreeViewItem =
new ClientDiffTreeViewItem(
nodeId,
parentItem.depth + 1,
(ClientDiffInfo)child);
parentItem.AddChild(changeTreeViewItem);
rows.Add(changeTreeViewItem);
}
}
static void TreeViewItemGUI(
TreeViewItem item,
Rect rowRect,
float rowHeight,
UnityDiffTree diffTree,
bool isSelected,
bool isFocused,
out float itemWidth)
{
if (item is MergeCategoryTreeViewItem)
{
MergeCategoryTreeViewItemGUI(
rowRect,
(MergeCategoryTreeViewItem)item,
isSelected,
isFocused,
out itemWidth);
return;
}
if (item is ChangeCategoryTreeViewItem)
{
ChangeCategoryTreeViewItemGUI(
rowRect,
(ChangeCategoryTreeViewItem)item,
isSelected,
isFocused,
out itemWidth);
return;
}
if (item is ClientDiffTreeViewItem)
{
ClientDiffTreeViewItemGUI(
rowRect,
rowHeight,
diffTree,
(ClientDiffTreeViewItem)item,
isSelected,
isFocused,
out itemWidth);
return;
}
itemWidth = 0;
}
static void MergeCategoryTreeViewItemGUI(
Rect rowRect,
MergeCategoryTreeViewItem item,
bool isSelected,
bool isFocused,
out float itemWidth)
{
string label = item.Category.CategoryName;
string infoLabel = PlasticLocalization.Name.ItemsCount.GetString(
item.Category.GetChildrenCount());
itemWidth = CalculateLabelWidth(label);
DrawTreeViewItem.ForCategoryItem(
rowRect,
item.depth,
label,
infoLabel,
isSelected,
isFocused);
}
static void ChangeCategoryTreeViewItemGUI(
Rect rowRect,
ChangeCategoryTreeViewItem item,
bool isSelected,
bool isFocused,
out float itemWidth)
{
string label = item.Category.CategoryName;
string infoLabel = PlasticLocalization.Name.ItemsCount.GetString(
item.Category.GetChildrenCount());
itemWidth = CalculateLabelWidth(label);
DrawTreeViewItem.ForCategoryItem(
rowRect,
item.depth,
label,
infoLabel,
isSelected,
isFocused);
}
static void ClientDiffTreeViewItemGUI(
Rect rowRect,
float rowHeight,
UnityDiffTree diffTree,
ClientDiffTreeViewItem item,
bool isSelected,
bool isFocused,
out float itemWidth)
{
string label = ClientDiffView.GetColumnText(
item.Difference.DiffWithMount.Mount.RepSpec,
item.Difference.DiffWithMount.Difference,
PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn));
if (diffTree.HasMeta(item.Difference))
label = string.Concat(label, UnityConstants.TREEVIEW_META_LABEL);
Texture icon = GetClientDiffIcon(
item.Difference.DiffWithMount.Difference.IsDirectory,
label);
itemWidth = CalculateItemWidth(label, icon, rowHeight);
DrawTreeViewItem.ForItemCell(
rowRect,
rowHeight,
item.depth,
icon,
null,
label,
isSelected,
isFocused,
false,
false);
}
static float CalculateItemWidth(
string label,
Texture icon,
float rowHeight)
{
float labelWidth = CalculateLabelWidth(label);
float iconWidth = rowHeight * ((float)icon.width / icon.height);
return labelWidth + iconWidth;
}
static float CalculateLabelWidth(string label)
{
GUIContent content = new GUIContent(label);
Vector2 contentSize = DefaultStyles.label.CalcSize(content);
return contentSize.x;
}
static Texture GetClientDiffIcon(bool isDirectory, string path)
{
if (isDirectory)
return Images.GetDirectoryIcon();
return Images.GetFileIconFromCmPath(path);
}
bool mExpandCategories;
TreeViewItemIds<IDiffCategory, ITreeViewNode> mTreeViewItemIds =
new TreeViewItemIds<IDiffCategory, ITreeViewNode>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
UnityDiffTree mDiffTree = new UnityDiffTree();
MultiColumnHeaderState.Column mHorizontalColumn;
float mLargestRowWidth;
readonly CooldownWindowDelayer mCooldownFilterAction;
static readonly List<string> ColumnsNames = new List<string> {
PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn)};
readonly DiffTreeViewMenu mMenu;
}
}

View File

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

View File

@@ -0,0 +1,323 @@
using UnityEditor;
using UnityEngine;
using Codice.Client.Common.EventTracking;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Diff;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.Tool;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class DiffTreeViewMenu
{
internal interface IMetaMenuOperations
{
bool SelectionHasMeta();
void DiffMeta();
void HistoryMeta();
}
internal DiffTreeViewMenu(
IDiffTreeViewMenuOperations operations,
IMetaMenuOperations metaMenuOperations)
{
mOperations = operations;
mMetaMenuOperations = metaMenuOperations;
BuildComponents();
}
internal void Popup()
{
GenericMenu menu = new GenericMenu();
UpdateMenuItems(menu);
menu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
DiffTreeViewMenuOperations operationToExecute = GetMenuOperation(e);
if (operationToExecute == DiffTreeViewMenuOperations.None)
return false;
SelectedDiffsGroupInfo info =
mOperations.GetSelectedDiffsGroupInfo();
DiffTreeViewMenuOperations operations =
DiffTreeViewMenuUpdater.GetAvailableMenuOperations(info);
if (!operations.HasFlag(operationToExecute))
return false;
ProcessMenuOperation(operationToExecute);
return true;
}
void SaveRevisionAsMenuItem_Click()
{
mOperations.SaveRevisionAs();
}
void DiffMenuItem_Click()
{
mOperations.Diff();
}
void DiffMetaMenuItem_Click()
{
mMetaMenuOperations.DiffMeta();
}
void HistoryMenuItem_Click()
{
mOperations.History();
}
void HistoryMetaMenuItem_Click()
{
mMetaMenuOperations.HistoryMeta();
}
void RevertMenuItem_Click()
{
mOperations.RevertChanges();
}
void UndeleteMenuItem_Click()
{
mOperations.Undelete();
}
void UndeleteToSpecifiedPathMenuItem_Click()
{
mOperations.UndeleteToSpecifiedPaths();
}
void CopyFilePathMenuItem_Click()
{
mOperations.CopyFilePath(relativePath: false);
}
void CopyRelativeFilePathMenuItem_Click()
{
mOperations.CopyFilePath(relativePath: true);
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedDiffsGroupInfo groupInfo =
mOperations.GetSelectedDiffsGroupInfo();
DiffTreeViewMenuOperations operations =
DiffTreeViewMenuUpdater.GetAvailableMenuOperations(groupInfo);
if (operations == DiffTreeViewMenuOperations.None)
{
menu.AddDisabledItem(GetNoActionMenuItemContent());
return;
}
bool isMultipleSelection = groupInfo.SelectedItemsCount > 1;
bool selectionHasMeta = mMetaMenuOperations.SelectionHasMeta();
if (operations.HasFlag(DiffTreeViewMenuOperations.SaveAs))
menu.AddItem(mSaveRevisionAsMenuItemContent, false, SaveRevisionAsMenuItem_Click);
if (operations.HasFlag(DiffTreeViewMenuOperations.Diff))
menu.AddItem(mDiffMenuItemContent, false, DiffMenuItem_Click);
else
menu.AddDisabledItem(mDiffMenuItemContent, false);
if (mMetaMenuOperations.SelectionHasMeta())
{
if (operations.HasFlag(DiffTreeViewMenuOperations.Diff))
menu.AddItem(mDiffMetaMenuItemContent, false, DiffMetaMenuItem_Click);
else
menu.AddDisabledItem(mDiffMetaMenuItemContent);
}
menu.AddSeparator(string.Empty);
if (operations.HasFlag(DiffTreeViewMenuOperations.History))
menu.AddItem(mViewHistoryMenuItemContent, false, HistoryMenuItem_Click);
else
menu.AddDisabledItem(mViewHistoryMenuItemContent, false);
if (mMetaMenuOperations.SelectionHasMeta())
{
if (operations.HasFlag(DiffTreeViewMenuOperations.History))
menu.AddItem(mViewHistoryMetaMenuItemContent, false, HistoryMetaMenuItem_Click);
else
menu.AddDisabledItem(mViewHistoryMetaMenuItemContent, false);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.RevertChanges))
{
menu.AddSeparator(string.Empty);
mRevertMenuItemContent.text = GetRevertMenuItemText(
isMultipleSelection,
selectionHasMeta);
menu.AddItem(mRevertMenuItemContent, false, RevertMenuItem_Click);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.Undelete) ||
operations.HasFlag(DiffTreeViewMenuOperations.UndeleteToSpecifiedPaths))
{
menu.AddSeparator(string.Empty);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.Undelete))
{
mUndeleteMenuItemContent.text = GetUndeleteMenuItemText(
isMultipleSelection,
selectionHasMeta);
menu.AddItem(mUndeleteMenuItemContent, false, UndeleteMenuItem_Click);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.UndeleteToSpecifiedPaths))
{
mUndeleteToSpecifiedPathMenuItemContent.text = GetUndeleteToSpecifiedPathMenuItemText(
isMultipleSelection,
selectionHasMeta);
menu.AddItem(mUndeleteToSpecifiedPathMenuItemContent, false, UndeleteToSpecifiedPathMenuItem_Click);
}
if (operations.HasFlag(DiffTreeViewMenuOperations.CopyFilePath))
{
menu.AddSeparator(string.Empty);
menu.AddItem(
mCopyFilePathMenuItemContent, false, CopyFilePathMenuItem_Click);
menu.AddItem(
mCopyRelativeFilePathMenuItemContent, false, CopyRelativeFilePathMenuItem_Click);
}
}
GUIContent GetNoActionMenuItemContent()
{
if (mNoActionMenuItemContent == null)
{
mNoActionMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.
Name.NoActionMenuItem));
}
return mNoActionMenuItemContent;
}
static string GetRevertMenuItemText(
bool isMultipleSelection,
bool selectionHasMeta)
{
if (selectionHasMeta && !isMultipleSelection)
return PlasticLocalization.GetString(PlasticLocalization.Name.UndoThisChangePlusMeta);
return isMultipleSelection ?
PlasticLocalization.GetString(PlasticLocalization.Name.UndoSelectedChanges) :
PlasticLocalization.GetString(PlasticLocalization.Name.UndoThisChange);
}
static string GetUndeleteMenuItemText(
bool isMultipleSelection,
bool selectionHasMeta)
{
if (selectionHasMeta && !isMultipleSelection)
return PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteRevisionPlusMeta);
return isMultipleSelection ?
PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteSelectedRevisions) :
PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteRevisions);
}
static string GetUndeleteToSpecifiedPathMenuItemText(
bool isMultipleSelection,
bool selectionHasMeta)
{
if (selectionHasMeta && !isMultipleSelection)
return PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteRevisionPlusMetaPath);
return isMultipleSelection ?
PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteSelectedRevisionsPaths) :
PlasticLocalization.GetString(PlasticLocalization.Name.UndeleteRevisionPath);
}
void ProcessMenuOperation(DiffTreeViewMenuOperations operationToExecute)
{
if (operationToExecute == DiffTreeViewMenuOperations.SaveAs)
{
SaveRevisionAsMenuItem_Click();
return;
}
if (operationToExecute == DiffTreeViewMenuOperations.Diff)
{
DiffMenuItem_Click();
return;
}
if (operationToExecute == DiffTreeViewMenuOperations.History)
{
HistoryMenuItem_Click();
}
}
static DiffTreeViewMenuOperations GetMenuOperation(Event e)
{
if (Keyboard.IsControlOrCommandKeyPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.D))
return DiffTreeViewMenuOperations.Diff;
if (Keyboard.IsControlOrCommandKeyPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.H))
return DiffTreeViewMenuOperations.History;
return DiffTreeViewMenuOperations.None;
}
void BuildComponents()
{
mSaveRevisionAsMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.DiffMenuItemSaveRevisionAs));
mDiffMenuItemContent = new GUIContent(
string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.DiffMenuItem),
GetPlasticShortcut.ForDiff()));
mDiffMetaMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.DiffMetaMenuItem));
mViewHistoryMenuItemContent = new GUIContent(
string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.ViewHistoryMenuItem),
GetPlasticShortcut.ForHistory()));
mViewHistoryMetaMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.ViewHistoryMetaMenuItem));
mRevertMenuItemContent = new GUIContent();
mUndeleteMenuItemContent = new GUIContent();
mUndeleteToSpecifiedPathMenuItemContent = new GUIContent();
mCopyFilePathMenuItemContent = new GUIContent(PlasticLocalization.Name.CopyFilePathMenuItem.GetString());
mCopyRelativeFilePathMenuItemContent =
new GUIContent(PlasticLocalization.Name.CopyRelativeFilePathMenuItem.GetString());
}
GUIContent mNoActionMenuItemContent;
GUIContent mSaveRevisionAsMenuItemContent;
GUIContent mDiffMenuItemContent;
GUIContent mDiffMetaMenuItemContent;
GUIContent mViewHistoryMenuItemContent;
GUIContent mViewHistoryMetaMenuItemContent;
GUIContent mRevertMenuItemContent;
GUIContent mUndeleteMenuItemContent;
GUIContent mUndeleteToSpecifiedPathMenuItemContent;
GUIContent mCopyFilePathMenuItemContent;
GUIContent mCopyRelativeFilePathMenuItemContent;
readonly IDiffTreeViewMenuOperations mOperations;
readonly IMetaMenuOperations mMetaMenuOperations;
}
}

View File

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

View File

@@ -0,0 +1,33 @@
using System.Collections.Generic;
using Codice.Utils;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal static class GetClientDiffInfos
{
internal static List<ClientDiffInfo> FromCategories(List<IDiffCategory> categories)
{
List<ClientDiffInfo> result = new List<ClientDiffInfo>();
foreach (ITreeViewNode node in categories)
AddClientDiffInfos(node, result);
return result;
}
static void AddClientDiffInfos(ITreeViewNode node, List<ClientDiffInfo> result)
{
if (node is ClientDiffInfo)
{
result.Add((ClientDiffInfo)node);
return;
}
for (int i = 0; i < node.GetChildrenCount(); i++)
AddClientDiffInfos(node.GetChild(i), result);
}
}
}

View File

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

View File

@@ -0,0 +1,18 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class MergeCategoryTreeViewItem : TreeViewItem
{
internal CategoryGroup Category { get; private set; }
internal MergeCategoryTreeViewItem(
int id, int depth, CategoryGroup categoryGroup)
: base(id, depth, categoryGroup.GetHeaderText())
{
Category = categoryGroup;
}
}
}

View File

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

View File

@@ -0,0 +1,233 @@
using System.Collections.Generic;
using Codice.Client.Commands;
using Codice.Client.Common;
using Codice.CM.Common;
using Codice.Utils;
using PlasticGui;
using PlasticGui.Diff;
using PlasticGui.WorkspaceWindow.Diff;
namespace Unity.PlasticSCM.Editor.Views.Diff
{
internal class UnityDiffTree
{
internal UnityDiffTree()
{
mInnerTree = new DiffTree();
mMetaCache = new MetaCache();
}
internal void BuildCategories(
WorkspaceInfo wkInfo,
List<ClientDiff> diffs,
BranchResolver brResolver,
bool skipMergeTracking)
{
mInnerTree.BuildCategories(
RevisionInfoCodeReviewAdapter.CalculateCodeReviewEntries(
wkInfo,
diffs,
brResolver,
skipMergeTracking),
brResolver);
mMetaCache.Build(mInnerTree.GetNodes());
}
internal List<IDiffCategory> GetNodes()
{
return mInnerTree.GetNodes();
}
internal bool HasMeta(ClientDiffInfo difference)
{
return mMetaCache.ContainsMeta(difference);
}
internal ClientDiffInfo GetMetaDiff(ClientDiffInfo diff)
{
return mMetaCache.GetExistingMeta(diff);
}
internal void FillWithMeta(List<ClientDiffInfo> diffs)
{
diffs.AddRange(
mMetaCache.GetExistingMeta(diffs));
}
internal void Sort(string key, bool sortAscending)
{
mInnerTree.Sort(key, sortAscending);
}
internal void Filter(Filter filter, List<string> columnNames)
{
mInnerTree.Filter(filter, columnNames);
}
MetaCache mMetaCache = new MetaCache();
DiffTree mInnerTree;
class MetaCache
{
internal void Build(List<IDiffCategory> categories)
{
mCache.Clear();
HashSet<string> indexedKeys = BuildIndexedKeys(
GetClientDiffInfos.FromCategories(categories));
for (int i = 0; i < categories.Count; i++)
{
ExtractToMetaCache(
(ITreeViewNode)categories[i],
i,
mCache,
indexedKeys);
}
}
internal bool ContainsMeta(ClientDiffInfo diff)
{
return mCache.ContainsKey(
BuildKey.ForMetaDiff(diff));
}
internal ClientDiffInfo GetExistingMeta(ClientDiffInfo diff)
{
ClientDiffInfo result;
if (!mCache.TryGetValue(BuildKey.ForMetaDiff(diff), out result))
return null;
return result;
}
internal List<ClientDiffInfo> GetExistingMeta(List<ClientDiffInfo> diffs)
{
List<ClientDiffInfo> result = new List<ClientDiffInfo>();
foreach (ClientDiffInfo diff in diffs)
{
string key = BuildKey.ForMetaDiff(diff);
ClientDiffInfo metaDiff;
if (!mCache.TryGetValue(key, out metaDiff))
continue;
result.Add(metaDiff);
}
return result;
}
static void ExtractToMetaCache(
ITreeViewNode node,
int nodeIndex,
Dictionary<string, ClientDiffInfo> cache,
HashSet<string> indexedKeys)
{
if (node is ClientDiffInfo)
{
ClientDiffInfo diff = (ClientDiffInfo)node;
string path = diff.DiffWithMount.Difference.Path;
if (!MetaPath.IsMetaPath(path))
return;
string realPath = MetaPath.GetPathFromMetaPath(path);
if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
BuildKey.GetCategoryGroup(diff),
BuildKey.GetChangeCategory(diff),
realPath)))
return;
// found foo.c and foo.c.meta
// with the same chage types - move .meta to cache
cache.Add(BuildKey.ForDiff(diff), diff);
((ChangeCategory)node.GetParent()).RemoveDiffAt(nodeIndex);
}
for (int i = node.GetChildrenCount() - 1; i >= 0; i--)
{
ExtractToMetaCache(
node.GetChild(i),
i,
cache,
indexedKeys);
}
}
HashSet<string> BuildIndexedKeys(List<ClientDiffInfo> diffs)
{
HashSet<string> result = new HashSet<string>();
foreach (ClientDiffInfo diff in diffs)
{
if (MetaPath.IsMetaPath(diff.DiffWithMount.Difference.Path))
continue;
result.Add(BuildKey.ForDiff(diff));
}
return result;
}
Dictionary<string, ClientDiffInfo> mCache =
new Dictionary<string, ClientDiffInfo>();
static class BuildKey
{
internal static string ForDiff(
ClientDiffInfo diff)
{
return BuildCacheKey(
GetCategoryGroup(diff),
GetChangeCategory(diff),
diff.DiffWithMount.Difference.Path);
}
internal static string ForMetaDiff(
ClientDiffInfo diff)
{
return BuildCacheKey(
GetCategoryGroup(diff),
GetChangeCategory(diff),
MetaPath.GetMetaPath(diff.DiffWithMount.Difference.Path));
}
internal static string BuildCacheKey(
CategoryGroup categoryGroup,
ChangeCategory changeCategory,
string path)
{
string result = string.Concat(changeCategory.Type, ":", path);
if (categoryGroup == null)
return result;
return string.Concat(categoryGroup.GetHeaderText(), ":", result);
}
internal static ChangeCategory GetChangeCategory(ClientDiffInfo diff)
{
return (ChangeCategory)diff.GetParent();
}
internal static CategoryGroup GetCategoryGroup(ClientDiffInfo diff)
{
ChangeCategory changeCategory = GetChangeCategory(diff);
ITreeViewNode categoryGroup = changeCategory.GetParent();
if (categoryGroup == null)
return null;
return (CategoryGroup)categoryGroup;
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,258 @@
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using Codice.Client.Common;
using Codice.Client.Common.EventTracking;
using Codice.CM.Common;
using PlasticGui;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.UIElements;
using Unity.PlasticSCM.Editor.Views.Welcome;
namespace Unity.PlasticSCM.Editor.Views
{
internal class DownloadPlasticExeDialog : PlasticDialog, DownloadAndInstallOperation.INotify
{
internal bool IsPlasticInstalling { get { return mIsPlasticInstalling; } }
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, DIALOG_WIDTH, DIALOG_HEIGHT);
}
}
internal static ProgressControlsForDialogs.Data Show(
RepositorySpec repSpec,
bool isGluonMode,
string installCloudFrom,
string installEnterpriseFrom,
string cancelInstallFrom,
ProgressControlsForDialogs.Data progressData)
{
DownloadPlasticExeDialog dialog;
if (HasOpenInstances<DownloadPlasticExeDialog>())
{
dialog = GetWindow<DownloadPlasticExeDialog>(true);
}
else
{
dialog = Create(repSpec, isGluonMode, installCloudFrom, installEnterpriseFrom, cancelInstallFrom, progressData);
dialog.RunUtility(focusedWindow);
}
return progressData != null ? progressData : dialog.mProgressControls.ProgressData;
}
static DownloadPlasticExeDialog Create(
RepositorySpec repSpec,
bool isGluonMode,
string installCloudFrom,
string installEnterpriseFrom,
string cancelInstallFrom,
ProgressControlsForDialogs.Data progressData)
{
var instance = CreateInstance<DownloadPlasticExeDialog>();
instance.mRepSpec = repSpec;
instance.mInstallCloudFrom = installCloudFrom;
instance.mInstallEnterpriseFrom = installEnterpriseFrom;
instance.mCancelInstallFrom = cancelInstallFrom;
instance.mIsGluonMode = isGluonMode;
instance.mProgressData = progressData;
instance.mInstallerFile = GetInstallerTmpFileName.ForPlatform();
instance.mIsCloudEdition = EditionToken.IsCloudEdition();
instance.mTitle = PlasticLocalization.Name.UnityVersionControl.GetString();
return instance;
}
protected override string GetTitle()
{
return mTitle;
}
void OnEnable()
{
BuildComponents();
}
void OnDestroy()
{
Dispose();
}
protected override void OnModalGUI()
{
if (InstallationFinished())
{
mMessageLabel.text = PlasticLocalization.Name.UnityVersionControlInstalled.GetString();
mCancelButton.text = PlasticLocalization.Name.CloseButton.GetString();
mConfirmMessageLabel.Collapse();
mDownloadButton.Collapse();
maxSize = new Vector2(DIALOG_WIDTH, REDUCED_DIALOG_HEIGHT);
return;
}
if (mProgressData != null)
{
if (mProgressControlsContainer.Children().OfType<ProgressControlsForDialogs>().Any())
{
mProgressControlsContainer.RemoveAt(0);
mProgressLabel = new Label(GetMessageFromProgressData(mProgressData));
mProgressControlsContainer.Add(mProgressLabel);
}
mProgressLabel.text = GetMessageFromProgressData(mProgressData);
UpdateButtonsStatuses();
}
}
void CancelButton_Clicked()
{
if (!IsExeAvailable.ForMode(mIsGluonMode))
TrackFeatureUseEvent.For(mRepSpec, mCancelInstallFrom);
Close();
}
void DownloadButton_Clicked()
{
if (mIsCloudEdition)
{
TrackFeatureUseEvent.For(mRepSpec, mInstallCloudFrom);
DownloadAndInstallOperation.Run(
Edition.Cloud, mInstallerFile, mProgressControls, this);
}
else
{
TrackFeatureUseEvent.For(mRepSpec, mInstallEnterpriseFrom);
DownloadAndInstallOperation.Run(
Edition.Enterprise, mInstallerFile, mProgressControls, this);
}
}
void DownloadAndInstallOperation.INotify.InstallationStarted()
{
mIsPlasticInstalling = true;
}
void DownloadAndInstallOperation.INotify.InstallationFinished()
{
mIsPlasticInstalling = false;
}
bool InstallationFinished()
{
return mCancelButton.enabledSelf && IsExeAvailable.ForMode(mIsGluonMode);
}
void UpdateButtonsStatuses()
{
if (!string.IsNullOrEmpty(mProgressData.StatusMessage))
{
mCancelButton.SetEnabled(true);
mCancelButton.text = PlasticLocalization.Name.CloseButton.GetString();
mDownloadButton.Collapse();
return;
}
if (IsExeAvailable.ForMode(mIsGluonMode))
{
mCancelButton.SetEnabled(true);
return;
}
mDownloadButton.SetEnabled(false);
mCancelButton.SetEnabled(false);
}
static string GetMessageFromProgressData(ProgressControlsForDialogs.Data data)
{
if (!string.IsNullOrEmpty(data.StatusMessage))
{
return data.StatusMessage;
}
else
{
if (data.ProgressPercent >= 0)
return string.Format("{0} ({1}%)", data.ProgressMessage, (int)(data.ProgressPercent * 100));
else
return data.ProgressMessage;
}
}
void Dispose()
{
mDownloadButton.clicked -= DownloadButton_Clicked;
mCancelButton.clicked -= CancelButton_Clicked;
}
void BuildComponents()
{
VisualElement root = rootVisualElement;
root.Clear();
InitializeLayoutAndStyles();
mMessageLabel = root.Q<Label>("title");
mConfirmMessageLabel = root.Q<Label>("message");
mDownloadButton = root.Q<Button>("download");
mCancelButton = root.Q<Button>("cancel");
mProgressControlsContainer = root.Q<VisualElement>("progressControlsContainer");
mMessageLabel.text = PlasticLocalization.Name.InstallUnityVersionControl.GetString();
mConfirmMessageLabel.text = PlasticLocalization.Name.InstallConfirmationMessage.GetString();
mDownloadButton.text = PlasticLocalization.Name.YesButton.GetString();
mDownloadButton.clicked += DownloadButton_Clicked;
mCancelButton.text = PlasticLocalization.Name.NoButton.GetString();
mCancelButton.clicked += CancelButton_Clicked;
mProgressControls = new ProgressControlsForDialogs(
new VisualElement[] {
mDownloadButton,
mCancelButton
});
mProgressControlsContainer.Add(mProgressControls);
}
void InitializeLayoutAndStyles()
{
rootVisualElement.LoadLayout(typeof(DownloadPlasticExeDialog).Name);
rootVisualElement.LoadStyle(typeof(DownloadPlasticExeDialog).Name);
}
string mTitle;
Label mMessageLabel;
Label mConfirmMessageLabel;
Label mProgressLabel;
Button mDownloadButton;
Button mCancelButton;
ProgressControlsForDialogs mProgressControls;
VisualElement mProgressControlsContainer;
RepositorySpec mRepSpec;
string mInstallCloudFrom;
string mInstallEnterpriseFrom;
string mCancelInstallFrom;
string mInstallerFile;
bool mIsCloudEdition;
bool mIsGluonMode;
bool mIsPlasticInstalling;
ProgressControlsForDialogs.Data mProgressData;
const float DIALOG_WIDTH = 500;
const float DIALOG_HEIGHT = 250;
const float REDUCED_DIALOG_HEIGHT = 125;
}
}

View File

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

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using Codice.Client.Common.Threading;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Items;
namespace Unity.PlasticSCM.Editor.Views
{
internal static class FileSystemOperation
{
internal static string GetExePath()
{
string title = PlasticLocalization.GetString(
PlasticLocalization.Name.BrowseForExecutableFile);
string directory = Environment.GetFolderPath(
Environment.SpecialFolder.ProgramFiles);
string path = EditorUtility.OpenFilePanel(title, directory, null);
if (path.Length != 0)
return path;
return null;
}
internal static void Open(List<string> files)
{
try
{
foreach (string file in files)
OpenFile(file);
}
catch (Exception ex)
{
ExceptionsHandler.DisplayException(ex);
}
}
internal static void OpenInExplorer(string path)
{
EditorUtility.RevealInFinder(path);
}
static void OpenFile(string path)
{
if (path == null)
return;
string relativePath = GetRelativePath.ToApplication(path);
bool result = AssetDatabase.OpenAsset(
AssetDatabase.LoadMainAssetAtPath(relativePath));
if (result)
return;
OpenOperation.OpenFile(path);
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal enum HistoryListColumn
{
Changeset,
CreationDate,
CreatedBy,
Comment,
Branch,
}
[Serializable]
internal class HistoryListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static HistoryListHeaderState GetDefault()
{
return new HistoryListHeaderState(BuildColumns());
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.BranchColumn));
return result;
}
internal static string GetColumnName(HistoryListColumn column)
{
switch (column)
{
case HistoryListColumn.Changeset:
return PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetColumn);
case HistoryListColumn.CreationDate:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn);
case HistoryListColumn.CreatedBy:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn);
case HistoryListColumn.Comment:
return PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn);
case HistoryListColumn.Branch:
return PlasticLocalization.GetString(PlasticLocalization.Name.BranchColumn);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
if (mColumsAllowedToggleVisibility != null)
TreeHeaderColumns.SetVisibilities(columns, mColumsAllowedToggleVisibility);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 100,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.Changeset)),
minWidth = 50,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 250,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.CreationDate)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 250,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.CreatedBy)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 400,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.Comment)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
new Column()
{
width = 200,
headerContent = new GUIContent(
GetColumnName(HistoryListColumn.Branch)),
minWidth = 100,
sortingArrowAlignment = TextAlignment.Right
},
};
}
HistoryListHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
if (mColumsAllowedToggleVisibility == null)
mColumsAllowedToggleVisibility = TreeHeaderColumns.GetVisibilities(columns);
}
[SerializeField]
string[] mHeaderTitles;
[SerializeField]
bool[] mColumsAllowedToggleVisibility;
}
}

View File

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

View File

@@ -0,0 +1,411 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.History;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Avatar;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal class HistoryListView : TreeView
{
internal HistoryListView(
string wkPath,
RepositorySpec repSpec,
HistoryListHeaderState headerState,
HistoryListViewMenu menu,
List<string> columnNames) :
base(new TreeViewState())
{
mWkPath = wkPath;
mRepSpec = repSpec;
mMenu = menu;
mColumnNames = columnNames;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = false;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
public override void OnGUI(Rect rect)
{
base.OnGUI(rect);
Event e = Event.current;
if (e.type != EventType.KeyDown)
return;
bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e);
if (isProcessed)
e.Use();
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(
TreeViewItem rootItem)
{
if (mRevisionsList == null)
{
ClearRows(rootItem, mRows);
return mRows;
}
RegenerateRows(
mListViewItemIds,
mRevisionsList,
rootItem,
mRows);
return mRows;
}
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 HistoryListViewItem)
{
HistoryListViewItem historyListViewItem = (HistoryListViewItem)args.item;
HistoryListViewItemGUI(
mWkPath,
mRepSpec,
rowHeight,
historyListViewItem,
args,
mLoadedRevisionId == historyListViewItem.Revision.Id,
Repaint);
return;
}
base.RowGUI(args);
}
internal void BuildModel(
HistoryRevisionList historyRevisionList,
long loadedRevisionId)
{
mListViewItemIds.Clear();
mRevisionsList = historyRevisionList;
mLoadedRevisionId = loadedRevisionId;
}
internal void Refilter()
{
if (mRevisionsList == null)
return;
Filter filter = new Filter(searchString);
mRevisionsList.Filter(filter, mColumnNames, null, null);
}
internal void Sort()
{
if (mRevisionsList == null)
return;
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mRevisionsList.Sort(
mColumnNames[sortedColumnIdx],
sortAscending);
}
internal long GetLoadedRevisionId()
{
return mLoadedRevisionId;
}
internal List<RepObjectInfo> GetSelectedRepObjectInfos()
{
List<RepObjectInfo> result = new List<RepObjectInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<RepObjectInfo, int> item
in mListViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
result.Add(item.Key);
}
return result;
}
internal List<RepObjectInfo> GetAllRepObjectInfos()
{
List<RepObjectInfo> result = new List<RepObjectInfo>();
foreach (KeyValuePair<RepObjectInfo, int> item
in mListViewItemIds.GetInfoItems())
{
result.Add(item.Key);
}
return result;
}
internal List<HistoryRevision> GetSelectedHistoryRevisions()
{
return GetSelectedRepObjectInfos().OfType<HistoryRevision>().ToList();
}
internal void SelectRepObjectInfos(
List<RepObjectInfo> repObjectsToSelect)
{
List<int> idsToSelect = new List<int>();
foreach (RepObjectInfo repObjectInfo in repObjectsToSelect)
{
int repObjectInfoId = GetTreeIdForItem(repObjectInfo);
if (repObjectInfoId == -1)
continue;
idsToSelect.Add(repObjectInfoId);
}
TableViewOperations.SetSelectionAndScroll(this, idsToSelect);
}
int GetTreeIdForItem(RepObjectInfo currentRepObjectInfo)
{
foreach (KeyValuePair<RepObjectInfo, int> item in mListViewItemIds.GetInfoItems())
{
if (!currentRepObjectInfo.Equals(item.Key))
continue;
if (!currentRepObjectInfo.GUID.Equals(item.Key.GUID))
continue;
return item.Value;
}
return -1;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
ListViewItemIds<RepObjectInfo> listViewItemIds,
HistoryRevisionList revisions,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (revisions.GetCount() == 0)
return;
foreach (RepObjectInfo objectInfo in revisions.GetRevisions())
{
int objectId;
if (!listViewItemIds.TryGetInfoItemId(objectInfo, out objectId))
objectId = listViewItemIds.AddInfoItem(objectInfo);
HistoryListViewItem changesetListViewItem =
new HistoryListViewItem(objectId, objectInfo);
rootItem.AddChild(changesetListViewItem);
rows.Add(changesetListViewItem);
}
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void HistoryListViewItemGUI(
string wkPath,
RepositorySpec repSpec,
float rowHeight,
HistoryListViewItem item,
RowGUIArgs args,
bool isBoldText,
Action avatarLoadedAction)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
HistoryListColumn column =
(HistoryListColumn)args.GetColumn(visibleColumnIdx);
HistoryListViewItemCellGUI(
cellRect,
rowHeight,
wkPath,
repSpec,
item,
column,
avatarLoadedAction,
args.selected,
args.focused,
isBoldText);
}
}
static void HistoryListViewItemCellGUI(
Rect rect,
float rowHeight,
string wkPath,
RepositorySpec repSpec,
HistoryListViewItem item,
HistoryListColumn column,
Action avatarLoadedAction,
bool isSelected,
bool isFocused,
bool isBoldText)
{
string columnText = HistoryInfoView.GetColumnText(
wkPath, repSpec, item.Revision,
HistoryListHeaderState.GetColumnName(column));
if (column == HistoryListColumn.Changeset)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
0,
GetRevisionIcon(item.Revision),
null,
columnText,
isSelected,
isFocused,
isBoldText,
false);
return;
}
if (column == HistoryListColumn.CreatedBy)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
-1,
GetAvatar.ForEmail(columnText, avatarLoadedAction),
null,
columnText,
isSelected,
isFocused,
isBoldText,
false);
return;
}
if (column == HistoryListColumn.Branch)
{
DrawTreeViewItem.ForSecondaryLabel(
rect, columnText, isSelected, isFocused, isBoldText);
return;
}
DrawTreeViewItem.ForLabel(
rect, columnText, isSelected, isFocused, isBoldText);
}
static Texture GetRevisionIcon(RepObjectInfo revision)
{
if (revision is MoveRealizationInfo)
return Images.GetMovedIcon();
if (revision is RemovedRealizationInfo)
return Images.GetDeletedIcon();
return Images.GetFileIcon();
}
ListViewItemIds<RepObjectInfo> mListViewItemIds = new ListViewItemIds<RepObjectInfo>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
HistoryRevisionList mRevisionsList;
long mLoadedRevisionId;
readonly CooldownWindowDelayer mCooldownFilterAction;
readonly HistoryListViewMenu mMenu;
readonly List<string> mColumnNames;
readonly RepositorySpec mRepSpec;
readonly string mWkPath;
}
}

View File

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

View File

@@ -0,0 +1,20 @@

using UnityEditor.IMGUI.Controls;
using Codice.CM.Common;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal class HistoryListViewItem : TreeViewItem
{
internal RepObjectInfo Revision { get; private set; }
internal HistoryListViewItem(int id, RepObjectInfo revision)
: base(id, 1)
{
Revision = revision;
displayName = id.ToString();
}
}
}

View File

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

View File

@@ -0,0 +1,224 @@
using UnityEditor;
using UnityEngine;
using PlasticGui;
using PlasticGui.WorkspaceWindow.History;
using PlasticGui.WorkspaceWindow.Open;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.History
{
internal class HistoryListViewMenu
{
internal GenericMenu Menu { get { return mMenu; } }
public interface IMenuOperations
{
long GetSelectedChangesetId();
}
internal HistoryListViewMenu(
IOpenMenuOperations openMenuOperations,
IHistoryViewMenuOperations operations,
IMenuOperations menuOperations)
{
mOpenMenuOperations = openMenuOperations;
mOperations = operations;
mMenuOperations = menuOperations;
BuildComponents();
}
internal void Popup()
{
mMenu = new GenericMenu();
UpdateMenuItems(mMenu);
mMenu.ShowAsContext();
}
internal bool ProcessKeyActionIfNeeded(Event e)
{
HistoryMenuOperations operationToExecute = GetMenuOperation(e);
if (operationToExecute == HistoryMenuOperations.None)
return false;
SelectedHistoryGroupInfo info =
mOperations.GetSelectedHistoryGroupInfo();
HistoryMenuOperations operations =
HistoryMenuUpdater.GetAvailableMenuOperations(info);
if (!operations.HasFlag(operationToExecute))
return false;
ProcessMenuOperation(operationToExecute);
return true;
}
void OpenRevisionMenu_Click()
{
mOpenMenuOperations.Open();
}
void OpenRevisionWithMenu_Click()
{
mOpenMenuOperations.OpenWith();
}
void SaveRevisionasMenu_Click()
{
mOperations.SaveRevisionAs();
}
void DiffWithPreviousMenuItem_Click()
{
mOperations.DiffWithPrevious();
}
void DiffSelectedRevisionsMenu_Click()
{
mOperations.DiffSelectedRevisions();
}
void DiffChangesetMenu_Click()
{
mOperations.DiffChangeset();
}
void RevertToThisRevisionMenu_Click()
{
mOperations.RevertToThisRevision();
}
void UpdateMenuItems(GenericMenu menu)
{
SelectedHistoryGroupInfo info =
mOperations.GetSelectedHistoryGroupInfo();
HistoryMenuOperations operations =
HistoryMenuUpdater.GetAvailableMenuOperations(info);
OpenMenuOperations openOperations =
GetOpenMenuOperations.ForHistoryView(info);
if (operations == HistoryMenuOperations.None &&
openOperations == OpenMenuOperations.None)
{
menu.AddDisabledItem(GetNoActionMenuItemContent(), false);
return;
}
if (openOperations.HasFlag(OpenMenuOperations.Open))
menu.AddItem(mOpenRevisionMenuItemContent, false, OpenRevisionMenu_Click);
else
menu.AddDisabledItem(mOpenRevisionMenuItemContent, false);
if (openOperations.HasFlag(OpenMenuOperations.OpenWith))
menu.AddItem(mOpenRevisionWithMenuItemContent, false, OpenRevisionWithMenu_Click);
else
menu.AddDisabledItem(mOpenRevisionWithMenuItemContent, false);
if (operations.HasFlag(HistoryMenuOperations.SaveAs))
menu.AddItem(mSaveRevisionAsMenuItemContent, false, SaveRevisionasMenu_Click);
else
menu.AddDisabledItem(mSaveRevisionAsMenuItemContent, false);
menu.AddSeparator(string.Empty);
if (operations.HasFlag(HistoryMenuOperations.DiffWithPrevious))
menu.AddItem(mDiffWithPreviousMenuItemContent, false, DiffWithPreviousMenuItem_Click);
if (operations.HasFlag(HistoryMenuOperations.DiffSelected))
menu.AddItem(mDiffSelectedRevisionsMenuItemContent, false, DiffSelectedRevisionsMenu_Click);
mDiffChangesetMenuItemContent.text =
PlasticLocalization.GetString(PlasticLocalization.Name.HistoryMenuItemDiffChangeset) +
string.Format(" {0}", GetSelectedChangesetName(mMenuOperations));
if (operations.HasFlag(HistoryMenuOperations.DiffChangeset))
menu.AddItem(mDiffChangesetMenuItemContent, false, DiffChangesetMenu_Click);
else
menu.AddDisabledItem(mDiffChangesetMenuItemContent, false);
menu.AddSeparator(string.Empty);
if (operations.HasFlag(HistoryMenuOperations.RevertTo))
menu.AddItem(mRevertToThisRevisionMenuItemContent, false, RevertToThisRevisionMenu_Click);
else
menu.AddDisabledItem(mRevertToThisRevisionMenuItemContent, false);
}
static HistoryMenuOperations GetMenuOperation(Event e)
{
if (Keyboard.IsControlOrCommandKeyPressed(e) && Keyboard.IsKeyPressed(e, KeyCode.D))
return HistoryMenuOperations.DiffWithPrevious;
return HistoryMenuOperations.None;
}
void ProcessMenuOperation(HistoryMenuOperations operationToExecute)
{
if (operationToExecute == HistoryMenuOperations.DiffWithPrevious)
{
DiffWithPreviousMenuItem_Click();
}
}
GUIContent GetNoActionMenuItemContent()
{
if (mNoActionMenuItemContent == null)
{
mNoActionMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.
Name.NoActionMenuItem));
}
return mNoActionMenuItemContent;
}
static string GetSelectedChangesetName(IMenuOperations menuOperations)
{
long selectedChangesetId = menuOperations.GetSelectedChangesetId();
if (selectedChangesetId == -1)
return string.Empty;
return selectedChangesetId.ToString();
}
void BuildComponents()
{
mOpenRevisionMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.HistoryMenuItemOpen));
mOpenRevisionWithMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.HistoryMenuItemOpenWith));
mSaveRevisionAsMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.SaveThisRevisionAs));
mDiffWithPreviousMenuItemContent = new GUIContent(string.Format("{0} {1}",
PlasticLocalization.GetString(PlasticLocalization.Name.HistoryMenuItemDiffWithPrevious),
GetPlasticShortcut.ForDiff()));
mDiffSelectedRevisionsMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.HistoryMenuItemDiffSelectedRevisions));
mDiffChangesetMenuItemContent = new GUIContent();
mRevertToThisRevisionMenuItemContent = new GUIContent(PlasticLocalization.
GetString(PlasticLocalization.Name.HistoryMenuItemRevertToThisRevision));
}
GenericMenu mMenu;
GUIContent mNoActionMenuItemContent;
GUIContent mOpenRevisionMenuItemContent;
GUIContent mOpenRevisionWithMenuItemContent;
GUIContent mSaveRevisionAsMenuItemContent;
GUIContent mDiffWithPreviousMenuItemContent;
GUIContent mDiffSelectedRevisionsMenuItemContent;
GUIContent mDiffChangesetMenuItemContent;
GUIContent mRevertToThisRevisionMenuItemContent;
readonly IOpenMenuOperations mOpenMenuOperations;
readonly IHistoryViewMenuOperations mOperations;
readonly IMenuOperations mMenuOperations;
}
}

View File

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

Some files were not shown because too many files have changed in this diff Show More