DiffPanel.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. using System.Collections.Generic;
  2. using UnityEditor;
  3. using UnityEditor.IMGUI.Controls;
  4. using UnityEngine;
  5. using Codice.Client.Commands;
  6. using Codice.Client.Common;
  7. using Codice.Client.Common.Threading;
  8. using Codice.CM.Common;
  9. using PlasticGui;
  10. using PlasticGui.WorkspaceWindow.Diff;
  11. using Unity.PlasticSCM.Editor.AssetUtils;
  12. using Unity.PlasticSCM.Editor.UI;
  13. using Unity.PlasticSCM.Editor.UI.Progress;
  14. using Unity.PlasticSCM.Editor.Views.Diff.Dialogs;
  15. using Unity.PlasticSCM.Editor.Tool;
  16. namespace Unity.PlasticSCM.Editor.Views.Diff
  17. {
  18. internal class DiffPanel :
  19. IDiffTreeViewMenuOperations,
  20. DiffTreeViewMenu.IMetaMenuOperations,
  21. UndeleteClientDiffsOperation.IGetRestorePathDialog
  22. {
  23. internal DiffPanel(
  24. WorkspaceInfo wkInfo,
  25. IWorkspaceWindow workspaceWindow,
  26. IViewSwitcher viewSwitcher,
  27. IHistoryViewLauncher historyViewLauncher,
  28. EditorWindow parentWindow,
  29. bool isGluonMode)
  30. {
  31. mWkInfo = wkInfo;
  32. mWorkspaceWindow = workspaceWindow;
  33. mViewSwitcher = viewSwitcher;
  34. mHistoryViewLauncher = historyViewLauncher;
  35. mParentWindow = parentWindow;
  36. mGuiMessage = new UnityPlasticGuiMessage(parentWindow);
  37. mIsGluonMode = isGluonMode;
  38. BuildComponents();
  39. mProgressControls = new ProgressControlsForViews();
  40. }
  41. internal void ClearInfo()
  42. {
  43. ClearData();
  44. mParentWindow.Repaint();
  45. }
  46. internal void UpdateInfo(
  47. MountPointWithPath mountWithPath,
  48. ChangesetInfo csetInfo)
  49. {
  50. FillData(mountWithPath, csetInfo);
  51. mParentWindow.Repaint();
  52. }
  53. internal void OnDisable()
  54. {
  55. mSearchField.downOrUpArrowKeyPressed -=
  56. SearchField_OnDownOrUpArrowKeyPressed;
  57. }
  58. internal void Update()
  59. {
  60. mProgressControls.UpdateProgress(mParentWindow);
  61. }
  62. internal void OnGUI()
  63. {
  64. EditorGUILayout.BeginVertical();
  65. DoActionsToolbar(
  66. mDiffs,
  67. mProgressControls,
  68. GetHeaderLabelText(mSelectedChangesetInfo),
  69. mIsSkipMergeTrackingButtonVisible,
  70. mIsSkipMergeTrackingButtonChecked,
  71. mSearchField,
  72. mDiffTreeView);
  73. DoDiffTreeViewArea(
  74. mDiffTreeView,
  75. mProgressControls.IsOperationRunning());
  76. if (mProgressControls.HasNotification())
  77. {
  78. DrawProgressForViews.ForNotificationArea(
  79. mProgressControls.ProgressData);
  80. }
  81. EditorGUILayout.EndVertical();
  82. }
  83. SelectedDiffsGroupInfo IDiffTreeViewMenuOperations.GetSelectedDiffsGroupInfo()
  84. {
  85. return SelectedDiffsGroupInfo.BuildFromSelectedNodes(
  86. DiffSelection.GetSelectedDiffsWithoutMeta(mDiffTreeView));
  87. }
  88. void IDiffTreeViewMenuOperations.Diff()
  89. {
  90. if (LaunchTool.ShowDownloadPlasticExeWindow(mIsGluonMode))
  91. return;
  92. ClientDiffInfo clientDiffInfo =
  93. DiffSelection.GetSelectedDiff(mDiffTreeView);
  94. DiffOperation.DiffClientDiff(
  95. mWkInfo,
  96. clientDiffInfo.DiffWithMount.Mount.Mount,
  97. clientDiffInfo.DiffWithMount.Difference,
  98. xDiffLauncher: null,
  99. imageDiffLauncher: null);
  100. }
  101. void IDiffTreeViewMenuOperations.History()
  102. {
  103. ClientDiffInfo clientDiffInfo =
  104. DiffSelection.GetSelectedDiff(mDiffTreeView);
  105. mHistoryViewLauncher.ShowHistoryView(
  106. clientDiffInfo.DiffWithMount.Mount.RepSpec,
  107. clientDiffInfo.DiffWithMount.Difference.RevInfo.ItemId,
  108. clientDiffInfo.DiffWithMount.Difference.Path,
  109. clientDiffInfo.DiffWithMount.Difference.IsDirectory);
  110. }
  111. void IDiffTreeViewMenuOperations.RevertChanges()
  112. {
  113. RevertClientDiffsOperation.RevertChanges(
  114. mWkInfo,
  115. DiffSelection.GetSelectedDiffs(mDiffTreeView),
  116. mWorkspaceWindow,
  117. mProgressControls,
  118. mGuiMessage,
  119. AfterRevertOrUndeleteOperation);
  120. }
  121. void IDiffTreeViewMenuOperations.Undelete()
  122. {
  123. UndeleteClientDiffsOperation.Undelete(
  124. mWkInfo,
  125. DiffSelection.GetSelectedDiffs(mDiffTreeView),
  126. mWorkspaceWindow,
  127. mProgressControls,
  128. this,
  129. mGuiMessage,
  130. AfterRevertOrUndeleteOperation);
  131. }
  132. void IDiffTreeViewMenuOperations.UndeleteToSpecifiedPaths()
  133. {
  134. UndeleteClientDiffsOperation.UndeleteToSpecifiedPaths(
  135. mWkInfo,
  136. DiffSelection.GetSelectedDiffs(mDiffTreeView),
  137. mWorkspaceWindow,
  138. mProgressControls,
  139. this,
  140. mGuiMessage,
  141. AfterRevertOrUndeleteOperation);
  142. }
  143. bool DiffTreeViewMenu.IMetaMenuOperations.SelectionHasMeta()
  144. {
  145. return mDiffTreeView.SelectionHasMeta();
  146. }
  147. void DiffTreeViewMenu.IMetaMenuOperations.DiffMeta()
  148. {
  149. if (LaunchTool.ShowDownloadPlasticExeWindow(mIsGluonMode))
  150. return;
  151. ClientDiffInfo clientDiffInfo =
  152. DiffSelection.GetSelectedDiff(mDiffTreeView);
  153. ClientDiffInfo clientDiffInfoMeta =
  154. mDiffTreeView.GetMetaDiff(clientDiffInfo);
  155. DiffOperation.DiffClientDiff(
  156. mWkInfo,
  157. clientDiffInfoMeta.DiffWithMount.Mount.Mount,
  158. clientDiffInfoMeta.DiffWithMount.Difference,
  159. xDiffLauncher: null,
  160. imageDiffLauncher: null);
  161. }
  162. GetRestorePathData
  163. UndeleteClientDiffsOperation.IGetRestorePathDialog.GetRestorePath(
  164. string wkPath, string restorePath, string explanation,
  165. bool isDirectory, bool showSkipButton)
  166. {
  167. return GetRestorePathDialog.GetRestorePath(
  168. wkPath, restorePath, explanation, isDirectory,
  169. showSkipButton, mParentWindow);
  170. }
  171. void DiffTreeViewMenu.IMetaMenuOperations.HistoryMeta()
  172. {
  173. ClientDiffInfo clientDiffInfo =
  174. DiffSelection.GetSelectedDiff(mDiffTreeView);
  175. ClientDiffInfo clientDiffInfoMeta =
  176. mDiffTreeView.GetMetaDiff(clientDiffInfo);
  177. mHistoryViewLauncher.ShowHistoryView(
  178. clientDiffInfoMeta.DiffWithMount.Mount.RepSpec,
  179. clientDiffInfoMeta.DiffWithMount.Difference.RevInfo.ItemId,
  180. clientDiffInfoMeta.DiffWithMount.Difference.Path,
  181. clientDiffInfoMeta.DiffWithMount.Difference.IsDirectory);
  182. }
  183. void SearchField_OnDownOrUpArrowKeyPressed()
  184. {
  185. mDiffTreeView.SetFocusAndEnsureSelectedItem();
  186. }
  187. void AfterRevertOrUndeleteOperation()
  188. {
  189. RefreshAsset.UnityAssetDatabase();
  190. mViewSwitcher.ShowPendingChanges();
  191. }
  192. void ClearData()
  193. {
  194. mSelectedMountWithPath = null;
  195. mSelectedChangesetInfo = null;
  196. mDiffs = null;
  197. ClearDiffs();
  198. }
  199. void FillData(
  200. MountPointWithPath mountWithPath,
  201. ChangesetInfo csetInfo)
  202. {
  203. mSelectedMountWithPath = mountWithPath;
  204. mSelectedChangesetInfo = csetInfo;
  205. ((IProgressControls)mProgressControls).ShowProgress(
  206. PlasticLocalization.GetString(PlasticLocalization.Name.Loading));
  207. mIsSkipMergeTrackingButtonVisible = false;
  208. IThreadWaiter waiter = ThreadWaiter.GetWaiter(100);
  209. waiter.Execute(
  210. /*threadOperationDelegate*/ delegate
  211. {
  212. mDiffs = PlasticGui.Plastic.API.GetChangesetDifferences(
  213. mountWithPath, csetInfo);
  214. },
  215. /*afterOperationDelegate*/ delegate
  216. {
  217. ((IProgressControls)mProgressControls).HideProgress();
  218. if (waiter.Exception != null)
  219. {
  220. ExceptionsHandler.DisplayException(waiter.Exception);
  221. return;
  222. }
  223. if (mSelectedMountWithPath != mountWithPath ||
  224. mSelectedChangesetInfo != csetInfo)
  225. return;
  226. if (mDiffs == null || mDiffs.Count == 0)
  227. {
  228. ClearDiffs();
  229. return;
  230. }
  231. mIsSkipMergeTrackingButtonVisible =
  232. ClientDiffList.HasMerges(mDiffs);
  233. bool skipMergeTracking =
  234. mIsSkipMergeTrackingButtonVisible &&
  235. mIsSkipMergeTrackingButtonChecked;
  236. UpdateDiffTreeView(
  237. mDiffs, skipMergeTracking, mDiffTreeView);
  238. });
  239. }
  240. void ClearDiffs()
  241. {
  242. mIsSkipMergeTrackingButtonVisible = false;
  243. ClearDiffTreeView(mDiffTreeView);
  244. ((IProgressControls)mProgressControls).ShowNotification(
  245. PlasticLocalization.GetString(PlasticLocalization.Name.NoContentToCompare));
  246. }
  247. static void ClearDiffTreeView(
  248. DiffTreeView diffTreeView)
  249. {
  250. diffTreeView.ClearModel();
  251. diffTreeView.Reload();
  252. }
  253. static void UpdateDiffTreeView(
  254. List<ClientDiff> diffs,
  255. bool skipMergeTracking,
  256. DiffTreeView diffTreeView)
  257. {
  258. diffTreeView.BuildModel(
  259. diffs, skipMergeTracking);
  260. diffTreeView.Refilter();
  261. diffTreeView.Sort();
  262. diffTreeView.Reload();
  263. }
  264. static string GetHeaderLabelText(
  265. ChangesetInfo changesetInfo)
  266. {
  267. if (changesetInfo == null)
  268. return PlasticLocalization.GetString(PlasticLocalization.Name.ChangesLabelPlural);
  269. return string.Format(
  270. PlasticLocalization.GetString(PlasticLocalization.Name.ChangesOfChangeset),
  271. changesetInfo.ChangesetId);
  272. }
  273. void DoActionsToolbar(
  274. List<ClientDiff> diffs,
  275. ProgressControlsForViews progressControls,
  276. string headerLabelText,
  277. bool isSkipMergeTrackingButtonVisible,
  278. bool isSkipMergeTrackingButtonChecked,
  279. SearchField searchField,
  280. DiffTreeView diffTreeView)
  281. {
  282. EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
  283. GUILayout.Label(headerLabelText,
  284. UnityStyles.DiffPanel.HeaderLabel);
  285. if (progressControls.IsOperationRunning())
  286. {
  287. DrawProgressForViews.ForIndeterminateProgress(
  288. progressControls.ProgressData);
  289. }
  290. GUILayout.FlexibleSpace();
  291. if (isSkipMergeTrackingButtonVisible)
  292. {
  293. DoSkipMergeTrackingButton(
  294. diffs,
  295. isSkipMergeTrackingButtonChecked,
  296. diffTreeView);
  297. }
  298. DrawSearchField.For(
  299. searchField,
  300. diffTreeView,
  301. UnityConstants.SEARCH_FIELD_WIDTH);
  302. EditorGUILayout.EndHorizontal();
  303. }
  304. void DoSkipMergeTrackingButton(
  305. List<ClientDiff> diffs,
  306. bool isSkipMergeTrackingButtonChecked,
  307. DiffTreeView diffTreeView)
  308. {
  309. bool wasChecked = isSkipMergeTrackingButtonChecked;
  310. GUIContent buttonContent = new GUIContent(
  311. PlasticLocalization.GetString(
  312. PlasticLocalization.Name.SkipDiffMergeTracking));
  313. GUIStyle buttonStyle = EditorStyles.toolbarButton;
  314. float buttonWidth = buttonStyle.CalcSize(buttonContent).x + 10;
  315. Rect toggleRect = GUILayoutUtility.GetRect(
  316. buttonContent, buttonStyle, GUILayout.Width(buttonWidth));
  317. bool isChecked = GUI.Toggle(
  318. toggleRect, wasChecked, buttonContent, buttonStyle);
  319. if (wasChecked == isChecked)
  320. return;
  321. UpdateDiffTreeView(diffs, isChecked, diffTreeView);
  322. mIsSkipMergeTrackingButtonChecked = isChecked;
  323. }
  324. static void DoDiffTreeViewArea(
  325. DiffTreeView diffTreeView,
  326. bool isOperationRunning)
  327. {
  328. GUI.enabled = !isOperationRunning;
  329. Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
  330. diffTreeView.OnGUI(rect);
  331. GUI.enabled = true;
  332. }
  333. void BuildComponents()
  334. {
  335. mSearchField = new SearchField();
  336. mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
  337. mDiffTreeView = new DiffTreeView(
  338. new DiffTreeViewMenu(this, this, mIsGluonMode));
  339. mDiffTreeView.Reload();
  340. }
  341. volatile List<ClientDiff> mDiffs;
  342. bool mIsSkipMergeTrackingButtonVisible;
  343. bool mIsSkipMergeTrackingButtonChecked;
  344. SearchField mSearchField;
  345. DiffTreeView mDiffTreeView;
  346. ChangesetInfo mSelectedChangesetInfo;
  347. MountPointWithPath mSelectedMountWithPath;
  348. readonly ProgressControlsForViews mProgressControls;
  349. readonly GuiMessage.IGuiMessage mGuiMessage;
  350. readonly EditorWindow mParentWindow;
  351. readonly IWorkspaceWindow mWorkspaceWindow;
  352. readonly IHistoryViewLauncher mHistoryViewLauncher;
  353. readonly IViewSwitcher mViewSwitcher;
  354. readonly WorkspaceInfo mWkInfo;
  355. readonly bool mIsGluonMode;
  356. }
  357. }