From 3683ab5191fd51cccbc95f75e4830788d0ed74cd 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 Review points addressed --- .../org/eclipse/ui/actions/NewWizardMenu.java | 24 +++++++ .../eclipse/ui/actions/BaseNewWizardMenu.java | 6 +- .../eclipse/ui/internal/WorkbenchPlugin.java | 10 +++ .../ui/internal/dialogs/NewWizard.java | 52 ++++++++++++++ .../ui/internal/dialogs/NewWizardNewPage.java | 7 ++ .../dialogs/NewWizardSelectionPage.java | 3 + .../dialogs/RecentNewWizardSelection.java | 67 +++++++++++++++++++ .../META-INF/MANIFEST.MF | 2 +- 8 files changed, 168 insertions(+), 3 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..262f66ce954 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 actions = new LinkedList<>(); + if (!RecentNewWizardSelection.getInstance().getMenuIds().isEmpty()) { + for (String selectedItem : RecentNewWizardSelection.getInstance() + .getMenuIds()) { + IAction action = getAction(selectedItem); + actions.add(new ActionContributionItem(action)); + } + subMenuShortcutCheck(list, actions); + } 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..f043d79a7b9 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.134 */ - private IAction getAction(String id) { + public 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..6e6cd2d97c4 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 @@ -53,6 +53,8 @@ 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.WorkbenchPreferenceManager; import org.eclipse.ui.internal.help.CommandHelpServiceImpl; import org.eclipse.ui.internal.help.HelpServiceImpl; @@ -202,6 +204,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 @@ -766,6 +770,10 @@ public void start(BundleContext context) throws Exception { // to be loaded.s if (uiBundle != null) uiBundle.start(Bundle.START_TRANSIENT); + + recentNewWizardsPreferenceManager = new RecentNewWizardsPreferenceManager(); + recentNewWizardsPreferenceManager.populate(); + } catch (BundleException e) { WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$ } @@ -1048,6 +1056,8 @@ public void stop(BundleContext context) throws Exception { testableTracker.close(); testableTracker = null; } + // Store recently used new page shortcuts to preferences + recentNewWizardsPreferenceManager.shutdown(); 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..007350af138 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,11 @@ *******************************************************************************/ package org.eclipse.ui.internal.dialogs; +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 +173,52 @@ 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. + */ + 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 List.of(preferences.split(SEPARATOR)); + } + return List.of(); + } + + 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) { + WorkbenchPlugin.log(e); + } + } + + /** + * populates recently used new wizards into + * RecentNewWizardSelection from preferences. + */ + public void populate() { + getMenuShortcutsFromPreferences().stream() + .forEach(newPage -> RecentNewWizardSelection.getInstance().addItem(newPage)); + + } + + /** + * stores recently used new wizards to preferences. + */ + public void shutdown() { + Set menuIds = RecentNewWizardSelection.getInstance().getMenuIds(); + setMenuShortcutsToPreferences(menuIds); + } + } } 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..9a2821df31c 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 selected element or {@code null} + */ + 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..11b2e7e8692 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,9 @@ public void createControl(Composite parent) { * they will persist into the next invocation of this wizard page */ protected void saveWidgetValues() { + if (newResourcePage.getSelectedElement() != null) { + 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..8fcd6460fac --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/RecentNewWizardSelection.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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. + */ +public class RecentNewWizardSelection { + private Set menuIds = 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) { + menuIds.add(shortcut); + if (menuIds.size() > MAX_MENU_SIZE) { + Iterator iterator = menuIds.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 getMenuIds() { + return Collections.unmodifiableSet(menuIds); + } + +} diff --git a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF index 261f4fe712f..36729f7f926 100644 --- a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ui.workbench; singleton:=true -Bundle-Version: 3.133.100.qualifier +Bundle-Version: 3.134.0.qualifier Bundle-Activator: org.eclipse.ui.internal.WorkbenchPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName