PendingChangesTab.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEditor;
  4. using UnityEditor.IMGUI.Controls;
  5. using UnityEngine;
  6. using Codice.Client.BaseCommands;
  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 Codice.LogWrapper;
  14. using GluonGui;
  15. using GluonGui.WorkspaceWindow.Views.Checkin.Operations;
  16. using PlasticGui;
  17. using PlasticGui.Help.Actions;
  18. using PlasticGui.Help.Conditions;
  19. using PlasticGui.WorkspaceWindow;
  20. using PlasticGui.WorkspaceWindow.Diff;
  21. using PlasticGui.WorkspaceWindow.Items;
  22. using PlasticGui.WorkspaceWindow.Open;
  23. using PlasticGui.WorkspaceWindow.PendingChanges;
  24. using Unity.PlasticSCM.Editor.AssetsOverlays;
  25. using Unity.PlasticSCM.Editor.AssetUtils;
  26. using Unity.PlasticSCM.Editor.Help;
  27. using Unity.PlasticSCM.Editor.UI;
  28. using Unity.PlasticSCM.Editor.UI.Progress;
  29. using Unity.PlasticSCM.Editor.UI.Tree;
  30. using Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs;
  31. using Unity.PlasticSCM.Editor.Views.PendingChanges.PendingMergeLinks;
  32. using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
  33. using Unity.PlasticSCM.Editor.Tool;
  34. using GluonNewIncomingChangesUpdater = PlasticGui.Gluon.WorkspaceWindow.NewIncomingChangesUpdater;
  35. namespace Unity.PlasticSCM.Editor.Views.PendingChanges
  36. {
  37. internal partial class PendingChangesTab :
  38. IRefreshableView,
  39. IPendingChangesView,
  40. CheckinUIOperation.ICheckinView,
  41. PendingChangesViewMenu.IMetaMenuOperations,
  42. IPendingChangesMenuOperations,
  43. IOpenMenuOperations,
  44. IFilesFilterPatternsMenuOperations,
  45. PendingChangesOptionsDialog.IAutorefreshView
  46. {
  47. internal IProgressControls ProgressControlsForTesting { get { return mProgressControls; } }
  48. internal HelpPanel HelpPanelForTesting { get { return mHelpPanel; } }
  49. internal void SetMergeLinksForTesting(
  50. IDictionary<MountPoint, IList<PendingMergeLink>> mergeLinks)
  51. {
  52. mPendingMergeLinks = mergeLinks;
  53. UpdateMergeLinksList();
  54. }
  55. internal string CommentText { get; set; }
  56. internal bool ForceToShowComment { get; set; }
  57. internal PendingChangesTab(
  58. WorkspaceInfo wkInfo,
  59. ViewHost viewHost,
  60. bool isGluonMode,
  61. WorkspaceWindow workspaceWindow,
  62. IViewSwitcher switcher,
  63. IMergeViewLauncher mergeViewLauncher,
  64. IHistoryViewLauncher historyViewLauncher,
  65. PlasticGui.WorkspaceWindow.PendingChanges.PendingChanges pendingChanges,
  66. NewIncomingChangesUpdater developerNewIncomingChangesUpdater,
  67. GluonNewIncomingChangesUpdater gluonNewIncomingChangesUpdater,
  68. IAssetStatusCache assetStatusCache,
  69. NotificationDrawer notificationDrawer,
  70. EditorWindow parentWindow)
  71. {
  72. mWkInfo = wkInfo;
  73. mViewHost = viewHost;
  74. mIsGluonMode = isGluonMode;
  75. mWorkspaceWindow = workspaceWindow;
  76. mHistoryViewLauncher = historyViewLauncher;
  77. mPendingChanges = pendingChanges;
  78. mDeveloperNewIncomingChangesUpdater = developerNewIncomingChangesUpdater;
  79. mGluonNewIncomingChangesUpdater = gluonNewIncomingChangesUpdater;
  80. mAssetStatusCache = assetStatusCache;
  81. mNotificationDrawer = notificationDrawer;
  82. mParentWindow = parentWindow;
  83. mGuiMessage = new UnityPlasticGuiMessage(parentWindow);
  84. mCheckedStateManager = new CheckedStateManager();
  85. mNewChangesInWk = NewChangesInWk.Build(
  86. mWkInfo,
  87. new BuildWorkspacekIsRelevantNewChange());
  88. BuildComponents(isGluonMode, parentWindow);
  89. mBorderColor = EditorGUIUtility.isProSkin
  90. ? (Color)new Color32(35, 35, 35, 255)
  91. : (Color)new Color32(153, 153, 153, 255);
  92. mProgressControls = new ProgressControlsForViews();
  93. workspaceWindow.RegisterPendingChangesProgressControls(mProgressControls);
  94. mPendingChangesOperations = new PendingChangesOperations(
  95. mWkInfo,
  96. workspaceWindow,
  97. switcher,
  98. mergeViewLauncher,
  99. this,
  100. mProgressControls,
  101. workspaceWindow,
  102. null,
  103. null,
  104. null);
  105. InitIgnoreRulesAndRefreshView(mWkInfo.ClientPath, this);
  106. }
  107. internal void AutoRefresh()
  108. {
  109. if (mIsAutoRefreshDisabled)
  110. return;
  111. if (!PlasticGuiConfig.Get().Configuration.CommitAutoRefresh)
  112. return;
  113. if (mIsRefreshing || mWorkspaceWindow.IsOperationInProgress())
  114. return;
  115. if (mNewChangesInWk != null && !mNewChangesInWk.Detected())
  116. return;
  117. ((IRefreshableView)this).Refresh();
  118. }
  119. internal void ClearIsCommentWarningNeeded()
  120. {
  121. mIsCommentWarningNeeded = false;
  122. }
  123. internal void UpdateIsCommentWarningNeeded(string comment)
  124. {
  125. mIsCommentWarningNeeded = string.IsNullOrEmpty(comment)
  126. && mPendingChanges.HasPendingChanges();
  127. }
  128. internal void OnDisable()
  129. {
  130. mSearchField.downOrUpArrowKeyPressed -=
  131. SearchField_OnDownOrUpArrowKeyPressed;
  132. TreeHeaderSettings.Save(
  133. mPendingChangesTreeView.multiColumnHeader.state,
  134. UnityConstants.PENDING_CHANGES_TABLE_SETTINGS_NAME);
  135. }
  136. internal void Update()
  137. {
  138. mProgressControls.UpdateProgress(mParentWindow);
  139. }
  140. internal void OnGUI()
  141. {
  142. if (!string.IsNullOrEmpty(mGluonWarningMessage))
  143. DoWarningMessage(mGluonWarningMessage);
  144. DoActionsToolbar(
  145. mWkInfo,
  146. mIsGluonMode,
  147. this,
  148. mProgressControls,
  149. mParentWindow);
  150. DoChangesArea(
  151. mPendingChangesTreeView,
  152. mProgressControls.IsOperationRunning());
  153. // Border
  154. Rect result = GUILayoutUtility.GetRect(mParentWindow.position.width, 1);
  155. EditorGUI.DrawRect(result, mBorderColor);
  156. DoCommentsSection();
  157. if (HasPendingMergeLinks())
  158. DoMergeLinksArea(mMergeLinksListView, mParentWindow.position.width);
  159. if (mProgressControls.HasNotification())
  160. {
  161. DrawProgressForViews.ForNotificationArea(mProgressControls.ProgressData);
  162. }
  163. DrawHelpPanel.For(mHelpPanel);
  164. }
  165. void IPendingChangesView.ClearComments()
  166. {
  167. ClearComments();
  168. }
  169. void IRefreshableView.Refresh()
  170. {
  171. if (!mAreIgnoreRulesInitialized)
  172. return;
  173. DrawAssetOverlay.ClearCache();
  174. if (mDeveloperNewIncomingChangesUpdater != null)
  175. mDeveloperNewIncomingChangesUpdater.Update();
  176. if (mGluonNewIncomingChangesUpdater != null)
  177. mGluonNewIncomingChangesUpdater.Update(DateTime.Now);
  178. FillPendingChanges(mNewChangesInWk);
  179. }
  180. void IPendingChangesView.ClearChangesToCheck(List<string> changes)
  181. {
  182. mCheckedStateManager.ClearChangesToCheck(changes);
  183. mParentWindow.Repaint();
  184. }
  185. void IPendingChangesView.CleanCheckedElements(List<ChangeInfo> checkedChanges)
  186. {
  187. mCheckedStateManager.Clean(checkedChanges);
  188. mParentWindow.Repaint();
  189. }
  190. void IPendingChangesView.CheckChanges(List<string> changesToCheck)
  191. {
  192. mCheckedStateManager.SetChangesToCheck(changesToCheck);
  193. mParentWindow.Repaint();
  194. }
  195. bool IPendingChangesView.IncludeDependencies(
  196. IList<ChangeDependencies<ChangeInfo>> changesDependencies,
  197. string operation)
  198. {
  199. return DependenciesDialog.IncludeDependencies(
  200. mWkInfo, changesDependencies, operation, mParentWindow);
  201. }
  202. CheckinMergeNeededData IPendingChangesView.CheckinMergeNeeded()
  203. {
  204. return CheckinMergeNeededDialog.Merge(mWkInfo, mParentWindow);
  205. }
  206. SearchMatchesData IPendingChangesView.AskForMatches(string changePath)
  207. {
  208. throw new NotImplementedException();
  209. }
  210. void IPendingChangesView.CleanLinkedTasks()
  211. {
  212. }
  213. void PendingChangesOptionsDialog.IAutorefreshView.DisableAutorefresh()
  214. {
  215. mIsAutoRefreshDisabled = true;
  216. }
  217. void CheckinUIOperation.ICheckinView.CollapseWarningMessagePanel()
  218. {
  219. mGluonWarningMessage = string.Empty;
  220. mParentWindow.Repaint();
  221. }
  222. void CheckinUIOperation.ICheckinView.ExpandWarningMessagePanel(string text)
  223. {
  224. mGluonWarningMessage = text;
  225. mParentWindow.Repaint();
  226. }
  227. void PendingChangesOptionsDialog.IAutorefreshView.EnableAutorefresh()
  228. {
  229. mIsAutoRefreshDisabled = false;
  230. }
  231. void CheckinUIOperation.ICheckinView.ClearComments()
  232. {
  233. ClearComments();
  234. }
  235. bool PendingChangesViewMenu.IMetaMenuOperations.SelectionHasMeta()
  236. {
  237. return mPendingChangesTreeView.SelectionHasMeta();
  238. }
  239. void PendingChangesViewMenu.IMetaMenuOperations.DiffMeta()
  240. {
  241. if (LaunchTool.ShowDownloadPlasticExeWindow(mIsGluonMode))
  242. return;
  243. ChangeInfo selectedChange = PendingChangesSelection
  244. .GetSelectedChange(mPendingChangesTreeView);
  245. ChangeInfo selectedChangeMeta = mPendingChangesTreeView.GetMetaChange(
  246. selectedChange);
  247. ChangeInfo changedForMoved = mPendingChanges.GetChangedForMoved(selectedChange);
  248. ChangeInfo changedForMovedMeta = (changedForMoved == null) ?
  249. null : mPendingChangesTreeView.GetMetaChange(changedForMoved);
  250. DiffOperation.DiffWorkspaceContent(
  251. mWkInfo,
  252. selectedChangeMeta,
  253. changedForMovedMeta,
  254. mProgressControls,
  255. null,
  256. null);
  257. }
  258. void PendingChangesViewMenu.IMetaMenuOperations.HistoryMeta()
  259. {
  260. ChangeInfo selectedChange = PendingChangesSelection
  261. .GetSelectedChange(mPendingChangesTreeView);
  262. ChangeInfo selectedChangeMeta = mPendingChangesTreeView.GetMetaChange(
  263. selectedChange);
  264. mHistoryViewLauncher.ShowHistoryView(
  265. selectedChangeMeta.RepositorySpec,
  266. selectedChangeMeta.RevInfo.ItemId,
  267. selectedChangeMeta.Path,
  268. selectedChangeMeta.IsDirectory);
  269. }
  270. void PendingChangesViewMenu.IMetaMenuOperations.OpenMeta()
  271. {
  272. List<string> selectedPaths = PendingChangesSelection
  273. .GetSelectedMetaPaths(mPendingChangesTreeView);
  274. FileSystemOperation.Open(selectedPaths);
  275. }
  276. void PendingChangesViewMenu.IMetaMenuOperations.OpenMetaWith()
  277. {
  278. List<string> selectedPaths = PendingChangesSelection
  279. .GetSelectedMetaPaths(mPendingChangesTreeView);
  280. OpenOperation.OpenWith(
  281. FileSystemOperation.GetExePath(),
  282. selectedPaths);
  283. }
  284. void PendingChangesViewMenu.IMetaMenuOperations.OpenMetaInExplorer()
  285. {
  286. List<string> selectedPaths = PendingChangesSelection
  287. .GetSelectedMetaPaths(mPendingChangesTreeView);
  288. if (selectedPaths.Count < 1)
  289. return;
  290. FileSystemOperation.OpenInExplorer(selectedPaths[0]);
  291. }
  292. SelectedChangesGroupInfo IPendingChangesMenuOperations.GetSelectedChangesGroupInfo()
  293. {
  294. return PendingChangesSelection.GetSelectedChangesGroupInfo(
  295. mPendingChangesTreeView);
  296. }
  297. void IPendingChangesMenuOperations.Diff()
  298. {
  299. if (LaunchTool.ShowDownloadPlasticExeWindow(mIsGluonMode))
  300. return;
  301. ChangeInfo selectedChange = PendingChangesSelection
  302. .GetSelectedChange(mPendingChangesTreeView);
  303. DiffOperation.DiffWorkspaceContent(
  304. mWkInfo,
  305. selectedChange,
  306. mPendingChanges.GetChangedForMoved(selectedChange),
  307. null,
  308. null,
  309. null);
  310. }
  311. void IPendingChangesMenuOperations.UndoChanges()
  312. {
  313. List<ChangeInfo> changesToUndo = PendingChangesSelection
  314. .GetSelectedChanges(mPendingChangesTreeView);
  315. List<ChangeInfo> dependenciesCandidates =
  316. mPendingChangesTreeView.GetDependenciesCandidates(changesToUndo, true);
  317. UndoChangesForMode(mIsGluonMode, changesToUndo, dependenciesCandidates);
  318. }
  319. void IPendingChangesMenuOperations.SearchMatches()
  320. {
  321. ChangeInfo selectedChange = PendingChangesSelection
  322. .GetSelectedChange(mPendingChangesTreeView);
  323. if (selectedChange == null)
  324. return;
  325. SearchMatchesOperation operation = new SearchMatchesOperation(
  326. mWkInfo, mWorkspaceWindow, this,
  327. mProgressControls, mDeveloperNewIncomingChangesUpdater);
  328. operation.SearchMatches(
  329. selectedChange,
  330. PendingChangesSelection.GetAllChanges(mPendingChangesTreeView));
  331. }
  332. void IPendingChangesMenuOperations.ApplyLocalChanges()
  333. {
  334. List<ChangeInfo> selectedChanges = PendingChangesSelection
  335. .GetSelectedChanges(mPendingChangesTreeView);
  336. if (selectedChanges.Count == 0)
  337. return;
  338. ApplyLocalChangesOperation operation = new ApplyLocalChangesOperation(
  339. mWkInfo, mWorkspaceWindow, this,
  340. mProgressControls, mDeveloperNewIncomingChangesUpdater);
  341. operation.ApplyLocalChanges(
  342. selectedChanges,
  343. PendingChangesSelection.GetAllChanges(mPendingChangesTreeView));
  344. }
  345. void IPendingChangesMenuOperations.Delete()
  346. {
  347. List<string> privateDirectoriesToDelete;
  348. List<string> privateFilesToDelete;
  349. if (!mPendingChangesTreeView.GetSelectedPathsToDelete(
  350. out privateDirectoriesToDelete,
  351. out privateFilesToDelete))
  352. return;
  353. DeleteOperation.Delete(
  354. mWorkspaceWindow, mProgressControls,
  355. privateDirectoriesToDelete, privateFilesToDelete,
  356. mDeveloperNewIncomingChangesUpdater,
  357. RefreshAsset.UnityAssetDatabase);
  358. }
  359. void IPendingChangesMenuOperations.Annotate()
  360. {
  361. throw new NotImplementedException();
  362. }
  363. void IPendingChangesMenuOperations.History()
  364. {
  365. ChangeInfo selectedChange = PendingChangesSelection.
  366. GetSelectedChange(mPendingChangesTreeView);
  367. mHistoryViewLauncher.ShowHistoryView(
  368. selectedChange.RepositorySpec,
  369. selectedChange.RevInfo.ItemId,
  370. selectedChange.Path,
  371. selectedChange.IsDirectory);
  372. }
  373. void IOpenMenuOperations.Open()
  374. {
  375. List<string> selectedPaths = PendingChangesSelection.
  376. GetSelectedPathsWithoutMeta(mPendingChangesTreeView);
  377. FileSystemOperation.Open(selectedPaths);
  378. }
  379. void IOpenMenuOperations.OpenWith()
  380. {
  381. List<string> selectedPaths = PendingChangesSelection.
  382. GetSelectedPathsWithoutMeta(mPendingChangesTreeView);
  383. OpenOperation.OpenWith(
  384. FileSystemOperation.GetExePath(),
  385. selectedPaths);
  386. }
  387. void IOpenMenuOperations.OpenWithCustom(string exePath, string args)
  388. {
  389. List<string> selectedPaths = PendingChangesSelection.
  390. GetSelectedPathsWithoutMeta(mPendingChangesTreeView);
  391. OpenOperation.OpenWith(exePath, selectedPaths);
  392. }
  393. void IOpenMenuOperations.OpenInExplorer()
  394. {
  395. List<string> selectedPaths = PendingChangesSelection
  396. .GetSelectedPathsWithoutMeta(mPendingChangesTreeView);
  397. if (selectedPaths.Count < 1)
  398. return;
  399. FileSystemOperation.OpenInExplorer(selectedPaths[0]);
  400. }
  401. void IFilesFilterPatternsMenuOperations.AddFilesFilterPatterns(
  402. FilterTypes type, FilterActions action, FilterOperationType operation)
  403. {
  404. List<string> selectedPaths = PendingChangesSelection.GetSelectedPaths(
  405. mPendingChangesTreeView);
  406. string[] rules = FilterRulesGenerator.GenerateRules(
  407. selectedPaths, mWkInfo.ClientPath, action, operation);
  408. bool isApplicableToAllWorkspaces = !mIsGluonMode;
  409. bool isAddOperation = operation == FilterOperationType.Add;
  410. FilterRulesConfirmationData filterRulesConfirmationData =
  411. FilterRulesConfirmationDialog.AskForConfirmation(
  412. rules, isAddOperation, isApplicableToAllWorkspaces, mParentWindow);
  413. AddFilesFilterPatternsOperation.Run(
  414. mWkInfo, mWorkspaceWindow, type, operation, filterRulesConfirmationData);
  415. }
  416. void SearchField_OnDownOrUpArrowKeyPressed()
  417. {
  418. mPendingChangesTreeView.SetFocusAndEnsureSelectedItem();
  419. }
  420. void InitIgnoreRulesAndRefreshView(
  421. string wkPath, IRefreshableView view)
  422. {
  423. IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
  424. waiter.Execute(
  425. /*threadOperationDelegate*/ delegate
  426. {
  427. if (IsIgnoreConfigDefined.For(wkPath))
  428. return;
  429. AddIgnoreRules.WriteRules(
  430. wkPath, UnityConditions.GetMissingIgnoredRules(wkPath));
  431. },
  432. /*afterOperationDelegate*/ delegate
  433. {
  434. mAreIgnoreRulesInitialized = true;
  435. view.Refresh();
  436. if (waiter.Exception == null)
  437. return;
  438. mLog.ErrorFormat(
  439. "Error adding ignore rules for Unity: {0}",
  440. waiter.Exception);
  441. mLog.DebugFormat(
  442. "Stack trace: {0}",
  443. waiter.Exception.StackTrace);
  444. });
  445. }
  446. void FillPendingChanges(INewChangesInWk newChangesInWk)
  447. {
  448. if (mIsRefreshing)
  449. return;
  450. mIsRefreshing = true;
  451. List<ChangeInfo> changesToSelect =
  452. PendingChangesSelection.GetChangesToFocus(mPendingChangesTreeView);
  453. ((IProgressControls)mProgressControls).ShowProgress(PlasticLocalization.
  454. GetString(PlasticLocalization.Name.LoadingPendingChanges));
  455. IDictionary<MountPoint, IList<PendingMergeLink>> mergeLinks = null;
  456. IThreadWaiter waiter = ThreadWaiter.GetWaiter();
  457. waiter.Execute(
  458. /*threadOperationDelegate*/ delegate
  459. {
  460. FilterManager.Get().Reload();
  461. WorkspaceStatusOptions options = WorkspaceStatusOptions.None;
  462. options |= WorkspaceStatusOptions.FindAdded;
  463. options |= WorkspaceStatusOptions.FindDeleted;
  464. options |= WorkspaceStatusOptions.FindMoved;
  465. options |= WorkspaceStatusOptions.SplitModifiedMoved;
  466. options |= PendingChangesOptions.GetWorkspaceStatusOptions();
  467. if (newChangesInWk != null)
  468. newChangesInWk.Detected();
  469. mPendingChanges.Calculate(
  470. options, PendingChangesOptions.GetMovedMatchingOptions());
  471. mergeLinks = PlasticGui.Plastic.API.GetPendingMergeLinks(mWkInfo);
  472. },
  473. /*afterOperationDelegate*/ delegate
  474. {
  475. mPendingMergeLinks = mergeLinks;
  476. try
  477. {
  478. if (waiter.Exception != null)
  479. {
  480. ExceptionsHandler.DisplayException(waiter.Exception);
  481. return;
  482. }
  483. UpdateChangesTree();
  484. UpdateMergeLinksList();
  485. PendingChangesSelection.SelectChanges(
  486. mPendingChangesTreeView, changesToSelect);
  487. }
  488. finally
  489. {
  490. ((IProgressControls)mProgressControls).HideProgress();
  491. //UpdateIsCommentWarningNeeded(CommentText);
  492. UpdateNotificationPanel();
  493. mIsRefreshing = false;
  494. }
  495. });
  496. }
  497. void DoCommentsSection()
  498. {
  499. EditorGUILayout.BeginVertical();
  500. EditorGUILayout.Space(10);
  501. EditorGUILayout.BeginHorizontal();
  502. EditorGUILayout.Space(2);
  503. EditorGUILayout.BeginVertical();
  504. GUILayout.FlexibleSpace();
  505. DrawUserIcon.ForPendeingChangesTab(CommentText);
  506. GUILayout.FlexibleSpace();
  507. EditorGUILayout.EndVertical();
  508. float width = Mathf.Clamp(mParentWindow.position.width, 300f, 820f);
  509. DrawCommentTextArea.For(
  510. this,
  511. width,
  512. mProgressControls.IsOperationRunning());
  513. EditorGUILayout.Space(2);
  514. // To center the action buttons vertically
  515. EditorGUILayout.BeginVertical();
  516. GUILayout.FlexibleSpace();
  517. DoOperationsToolbar(
  518. mWkInfo,
  519. mIsGluonMode,
  520. mAdvancedDropdownMenu,
  521. mProgressControls.IsOperationRunning());
  522. GUILayout.FlexibleSpace();
  523. EditorGUILayout.EndVertical();
  524. GUILayout.FlexibleSpace();
  525. EditorGUILayout.EndHorizontal();
  526. EditorGUILayout.Space(10);
  527. EditorGUILayout.EndVertical();
  528. }
  529. void DoOperationsToolbar(
  530. WorkspaceInfo wkInfo,
  531. bool isGluonMode,
  532. GenericMenu advancedDropdownMenu,
  533. bool isOperationRunning)
  534. {
  535. EditorGUILayout.BeginHorizontal();
  536. using (new GuiEnabled(!isOperationRunning))
  537. {
  538. if (DrawActionButton.ForCommentSection(PlasticLocalization.GetString(
  539. PlasticLocalization.Name.CheckinChanges)))
  540. {
  541. UpdateIsCommentWarningNeeded(CommentText);
  542. if (!mIsCommentWarningNeeded)
  543. CheckinForMode(wkInfo, isGluonMode, mKeepItemsLocked);
  544. }
  545. GUILayout.Space(2);
  546. if (DrawActionButton.ForCommentSection(PlasticLocalization.GetString(
  547. PlasticLocalization.Name.UndoChanges)))
  548. {
  549. UndoForMode(wkInfo, isGluonMode);
  550. }
  551. if (isGluonMode)
  552. {
  553. mKeepItemsLocked = EditorGUILayout.ToggleLeft(
  554. PlasticLocalization.GetString(PlasticLocalization.Name.KeepLocked),
  555. mKeepItemsLocked,
  556. GUILayout.Width(UnityConstants.EXTRA_LARGE_BUTTON_WIDTH));
  557. }
  558. //TODO: Codice - beta: hide the advanced menu until the behavior is implemented
  559. /*else
  560. {
  561. var dropDownContent = new GUIContent(string.Empty);
  562. var dropDownRect = GUILayoutUtility.GetRect(
  563. dropDownContent, EditorStyles.toolbarDropDown);
  564. if (EditorGUI.DropdownButton(dropDownRect, dropDownContent,
  565. FocusType.Passive, EditorStyles.toolbarDropDown))
  566. advancedDropdownMenu.DropDown(dropDownRect);
  567. }*/
  568. }
  569. if (mIsCommentWarningNeeded)
  570. {
  571. GUILayout.Space(5);
  572. DoCheckinWarningMessage();
  573. }
  574. EditorGUILayout.EndHorizontal();
  575. }
  576. void UpdateChangesTree()
  577. {
  578. mPendingChangesTreeView.BuildModel(mPendingChanges, mCheckedStateManager);
  579. mPendingChangesTreeView.Refilter();
  580. mPendingChangesTreeView.Sort();
  581. mPendingChangesTreeView.Reload();
  582. }
  583. static void DoWarningMessage(string message)
  584. {
  585. GUILayout.Label(message, UnityStyles.WarningMessage);
  586. }
  587. void UpdateMergeLinksList()
  588. {
  589. mMergeLinksListView.BuildModel(mPendingMergeLinks);
  590. mMergeLinksListView.Reload();
  591. }
  592. void UpdateNotificationPanel()
  593. {
  594. if (PlasticGui.Plastic.API.IsFsReaderWatchLimitReached(mWkInfo))
  595. {
  596. ((IProgressControls)mProgressControls).ShowWarning(PlasticLocalization.
  597. GetString(PlasticLocalization.Name.NotifyLinuxWatchLimitWarning));
  598. return;
  599. }
  600. }
  601. static void DoCheckinWarningMessage()
  602. {
  603. string label = PlasticLocalization.GetString(PlasticLocalization.Name.PleaseComment);
  604. GUILayout.Label(
  605. new GUIContent(label, Images.GetWarnIcon()),
  606. UnityStyles.PendingChangesTab.CommentWarningIcon);
  607. }
  608. void DoActionsToolbar(
  609. WorkspaceInfo workspaceInfo,
  610. bool isGluonMode,
  611. IRefreshableView refreshableView,
  612. ProgressControlsForViews progressControls,
  613. EditorWindow editorWindow)
  614. {
  615. EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
  616. string checkinHeader = string.Format(
  617. PlasticLocalization.GetString(PlasticLocalization.Name.CheckinHeader),
  618. mPendingChangesTreeView.GetSelectedItemCount(),
  619. mPendingChangesTreeView.GetTotalItemCount());
  620. GUILayout.Label(checkinHeader, UnityStyles.PendingChangesTab.HeaderLabel);
  621. if (progressControls.IsOperationRunning())
  622. {
  623. DrawProgressForViews.ForIndeterminateProgress(
  624. progressControls.ProgressData);
  625. }
  626. GUILayout.FlexibleSpace();
  627. DrawSearchField.For(
  628. mSearchField,
  629. mPendingChangesTreeView,
  630. UnityConstants.SEARCH_FIELD_WIDTH);
  631. DoRefreshButton(
  632. refreshableView,
  633. progressControls.IsOperationRunning());
  634. EditorGUILayout.EndHorizontal();
  635. }
  636. static void DoChangesArea(
  637. PendingChangesTreeView changesTreeView,
  638. bool isOperationRunning)
  639. {
  640. GUI.enabled = !isOperationRunning;
  641. Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
  642. changesTreeView.OnGUI(rect);
  643. GUI.enabled = true;
  644. }
  645. bool HasPendingMergeLinks()
  646. {
  647. if (mPendingMergeLinks == null)
  648. return false;
  649. return mPendingMergeLinks.Count > 0;
  650. }
  651. static void DoMergeLinksArea(
  652. MergeLinksListView mergeLinksListView, float width)
  653. {
  654. GUILayout.Label(
  655. PlasticLocalization.GetString(
  656. PlasticLocalization.Name.MergeLinkDescriptionColumn),
  657. EditorStyles.boldLabel);
  658. float desiredTreeHeight = mergeLinksListView.DesiredHeight;
  659. Rect treeRect = GUILayoutUtility.GetRect(
  660. 0,
  661. width,
  662. desiredTreeHeight,
  663. desiredTreeHeight);
  664. mergeLinksListView.OnGUI(treeRect);
  665. }
  666. static void DoRefreshButton(
  667. IRefreshableView refreshableView,
  668. bool isOperationRunning)
  669. {
  670. EditorGUI.BeginDisabledGroup(isOperationRunning);
  671. if (GUILayout.Button(new GUIContent(
  672. Images.GetRefreshIcon()), EditorStyles.toolbarButton))
  673. refreshableView.Refresh();
  674. EditorGUI.EndDisabledGroup();
  675. }
  676. void BuildComponents(
  677. bool isGluonMode,
  678. EditorWindow plasticWindow)
  679. {
  680. mHelpPanel = new HelpPanel(plasticWindow);
  681. mAdvancedDropdownMenu = new GenericMenu();
  682. mAdvancedDropdownMenu.AddItem(new GUIContent(
  683. PlasticLocalization.GetString(PlasticLocalization.Name.UndoUnchangedButton)),
  684. false, () => { });
  685. mSearchField = new SearchField();
  686. mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
  687. PendingChangesTreeHeaderState headerState =
  688. PendingChangesTreeHeaderState.GetDefault(isGluonMode);
  689. TreeHeaderSettings.Load(headerState,
  690. UnityConstants.PENDING_CHANGES_TABLE_SETTINGS_NAME,
  691. (int)PendingChangesTreeColumn.Item, true);
  692. mPendingChangesTreeView = new PendingChangesTreeView(
  693. mWkInfo, mIsGluonMode, headerState,
  694. PendingChangesTreeHeaderState.GetColumnNames(),
  695. new PendingChangesViewMenu(this, this, this, this, mIsGluonMode),
  696. mAssetStatusCache);
  697. mPendingChangesTreeView.Reload();
  698. mMergeLinksListView = new MergeLinksListView();
  699. mMergeLinksListView.Reload();
  700. }
  701. INewChangesInWk mNewChangesInWk;
  702. GenericMenu mAdvancedDropdownMenu;
  703. void ClearComments()
  704. {
  705. CommentText = string.Empty;
  706. ForceToShowComment = true;
  707. mParentWindow.Repaint();
  708. }
  709. PendingChangesTreeView mPendingChangesTreeView;
  710. MergeLinksListView mMergeLinksListView;
  711. HelpPanel mHelpPanel;
  712. volatile bool mAreIgnoreRulesInitialized = false;
  713. bool mIsRefreshing;
  714. bool mIsAutoRefreshDisabled;
  715. bool mIsCommentWarningNeeded = false;
  716. bool mKeepItemsLocked;
  717. string mGluonWarningMessage;
  718. IDictionary<MountPoint, IList<PendingMergeLink>> mPendingMergeLinks;
  719. SearchField mSearchField;
  720. Color mBorderColor;
  721. readonly ProgressControlsForViews mProgressControls;
  722. readonly EditorWindow mParentWindow;
  723. readonly NotificationDrawer mNotificationDrawer;
  724. readonly IAssetStatusCache mAssetStatusCache;
  725. readonly PendingChangesOperations mPendingChangesOperations;
  726. readonly CheckedStateManager mCheckedStateManager;
  727. readonly GuiMessage.IGuiMessage mGuiMessage;
  728. readonly NewIncomingChangesUpdater mDeveloperNewIncomingChangesUpdater;
  729. readonly GluonNewIncomingChangesUpdater mGluonNewIncomingChangesUpdater;
  730. readonly bool mIsGluonMode;
  731. readonly IHistoryViewLauncher mHistoryViewLauncher;
  732. readonly PlasticGui.WorkspaceWindow.PendingChanges.PendingChanges mPendingChanges;
  733. readonly WorkspaceWindow mWorkspaceWindow;
  734. readonly ViewHost mViewHost;
  735. readonly WorkspaceInfo mWkInfo;
  736. static readonly ILog mLog = LogManager.GetLogger("PendingChangesTab");
  737. }
  738. }