PlasticProjectSettingsProvider.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. using Codice.Client.Commands;
  2. using Codice.Client.Common.FsNodeReaders;
  3. using Codice.Client.Common.Threading;
  4. using Codice.CM.Common;
  5. using Codice.Utils;
  6. using PlasticGui;
  7. using PlasticGui.WorkspaceWindow.PendingChanges;
  8. using Unity.PlasticSCM.Editor.UI;
  9. using UnityEditor;
  10. using UnityEngine;
  11. using UnityEngine.UIElements;
  12. namespace Unity.PlasticSCM.Editor
  13. {
  14. class PlasticProjectSettingsProvider : SettingsProvider
  15. {
  16. public PlasticProjectSettingsProvider(string path, SettingsScope scope = SettingsScope.User)
  17. : base(path, scope) { }
  18. /// <summary>
  19. /// When initialized
  20. /// </summary>
  21. public override void OnActivate(string searchContext, VisualElement rootElement)
  22. {
  23. IAutoRefreshView autoRefreshView = GetPendingChangesView();
  24. if (autoRefreshView != null)
  25. autoRefreshView.DisableAutoRefresh();
  26. // Check if FSWatcher should be enabled
  27. WorkspaceInfo workspaceInfo = FindWorkspace.InfoForApplicationPath(
  28. Application.dataPath,
  29. PlasticApp.PlasticAPI);
  30. CheckFsWatcher(workspaceInfo);
  31. mInitialOptions = new PendingChangesOptions();
  32. mInitialOptions.LoadPendingChangesOptions();
  33. SetOptions(mInitialOptions);
  34. }
  35. public override void OnDeactivate()
  36. {
  37. if (mInitialOptions == null)
  38. return;
  39. bool isDialogueDirty = false;
  40. try
  41. {
  42. PendingChangesOptions currentOptions = GetOptions();
  43. isDialogueDirty = IsDirty(currentOptions);
  44. if (!isDialogueDirty)
  45. return;
  46. currentOptions.SavePreferences();
  47. }
  48. finally
  49. {
  50. IAutoRefreshView autoRefreshView = GetPendingChangesView();
  51. if (autoRefreshView != null)
  52. {
  53. autoRefreshView.EnableAutoRefresh();
  54. if (isDialogueDirty)
  55. autoRefreshView.ForceRefresh();
  56. }
  57. }
  58. }
  59. /// <summary>
  60. /// Called every frame for the Projects Setting window/Plastic SCM category
  61. /// </summary>
  62. public override void OnGUI(string searchContext)
  63. {
  64. EditorGUIUtility.labelWidth = 395;
  65. DoGeneralSettings();
  66. DoFileChangeSettings();
  67. DoFileVisibililySettings();
  68. DoFileDetectionSetings();
  69. DoFsWatcherMessage(mFSWatcherEnabled);
  70. }
  71. [SettingsProvider]
  72. public static SettingsProvider CreateSettingsProvider()
  73. {
  74. if (CollabPlugin.IsEnabled())
  75. return null;
  76. if (!FindWorkspace.HasWorkspace(Application.dataPath))
  77. return null;
  78. PlasticProjectSettingsProvider provider = new PlasticProjectSettingsProvider(
  79. UnityConstants.PROJECT_SETTINGS_MENU_TITLE, SettingsScope.Project)
  80. {
  81. keywords = GetSearchKeywordsFromGUIContentProperties<Styles>()
  82. };
  83. return provider;
  84. }
  85. void DoGeneralSettings()
  86. {
  87. EditorGUILayout.Space(5);
  88. GUILayout.Label(
  89. PlasticLocalization.GetString(
  90. PlasticLocalization.Name.ProjectSettingsGeneral),
  91. EditorStyles.boldLabel);
  92. EditorGUILayout.Space(1);
  93. mShowCheckouts = EditorGUILayout.Toggle(Styles.showCheckouts, mShowCheckouts);
  94. mAutoRefresh = EditorGUILayout.Toggle(Styles.autoRefresh, mAutoRefresh);
  95. }
  96. void DoFileChangeSettings()
  97. {
  98. EditorGUILayout.Space(5);
  99. GUILayout.Label(
  100. PlasticLocalization.GetString(
  101. PlasticLocalization.Name.ProjectSettingsFileChange),
  102. EditorStyles.boldLabel);
  103. EditorGUILayout.Space(1);
  104. mShowChangedFiles = EditorGUILayout.Toggle(Styles.showChangedFiles, mShowChangedFiles);
  105. mCheckFileContent = EditorGUILayout.Toggle(Styles.checkFileContent, mCheckFileContent);
  106. }
  107. void DoFileVisibililySettings()
  108. {
  109. EditorGUILayout.Space(5);
  110. GUILayout.Label(
  111. PlasticLocalization.GetString(
  112. PlasticLocalization.Name.ProjectSettingsFileVisibility),
  113. EditorStyles.boldLabel);
  114. EditorGUILayout.Space(1);
  115. mUseChangeLists = EditorGUILayout.Toggle(Styles.useChangeLists, mUseChangeLists);
  116. mShowPrivateFields = EditorGUILayout.Toggle(Styles.showPrivateFields, mShowPrivateFields);
  117. mShowIgnoredFiles = EditorGUILayout.Toggle(Styles.showIgnoredFields, mShowIgnoredFiles);
  118. mShowHiddenFiles = EditorGUILayout.Toggle(Styles.showHiddenFields, mShowHiddenFiles);
  119. mShowDeletedFiles = EditorGUILayout.Toggle(Styles.showDeletedFilesDirs, mShowDeletedFiles);
  120. }
  121. void DoFileDetectionSetings()
  122. {
  123. EditorGUILayout.Space(5);
  124. GUILayout.Label(
  125. PlasticLocalization.GetString(
  126. PlasticLocalization.Name.ProjectSettingsMoveAndRename),
  127. EditorStyles.boldLabel);
  128. EditorGUILayout.Space(1);
  129. mShowMovedFiles = EditorGUILayout.Toggle(Styles.showMovedFiles, mShowMovedFiles);
  130. mMatchBinarySameExtension = EditorGUILayout.Toggle(Styles.matchBinarySameExtension, mMatchBinarySameExtension);
  131. mMatchTextSameExtension = EditorGUILayout.Toggle(Styles.matchTextSameExtension, mMatchTextSameExtension);
  132. mSimilarityPercent = EditorGUILayout.IntSlider(Styles.similarityPercent, mSimilarityPercent, 0, 100);
  133. }
  134. /*** FS Watcher Message ***/
  135. void DoFsWatcherMessage(bool isEnabled)
  136. {
  137. EditorGUILayout.Space(45);
  138. GUIContent message = new GUIContent(
  139. isEnabled ?
  140. GetFsWatcherEnabledMessage() :
  141. GetFsWatcherDisabledMessage(),
  142. isEnabled ?
  143. Images.GetInfoIcon() :
  144. Images.GetWarnIcon());
  145. GUILayout.Label(message, UnityStyles.Dialog.Toggle, GUILayout.Height(32));
  146. GUILayout.Space(-10);
  147. string formattedExplanation = isEnabled ?
  148. GetFsWatcherEnabledExplanation() :
  149. GetFsWatcherDisabledExplanation();
  150. string helpLink = GetHelpLink();
  151. DrawTextBlockWithEndLink.For(
  152. helpLink, formattedExplanation, UnityStyles.Paragraph);
  153. }
  154. void CheckFsWatcher(WorkspaceInfo wkInfo)
  155. {
  156. bool isFileSystemWatcherEnabled = false;
  157. IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
  158. waiter.Execute(
  159. /*threadOperationDelegate*/
  160. delegate
  161. {
  162. isFileSystemWatcherEnabled =
  163. IsFileSystemWatcherEnabled(wkInfo);
  164. },
  165. /*afterOperationDelegate*/
  166. delegate
  167. {
  168. if (waiter.Exception != null)
  169. return;
  170. mFSWatcherEnabled = isFileSystemWatcherEnabled;
  171. });
  172. }
  173. PendingChangesOptions GetOptions()
  174. {
  175. WorkspaceStatusOptions resultWkStatusOptions =
  176. WorkspaceStatusOptions.None;
  177. if (mShowCheckouts)
  178. {
  179. resultWkStatusOptions |= WorkspaceStatusOptions.FindCheckouts;
  180. resultWkStatusOptions |= WorkspaceStatusOptions.FindReplaced;
  181. resultWkStatusOptions |= WorkspaceStatusOptions.FindCopied;
  182. }
  183. if (mShowChangedFiles)
  184. resultWkStatusOptions |= WorkspaceStatusOptions.FindChanged;
  185. if (mShowPrivateFields)
  186. resultWkStatusOptions |= WorkspaceStatusOptions.FindPrivates;
  187. if (mShowIgnoredFiles)
  188. resultWkStatusOptions |= WorkspaceStatusOptions.ShowIgnored;
  189. if (mShowHiddenFiles)
  190. resultWkStatusOptions |= WorkspaceStatusOptions.ShowHiddenChanges;
  191. if (mShowDeletedFiles)
  192. resultWkStatusOptions |= WorkspaceStatusOptions.FindLocallyDeleted;
  193. if (mShowMovedFiles)
  194. resultWkStatusOptions |= WorkspaceStatusOptions.CalculateLocalMoves;
  195. MovedMatchingOptions matchingOptions = new MovedMatchingOptions();
  196. matchingOptions.AllowedChangesPerUnit =
  197. (100 - mSimilarityPercent) / 100f;
  198. matchingOptions.bBinMatchingOnlySameExtension =
  199. mMatchBinarySameExtension;
  200. matchingOptions.bTxtMatchingOnlySameExtension =
  201. mMatchTextSameExtension;
  202. return new PendingChangesOptions(
  203. resultWkStatusOptions,
  204. matchingOptions,
  205. mUseChangeLists,
  206. mAutoRefresh,
  207. false,
  208. mCheckFileContent,
  209. false);
  210. }
  211. void SetOptions(PendingChangesOptions options)
  212. {
  213. mShowCheckouts = IsEnabled(
  214. WorkspaceStatusOptions.FindCheckouts, options.WorkspaceStatusOptions);
  215. mAutoRefresh = options.AutoRefresh;
  216. mShowChangedFiles = IsEnabled(
  217. WorkspaceStatusOptions.FindChanged, options.WorkspaceStatusOptions);
  218. mCheckFileContent = options.CheckFileContentForChanged;
  219. mUseChangeLists = options.UseChangeLists;
  220. mShowPrivateFields = IsEnabled(
  221. WorkspaceStatusOptions.FindPrivates, options.WorkspaceStatusOptions);
  222. mShowIgnoredFiles = IsEnabled(
  223. WorkspaceStatusOptions.ShowIgnored, options.WorkspaceStatusOptions);
  224. mShowHiddenFiles = IsEnabled(
  225. WorkspaceStatusOptions.ShowHiddenChanges, options.WorkspaceStatusOptions);
  226. mShowDeletedFiles = IsEnabled(
  227. WorkspaceStatusOptions.FindLocallyDeleted, options.WorkspaceStatusOptions);
  228. mShowMovedFiles = IsEnabled(
  229. WorkspaceStatusOptions.CalculateLocalMoves, options.WorkspaceStatusOptions);
  230. mMatchBinarySameExtension =
  231. options.MovedMatchingOptions.bBinMatchingOnlySameExtension;
  232. mMatchTextSameExtension =
  233. options.MovedMatchingOptions.bTxtMatchingOnlySameExtension;
  234. mSimilarityPercent = (int)((1 - options.MovedMatchingOptions.AllowedChangesPerUnit) * 100f);
  235. }
  236. bool IsDirty(PendingChangesOptions currentOptions)
  237. {
  238. return !mInitialOptions.AreSameOptions(currentOptions);
  239. }
  240. static string GetFsWatcherEnabledMessage()
  241. {
  242. if (PlatformIdentifier.IsWindows() || PlatformIdentifier.IsMac())
  243. return PlasticLocalization.GetString(
  244. PlasticLocalization.Name.PendingChangesFilesystemWatcherEnabled);
  245. return PlasticLocalization.GetString(
  246. PlasticLocalization.Name.PendingChangesINotifyEnabled);
  247. }
  248. static string GetFsWatcherDisabledMessage()
  249. {
  250. if (PlatformIdentifier.IsWindows() || PlatformIdentifier.IsMac())
  251. return PlasticLocalization.GetString(
  252. PlasticLocalization.Name.PendingChangesFilesystemWatcherDisabled);
  253. return PlasticLocalization.GetString(
  254. PlasticLocalization.Name.PendingChangesINotifyDisabled);
  255. }
  256. static string GetFsWatcherEnabledExplanation()
  257. {
  258. if (PlatformIdentifier.IsWindows() || PlatformIdentifier.IsMac())
  259. return PlasticLocalization.GetString(
  260. PlasticLocalization.Name.PendingChangesFilesystemWatcherEnabledExplanation);
  261. return PlasticLocalization.GetString(
  262. PlasticLocalization.Name.PendingChangesINotifyEnabledExplanation);
  263. }
  264. static string GetFsWatcherDisabledExplanation()
  265. {
  266. if (PlatformIdentifier.IsWindows() || PlatformIdentifier.IsMac())
  267. {
  268. return PlasticLocalization.GetString(
  269. PlasticLocalization.Name.PendingChangesFilesystemWatcherDisabledExplanation)
  270. .Replace("[[HELP_URL|{0}]]", "{0}");
  271. }
  272. return PlasticLocalization.GetString(
  273. PlasticLocalization.Name.PendingChangesINotifyDisabledExplanation);
  274. }
  275. static string GetHelpLink()
  276. {
  277. if (PlatformIdentifier.IsWindows() || PlatformIdentifier.IsMac())
  278. return FS_WATCHER_HELP_URL;
  279. return INOTIFY_HELP_URL;
  280. }
  281. static bool IsFileSystemWatcherEnabled(WorkspaceInfo wkInfo)
  282. {
  283. return WorkspaceWatcherFsNodeReadersCache.Get().
  284. IsWatcherEnabled(wkInfo);
  285. }
  286. static bool IsEnabled(WorkspaceStatusOptions option, WorkspaceStatusOptions options)
  287. {
  288. return (options & option) == option;
  289. }
  290. static IAutoRefreshView GetPendingChangesView()
  291. {
  292. if (!EditorWindow.HasOpenInstances<PlasticWindow>())
  293. return null;
  294. PlasticWindow window = EditorWindow.
  295. GetWindow<PlasticWindow>(null, false);
  296. return window.GetPendingChangesView();
  297. }
  298. internal interface IAutoRefreshView
  299. {
  300. void DisableAutoRefresh();
  301. void EnableAutoRefresh();
  302. void ForceRefresh();
  303. }
  304. /// <summary>
  305. /// UI styles and label content
  306. /// </summary>
  307. class Styles
  308. {
  309. internal static GUIContent showCheckouts =
  310. new GUIContent(PlasticLocalization.GetString(
  311. PlasticLocalization.Name.PendingChangesShowCheckouts),
  312. PlasticLocalization.GetString(
  313. PlasticLocalization.Name.PendingChangesShowCheckoutsExplanation));
  314. internal static GUIContent autoRefresh =
  315. new GUIContent(PlasticLocalization.GetString(
  316. PlasticLocalization.Name.PendingChangesAutoRefresh),
  317. PlasticLocalization.GetString(
  318. PlasticLocalization.Name.PendingChangesAutoRefreshExplanation));
  319. internal static GUIContent showChangedFiles =
  320. new GUIContent(PlasticLocalization.GetString(
  321. PlasticLocalization.Name.PendingChangesFindChanged),
  322. PlasticLocalization.GetString(
  323. PlasticLocalization.Name.PendingChangesFindChangedExplanation));
  324. internal static GUIContent checkFileContent =
  325. new GUIContent(PlasticLocalization.GetString(
  326. PlasticLocalization.Name.PendingChangesCheckFileContent),
  327. PlasticLocalization.GetString(
  328. PlasticLocalization.Name.PendingChangesCheckFileContentExplanation));
  329. internal static GUIContent useChangeLists =
  330. new GUIContent(PlasticLocalization.GetString(
  331. PlasticLocalization.Name.PendingChangesGroupInChangeLists),
  332. PlasticLocalization.GetString(
  333. PlasticLocalization.Name.PendingChangesGroupInChangeListsExplanation));
  334. internal static GUIContent showPrivateFields =
  335. new GUIContent(PlasticLocalization.GetString(
  336. PlasticLocalization.Name.PendingChangesShowPrivateFiles),
  337. PlasticLocalization.GetString(
  338. PlasticLocalization.Name.PendingChangesShowPrivateFilesExplanation));
  339. internal static GUIContent showIgnoredFields =
  340. new GUIContent(PlasticLocalization.GetString(
  341. PlasticLocalization.Name.PendingChangesShowIgnoredFiles),
  342. PlasticLocalization.GetString(
  343. PlasticLocalization.Name.PendingChangesShowIgnoredFilesExplanation));
  344. internal static GUIContent showHiddenFields =
  345. new GUIContent(PlasticLocalization.GetString(
  346. PlasticLocalization.Name.PendingChangesShowHiddenFiles),
  347. PlasticLocalization.GetString(
  348. PlasticLocalization.Name.PendingChangesShowHiddenFilesExplanation));
  349. internal static GUIContent showDeletedFilesDirs =
  350. new GUIContent(PlasticLocalization.GetString(
  351. PlasticLocalization.Name.PendingChangesShowDeletedFiles),
  352. PlasticLocalization.GetString(
  353. PlasticLocalization.Name.PendingChangesShowDeletedFilesExplanation));
  354. internal static GUIContent showMovedFiles =
  355. new GUIContent(PlasticLocalization.GetString(
  356. PlasticLocalization.Name.PendingChangesFindMovedFiles),
  357. PlasticLocalization.GetString(
  358. PlasticLocalization.Name.PendingChangesFindMovedFilesExplanation));
  359. internal static GUIContent matchBinarySameExtension =
  360. new GUIContent(PlasticLocalization.GetString(
  361. PlasticLocalization.Name.PendingChangesMatchBinarySameExtension),
  362. PlasticLocalization.GetString(
  363. PlasticLocalization.Name.PendingChangesMatchBinarySameExtensionExplanation));
  364. internal static GUIContent matchTextSameExtension =
  365. new GUIContent(PlasticLocalization.GetString(
  366. PlasticLocalization.Name.PendingChangesMatchTextSameExtension),
  367. PlasticLocalization.GetString(
  368. PlasticLocalization.Name.PendingChangesMatchTextSameExtensionExplanation));
  369. internal static GUIContent similarityPercent =
  370. new GUIContent(PlasticLocalization.GetString(
  371. PlasticLocalization.Name.PendingChangesSimilarityPercentage),
  372. PlasticLocalization.GetString(
  373. PlasticLocalization.Name.PendingChangesSimilarityPercentageExplanation));
  374. }
  375. PendingChangesOptions mInitialOptions;
  376. bool mShowCheckouts;
  377. bool mAutoRefresh;
  378. bool mFSWatcherEnabled;
  379. bool mShowChangedFiles;
  380. bool mCheckFileContent;
  381. bool mUseChangeLists;
  382. bool mShowPrivateFields;
  383. bool mShowIgnoredFiles;
  384. bool mShowHiddenFiles;
  385. bool mShowDeletedFiles;
  386. bool mShowMovedFiles;
  387. bool mMatchBinarySameExtension;
  388. bool mMatchTextSameExtension;
  389. int mSimilarityPercent;
  390. const string FS_WATCHER_HELP_URL = "https://plasticscm.com/download/help/support";
  391. const string INOTIFY_HELP_URL = "https://plasticscm.com/download/help/inotify";
  392. }
  393. }