Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

PendingChangesTab.cs 40KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  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.EventTracking;
  10. using Codice.Client.Common.FsNodeReaders;
  11. using Codice.Client.Common.Threading;
  12. using Codice.CM.Client.Gui;
  13. using Codice.CM.Common;
  14. using Codice.CM.Common.Merge;
  15. using Codice.LogWrapper;
  16. using GluonGui;
  17. using GluonGui.WorkspaceWindow.Views.Checkin.Operations;
  18. using PlasticGui;
  19. using PlasticGui.Help.Actions;
  20. using PlasticGui.Help.Conditions;
  21. using PlasticGui.WorkspaceWindow;
  22. using PlasticGui.WorkspaceWindow.Diff;
  23. using PlasticGui.WorkspaceWindow.Items;
  24. using PlasticGui.WorkspaceWindow.Open;
  25. using PlasticGui.WorkspaceWindow.PendingChanges;
  26. using PlasticGui.WorkspaceWindow.PendingChanges.Changelists;
  27. using Unity.PlasticSCM.Editor.AssetsOverlays;
  28. using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
  29. using Unity.PlasticSCM.Editor.AssetUtils;
  30. using Unity.PlasticSCM.Editor.AssetUtils.Processor;
  31. using Unity.PlasticSCM.Editor.Help;
  32. using Unity.PlasticSCM.Editor.Tool;
  33. using Unity.PlasticSCM.Editor.UI;
  34. using Unity.PlasticSCM.Editor.UI.Progress;
  35. using Unity.PlasticSCM.Editor.UI.StatusBar;
  36. using Unity.PlasticSCM.Editor.UI.Tree;
  37. using Unity.PlasticSCM.Editor.Views.PendingChanges.Dialogs;
  38. using Unity.PlasticSCM.Editor.Views.PendingChanges.PendingMergeLinks;
  39. using Unity.PlasticSCM.Editor.Views.Changesets;
  40. using GluonNewIncomingChangesUpdater = PlasticGui.Gluon.WorkspaceWindow.NewIncomingChangesUpdater;
  41. namespace Unity.PlasticSCM.Editor.Views.PendingChanges
  42. {
  43. internal partial class PendingChangesTab :
  44. IRefreshableView,
  45. PlasticProjectSettingsProvider.IAutoRefreshView,
  46. IPendingChangesView,
  47. CheckinUIOperation.ICheckinView,
  48. PendingChangesViewPendingChangeMenu.IMetaMenuOperations,
  49. IPendingChangesMenuOperations,
  50. IChangelistMenuOperations,
  51. IOpenMenuOperations,
  52. IFilesFilterPatternsMenuOperations,
  53. PendingChangesViewMenu.IGetSelectedNodes,
  54. ChangesetsTab.IRevertToChangesetListener
  55. {
  56. internal IProgressControls ProgressControlsForTesting { get { return mProgressControls; } }
  57. internal HelpPanel HelpPanelForTesting { get { return mHelpPanel; } }
  58. internal void SetMergeLinksForTesting(
  59. IDictionary<MountPoint, IList<PendingMergeLink>> mergeLinks)
  60. {
  61. mPendingMergeLinks = mergeLinks;
  62. UpdateMergeLinksList();
  63. }
  64. internal string CommentText { get; set; }
  65. internal bool ForceToShowComment { get; set; }
  66. internal PendingChangesTab(
  67. WorkspaceInfo wkInfo,
  68. ViewHost viewHost,
  69. bool isGluonMode,
  70. WorkspaceWindow workspaceWindow,
  71. IViewSwitcher switcher,
  72. IMergeViewLauncher mergeViewLauncher,
  73. IHistoryViewLauncher historyViewLauncher,
  74. LaunchTool.IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
  75. WorkspaceOperationsMonitor workspaceOperationsMonitor,
  76. NewIncomingChangesUpdater developerNewIncomingChangesUpdater,
  77. GluonNewIncomingChangesUpdater gluonNewIncomingChangesUpdater,
  78. IAssetStatusCache assetStatusCache,
  79. StatusBar statusBar,
  80. EditorWindow parentWindow)
  81. {
  82. mWkInfo = wkInfo;
  83. mViewHost = viewHost;
  84. mIsGluonMode = isGluonMode;
  85. mWorkspaceWindow = workspaceWindow;
  86. mHistoryViewLauncher = historyViewLauncher;
  87. mShowDownloadPlasticExeWindow = showDownloadPlasticExeWindow;
  88. mWorkspaceOperationsMonitor = workspaceOperationsMonitor;
  89. mDeveloperNewIncomingChangesUpdater = developerNewIncomingChangesUpdater;
  90. mGluonNewIncomingChangesUpdater = gluonNewIncomingChangesUpdater;
  91. mAssetStatusCache = assetStatusCache;
  92. mStatusBar = statusBar;
  93. mParentWindow = parentWindow;
  94. mGuiMessage = new UnityPlasticGuiMessage();
  95. mCheckedStateManager = new PendingChangesViewCheckedStateManager();
  96. mNewChangesInWk = NewChangesInWk.Build(
  97. mWkInfo,
  98. new BuildWorkspacekIsRelevantNewChange());
  99. BuildComponents(isGluonMode, parentWindow);
  100. mBorderColor = EditorGUIUtility.isProSkin
  101. ? (Color)new Color32(35, 35, 35, 255)
  102. : (Color)new Color32(153, 153, 153, 255);
  103. mProgressControls = new ProgressControlsForViews();
  104. mCooldownClearCheckinSuccessAction = new CooldownWindowDelayer(
  105. DelayedClearCheckinSuccess,
  106. UnityConstants.NOTIFICATION_CLEAR_INTERVAL);
  107. workspaceWindow.RegisterPendingChangesProgressControls(mProgressControls);
  108. mPendingChangesOperations = new PendingChangesOperations(
  109. mWkInfo,
  110. workspaceWindow,
  111. switcher,
  112. mergeViewLauncher,
  113. this,
  114. mProgressControls,
  115. workspaceWindow,
  116. null,
  117. null,
  118. null);
  119. InitIgnoreRulesAndRefreshView(mWkInfo.ClientPath, this);
  120. }
  121. internal void AutoRefresh()
  122. {
  123. if (mIsAutoRefreshDisabled)
  124. return;
  125. if (!PlasticGuiConfig.Get().Configuration.CommitAutoRefresh)
  126. return;
  127. if (mNewChangesInWk != null && !mNewChangesInWk.Detected())
  128. return;
  129. ((IRefreshableView)this).Refresh();
  130. }
  131. internal void ClearIsCommentWarningNeeded()
  132. {
  133. mIsEmptyCheckinCommentWarningNeeded = false;
  134. }
  135. internal void UpdateIsCommentWarningNeeded(string comment)
  136. {
  137. mIsEmptyCheckinCommentWarningNeeded =
  138. string.IsNullOrEmpty(comment) &&
  139. GuiClientConfig.Get().Configuration.ShowEmptyCommentWarning;
  140. mNeedsToShowEmptyCommentDialog = mIsEmptyCheckinCommentWarningNeeded;
  141. }
  142. internal void OnDisable()
  143. {
  144. mSearchField.downOrUpArrowKeyPressed -=
  145. SearchField_OnDownOrUpArrowKeyPressed;
  146. TreeHeaderSettings.Save(
  147. mPendingChangesTreeView.multiColumnHeader.state,
  148. UnityConstants.PENDING_CHANGES_TABLE_SETTINGS_NAME);
  149. }
  150. internal void Update()
  151. {
  152. mProgressControls.UpdateProgress(mParentWindow);
  153. // Displaying the dialog here, because showing it during the window's OnGUI function
  154. // caused errors
  155. if(mNeedsToShowEmptyCommentDialog)
  156. {
  157. mNeedsToShowEmptyCommentDialog = false;
  158. mHasPendingCheckinFromPreviousUpdate =
  159. EmptyCheckinMessageDialog.ShouldContinueWithCheckin(mParentWindow, mWkInfo);
  160. mIsEmptyCheckinCommentWarningNeeded = !mHasPendingCheckinFromPreviousUpdate;
  161. }
  162. }
  163. internal void OnGUI()
  164. {
  165. if (!string.IsNullOrEmpty(mGluonWarningMessage))
  166. DoWarningMessage(mGluonWarningMessage);
  167. DoActionsToolbar(
  168. mWkInfo,
  169. mIsGluonMode,
  170. mProgressControls);
  171. DoChangesArea(
  172. mPendingChangesTreeView,
  173. mProgressControls.IsOperationRunning(),
  174. mIsCheckedInSuccessful,
  175. mOrganizationToInviteUsers);
  176. if (HasPendingMergeLinks() && !mHasPendingMergeLinksFromRevert)
  177. DoMergeLinksArea(mMergeLinksListView, mParentWindow.position.width);
  178. // Border
  179. Rect result = GUILayoutUtility.GetRect(mParentWindow.position.width, 1);
  180. EditorGUI.DrawRect(result, mBorderColor);
  181. DoCommentsSection();
  182. if (mProgressControls.HasNotification())
  183. {
  184. DrawProgressForViews.ForNotificationArea(mProgressControls.ProgressData);
  185. }
  186. DrawHelpPanel.For(mHelpPanel);
  187. }
  188. internal void DrawSearchFieldForPendingChangesTab()
  189. {
  190. DrawSearchField.For(
  191. mSearchField,
  192. mPendingChangesTreeView,
  193. UnityConstants.SEARCH_FIELD_WIDTH);
  194. }
  195. void IPendingChangesView.SetDefaultComment(string defaultComment)
  196. {
  197. }
  198. void IPendingChangesView.ClearComments()
  199. {
  200. ClearComments();
  201. }
  202. void IRefreshableView.Refresh()
  203. {
  204. if (mProgressControls.IsOperationRunning())
  205. return;
  206. if (!mAreIgnoreRulesInitialized)
  207. return;
  208. if (mDeveloperNewIncomingChangesUpdater != null)
  209. mDeveloperNewIncomingChangesUpdater.Update(DateTime.Now);
  210. if (mGluonNewIncomingChangesUpdater != null)
  211. mGluonNewIncomingChangesUpdater.Update(DateTime.Now);
  212. FillPendingChanges(mNewChangesInWk);
  213. }
  214. void PlasticProjectSettingsProvider.IAutoRefreshView.DisableAutoRefresh()
  215. {
  216. mIsAutoRefreshDisabled = true;
  217. }
  218. void PlasticProjectSettingsProvider.IAutoRefreshView.EnableAutoRefresh()
  219. {
  220. mIsAutoRefreshDisabled = false;
  221. }
  222. void PlasticProjectSettingsProvider.IAutoRefreshView.ForceRefresh()
  223. {
  224. ((IRefreshableView)this).Refresh();
  225. }
  226. void IPendingChangesView.ClearChangesToCheck(List<string> changes)
  227. {
  228. mCheckedStateManager.ClearChangesToCheck(changes);
  229. mParentWindow.Repaint();
  230. }
  231. void IPendingChangesView.CleanCheckedElements(List<ChangeInfo> checkedChanges)
  232. {
  233. mCheckedStateManager.Clean(checkedChanges);
  234. mParentWindow.Repaint();
  235. }
  236. void IPendingChangesView.CheckChanges(List<string> changesToCheck)
  237. {
  238. mCheckedStateManager.SetChangesToCheck(changesToCheck);
  239. mParentWindow.Repaint();
  240. }
  241. bool IPendingChangesView.IncludeDependencies(
  242. IList<ChangeDependencies<ChangeInfo>> changesDependencies,
  243. string operation)
  244. {
  245. return DependenciesDialog.IncludeDependencies(
  246. mWkInfo, changesDependencies, operation, mParentWindow);
  247. }
  248. SearchMatchesData IPendingChangesView.AskForMatches(string changePath)
  249. {
  250. throw new NotImplementedException();
  251. }
  252. void IPendingChangesView.CleanLinkedTasks()
  253. {
  254. }
  255. void CheckinUIOperation.ICheckinView.CollapseWarningMessagePanel()
  256. {
  257. mGluonWarningMessage = string.Empty;
  258. mParentWindow.Repaint();
  259. }
  260. void CheckinUIOperation.ICheckinView.ExpandWarningMessagePanel(string text)
  261. {
  262. mGluonWarningMessage = text;
  263. mParentWindow.Repaint();
  264. }
  265. void CheckinUIOperation.ICheckinView.ClearComments()
  266. {
  267. ClearComments();
  268. }
  269. bool PendingChangesViewPendingChangeMenu.IMetaMenuOperations.SelectionHasMeta()
  270. {
  271. return mPendingChangesTreeView.SelectionHasMeta();
  272. }
  273. void PendingChangesViewPendingChangeMenu.IMetaMenuOperations.DiffMeta()
  274. {
  275. if (mShowDownloadPlasticExeWindow.Show(
  276. mWkInfo,
  277. mIsGluonMode,
  278. TrackFeatureUseEvent.Features.InstallPlasticCloudFromDiffWorkspaceContent,
  279. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromDiffWorkspaceContent,
  280. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromDiffWorkspaceContent))
  281. return;
  282. ChangeInfo selectedChange = PendingChangesSelection
  283. .GetSelectedChange(mPendingChangesTreeView);
  284. ChangeInfo selectedChangeMeta = mPendingChangesTreeView.GetMetaChange(
  285. selectedChange);
  286. ChangeInfo changedForMoved = mPendingChangesTreeView.GetChangedForMoved(selectedChange);
  287. ChangeInfo changedForMovedMeta = (changedForMoved == null) ?
  288. null : mPendingChangesTreeView.GetMetaChange(changedForMoved);
  289. DiffOperation.DiffWorkspaceContent(
  290. mWkInfo,
  291. selectedChangeMeta,
  292. changedForMovedMeta,
  293. mProgressControls,
  294. null,
  295. null);
  296. }
  297. void PendingChangesViewPendingChangeMenu.IMetaMenuOperations.HistoryMeta()
  298. {
  299. ChangeInfo selectedChange = PendingChangesSelection
  300. .GetSelectedChange(mPendingChangesTreeView);
  301. ChangeInfo selectedChangeMeta = mPendingChangesTreeView.GetMetaChange(
  302. selectedChange);
  303. mHistoryViewLauncher.ShowHistoryView(
  304. selectedChangeMeta.RepositorySpec,
  305. selectedChangeMeta.RevInfo.ItemId,
  306. selectedChangeMeta.Path,
  307. selectedChangeMeta.IsDirectory);
  308. }
  309. void PendingChangesViewPendingChangeMenu.IMetaMenuOperations.OpenMeta()
  310. {
  311. List<string> selectedPaths = PendingChangesSelection
  312. .GetSelectedMetaPaths(mPendingChangesTreeView);
  313. FileSystemOperation.Open(selectedPaths);
  314. }
  315. void PendingChangesViewPendingChangeMenu.IMetaMenuOperations.OpenMetaWith()
  316. {
  317. List<string> selectedPaths = PendingChangesSelection
  318. .GetSelectedMetaPaths(mPendingChangesTreeView);
  319. OpenOperation.OpenWith(
  320. FileSystemOperation.GetExePath(),
  321. selectedPaths);
  322. }
  323. void PendingChangesViewPendingChangeMenu.IMetaMenuOperations.OpenMetaInExplorer()
  324. {
  325. List<string> selectedPaths = PendingChangesSelection
  326. .GetSelectedMetaPaths(mPendingChangesTreeView);
  327. if (selectedPaths.Count < 1)
  328. return;
  329. FileSystemOperation.OpenInExplorer(selectedPaths[0]);
  330. }
  331. SelectedChangesGroupInfo IPendingChangesMenuOperations.GetSelectedChangesGroupInfo()
  332. {
  333. return PendingChangesSelection.GetSelectedChangesGroupInfo(
  334. mWkInfo.ClientPath, mPendingChangesTreeView);
  335. }
  336. void IPendingChangesMenuOperations.Diff()
  337. {
  338. if (mShowDownloadPlasticExeWindow.Show(
  339. mWkInfo,
  340. mIsGluonMode,
  341. TrackFeatureUseEvent.Features.InstallPlasticCloudFromDiffWorkspaceContent,
  342. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromDiffWorkspaceContent,
  343. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromDiffWorkspaceContent))
  344. return;
  345. ChangeInfo selectedChange = PendingChangesSelection
  346. .GetSelectedChange(mPendingChangesTreeView);
  347. DiffOperation.DiffWorkspaceContent(
  348. mWkInfo,
  349. selectedChange,
  350. mPendingChangesTreeView.GetChangedForMoved(selectedChange),
  351. null,
  352. null,
  353. null);
  354. }
  355. void IPendingChangesMenuOperations.UndoChanges()
  356. {
  357. List<ChangeInfo> changesToUndo = PendingChangesSelection
  358. .GetSelectedChanges(mPendingChangesTreeView);
  359. List<ChangeInfo> dependenciesCandidates =
  360. mPendingChangesTreeView.GetDependenciesCandidates(changesToUndo, true);
  361. UndoChangesForMode(
  362. mWkInfo, mIsGluonMode,
  363. changesToUndo, dependenciesCandidates);
  364. }
  365. void IPendingChangesMenuOperations.SearchMatches()
  366. {
  367. ChangeInfo selectedChange = PendingChangesSelection
  368. .GetSelectedChange(mPendingChangesTreeView);
  369. if (selectedChange == null)
  370. return;
  371. SearchMatchesOperation operation = new SearchMatchesOperation(
  372. mWkInfo, mWorkspaceWindow, this,
  373. mProgressControls, mDeveloperNewIncomingChangesUpdater);
  374. operation.SearchMatches(
  375. selectedChange,
  376. PendingChangesSelection.GetAllChanges(mPendingChangesTreeView),
  377. null);
  378. }
  379. void IPendingChangesMenuOperations.ApplyLocalChanges()
  380. {
  381. List<ChangeInfo> selectedChanges = PendingChangesSelection
  382. .GetSelectedChanges(mPendingChangesTreeView);
  383. if (selectedChanges.Count == 0)
  384. return;
  385. ApplyLocalChangesOperation operation = new ApplyLocalChangesOperation(
  386. mWkInfo, mWorkspaceWindow, this,
  387. mProgressControls, mDeveloperNewIncomingChangesUpdater);
  388. operation.ApplyLocalChanges(
  389. selectedChanges,
  390. PendingChangesSelection.GetAllChanges(mPendingChangesTreeView),
  391. null);
  392. }
  393. void IPendingChangesMenuOperations.Delete()
  394. {
  395. List<string> privateDirectoriesToDelete;
  396. List<string> privateFilesToDelete;
  397. if (!mPendingChangesTreeView.GetSelectedPathsToDelete(
  398. out privateDirectoriesToDelete,
  399. out privateFilesToDelete))
  400. return;
  401. DeleteOperation.Delete(
  402. mProgressControls,
  403. privateDirectoriesToDelete,
  404. privateFilesToDelete,
  405. mDeveloperNewIncomingChangesUpdater,
  406. RefreshAsset.UnityAssetDatabase,
  407. () => ((IWorkspaceWindow)mWorkspaceWindow).RefreshView(ViewType.ItemsView),
  408. () => ((IWorkspaceWindow)mWorkspaceWindow).RefreshView(ViewType.PendingChangesView));
  409. }
  410. void IPendingChangesMenuOperations.Annotate()
  411. {
  412. throw new NotImplementedException();
  413. }
  414. void IPendingChangesMenuOperations.History()
  415. {
  416. ChangeInfo selectedChange = PendingChangesSelection.
  417. GetSelectedChange(mPendingChangesTreeView);
  418. mHistoryViewLauncher.ShowHistoryView(
  419. selectedChange.RepositorySpec,
  420. selectedChange.RevInfo.ItemId,
  421. selectedChange.Path,
  422. selectedChange.IsDirectory);
  423. }
  424. SelectedChangesGroupInfo IChangelistMenuOperations.GetSelectedChangesGroupInfo()
  425. {
  426. return PendingChangesSelection.GetSelectedChangesGroupInfo(
  427. mWkInfo.ClientPath, mPendingChangesTreeView);
  428. }
  429. List<ChangeListInfo> IChangelistMenuOperations.GetSelectedChangelistInfos()
  430. {
  431. return PendingChangesSelection.GetSelectedChangeListInfos(
  432. mPendingChangesTreeView);
  433. }
  434. void IChangelistMenuOperations.Checkin()
  435. {
  436. List<ChangeInfo> changesToCheckin;
  437. List<ChangeInfo> dependenciesCandidates;
  438. mPendingChangesTreeView.GetCheckedChanges(
  439. PendingChangesSelection.GetSelectedChangelistNodes(mPendingChangesTreeView),
  440. false, out changesToCheckin, out dependenciesCandidates);
  441. CheckinChangesForMode(
  442. changesToCheckin, dependenciesCandidates,
  443. mWkInfo, mIsGluonMode, mKeepItemsLocked);
  444. }
  445. void IChangelistMenuOperations.Shelve()
  446. {
  447. if (mIsGluonMode)
  448. return;
  449. List<ChangeInfo> changesToShelve;
  450. List<ChangeInfo> dependenciesCandidates;
  451. mPendingChangesTreeView.GetCheckedChanges(
  452. PendingChangesSelection.GetSelectedChangelistNodes(mPendingChangesTreeView),
  453. false, out changesToShelve, out dependenciesCandidates);
  454. ShelveChanges(changesToShelve, dependenciesCandidates, mWkInfo);
  455. }
  456. void IChangelistMenuOperations.Undo()
  457. {
  458. List<ChangeInfo> changesToUndo;
  459. List<ChangeInfo> dependenciesCandidates;
  460. mPendingChangesTreeView.GetCheckedChanges(
  461. PendingChangesSelection.GetSelectedChangelistNodes(mPendingChangesTreeView),
  462. true, out changesToUndo, out dependenciesCandidates);
  463. UndoChangesForMode(
  464. mWkInfo, mIsGluonMode,
  465. changesToUndo, dependenciesCandidates);
  466. }
  467. void IChangelistMenuOperations.CreateNew()
  468. {
  469. ChangelistCreationData changelistCreationData =
  470. CreateChangelistDialog.CreateChangelist(mWkInfo, mParentWindow);
  471. ChangelistOperations.CreateNew(mWkInfo, this, changelistCreationData);
  472. }
  473. void IChangelistMenuOperations.MoveToNewChangelist(List<ChangeInfo> changes)
  474. {
  475. ChangelistCreationData changelistCreationData =
  476. CreateChangelistDialog.CreateChangelist(mWkInfo, mParentWindow);
  477. if (!changelistCreationData.Result)
  478. return;
  479. ChangelistOperations.CreateNew(mWkInfo, this, changelistCreationData);
  480. ChangelistOperations.MoveToChangelist(
  481. mWkInfo, this, changes,
  482. changelistCreationData.ChangelistInfo.Name);
  483. }
  484. void IChangelistMenuOperations.Edit()
  485. {
  486. ChangeListInfo changelistToEdit = PendingChangesSelection.GetSelectedChangeListInfo(
  487. mPendingChangesTreeView);
  488. ChangelistCreationData changelistCreationData = CreateChangelistDialog.EditChangelist(
  489. mWkInfo,
  490. changelistToEdit,
  491. mParentWindow);
  492. ChangelistOperations.Edit(mWkInfo, this, changelistToEdit, changelistCreationData);
  493. }
  494. void IChangelistMenuOperations.Delete()
  495. {
  496. ChangelistOperations.Delete(
  497. mWkInfo,
  498. this,
  499. PendingChangesSelection.GetSelectedChangelistNodes(mPendingChangesTreeView));
  500. }
  501. void IChangelistMenuOperations.MoveToChangelist(
  502. List<ChangeInfo> changes,
  503. string targetChangelist)
  504. {
  505. ChangelistOperations.MoveToChangelist(
  506. mWkInfo,
  507. this,
  508. changes,
  509. targetChangelist);
  510. }
  511. void IOpenMenuOperations.Open()
  512. {
  513. List<string> selectedPaths = PendingChangesSelection.
  514. GetSelectedPathsWithoutMeta(mPendingChangesTreeView);
  515. FileSystemOperation.Open(selectedPaths);
  516. }
  517. void IOpenMenuOperations.OpenWith()
  518. {
  519. List<string> selectedPaths = PendingChangesSelection.
  520. GetSelectedPathsWithoutMeta(mPendingChangesTreeView);
  521. OpenOperation.OpenWith(
  522. FileSystemOperation.GetExePath(),
  523. selectedPaths);
  524. }
  525. void IOpenMenuOperations.OpenWithCustom(string exePath, string args)
  526. {
  527. List<string> selectedPaths = PendingChangesSelection.
  528. GetSelectedPathsWithoutMeta(mPendingChangesTreeView);
  529. OpenOperation.OpenWith(exePath, selectedPaths);
  530. }
  531. void IOpenMenuOperations.OpenInExplorer()
  532. {
  533. List<string> selectedPaths = PendingChangesSelection
  534. .GetSelectedPathsWithoutMeta(mPendingChangesTreeView);
  535. if (selectedPaths.Count < 1)
  536. return;
  537. FileSystemOperation.OpenInExplorer(selectedPaths[0]);
  538. }
  539. void IFilesFilterPatternsMenuOperations.AddFilesFilterPatterns(
  540. FilterTypes type, FilterActions action, FilterOperationType operation)
  541. {
  542. List<string> selectedPaths = PendingChangesSelection.GetSelectedPaths(
  543. mPendingChangesTreeView);
  544. string[] rules = FilterRulesGenerator.GenerateRules(
  545. selectedPaths, mWkInfo.ClientPath, action, operation);
  546. bool isApplicableToAllWorkspaces = !mIsGluonMode;
  547. bool isAddOperation = operation == FilterOperationType.Add;
  548. FilterRulesConfirmationData filterRulesConfirmationData =
  549. FilterRulesConfirmationDialog.AskForConfirmation(
  550. rules, isAddOperation, isApplicableToAllWorkspaces, mParentWindow);
  551. AddFilesFilterPatternsOperation.Run(
  552. mWkInfo, mWorkspaceWindow, type, operation, filterRulesConfirmationData);
  553. }
  554. List<IPlasticTreeNode> PendingChangesViewMenu.IGetSelectedNodes.GetSelectedNodes()
  555. {
  556. return mPendingChangesTreeView.GetSelectedNodes();
  557. }
  558. void ChangesetsTab.IRevertToChangesetListener.OnSuccessOperation()
  559. {
  560. mHasPendingMergeLinksFromRevert = true;
  561. }
  562. void SearchField_OnDownOrUpArrowKeyPressed()
  563. {
  564. mPendingChangesTreeView.SetFocusAndEnsureSelectedItem();
  565. }
  566. void InitIgnoreRulesAndRefreshView(
  567. string wkPath, IRefreshableView view)
  568. {
  569. IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
  570. waiter.Execute(
  571. /*threadOperationDelegate*/ delegate
  572. {
  573. if (IsIgnoreConfigDefined.For(wkPath))
  574. return;
  575. AddIgnoreRules.WriteRules(
  576. wkPath, UnityConditions.GetMissingIgnoredRules(wkPath));
  577. },
  578. /*afterOperationDelegate*/ delegate
  579. {
  580. mAreIgnoreRulesInitialized = true;
  581. view.Refresh();
  582. if (waiter.Exception == null)
  583. return;
  584. mLog.ErrorFormat(
  585. "Error adding ignore rules for Unity: {0}",
  586. waiter.Exception);
  587. mLog.DebugFormat(
  588. "Stack trace: {0}",
  589. waiter.Exception.StackTrace);
  590. });
  591. }
  592. void FillPendingChanges(INewChangesInWk newChangesInWk)
  593. {
  594. if (mIsRefreshing)
  595. return;
  596. mIsRefreshing = true;
  597. List<ChangeInfo> changesToSelect =
  598. PendingChangesSelection.GetChangesToFocus(mPendingChangesTreeView);
  599. ((IProgressControls)mProgressControls).ShowProgress(PlasticLocalization.
  600. GetString(PlasticLocalization.Name.LoadingPendingChanges));
  601. IDictionary<MountPoint, IList<PendingMergeLink>> mergeLinks = null;
  602. WorkspaceStatusResult status = null;
  603. IThreadWaiter waiter = ThreadWaiter.GetWaiter();
  604. waiter.Execute(
  605. /*threadOperationDelegate*/ delegate
  606. {
  607. FilterManager.Get().Reload(mWkInfo);
  608. WorkspaceStatusOptions options = WorkspaceStatusOptions.None;
  609. options |= WorkspaceStatusOptions.FindAdded;
  610. options |= WorkspaceStatusOptions.FindDeleted;
  611. options |= WorkspaceStatusOptions.FindMoved;
  612. options |= WorkspaceStatusOptions.SplitModifiedMoved;
  613. options |= PendingChangesOptions.GetWorkspaceStatusOptions();
  614. if (newChangesInWk != null)
  615. newChangesInWk.Detected();
  616. status = GetStatus.ForWorkspace(
  617. mWkInfo,
  618. options,
  619. PendingChangesOptions.GetMovedMatchingOptions());
  620. mergeLinks = PlasticGui.Plastic.API.GetPendingMergeLinks(mWkInfo);
  621. },
  622. /*afterOperationDelegate*/ delegate
  623. {
  624. mPendingMergeLinks = mergeLinks;
  625. try
  626. {
  627. if (waiter.Exception != null)
  628. {
  629. ExceptionsHandler.DisplayException(waiter.Exception);
  630. return;
  631. }
  632. UpdateChangesTree(status.Changes);
  633. UpdateMergeLinksList();
  634. PendingChangesSelection.SelectChanges(
  635. mPendingChangesTreeView, changesToSelect);
  636. ClearAssetStatusCache();
  637. }
  638. finally
  639. {
  640. ((IProgressControls)mProgressControls).HideProgress();
  641. //UpdateIsCommentWarningNeeded(CommentText);
  642. UpdateNotificationPanel();
  643. mIsRefreshing = false;
  644. }
  645. });
  646. }
  647. void DoCommentsSection()
  648. {
  649. EditorGUILayout.BeginVertical(UnityStyles.PendingChangesTab.Comment);
  650. EditorGUILayout.Space(10);
  651. EditorGUILayout.BeginHorizontal();
  652. EditorGUILayout.Space(2);
  653. EditorGUILayout.BeginVertical();
  654. GUILayout.FlexibleSpace();
  655. DrawUserIcon.ForPendingChangesTab(CommentText);
  656. GUILayout.FlexibleSpace();
  657. EditorGUILayout.EndVertical();
  658. float width = Mathf.Clamp(mParentWindow.position.width, 300f, 820f);
  659. DrawCommentTextArea.For(
  660. this,
  661. width,
  662. mProgressControls.IsOperationRunning());
  663. EditorGUILayout.Space(2);
  664. // To center the action buttons vertically
  665. EditorGUILayout.BeginVertical();
  666. GUILayout.FlexibleSpace();
  667. DoOperationsToolbar(
  668. mWkInfo,
  669. mIsGluonMode,
  670. mAdvancedDropdownMenu,
  671. mProgressControls.IsOperationRunning());
  672. GUILayout.FlexibleSpace();
  673. EditorGUILayout.EndVertical();
  674. GUILayout.FlexibleSpace();
  675. EditorGUILayout.EndHorizontal();
  676. EditorGUILayout.Space(10);
  677. EditorGUILayout.EndVertical();
  678. }
  679. void DoOperationsToolbar(
  680. WorkspaceInfo wkInfo,
  681. bool isGluonMode,
  682. GenericMenu advancedDropdownMenu,
  683. bool isOperationRunning)
  684. {
  685. EditorGUILayout.BeginHorizontal();
  686. using (new GuiEnabled(!isOperationRunning))
  687. {
  688. if(mHasPendingCheckinFromPreviousUpdate)
  689. {
  690. mHasPendingCheckinFromPreviousUpdate = false;
  691. CheckinForMode(wkInfo, isGluonMode, mKeepItemsLocked);
  692. }
  693. else if (DrawActionButton.ForCommentSection(
  694. PlasticLocalization.GetString(
  695. PlasticLocalization.Name.CheckinChanges)))
  696. {
  697. UpdateIsCommentWarningNeeded(CommentText);
  698. if (!mIsEmptyCheckinCommentWarningNeeded &&
  699. mPendingChangesTreeView.GetCheckedItemCount() > 0)
  700. {
  701. CheckinForMode(wkInfo, isGluonMode, mKeepItemsLocked);
  702. }
  703. }
  704. GUILayout.Space(2);
  705. if (DrawActionButton.ForCommentSection(PlasticLocalization.GetString(
  706. PlasticLocalization.Name.UndoChanges)))
  707. {
  708. TrackFeatureUseEvent.For(PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
  709. TrackFeatureUseEvent.Features.UndoTextButton);
  710. UndoForMode(wkInfo, isGluonMode);
  711. }
  712. if (isGluonMode)
  713. {
  714. mKeepItemsLocked = EditorGUILayout.ToggleLeft(
  715. PlasticLocalization.GetString(PlasticLocalization.Name.KeepLocked),
  716. mKeepItemsLocked,
  717. GUILayout.Width(UnityConstants.EXTRA_LARGE_BUTTON_WIDTH));
  718. }
  719. //TODO: Codice - beta: hide the advanced menu until the behavior is implemented
  720. /*else
  721. {
  722. var dropDownContent = new GUIContent(string.Empty);
  723. var dropDownRect = GUILayoutUtility.GetRect(
  724. dropDownContent, EditorStyles.toolbarDropDown);
  725. if (EditorGUI.DropdownButton(dropDownRect, dropDownContent,
  726. FocusType.Passive, EditorStyles.toolbarDropDown))
  727. advancedDropdownMenu.DropDown(dropDownRect);
  728. }*/
  729. }
  730. EditorGUILayout.EndHorizontal();
  731. }
  732. void UpdateChangesTree(List<ChangeInfo> changes)
  733. {
  734. mPendingChangesTreeView.BuildModel(changes, mCheckedStateManager);
  735. mPendingChangesTreeView.Refilter();
  736. mPendingChangesTreeView.Sort();
  737. mPendingChangesTreeView.Reload();
  738. }
  739. static void DoWarningMessage(string message)
  740. {
  741. GUILayout.Label(message, UnityStyles.WarningMessage);
  742. }
  743. void UpdateMergeLinksList()
  744. {
  745. mMergeLinksListView.BuildModel(mPendingMergeLinks);
  746. mMergeLinksListView.Reload();
  747. if (!HasPendingMergeLinks())
  748. mHasPendingMergeLinksFromRevert = false;
  749. }
  750. void ClearAssetStatusCache()
  751. {
  752. if (mAssetStatusCache != null)
  753. mAssetStatusCache.Clear();
  754. ProjectWindow.Repaint();
  755. RepaintInspector.All();
  756. }
  757. void UpdateNotificationPanel()
  758. {
  759. if (PlasticGui.Plastic.API.IsFsReaderWatchLimitReached(mWkInfo))
  760. {
  761. ((IProgressControls)mProgressControls).ShowWarning(PlasticLocalization.
  762. GetString(PlasticLocalization.Name.NotifyLinuxWatchLimitWarning));
  763. return;
  764. }
  765. }
  766. void DoActionsToolbar(
  767. WorkspaceInfo workspaceInfo,
  768. bool isGluonMode,
  769. ProgressControlsForViews progressControls)
  770. {
  771. EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
  772. if (progressControls.IsOperationRunning())
  773. {
  774. DrawProgressForViews.ForIndeterminateProgress(
  775. progressControls.ProgressData);
  776. }
  777. GUILayout.FlexibleSpace();
  778. EditorGUILayout.EndHorizontal();
  779. }
  780. static void DoChangesArea(
  781. PendingChangesTreeView changesTreeView,
  782. bool isOperationRunning,
  783. bool isCheckedInSuccessful,
  784. string organizationToInviteUsers)
  785. {
  786. GUI.enabled = !isOperationRunning;
  787. Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
  788. changesTreeView.OnGUI(rect);
  789. if (changesTreeView.GetTotalItemCount() == 0)
  790. {
  791. DrawEmptyState(rect, isCheckedInSuccessful, organizationToInviteUsers);
  792. }
  793. GUI.enabled = true;
  794. }
  795. static void DrawEmptyState(
  796. Rect rect,
  797. bool isCheckedInSuccessful,
  798. string organizationToInviteUsers)
  799. {
  800. if (isCheckedInSuccessful)
  801. {
  802. DrawCheckinSuccessfulEmptyState(rect, organizationToInviteUsers);
  803. return;
  804. }
  805. DrawNoPendingChangesEmptyState(rect);
  806. }
  807. static void DrawNoPendingChangesEmptyState(Rect rect)
  808. {
  809. DrawTreeViewEmptyState.For(
  810. rect,
  811. PlasticLocalization.GetString(PlasticLocalization.Name.NoPendingChanges));
  812. }
  813. static void DrawCheckinSuccessfulEmptyState(
  814. Rect rect,
  815. string organizationToInviteUsers)
  816. {
  817. if (string.IsNullOrEmpty(organizationToInviteUsers))
  818. {
  819. DrawTreeViewEmptyState.For(
  820. rect,
  821. PlasticLocalization.GetString(PlasticLocalization.Name.CheckinCompleted),
  822. Images.GetStepOkIcon());
  823. return;
  824. }
  825. DrawInviteOtherTeamMembersEmptyState(rect, organizationToInviteUsers);
  826. }
  827. static void DrawInviteOtherTeamMembersEmptyState(Rect rect, string organizationToInviteUsers)
  828. {
  829. ExternalLink inviteUsersLink = new ExternalLink
  830. {
  831. Label = PlasticLocalization.GetString(PlasticLocalization.Name.InviteOtherTeamMembers),
  832. Url = UnityUrl.UnityDashboard.Plastic.GetForInviteUsers(organizationToInviteUsers)
  833. };
  834. DrawTreeViewEmptyState.For(
  835. rect,
  836. PlasticLocalization.GetString(PlasticLocalization.Name.CheckinCompleted),
  837. Images.GetStepOkIcon(),
  838. inviteUsersLink);
  839. }
  840. bool HasPendingMergeLinks()
  841. {
  842. if (mPendingMergeLinks == null)
  843. return false;
  844. return mPendingMergeLinks.Count > 0;
  845. }
  846. static void DoMergeLinksArea(
  847. MergeLinksListView mergeLinksListView, float width)
  848. {
  849. GUILayout.Label(
  850. PlasticLocalization.GetString(
  851. PlasticLocalization.Name.MergeLinkDescriptionColumn),
  852. EditorStyles.boldLabel);
  853. float desiredTreeHeight = mergeLinksListView.DesiredHeight;
  854. Rect treeRect = GUILayoutUtility.GetRect(
  855. 0,
  856. width,
  857. desiredTreeHeight,
  858. desiredTreeHeight);
  859. mergeLinksListView.OnGUI(treeRect);
  860. }
  861. void BuildComponents(
  862. bool isGluonMode,
  863. EditorWindow plasticWindow)
  864. {
  865. mHelpPanel = new HelpPanel(plasticWindow);
  866. mAdvancedDropdownMenu = new GenericMenu();
  867. mAdvancedDropdownMenu.AddItem(new GUIContent(
  868. PlasticLocalization.GetString(PlasticLocalization.Name.UndoUnchangedButton)),
  869. false, () => { });
  870. mSearchField = new SearchField();
  871. mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
  872. PendingChangesTreeHeaderState headerState =
  873. PendingChangesTreeHeaderState.GetDefault(isGluonMode);
  874. TreeHeaderSettings.Load(headerState,
  875. UnityConstants.PENDING_CHANGES_TABLE_SETTINGS_NAME,
  876. (int)PendingChangesTreeColumn.Item, true);
  877. mPendingChangesTreeView = new PendingChangesTreeView(
  878. mWkInfo, mIsGluonMode, headerState,
  879. PendingChangesTreeHeaderState.GetColumnNames(),
  880. new PendingChangesViewMenu(mWkInfo, this, this, this, this, this, this, mIsGluonMode),
  881. mAssetStatusCache);
  882. mPendingChangesTreeView.Reload();
  883. mMergeLinksListView = new MergeLinksListView();
  884. mMergeLinksListView.Reload();
  885. }
  886. INewChangesInWk mNewChangesInWk;
  887. GenericMenu mAdvancedDropdownMenu;
  888. void ClearComments()
  889. {
  890. CommentText = string.Empty;
  891. ForceToShowComment = true;
  892. mParentWindow.Repaint();
  893. }
  894. PendingChangesTreeView mPendingChangesTreeView;
  895. MergeLinksListView mMergeLinksListView;
  896. HelpPanel mHelpPanel;
  897. volatile bool mAreIgnoreRulesInitialized = false;
  898. bool mIsRefreshing;
  899. bool mIsAutoRefreshDisabled;
  900. bool mIsEmptyCheckinCommentWarningNeeded = false;
  901. bool mNeedsToShowEmptyCommentDialog = false;
  902. bool mHasPendingCheckinFromPreviousUpdate = false;
  903. bool mHasPendingMergeLinksFromRevert = false;
  904. bool mKeepItemsLocked;
  905. string mGluonWarningMessage;
  906. bool mIsCheckedInSuccessful;
  907. string mOrganizationToInviteUsers;
  908. IDictionary<MountPoint, IList<PendingMergeLink>> mPendingMergeLinks;
  909. SearchField mSearchField;
  910. Color mBorderColor;
  911. readonly ProgressControlsForViews mProgressControls;
  912. readonly EditorWindow mParentWindow;
  913. readonly StatusBar mStatusBar;
  914. readonly CooldownWindowDelayer mCooldownClearCheckinSuccessAction;
  915. readonly IAssetStatusCache mAssetStatusCache;
  916. readonly PendingChangesOperations mPendingChangesOperations;
  917. readonly PendingChangesViewCheckedStateManager mCheckedStateManager;
  918. readonly GuiMessage.IGuiMessage mGuiMessage;
  919. readonly NewIncomingChangesUpdater mDeveloperNewIncomingChangesUpdater;
  920. readonly GluonNewIncomingChangesUpdater mGluonNewIncomingChangesUpdater;
  921. readonly bool mIsGluonMode;
  922. readonly WorkspaceOperationsMonitor mWorkspaceOperationsMonitor;
  923. readonly LaunchTool.IShowDownloadPlasticExeWindow mShowDownloadPlasticExeWindow;
  924. readonly IHistoryViewLauncher mHistoryViewLauncher;
  925. readonly WorkspaceWindow mWorkspaceWindow;
  926. readonly ViewHost mViewHost;
  927. readonly WorkspaceInfo mWkInfo;
  928. static readonly ILog mLog = LogManager.GetLogger("PendingChangesTab");
  929. }
  930. }