From 295f6975dabd02491c5cf23c79112c5e0a1c8a51 Mon Sep 17 00:00:00 2001 From: lathapatil Date: Mon, 3 Jun 2024 17:51:23 +0530 Subject: [PATCH] Show recently used File > New wizards Changes requested in the PR https://github.com/eclipse-platform/eclipse.platform.ui/pull/1837 are addressed here --- .../org/eclipse/ui/actions/NewWizardMenu.java | 24 +++++++ .../eclipse/ui/actions/BaseNewWizardMenu.java | 6 +- .../eclipse/ui/internal/WorkbenchPlugin.java | 15 ++++ .../ui/internal/dialogs/NewWizard.java | 39 +++++++++++ .../ui/internal/dialogs/NewWizardNewPage.java | 7 ++ .../dialogs/NewWizardSelectionPage.java | 1 + .../dialogs/RecentNewWizardSelection.java | 69 +++++++++++++++++++ 7 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/RecentNewWizardSelection.java diff --git a/bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewWizardMenu.java b/bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewWizardMenu.java index f076931e1ba..ec29ae37ee7 100644 --- a/bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewWizardMenu.java +++ b/bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewWizardMenu.java @@ -15,8 +15,12 @@ package org.eclipse.ui.actions; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; +import java.util.Set; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; @@ -28,6 +32,7 @@ import org.eclipse.ui.activities.WorkbenchActivityHelper; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.actions.NewWizardShortcutAction; +import org.eclipse.ui.internal.dialogs.RecentNewWizardSelection; import org.eclipse.ui.internal.dialogs.WorkbenchWizardElement; import org.eclipse.ui.internal.registry.WizardsRegistryReader; import org.eclipse.ui.wizards.IWizardCategory; @@ -186,9 +191,28 @@ protected void addItems(List list) { list.add(new ActionContributionItem(newExampleAction)); list.add(new Separator()); } + // To add shortcuts from OTHER... wizard regardless of perspective + Collection otherItems = new LinkedList<>(); + if (!RecentNewWizardSelection.getInstance().getSelectedFromOther().isEmpty()) { + for (String selectedItemsFormOthers : RecentNewWizardSelection.getInstance() + .getSelectedFromOther()) { + IAction action = getAction(selectedItemsFormOthers); + otherItems.add(new ActionContributionItem(action)); + } + subMenuShortcutCheck(list, otherItems); + } list.add(new ActionContributionItem(getShowDialogAction())); } + private void subMenuShortcutCheck(List list, Collection otherItems) { + Set existingShortcutsInPerspective = new HashSet<>(list); + for (IContributionItem item : otherItems) { + if (!existingShortcutsInPerspective.contains(item)) { + list.add(item); + existingShortcutsInPerspective.add(item); + } + } + } private boolean isNewProjectWizardAction(IAction action) { if (action instanceof NewWizardShortcutAction) { IWizardDescriptor wizardDescriptor= ((NewWizardShortcutAction) action).getWizardDescriptor(); diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/actions/BaseNewWizardMenu.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/actions/BaseNewWizardMenu.java index a94e8afe169..0d447c87d65 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/actions/BaseNewWizardMenu.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/actions/BaseNewWizardMenu.java @@ -163,10 +163,12 @@ public void dispose() { } } - /* + /** * Returns the action for the given wizard id, or null if not found. + * + * @since 3.132 */ - private IAction getAction(String id) { + protected IAction getAction(String id) { // Keep a cache, rather than creating a new action each time, // so that image caching in ActionContributionItem works. IAction action = actions.get(id); diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java index 17e5ca31874..9adb02915bc 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java @@ -21,7 +21,9 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Locale; +import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; @@ -53,6 +55,9 @@ import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.decorators.DecoratorManager; +import org.eclipse.ui.internal.dialogs.NewWizard; +import org.eclipse.ui.internal.dialogs.NewWizard.RecentNewWizardsPreferenceManager; +import org.eclipse.ui.internal.dialogs.RecentNewWizardSelection; import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceManager; import org.eclipse.ui.internal.help.CommandHelpServiceImpl; import org.eclipse.ui.internal.help.HelpServiceImpl; @@ -202,6 +207,8 @@ public class WorkbenchPlugin extends AbstractUIPlugin { private ICommandHelpService commandHelpService; + private NewWizard.RecentNewWizardsPreferenceManager recentNewWizardsPreferenceManager; + /** * Create an instance of the WorkbenchPlugin. The workbench plugin is * effectively the "application" for the workbench UI. The entire UI operates as @@ -210,6 +217,7 @@ public class WorkbenchPlugin extends AbstractUIPlugin { public WorkbenchPlugin() { super(); inst = this; + recentNewWizardsPreferenceManager = new RecentNewWizardsPreferenceManager(); } /** @@ -766,6 +774,10 @@ public void start(BundleContext context) throws Exception { // to be loaded.s if (uiBundle != null) uiBundle.start(Bundle.START_TRANSIENT); + + List recentlyUsedNewWizards = recentNewWizardsPreferenceManager.getMenuShortcutsFromPreferences(); + recentlyUsedNewWizards.stream().forEach(newPage -> RecentNewWizardSelection.getInstance().addItem(newPage)); + } catch (BundleException e) { WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$ } @@ -1048,6 +1060,9 @@ public void stop(BundleContext context) throws Exception { testableTracker.close(); testableTracker = null; } + // Store recently used new page shortcuts to preferences + Set selectedFromOther = RecentNewWizardSelection.getInstance().getSelectedFromOther(); + recentNewWizardsPreferenceManager.setMenuShortcutsToPreferences(selectedFromOther); super.stop(context); } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizard.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizard.java index a44cac9d2bd..d347f8f4abd 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizard.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizard.java @@ -13,7 +13,13 @@ *******************************************************************************/ package org.eclipse.ui.internal.dialogs; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; import java.util.StringTokenizer; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizard; import org.eclipse.jface.wizard.Wizard; @@ -169,4 +175,37 @@ public boolean canFinish() { return super.canFinish(); } + /** + * A RecentNewWizardsPreferenceManager is used to store and fetch + * the most recent new wizards used or created from the "Other" shortcut, which + * is part of the menu manager with New Wizard actions, from preferences. + * + * @since 3.5 + */ + + public static class RecentNewWizardsPreferenceManager { + + private static final String PLUGIN_ID = "org.eclipse.ui.workbench"; //$NON-NLS-1$ + private static final String RECENT_NEW_MENU_ITEMS = "recentNewMenuItems"; //$NON-NLS-1$ + private static final String SEPARATOR = ","; //$NON-NLS-1$ + + public List getMenuShortcutsFromPreferences() { + IEclipsePreferences pref = InstanceScope.INSTANCE.getNode(PLUGIN_ID); + String preferences = pref.get(RECENT_NEW_MENU_ITEMS, null); + if (preferences != null && !preferences.trim().isEmpty()) { + return Arrays.asList(preferences.split(SEPARATOR)); + } + return new ArrayList<>(); + } + + public void setMenuShortcutsToPreferences(Set items) { + IEclipsePreferences pref = InstanceScope.INSTANCE.getNode(PLUGIN_ID); + pref.put(RECENT_NEW_MENU_ITEMS, String.join(SEPARATOR, items)); + try { + pref.flush(); + } catch (org.osgi.service.prefs.BackingStoreException e) { + e.printStackTrace(); + } + } + } } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizardNewPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizardNewPage.java index 9b75c8fd162..991865bb717 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizardNewPage.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizardNewPage.java @@ -689,4 +689,11 @@ public IWorkbenchWizard createWizard() throws CoreException { updateDescription(selectedObject); } + + /** + * @return Returns the selectedElement. + */ + public IWizardDescriptor getSelectedElement() { + return selectedElement; + } } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizardSelectionPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizardSelectionPage.java index 1fc475163f2..d8b6d119113 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizardSelectionPage.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/NewWizardSelectionPage.java @@ -94,6 +94,7 @@ public void createControl(Composite parent) { * they will persist into the next invocation of this wizard page */ protected void saveWidgetValues() { + RecentNewWizardSelection.getInstance().addItem(newResourcePage.getSelectedElement().getId()); newResourcePage.saveWidgetValues(); } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/RecentNewWizardSelection.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/RecentNewWizardSelection.java new file mode 100644 index 00000000000..7a381f5f5d1 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/RecentNewWizardSelection.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2023 ETAS GmbH and others, all rights reserved. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ETAS GmbH - initial API and implementation + *******************************************************************************/ + +package org.eclipse.ui.internal.dialogs; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * A RecentNewWizardSelection is used to manage the five most + * recent new wizards used or created from the "Other" shortcut, which is part + * of the menu manager with New Wizard actions. The recently used new wizards + * will appear before the "Other" shortcut. + * + * @since 3.5 + */ +public class RecentNewWizardSelection { + private Set selectedFromOther = new LinkedHashSet<>(); + private static RecentNewWizardSelection instance; + private static final int MAX_MENU_SIZE = 5; + + public static RecentNewWizardSelection getInstance() { + synchronized (RecentNewWizardSelection.class) { + if (instance == null) { + instance = new RecentNewWizardSelection(); + } + return instance; + } + } + + /** + * Adds the new wizard menu shortcut ID to the set and removes the oldest one if + * the number of recently used new wizard menu shortcuts exceeds MAX_MENU_SIZE. + * + * @param shortcut the new wizard menu shortcut ID + */ + public void addItem(String shortcut) { + selectedFromOther.add(shortcut); + if (selectedFromOther.size() > MAX_MENU_SIZE) { + Iterator iterator = selectedFromOther.iterator(); + iterator.next(); + iterator.remove(); + } + } + + /** + * Returns the set of recently used new wizard menu shortcut IDs. + * + * @return the set of recently used new wizard menu shortcut IDs + */ + + public Set getSelectedFromOther() { + return Collections.unmodifiableSet(selectedFromOther); + } + +}