public static void UninstallPackage() { // Display MultiSelectWindow MultiSelectWindow window = MultiSelectWindow.CreateMultiSelectWindow(windowTitle); window.AvailableItems = GetSelectionList(); window.Sort(1); window.Caption = caption; window.ApplyLabel = applylable; window.OnApply = () => { if (window.SelectedItems.Count > 0) { VersionHandlerImpl.ManifestReferences.DeletePackages(window.SelectedItems); if (window.SelectedItems.Count == window.AvailableItems.Count) { VersionHandlerImpl.analytics.Report("uninstallpackagewindow/confirm/all", "Confirm to Uninstall All Packages"); } else { VersionHandlerImpl.analytics.Report("uninstallpackagewindow/confirm/subset", "Confirm to Uninstall a Subset of Packages"); } } }; window.OnCancel = () => { VersionHandlerImpl.analytics.Report("uninstallpackagewindow/cancel", "Cancel to Uninstall Packages"); }; window.Show(); VersionHandlerImpl.analytics.Report("uninstallpackagewindow/show", "Show Uninstall Package Window"); }
/// <summary> /// Get the existing multi-select window or create a new one. /// </summary> /// <param name="title">Title to display on the window.</param> /// <returns>Reference to this class</returns> public static MultiSelectWindow CreateMultiSelectWindow(string title) { MultiSelectWindow window = (MultiSelectWindow)EditorWindow.GetWindow( typeof(MultiSelectWindow), true, title, true); window.Initialize(); return(window); }
/// <summary> /// Update manifest file based on the settings. /// </summary> /// <param name="mode">Manifest modification mode being applied.</param> /// <param name="promptBeforeAction">Whether to display a window that prompts the user for /// confirmation before applying changes.</param> /// <param name="showDisableButton">Whether to show a button to disable auto-registry /// addition.</param> /// <param name="scopePrefixFilter">List of scope prefixes used to filter the set of registries /// being operated on.</param> internal static void UpdateManifest(ManifestModificationMode mode, bool promptBeforeAction = true, bool showDisableButton = false, IEnumerable <string> scopePrefixFilter = null) { if (!ScopedRegistriesSupported) { logger.Log(String.Format("Scoped registries not supported in this version of Unity."), level: LogLevel.Verbose); return; } PackageManifestModifier modifier = new PackageManifestModifier() { Logger = logger }; Dictionary <string, List <PackageManagerRegistry> > manifestRegistries = modifier.ReadManifest() ? modifier.PackageManagerRegistries : null; if (manifestRegistries == null) { PackageManagerResolver.analytics.Report( "registry_manifest/read/failed", "Update Manifest failed: Read/Parse manifest failed"); return; } var xmlRegistries = ReadRegistriesFromXml(); // Filter registries using the scope prefixes. if (scopePrefixFilter != null) { foreach (var registry in new List <PackageManagerRegistry>(xmlRegistries.Values)) { bool removeRegistry = true; foreach (var scope in registry.Scopes) { foreach (var scopePrefix in scopePrefixFilter) { if (scope.StartsWith(scopePrefix)) { removeRegistry = false; } } } if (removeRegistry) { xmlRegistries.Remove(registry.Url); } } } // Filter the set of considered registries based upon the modification mode. HashSet <string> selectedRegistryUrls = null; switch (mode) { case ManifestModificationMode.Add: // Remove all items from the XML loaded registries that are present in the manifest. foreach (var url in manifestRegistries.Keys) { xmlRegistries.Remove(url); } selectedRegistryUrls = new HashSet <string>(xmlRegistries.Keys); break; case ManifestModificationMode.Remove: // Remove all items from the XML loaded registries that are not present in the // manifest. foreach (var url in new List <string>(xmlRegistries.Keys)) { if (!manifestRegistries.ContainsKey(url)) { xmlRegistries.Remove(url); } } selectedRegistryUrls = new HashSet <string>(xmlRegistries.Keys); break; case ManifestModificationMode.Modify: selectedRegistryUrls = new HashSet <string>(); // Keep all XML loaded registries and select the items in the manifest. foreach (var url in xmlRegistries.Keys) { if (manifestRegistries.ContainsKey(url)) { selectedRegistryUrls.Add(url); } } break; } // Applies the manifest modification based upon the modification mode. Action <HashSet <string> > syncRegistriesToManifest = (urlSelectionToApply) => { var addedRegistries = new List <PackageManagerRegistry>(); SyncRegistriesToManifest(modifier, xmlRegistries, manifestRegistries, urlSelectionToApply, addRegistries: (mode == ManifestModificationMode.Add || mode == ManifestModificationMode.Modify), removeRegistries: (mode == ManifestModificationMode.Remove || mode == ManifestModificationMode.Modify), invertSelection: mode == ManifestModificationMode.Remove, addedRegistries: addedRegistries); // If any registries were added try migration if enabled. if (addedRegistries.Count > 0 && PromptToMigratePackages) { PackageMigrator.MigratePackages(); } }; // Get the manifest json string based on the current selection and mode. Func <HashSet <string>, string> getManifestJsonAfterChange = (urlSelectionToApply) => { PackageManifestModifier clonedModifier = new PackageManifestModifier(modifier); List <PackageManagerRegistry> toAdd; List <PackageManagerRegistry> toRemove; SyncRegistriesToModifier(clonedModifier, out toAdd, out toRemove, xmlRegistries, manifestRegistries, urlSelectionToApply, addRegistries: (mode == ManifestModificationMode.Add || mode == ManifestModificationMode.Modify), removeRegistries: (mode == ManifestModificationMode.Remove || mode == ManifestModificationMode.Modify), invertSelection: mode == ManifestModificationMode.Remove); return(clonedModifier.GetManifestJson()); }; if (xmlRegistries.Count > 0) { if (promptBeforeAction) { // Build a list of items to display. var registryItems = new List <KeyValuePair <string, string> >(); foreach (var kv in xmlRegistries) { registryItems.Add(new KeyValuePair <string, string>(kv.Key, kv.Value.Name)); } // Optional when prompting is enabled or forced. var window = MultiSelectWindow.CreateMultiSelectWindow <PackageManagerResolverWindow>( PLUGIN_NAME); window.minSize = new Vector2(1024, 500); window.AvailableItems = registryItems; window.Sort(1); window.SelectedItems = selectedRegistryUrls; switch (mode) { case ManifestModificationMode.Add: window.Caption = String.Format("{0}\n\n{1}\n\n{2}", ADD_REGISTRIES_QUESTION, ADD_REGISTRIES_DESCRIPTION, MODIFY_MENU_ITEM_DESCRIPTION); window.ApplyLabel = "Add Selected Registries"; break; case ManifestModificationMode.Remove: window.Caption = String.Format("{0}\n\n{1}{2}", REMOVE_REGISTRIES_QUESTION, REMOVE_REGISTRIES_DESCRIPTION, MODIFY_MENU_ITEM_DESCRIPTION); window.ApplyLabel = "Remove Selected Registries"; break; case ManifestModificationMode.Modify: window.Caption = String.Format("{0}\n\n{1} {2}", ADD_OR_REMOVE_REGISTRIES_QUESTION, ADD_REGISTRIES_DESCRIPTION, REMOVE_REGISTRIES_DESCRIPTION); window.ApplyLabel = "Modify Registries"; break; } window.RenderItem = (item) => { var registry = xmlRegistries[item.Key]; var termsOfService = registry.TermsOfService; if (!String.IsNullOrEmpty(termsOfService)) { if (GUILayout.Button("View Terms of Service")) { Application.OpenURL(termsOfService); } } var privacyPolicy = registry.PrivacyPolicy; if (!String.IsNullOrEmpty(privacyPolicy)) { if (GUILayout.Button("View Privacy Policy")) { Application.OpenURL(privacyPolicy); } } }; // Set the scroll position to the bottom since "scopedRegistry" section is most // likely at the bottom of the file. scrollManifestViewLeft = new Vector2(0.0f, float.PositiveInfinity); scrollManifestViewRight = new Vector2(0.0f, float.PositiveInfinity); // Render the change in manifest.json dynamically. window.RenderAfterItems = () => { GUILayout.Label("Changes to Packages/manifest.json"); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); GUILayout.Label("Before", EditorStyles.boldLabel); EditorGUILayout.Space(); scrollManifestViewLeft = EditorGUILayout.BeginScrollView(scrollManifestViewLeft, GUILayout.MaxWidth(window.position.width / 2.0f)); EditorGUILayout.TextArea(modifier.GetManifestJson()); EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); EditorGUILayout.Space(); EditorGUILayout.BeginVertical(); GUILayout.Label("After", EditorStyles.boldLabel); EditorGUILayout.Space(); scrollManifestViewRight = EditorGUILayout.BeginScrollView(scrollManifestViewRight, GUILayout.MaxWidth(window.position.width / 2.0f)); EditorGUILayout.TextArea(getManifestJsonAfterChange(window.SelectedItems)); EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); }; if (showDisableButton) { window.RenderBeforeCancelApply = () => { if (GUILayout.Button("Disable Registry Addition")) { Enable = false; window.Close(); } }; } window.OnApply = () => { syncRegistriesToManifest(window.SelectedItems); }; window.Show(); } else { syncRegistriesToManifest(selectedRegistryUrls); } } }
/// <summary> /// Update manifest file based on the settings. /// </summary> /// <param name="mode">Manifest modification mode being applied.</param> /// <param name="promptBeforeAction">Whether to display a window that prompts the user for /// confirmation before applying changes.</param> /// <param name="showDisableButton">Whether to show a button to disable auto-registry /// addition.</param> /// <param name="scopePrefixFilter">List of scope prefixes used to filter the set of registries /// being operated on.</param> private static void UpdateManifest(ManifestModificationMode mode, bool promptBeforeAction = true, bool showDisableButton = false, IEnumerable <string> scopePrefixFilter = null) { if (!ScopedRegistriesSupported) { logger.Log(String.Format("Scoped registries not supported in this version of Unity."), level: LogLevel.Verbose); return; } PackageManifestModifier modifier = new PackageManifestModifier() { Logger = logger }; Dictionary <string, List <UnityPackageManagerRegistry> > manifestRegistries = modifier.ReadManifest() ? modifier.UnityPackageManagerRegistries : null; if (manifestRegistries == null) { UnityPackageManagerResolver.analytics.Report( "registry_manifest/read/failed", "Update Manifest failed: Read/Parse manifest failed"); return; } var xmlRegistries = ReadRegistriesFromXml(); // Filter registries using the scope prefixes. if (scopePrefixFilter != null) { foreach (var registry in new List <UnityPackageManagerRegistry>(xmlRegistries.Values)) { bool removeRegistry = true; foreach (var scope in registry.Scopes) { foreach (var scopePrefix in scopePrefixFilter) { if (scope.StartsWith(scopePrefix)) { removeRegistry = false; } } } if (removeRegistry) { xmlRegistries.Remove(registry.Url); } } } // Filter the set of considered registries based upon the modification mode. HashSet <string> selectedRegistryUrls = null; switch (mode) { case ManifestModificationMode.Add: // Remove all items from the XML loaded registries that are present in the manifest. foreach (var url in manifestRegistries.Keys) { xmlRegistries.Remove(url); } selectedRegistryUrls = new HashSet <string>(xmlRegistries.Keys); break; case ManifestModificationMode.Remove: // Remove all items from the XML loaded registries that are not present in the // manifest. foreach (var url in new List <string>(xmlRegistries.Keys)) { if (!manifestRegistries.ContainsKey(url)) { xmlRegistries.Remove(url); } } selectedRegistryUrls = new HashSet <string>(xmlRegistries.Keys); break; case ManifestModificationMode.Modify: selectedRegistryUrls = new HashSet <string>(); // Keep all XML loaded registries and select the items in the manifest. foreach (var url in xmlRegistries.Keys) { if (manifestRegistries.ContainsKey(url)) { selectedRegistryUrls.Add(url); } } break; } // Applies the manifest modification based upon the modification mode. Action <HashSet <string> > syncRegistriesToManifest = (urlSelectionToApply) => { SyncRegistriesToManifest(modifier, xmlRegistries, manifestRegistries, urlSelectionToApply, addRegistries: (mode == ManifestModificationMode.Add || mode == ManifestModificationMode.Modify), removeRegistries: (mode == ManifestModificationMode.Remove || mode == ManifestModificationMode.Modify), invertSelection: mode == ManifestModificationMode.Remove); }; if (xmlRegistries.Count > 0) { if (promptBeforeAction) { // Build a list of items to display. var registryItems = new List <KeyValuePair <string, string> >(); foreach (var kv in xmlRegistries) { registryItems.Add(new KeyValuePair <string, string>(kv.Key, kv.Value.Name)); } // Optional when prompting is enabled or forced. var window = MultiSelectWindow.CreateMultiSelectWindow(PLUGIN_NAME); window.minSize = new Vector2(1024, 500); window.AvailableItems = registryItems; window.Sort(1); window.SelectedItems = selectedRegistryUrls; switch (mode) { case ManifestModificationMode.Add: window.Caption = String.Format("{0}\n\n{1}\n\n{2}", ADD_REGISTRIES_QUESTION, ADD_REGISTRIES_DESCRIPTION, MODIFY_MENU_ITEM_DESCRIPTION); window.ApplyLabel = "Add Selected Registries"; break; case ManifestModificationMode.Remove: window.Caption = String.Format("{0}\n\n{1}{2}", REMOVE_REGISTRIES_QUESTION, REMOVE_REGISTRIES_DESCRIPTION, MODIFY_MENU_ITEM_DESCRIPTION); window.ApplyLabel = "Remove Selected Registries"; break; case ManifestModificationMode.Modify: window.Caption = String.Format("{0}\n\n{1} {2}", ADD_OR_REMOVE_REGISTRIES_QUESTION, ADD_REGISTRIES_DESCRIPTION, REMOVE_REGISTRIES_DESCRIPTION); window.ApplyLabel = "Modify Registries"; break; } window.RenderItem = (item) => { var registry = xmlRegistries[item.Key]; var termsOfService = registry.TermsOfService; if (!String.IsNullOrEmpty(termsOfService)) { if (GUILayout.Button("View Terms of Service")) { Application.OpenURL(termsOfService); } } var privacyPolicy = registry.PrivacyPolicy; if (!String.IsNullOrEmpty(privacyPolicy)) { if (GUILayout.Button("View Privacy Policy")) { Application.OpenURL(privacyPolicy); } } }; if (showDisableButton) { window.RenderBeforeCancelApply = () => { if (GUILayout.Button("Disable Registry Addition")) { Enable = false; window.Close(); } }; } window.OnApply = () => { syncRegistriesToManifest(window.SelectedItems); }; window.Show(); } else { syncRegistriesToManifest(selectedRegistryUrls); } } }