IncomingChangesTab.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEditor;
  4. using UnityEngine;
  5. using Codice.Client.BaseCommands;
  6. using Codice.Client.BaseCommands.Merge;
  7. using Codice.Client.Commands;
  8. using Codice.Client.Common;
  9. using Codice.Client.Common.FsNodeReaders;
  10. using Codice.Client.Common.Threading;
  11. using Codice.CM.Common;
  12. using Codice.CM.Common.Merge;
  13. using PlasticGui;
  14. using PlasticGui.WorkspaceWindow;
  15. using PlasticGui.WorkspaceWindow.BranchExplorer;
  16. using PlasticGui.WorkspaceWindow.Diff;
  17. using PlasticGui.WorkspaceWindow.IncomingChanges;
  18. using PlasticGui.WorkspaceWindow.Merge;
  19. using Unity.PlasticSCM.Editor.AssetUtils;
  20. using Unity.PlasticSCM.Editor.UI;
  21. using Unity.PlasticSCM.Editor.UI.Progress;
  22. using Unity.PlasticSCM.Editor.UI.Tree;
  23. using Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer.DirectoryConflicts;
  24. using Unity.PlasticSCM.Editor.Tool;
  25. namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
  26. {
  27. internal class IncomingChangesTab :
  28. IIncomingChangesTab,
  29. IRefreshableView,
  30. MergeViewLogic.IMergeView,
  31. MergeChangesTree.IGetConflictResolution,
  32. IIncomingChangesViewMenuOperations,
  33. IncomingChangesViewMenu.IMetaMenuOperations
  34. {
  35. internal IncomingChangesTab(
  36. WorkspaceInfo wkInfo,
  37. IWorkspaceWindow workspaceWindow,
  38. IViewSwitcher switcher,
  39. NewIncomingChangesUpdater newIncomingChangesUpdater,
  40. EditorWindow parentWindow)
  41. {
  42. mWkInfo = wkInfo;
  43. mWorkspaceWindow = workspaceWindow;
  44. mSwitcher = switcher;
  45. mNewIncomingChangesUpdater = newIncomingChangesUpdater;
  46. mParentWindow = parentWindow;
  47. mGuiMessage = new UnityPlasticGuiMessage(parentWindow);
  48. BuildComponents(mWkInfo);
  49. mProgressControls = new ProgressControlsForViews();
  50. PlasticNotifier plasticNotifier = new PlasticNotifier();
  51. mMergeController = new MergeController(
  52. mWkInfo,
  53. null,
  54. null,
  55. EnumMergeType.IncomingMerge,
  56. true,
  57. plasticNotifier,
  58. null);
  59. mMergeViewLogic = new MergeViewLogic(
  60. mWkInfo,
  61. EnumMergeType.IncomingMerge,
  62. true,
  63. mMergeController,
  64. plasticNotifier,
  65. ShowIncomingChangesFrom.NotificationBar,
  66. null,
  67. mNewIncomingChangesUpdater,
  68. null,
  69. this,
  70. NewChangesInWk.Build(mWkInfo, new BuildWorkspacekIsRelevantNewChange()),
  71. mProgressControls,
  72. null);
  73. ((IRefreshableView)this).Refresh();
  74. }
  75. bool IIncomingChangesTab.IsVisible{ get; set; }
  76. void IIncomingChangesTab.OnDisable()
  77. {
  78. TreeHeaderSettings.Save(
  79. mIncomingChangesTreeView.multiColumnHeader.state,
  80. UnityConstants.DEVELOPER_INCOMING_CHANGES_TABLE_SETTINGS_NAME);
  81. }
  82. void IIncomingChangesTab.Update()
  83. {
  84. mProgressControls.UpdateProgress(mParentWindow);
  85. }
  86. void IIncomingChangesTab.OnGUI()
  87. {
  88. if (Event.current.type == EventType.Layout)
  89. {
  90. mHasPendingDirectoryConflicts =
  91. MergeTreeResultParser.GetUnsolvedDirectoryConflictsCount(mResultConflicts) > 0;
  92. mIsOperationRunning = mProgressControls.IsOperationRunning();
  93. }
  94. DoActionsToolbar(
  95. mIsProcessMergesButtonVisible,
  96. mIsCancelMergesButtonVisible,
  97. mIsProcessMergesButtonEnabled,
  98. mIsCancelMergesButtonEnabled,
  99. mProcessMergesButtonText,
  100. mHasPendingDirectoryConflicts,
  101. mIsOperationRunning,
  102. mWorkspaceWindow,
  103. mMergeViewLogic,
  104. mProgressControls.ProgressData);
  105. DoFileConflictsArea(
  106. mIncomingChangesTreeView,
  107. mResultConflicts,
  108. mSolvedFileConflicts,
  109. mRootMountPoint,
  110. mIsOperationRunning);
  111. List<MergeChangeInfo> selectedIncomingChanges =
  112. mIncomingChangesTreeView.GetSelectedIncomingChanges();
  113. if (GetSelectedIncomingChangesGroupInfo.For(
  114. selectedIncomingChanges).IsDirectoryConflictsSelection &&
  115. !Mouse.IsRightMouseButtonPressed(Event.current))
  116. {
  117. DoDirectoryConflictResolutionPanel(
  118. selectedIncomingChanges,
  119. new Action<MergeChangeInfo>(ResolveDirectoryConflict),
  120. mConflictResolutionStates);
  121. }
  122. if (mIsMessageLabelVisible)
  123. DoInfoMessageArea(mMessageLabelText);
  124. if (mIsErrorMessageLabelVisible)
  125. DoErrorMessageArea(mErrorMessageLabelText);
  126. if (mProgressControls.HasNotification())
  127. {
  128. DrawProgressForViews.ForNotificationArea(
  129. mProgressControls.ProgressData);
  130. }
  131. }
  132. void IIncomingChangesTab.AutoRefresh()
  133. {
  134. BranchInfo workingBranch = null;
  135. IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
  136. waiter.Execute(
  137. /*threadOperationDelegate*/ delegate
  138. {
  139. workingBranch = OverlappedCalculator.GetWorkingBranch(
  140. mWkInfo.ClientPath);
  141. },
  142. /*afterOperationDelegate*/ delegate
  143. {
  144. if (waiter.Exception != null)
  145. {
  146. ExceptionsHandler.DisplayException(waiter.Exception);
  147. return;
  148. }
  149. mMergeController.UpdateMergeObjectInfoIfNeeded(workingBranch);
  150. mMergeViewLogic.AutoRefresh();
  151. });
  152. }
  153. void IRefreshableView.Refresh()
  154. {
  155. BranchInfo workingBranch = null;
  156. IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
  157. waiter.Execute(
  158. /*threadOperationDelegate*/ delegate
  159. {
  160. workingBranch = OverlappedCalculator.GetWorkingBranch(
  161. mWkInfo.ClientPath);
  162. },
  163. /*afterOperationDelegate*/ delegate
  164. {
  165. if (waiter.Exception != null)
  166. {
  167. ExceptionsHandler.DisplayException(waiter.Exception);
  168. return;
  169. }
  170. mMergeController.UpdateMergeObjectInfoIfNeeded(workingBranch);
  171. mMergeViewLogic.Refresh();
  172. });
  173. }
  174. void MergeViewLogic.IMergeView.UpdateData(
  175. MergeTreeResult resultConflicts,
  176. ExplainMergeData explainMergeData,
  177. MergeSolvedFileConflicts solvedFileConflicts,
  178. MountPointWithPath rootMountPoint,
  179. bool isIncomingMerge,
  180. bool isMergeTo,
  181. bool isUpdateMerge,
  182. bool mergeHasFinished)
  183. {
  184. HideMessage();
  185. ShowProcessMergesButton(MergeViewTexts.GetProcessMergeButtonText(
  186. MergeTreeResultParser.GetFileConflictsCount(resultConflicts) > 0,
  187. true));
  188. mResultConflicts = resultConflicts;
  189. mSolvedFileConflicts = solvedFileConflicts;
  190. mRootMountPoint = rootMountPoint;
  191. mConflictResolutionStates.Clear();
  192. UpdateFileConflictsTree(
  193. MergeChangesTree.BuildForIncomingChangesView(
  194. mResultConflicts,
  195. this,
  196. mRootMountPoint),
  197. mIncomingChangesTreeView);
  198. }
  199. void MergeViewLogic.IMergeView.UpdateSolvedFileConflicts(
  200. MergeSolvedFileConflicts solvedFileConflicts)
  201. {
  202. mIncomingChangesTreeView.UpdateSolvedFileConflicts(
  203. solvedFileConflicts);
  204. }
  205. void MergeViewLogic.IMergeView.ShowMessage(
  206. string title,
  207. string message,
  208. bool isErrorMessage)
  209. {
  210. if (isErrorMessage)
  211. {
  212. mErrorMessageLabelText = message;
  213. mIsErrorMessageLabelVisible = true;
  214. return;
  215. }
  216. mMessageLabelText = message;
  217. mIsMessageLabelVisible = true;
  218. }
  219. string MergeViewLogic.IMergeView.GetComments(out bool bCancel)
  220. {
  221. bCancel = false;
  222. return string.Empty;
  223. }
  224. void MergeViewLogic.IMergeView.DisableProcessMergesButton()
  225. {
  226. mIsProcessMergesButtonEnabled = false;
  227. }
  228. void MergeViewLogic.IMergeView.ShowCancelButton()
  229. {
  230. mIsCancelMergesButtonEnabled = true;
  231. mIsCancelMergesButtonVisible = true;
  232. }
  233. void MergeViewLogic.IMergeView.HideCancelButton()
  234. {
  235. mIsCancelMergesButtonEnabled = false;
  236. mIsCancelMergesButtonVisible = false;
  237. }
  238. SelectedIncomingChangesGroupInfo IIncomingChangesViewMenuOperations.GetSelectedIncomingChangesGroupInfo()
  239. {
  240. return IncomingChangesSelection.GetSelectedGroupInfo(mIncomingChangesTreeView);
  241. }
  242. string MergeChangesTree.IGetConflictResolution.GetConflictResolution(
  243. DirectoryConflict conflict)
  244. {
  245. return mMergeViewLogic.GetConflictResolution(conflict);
  246. }
  247. void IIncomingChangesViewMenuOperations.MergeContributors()
  248. {
  249. List<string> selectedPaths = IncomingChangesSelection.
  250. GetPathsFromSelectedFileConflictsIncludingMeta(
  251. mIncomingChangesTreeView);
  252. mMergeViewLogic.ProcessMerges(
  253. mWorkspaceWindow,
  254. mSwitcher,
  255. mGuiMessage,
  256. selectedPaths,
  257. MergeContributorType.MergeContributors,
  258. RefreshAsset.UnityAssetDatabase);
  259. }
  260. void IIncomingChangesViewMenuOperations.MergeKeepingSourceChanges()
  261. {
  262. List<string> selectedPaths = IncomingChangesSelection.
  263. GetPathsFromSelectedFileConflictsIncludingMeta(
  264. mIncomingChangesTreeView);
  265. mMergeViewLogic.ProcessMerges(
  266. mWorkspaceWindow,
  267. mSwitcher,
  268. mGuiMessage,
  269. selectedPaths,
  270. MergeContributorType.KeepSource,
  271. RefreshAsset.UnityAssetDatabase);
  272. }
  273. void IIncomingChangesViewMenuOperations.MergeKeepingWorkspaceChanges()
  274. {
  275. List<string> selectedPaths = IncomingChangesSelection.
  276. GetPathsFromSelectedFileConflictsIncludingMeta(
  277. mIncomingChangesTreeView);
  278. mMergeViewLogic.ProcessMerges(
  279. mWorkspaceWindow,
  280. mSwitcher,
  281. mGuiMessage,
  282. selectedPaths,
  283. MergeContributorType.KeepDestination,
  284. RefreshAsset.UnityAssetDatabase);
  285. }
  286. void IIncomingChangesViewMenuOperations.DiffYoursWithIncoming()
  287. {
  288. MergeChangeInfo incomingChange = IncomingChangesSelection.
  289. GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
  290. if (incomingChange == null)
  291. return;
  292. DiffYoursWithIncoming(
  293. incomingChange,
  294. mWkInfo);
  295. }
  296. void IIncomingChangesViewMenuOperations.DiffIncomingChanges()
  297. {
  298. MergeChangeInfo incomingChange = IncomingChangesSelection.
  299. GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
  300. if (incomingChange == null)
  301. return;
  302. DiffIncomingChanges(
  303. incomingChange,
  304. mWkInfo);
  305. }
  306. void IncomingChangesViewMenu.IMetaMenuOperations.DiffIncomingChanges()
  307. {
  308. MergeChangeInfo incomingChange = IncomingChangesSelection.
  309. GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
  310. if (incomingChange == null)
  311. return;
  312. DiffIncomingChanges(
  313. mIncomingChangesTreeView.GetMetaChange(incomingChange),
  314. mWkInfo);
  315. }
  316. void IncomingChangesViewMenu.IMetaMenuOperations.DiffYoursWithIncoming()
  317. {
  318. MergeChangeInfo incomingChange = IncomingChangesSelection.
  319. GetSingleSelectedIncomingChange(mIncomingChangesTreeView);
  320. if (incomingChange == null)
  321. return;
  322. DiffYoursWithIncoming(
  323. mIncomingChangesTreeView.GetMetaChange(incomingChange),
  324. mWkInfo);
  325. }
  326. bool IncomingChangesViewMenu.IMetaMenuOperations.SelectionHasMeta()
  327. {
  328. return mIncomingChangesTreeView.SelectionHasMeta();
  329. }
  330. static void DiffYoursWithIncoming(
  331. MergeChangeInfo incomingChange,
  332. WorkspaceInfo wkInfo)
  333. {
  334. if (LaunchTool.ShowDownloadPlasticExeWindow(false))
  335. return;
  336. DiffOperation.DiffYoursWithIncoming(
  337. wkInfo,
  338. incomingChange.GetMount(),
  339. incomingChange.GetRevision(),
  340. incomingChange.GetPath(),
  341. xDiffLauncher: null,
  342. imageDiffLauncher: null);
  343. }
  344. static void DiffIncomingChanges(
  345. MergeChangeInfo incomingChange,
  346. WorkspaceInfo wkInfo)
  347. {
  348. if (LaunchTool.ShowDownloadPlasticExeWindow(false))
  349. return;
  350. DiffOperation.DiffRevisions(
  351. wkInfo,
  352. incomingChange.GetMount().RepSpec,
  353. incomingChange.GetBaseRevision(),
  354. incomingChange.GetRevision(),
  355. incomingChange.GetPath(),
  356. incomingChange.GetPath(),
  357. true,
  358. xDiffLauncher: null,
  359. imageDiffLauncher: null);
  360. }
  361. void ShowProcessMergesButton(string processMergesButtonText)
  362. {
  363. mProcessMergesButtonText = processMergesButtonText;
  364. mIsProcessMergesButtonEnabled = true;
  365. mIsProcessMergesButtonVisible = true;
  366. }
  367. void HideMessage()
  368. {
  369. mMessageLabelText = string.Empty;
  370. mIsMessageLabelVisible = false;
  371. mErrorMessageLabelText = string.Empty;
  372. mIsErrorMessageLabelVisible = false;
  373. }
  374. static void DoDirectoryConflictResolutionPanel(
  375. List<MergeChangeInfo> selectedChangeInfos,
  376. Action<MergeChangeInfo> resolveDirectoryConflictAction,
  377. Dictionary<DirectoryConflict, ConflictResolutionState> conflictResolutionStates)
  378. {
  379. MergeChangeInfo selectedDirectoryConflict = selectedChangeInfos[0];
  380. if (selectedDirectoryConflict.DirectoryConflict.IsResolved())
  381. return;
  382. DirectoryConflictUserInfo conflictUserInfo;
  383. DirectoryConflictAction[] conflictActions;
  384. DirectoryConflictResolutionInfo.FromDirectoryConflict(
  385. selectedDirectoryConflict.GetMount(),
  386. selectedDirectoryConflict.DirectoryConflict,
  387. out conflictUserInfo,
  388. out conflictActions);
  389. ConflictResolutionState conflictResolutionState = GetConflictResolutionState(
  390. selectedDirectoryConflict.DirectoryConflict,
  391. conflictActions,
  392. conflictResolutionStates);
  393. int pendingSelectedConflictsCount = GetPendingConflictsCount(
  394. selectedChangeInfos);
  395. DrawDirectoryResolutionPanel.ForConflict(
  396. selectedDirectoryConflict,
  397. (pendingSelectedConflictsCount <= 1) ? 0 : pendingSelectedConflictsCount - 1,
  398. conflictUserInfo,
  399. conflictActions,
  400. resolveDirectoryConflictAction,
  401. ref conflictResolutionState);
  402. }
  403. void ResolveDirectoryConflict(MergeChangeInfo conflict)
  404. {
  405. ConflictResolutionState state;
  406. if (!mConflictResolutionStates.TryGetValue(conflict.DirectoryConflict, out state))
  407. return;
  408. List<DirectoryConflictResolutionData> conflictResolutions =
  409. new List<DirectoryConflictResolutionData>();
  410. AddConflictResolution(
  411. conflict,
  412. state.ResolveAction,
  413. state.RenameValue,
  414. conflictResolutions);
  415. MergeChangeInfo metaConflict =
  416. mIncomingChangesTreeView.GetMetaChange(conflict);
  417. if (metaConflict != null)
  418. {
  419. AddConflictResolution(
  420. metaConflict,
  421. state.ResolveAction,
  422. MetaPath.GetMetaPath(state.RenameValue),
  423. conflictResolutions);
  424. }
  425. if (state.IsApplyActionsForNextConflictsChecked)
  426. {
  427. foreach (MergeChangeInfo otherConflict in mIncomingChangesTreeView.GetSelectedIncomingChanges())
  428. {
  429. AddConflictResolution(
  430. otherConflict,
  431. state.ResolveAction,
  432. state.RenameValue,
  433. conflictResolutions);
  434. }
  435. }
  436. mMergeViewLogic.ResolveDirectoryConflicts(conflictResolutions);
  437. }
  438. static void AddConflictResolution(
  439. MergeChangeInfo conflict,
  440. DirectoryConflictResolveActions resolveAction,
  441. string renameValue,
  442. List<DirectoryConflictResolutionData> conflictResolutions)
  443. {
  444. conflictResolutions.Add(new DirectoryConflictResolutionData(
  445. conflict.DirectoryConflict,
  446. conflict.Xlink,
  447. conflict.GetMount().Mount,
  448. resolveAction,
  449. renameValue));
  450. }
  451. void DoActionsToolbar(
  452. bool isProcessMergesButtonVisible,
  453. bool isCancelMergesButtonVisible,
  454. bool isProcessMergesButtonEnabled,
  455. bool isCancelMergesButtonEnabled,
  456. string processMergesButtonText,
  457. bool hasPendingDirectoryConflictsCount,
  458. bool isOperationRunning,
  459. IWorkspaceWindow workspaceWindow,
  460. MergeViewLogic mergeViewLogic,
  461. ProgressControlsForViews.Data progressData)
  462. {
  463. GUIStyle guiStyle = new GUIStyle();
  464. guiStyle.margin = new RectOffset(5, 5, 5, 5);
  465. EditorGUILayout.BeginHorizontal(guiStyle);
  466. if (isProcessMergesButtonVisible)
  467. {
  468. DoProcessMergesButton(
  469. isProcessMergesButtonEnabled && !hasPendingDirectoryConflictsCount,
  470. processMergesButtonText,
  471. mSwitcher,
  472. workspaceWindow,
  473. mGuiMessage,
  474. mergeViewLogic);
  475. }
  476. if (isCancelMergesButtonVisible)
  477. {
  478. DoCancelMergesButton(
  479. isCancelMergesButtonEnabled,
  480. mergeViewLogic);
  481. }
  482. if (hasPendingDirectoryConflictsCount)
  483. {
  484. GUILayout.Space(5);
  485. DoWarningMessage();
  486. }
  487. if (isOperationRunning)
  488. {
  489. DrawProgressForViews.ForIndeterminateProgress(
  490. progressData);
  491. }
  492. GUILayout.FlexibleSpace();
  493. DoRefreshButton(
  494. !isOperationRunning,
  495. mergeViewLogic);
  496. EditorGUILayout.EndHorizontal();
  497. }
  498. static void DoFileConflictsArea(
  499. IncomingChangesTreeView incomingChangesTreeView,
  500. MergeTreeResult conflicts,
  501. MergeSolvedFileConflicts solvedConflicts,
  502. MountPointWithPath mount,
  503. bool isOperationRunning)
  504. {
  505. DoConflictsHeader(
  506. conflicts,
  507. solvedConflicts,
  508. mount);
  509. DoConflictsTree(
  510. incomingChangesTreeView,
  511. isOperationRunning);
  512. }
  513. static void DoConflictsTree(
  514. IncomingChangesTreeView incomingChangesTreeView,
  515. bool isOperationRunning)
  516. {
  517. GUI.enabled = !isOperationRunning;
  518. Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
  519. incomingChangesTreeView.OnGUI(rect);
  520. GUI.enabled = true;
  521. }
  522. static void DoConflictsHeader(
  523. MergeTreeResult conflicts,
  524. MergeSolvedFileConflicts solvedFileConflicts,
  525. MountPointWithPath mount)
  526. {
  527. if (conflicts == null || mount == null)
  528. return;
  529. EditorGUILayout.BeginHorizontal();
  530. DoDirectoryConflictsHeader(conflicts);
  531. DoFileConflictsHeader(
  532. conflicts,
  533. solvedFileConflicts,
  534. mount);
  535. GUILayout.FlexibleSpace();
  536. EditorGUILayout.EndHorizontal();
  537. }
  538. static void DoDirectoryConflictsHeader(MergeTreeResult conflicts)
  539. {
  540. int directoryConflictsCount =
  541. MergeTreeResultParser.GetDirectoryConflictsCount(conflicts);
  542. int pendingDirectoryConflictsCount =
  543. MergeTreeResultParser.GetUnsolvedDirectoryConflictsCount(
  544. conflicts);
  545. if (directoryConflictsCount == 0)
  546. return;
  547. GUIStyle pendingDirectoryConflictsOfTotalStyle =
  548. pendingDirectoryConflictsCount > 0 ?
  549. UnityStyles.IncomingChangesTab.RedPendingConflictsOfTotalLabel :
  550. UnityStyles.IncomingChangesTab.GreenPendingConflictsOfTotalLabel;
  551. GUILayout.Label(
  552. string.Format("{0}/{1}", pendingDirectoryConflictsCount, directoryConflictsCount),
  553. pendingDirectoryConflictsOfTotalStyle);
  554. GUILayout.Label(
  555. MergeViewTexts.GetDirectoryConflictsUnsolvedCaption(directoryConflictsCount),
  556. UnityStyles.IncomingChangesTab.PendingConflictsLabel);
  557. }
  558. static void DoFileConflictsHeader(
  559. MergeTreeResult conflicts,
  560. MergeSolvedFileConflicts solvedFileConflicts,
  561. MountPointWithPath mount)
  562. {
  563. int fileConflictsCount = MergeTreeResultParser.GetFileConflictsCount(conflicts);
  564. int pendingFileConflictsCount = MergeTreeResultParser.GetUnsolvedFileConflictsCount(
  565. conflicts, mount.Id, solvedFileConflicts);
  566. GUIStyle pendingFileConflictsOfTotalStyle =
  567. pendingFileConflictsCount > 0 ?
  568. UnityStyles.IncomingChangesTab.RedPendingConflictsOfTotalLabel :
  569. UnityStyles.IncomingChangesTab.GreenPendingConflictsOfTotalLabel;
  570. GUILayout.Label(
  571. string.Format("{0}/{1}", pendingFileConflictsCount, fileConflictsCount),
  572. pendingFileConflictsOfTotalStyle);
  573. GUILayout.Label(
  574. MergeViewTexts.GetFileConflictsCaption(fileConflictsCount, true),
  575. UnityStyles.IncomingChangesTab.PendingConflictsLabel);
  576. GUILayout.Space(5);
  577. GUILayout.Label(
  578. MergeViewTexts.GetChangesToApplyCaption(
  579. MergeTreeResultParser.GetChangesToApplySummary(conflicts)),
  580. UnityStyles.IncomingChangesTab.ChangesToApplySummaryLabel);
  581. }
  582. static void AfterProcessMerges()
  583. {
  584. EditorWindow.GetWindow<PlasticWindow>().
  585. mNotificationDrawer.Notify("Project successfully updated",
  586. UnityEditor.MessageType.None,
  587. Images.Name.StepOk);
  588. RefreshAsset.UnityAssetDatabase();
  589. }
  590. static void DoProcessMergesButton(
  591. bool isEnabled,
  592. string processMergesButtonText,
  593. IViewSwitcher switcher,
  594. IWorkspaceWindow workspaceWindow,
  595. GuiMessage.IGuiMessage guiMessage,
  596. MergeViewLogic mergeViewLogic)
  597. {
  598. GUI.enabled = isEnabled;
  599. if (DrawActionButton.For(processMergesButtonText))
  600. {
  601. mergeViewLogic.ProcessMerges(
  602. workspaceWindow,
  603. switcher,
  604. guiMessage,
  605. new List<string>(),
  606. MergeContributorType.MergeContributors,
  607. AfterProcessMerges);
  608. }
  609. GUI.enabled = true;
  610. }
  611. void DoCancelMergesButton(
  612. bool isEnabled,
  613. MergeViewLogic mergeViewLogic)
  614. {
  615. GUI.enabled = isEnabled;
  616. if (DrawActionButton.For(PlasticLocalization.GetString(
  617. PlasticLocalization.Name.CancelButton)))
  618. {
  619. mergeViewLogic.Cancel();
  620. mIsCancelMergesButtonEnabled = false;
  621. }
  622. GUI.enabled = true;
  623. }
  624. static void DoWarningMessage()
  625. {
  626. string label = PlasticLocalization.GetString(PlasticLocalization.Name.SolveConflictsInLable);
  627. GUILayout.Label(
  628. new GUIContent(label, Images.GetWarnIcon()),
  629. UnityStyles.IncomingChangesTab.HeaderWarningLabel);
  630. }
  631. static void DoRefreshButton(
  632. bool isEnabled,
  633. MergeViewLogic mergeViewLogic)
  634. {
  635. GUI.enabled = isEnabled;
  636. if (GUILayout.Button(new GUIContent(
  637. Images.GetRefreshIcon())))
  638. mergeViewLogic.Refresh();
  639. GUI.enabled = true;
  640. }
  641. void UpdateFileConflictsTree(
  642. MergeChangesTree incomingChangesTree,
  643. IncomingChangesTreeView incomingChangesTreeView)
  644. {
  645. UnityIncomingChangesTree unityIncomingChangesTree = null;
  646. IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
  647. waiter.Execute(
  648. /*threadOperationDelegate*/ delegate
  649. {
  650. unityIncomingChangesTree = UnityIncomingChangesTree.BuildIncomingChangeCategories(
  651. incomingChangesTree);
  652. incomingChangesTree.ResolveUserNames(
  653. new MergeChangesTree.ResolveUserName());
  654. },
  655. /*afterOperationDelegate*/ delegate
  656. {
  657. incomingChangesTreeView.BuildModel(unityIncomingChangesTree);
  658. incomingChangesTreeView.Sort();
  659. incomingChangesTreeView.Reload();
  660. incomingChangesTreeView.SelectFirstUnsolvedDirectoryConflict();
  661. });
  662. }
  663. static void DoInfoMessageArea(string message)
  664. {
  665. EditorGUILayout.BeginHorizontal();
  666. EditorGUILayout.HelpBox(message, MessageType.Info);
  667. EditorGUILayout.EndHorizontal();
  668. }
  669. static void DoErrorMessageArea(string message)
  670. {
  671. EditorGUILayout.BeginHorizontal();
  672. EditorGUILayout.HelpBox(message, MessageType.Error);
  673. EditorGUILayout.EndHorizontal();
  674. }
  675. void BuildComponents(WorkspaceInfo wkInfo)
  676. {
  677. IncomingChangesTreeHeaderState incomingChangesHeaderState =
  678. IncomingChangesTreeHeaderState.GetDefault();
  679. TreeHeaderSettings.Load(incomingChangesHeaderState,
  680. UnityConstants.DEVELOPER_INCOMING_CHANGES_TABLE_SETTINGS_NAME,
  681. (int)IncomingChangesTreeColumn.Path, true);
  682. mIncomingChangesTreeView = new IncomingChangesTreeView(
  683. wkInfo, incomingChangesHeaderState,
  684. IncomingChangesTreeHeaderState.GetColumnNames(),
  685. new IncomingChangesViewMenu(this, this));
  686. mIncomingChangesTreeView.Reload();
  687. }
  688. static ConflictResolutionState GetConflictResolutionState(
  689. DirectoryConflict directoryConflict,
  690. DirectoryConflictAction[] conflictActions,
  691. Dictionary<DirectoryConflict, ConflictResolutionState> conflictResoltionStates)
  692. {
  693. ConflictResolutionState result;
  694. if (conflictResoltionStates.TryGetValue(directoryConflict, out result))
  695. return result;
  696. result = ConflictResolutionState.Build(directoryConflict, conflictActions);
  697. conflictResoltionStates.Add(directoryConflict, result);
  698. return result;
  699. }
  700. static int GetPendingConflictsCount(
  701. List<MergeChangeInfo> selectedChangeInfos)
  702. {
  703. int result = 0;
  704. foreach (MergeChangeInfo changeInfo in selectedChangeInfos)
  705. {
  706. if (changeInfo.DirectoryConflict.IsResolved())
  707. continue;
  708. result++;
  709. }
  710. return result;
  711. }
  712. bool mIsProcessMergesButtonVisible;
  713. bool mIsCancelMergesButtonVisible;
  714. bool mIsMessageLabelVisible;
  715. bool mIsErrorMessageLabelVisible;
  716. bool mIsProcessMergesButtonEnabled;
  717. bool mIsCancelMergesButtonEnabled;
  718. bool mHasPendingDirectoryConflicts;
  719. bool mIsOperationRunning;
  720. string mProcessMergesButtonText;
  721. string mMessageLabelText;
  722. string mErrorMessageLabelText;
  723. IncomingChangesTreeView mIncomingChangesTreeView;
  724. MergeTreeResult mResultConflicts;
  725. MergeSolvedFileConflicts mSolvedFileConflicts;
  726. MountPointWithPath mRootMountPoint;
  727. Dictionary<DirectoryConflict, ConflictResolutionState> mConflictResolutionStates =
  728. new Dictionary<DirectoryConflict, ConflictResolutionState>();
  729. readonly ProgressControlsForViews mProgressControls;
  730. readonly MergeViewLogic mMergeViewLogic;
  731. readonly MergeController mMergeController;
  732. readonly GuiMessage.IGuiMessage mGuiMessage;
  733. readonly EditorWindow mParentWindow;
  734. readonly NewIncomingChangesUpdater mNewIncomingChangesUpdater;
  735. readonly IViewSwitcher mSwitcher;
  736. readonly IWorkspaceWindow mWorkspaceWindow;
  737. readonly WorkspaceInfo mWkInfo;
  738. }
  739. }