diff options
Diffstat (limited to 'org.eclipse.egit.ui/src/org/eclipse')
3 files changed, 296 insertions, 140 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositoryMenuUtil.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositoryMenuUtil.java index 3c04ffa220..01ec794a22 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositoryMenuUtil.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositoryMenuUtil.java @@ -32,22 +32,12 @@ import org.eclipse.egit.ui.internal.CommonUtils; import org.eclipse.egit.ui.internal.UIIcons; import org.eclipse.egit.ui.internal.UIText; import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuCreator; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.lib.Repository; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.ToolItem; -import org.eclipse.swt.widgets.Widget; -import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; /** * Provides a way to populate a menu with a list of repositories. @@ -100,6 +90,7 @@ public final class RepositoryMenuUtil { * to perform on the chosen repository * @return the (possibly empty) list of actions */ + @NonNull public static Collection<IAction> getRepositoryActions(boolean includeBare, @Nullable File currentRepoDir, @NonNull Consumer<Repository> action) { @@ -165,8 +156,7 @@ public final class RepositoryMenuUtil { * menu of all registered repositories, performing a given action on a * selected repository. */ - public static class RepositoryToolbarAction extends Action - implements IWorkbenchAction, IMenuCreator { + public static class RepositoryToolbarAction extends ToolbarMenuAction { private final RepositoryUtil util = org.eclipse.egit.core.Activator .getDefault().getRepositoryUtil(); @@ -181,10 +171,6 @@ public final class RepositoryMenuUtil { private final boolean includeBare; - private Menu menu; - - private boolean showMenu; - /** * Creates a new {@link RepositoryToolbarAction} with the given * {@code action} and default text, image, and tooltip. @@ -231,7 +217,7 @@ public final class RepositoryMenuUtil { @Nullable ImageDescriptor image, @Nullable String tooltip, boolean includeBare, @NonNull Supplier<Repository> currentRepo, @NonNull Consumer<Repository> action) { - super(text, IAction.AS_DROP_DOWN_MENU); + super(text); setImageDescriptor(image); setToolTipText(tooltip == null ? text : tooltip); this.includeBare = includeBare; @@ -247,69 +233,19 @@ public final class RepositoryMenuUtil { preferences.addPreferenceChangeListener(listener); } - @Override - public void run() { - showMenu = true; - } - - @Override - public void runWithEvent(Event event) { - if (!isEnabled()) { - return; - } - // Show the menu also when the button is clicked, unless run() is - // overridden (and not called via super). - showMenu = false; - run(); - Widget widget = event.widget; - if (showMenu && (widget instanceof ToolItem)) { - ToolItem item = (ToolItem) widget; - Rectangle bounds = item.getBounds(); - event.detail = SWT.ARROW; - event.x = bounds.x; - event.y = bounds.y + bounds.height; - item.notifyListeners(SWT.Selection, event); - } - } @Override - public IMenuCreator getMenuCreator() { - return this; - } - - @Override - public Menu getMenu(Control parent) { - if (menu != null) { - menu.dispose(); - menu = null; - } - if (isEnabled()) { - Repository current = currentRepo.get(); - File gitDir = current == null ? null : current.getDirectory(); - Collection<IAction> actions = RepositoryMenuUtil - .getRepositoryActions(includeBare, gitDir, action); - menu = new Menu(parent); - for (IAction a : actions) { - ActionContributionItem item = new ActionContributionItem(a); - item.fill(menu, -1); - } - } - return menu; - } - - @Override - public Menu getMenu(Menu parent) { - // Not used - return null; + public Collection<IAction> getActions() { + Repository current = currentRepo.get(); + File gitDir = current == null ? null : current.getDirectory(); + return RepositoryMenuUtil.getRepositoryActions(includeBare, gitDir, + action); } @Override public void dispose() { - if (menu != null) { - menu.dispose(); - menu = null; - } preferences.removePreferenceChangeListener(listener); + super.dispose(); } } } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/ToolbarMenuAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/ToolbarMenuAction.java new file mode 100644 index 0000000000..799913e8ee --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/ToolbarMenuAction.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (C) 2019 Thomas Wolf <thomas.wolf@paranor.ch> + * + * 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 + *******************************************************************************/ +package org.eclipse.egit.ui.internal.components; + +import java.util.Collection; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; + +/** + * Specialized {@link Action} intended to be used in a + * {@link org.eclipse.jface.action.ToolBarManager ToolBarManager} for buttons + * with a drop-down menu. By default selecting the button itself will also show + * the menu; if that is not desired, override {@link #runWithEvent(Event)} or + * {@link #run()}. + */ +public abstract class ToolbarMenuAction extends Action + implements IWorkbenchAction, IMenuCreator { + + private Menu menu; + + private boolean showMenu; + + /** + * Creates a new {@link ToolbarMenuAction}. + * + * @param title + * for the action + */ + public ToolbarMenuAction(String title) { + super(title, IAction.AS_DROP_DOWN_MENU); + } + + @Override + public void run() { + showMenu = true; + } + + @Override + public void runWithEvent(Event event) { + if (!isEnabled()) { + return; + } + // Show the menu also when the button is clicked, unless run() is + // overridden (and not called via super). + showMenu = false; + run(); + Widget widget = event.widget; + if (showMenu && (widget instanceof ToolItem)) { + ToolItem item = (ToolItem) widget; + Rectangle bounds = item.getBounds(); + event.detail = SWT.ARROW; + event.x = bounds.x; + event.y = bounds.y + bounds.height; + item.notifyListeners(SWT.Selection, event); + } + } + + @Override + public IMenuCreator getMenuCreator() { + return this; + } + + @Override + public Menu getMenu(Menu parent) { + // Not used + return null; + } + + @Override + public Menu getMenu(Control parent) { + if (menu != null) { + menu.dispose(); + menu = null; + } + if (isEnabled()) { + menu = new Menu(parent); + for (IAction action : getActions()) { + ActionContributionItem item = new ActionContributionItem( + action); + item.fill(menu, -1); + } + } + return menu; + } + + /** + * Obtains the actions to display in the drop-down menu. + * + * @return the actions + */ + @NonNull + protected abstract Collection<IAction> getActions(); + + @Override + public void dispose() { + if (menu != null) { + menu.dispose(); + menu = null; + } + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java index 68de0f9a6b..2645c32de6 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java @@ -25,7 +25,9 @@ import java.io.File; import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; import java.util.HashSet; @@ -92,6 +94,7 @@ import org.eclipse.egit.ui.internal.commit.CommitProposalProcessor; import org.eclipse.egit.ui.internal.commit.DiffViewer; import org.eclipse.egit.ui.internal.components.PartVisibilityListener; import org.eclipse.egit.ui.internal.components.RepositoryMenuUtil.RepositoryToolbarAction; +import org.eclipse.egit.ui.internal.components.ToolbarMenuAction; import org.eclipse.egit.ui.internal.decorators.ProblemLabelDecorator; import org.eclipse.egit.ui.internal.dialogs.CommandConfirmation; import org.eclipse.egit.ui.internal.dialogs.CommitMessageArea; @@ -341,6 +344,8 @@ public class StagingView extends ViewPart private Presentation presentation = Presentation.LIST; + private PresentationAction presentationAction; + private Set<IPath> pathsToExpandInStaged = new HashSet<>(); private Set<IPath> pathsToExpandInUnstaged = new HashSet<>(); @@ -839,6 +844,8 @@ public class StagingView extends ViewPart unstageAllAction.setEnabled(false); stageAllAction.setEnabled(false); + createPresentationActions(); + unstagedSection = toolkit.createSection(stagingSashForm, ExpandableComposite.SHORT_TITLE_BAR); unstagedSection.clientVerticalSpacing = 0; @@ -1172,6 +1179,7 @@ public class StagingView extends ViewPart } }; + initPresentation(); partListener = new PartListener(); IPreferenceStore preferenceStore = getPreferenceStore(); @@ -1545,6 +1553,8 @@ public class StagingView extends ViewPart unstagedToolBarManager.add(stageAction); unstagedToolBarManager.add(stageAllAction); + unstagedToolBarManager.add(presentationAction); + presentationAction.setToolbar(unstagedToolBarManager); unstagedToolBarManager.add(sortAction); unstagedToolBarManager.add(unstagedExpandAllAction); unstagedToolBarManager.add(unstagedCollapseAllAction); @@ -1730,6 +1740,84 @@ public class StagingView extends ViewPart } } + private void createPresentationActions() { + listPresentationAction = new Action(UIText.StagingView_List, + IAction.AS_RADIO_BUTTON) { + @Override + public void run() { + if (!isChecked()) { + return; + } + switchToListMode(); + refreshViewers(); + } + }; + listPresentationAction.setImageDescriptor(UIIcons.FLAT); + + treePresentationAction = new Action(UIText.StagingView_Tree, + IAction.AS_RADIO_BUTTON) { + @Override + public void run() { + if (!isChecked()) { + return; + } + presentation = Presentation.TREE; + setPresentation(presentation, false); + listPresentationAction.setChecked(false); + compactTreePresentationAction.setChecked(false); + setExpandCollapseActionsVisible(false, isExpandAllowed(false), + true); + setExpandCollapseActionsVisible(true, isExpandAllowed(true), + true); + refreshViewers(); + } + }; + treePresentationAction.setImageDescriptor(UIIcons.HIERARCHY); + + compactTreePresentationAction = new Action( + UIText.StagingView_CompactTree, IAction.AS_RADIO_BUTTON) { + @Override + public void run() { + if (!isChecked()) { + return; + } + switchToCompactModeInternal(false); + refreshViewers(); + } + + }; + compactTreePresentationAction.setImageDescriptor(UIIcons.COMPACT); + + presentationAction = new PresentationAction(getPreferenceStore(), + listPresentationAction, treePresentationAction, + compactTreePresentationAction); + presentationAction.setImageDescriptor(UIIcons.FLAT); + } + + private void initPresentation() { + presentation = readPresentation(UIPreferences.STAGING_VIEW_PRESENTATION, + Presentation.LIST); + switch (presentation) { + case LIST: + presentationAction.setImageDescriptor(UIIcons.FLAT); + listPresentationAction.setChecked(true); + setExpandCollapseActionsVisible(false, false, false); + setExpandCollapseActionsVisible(true, false, false); + break; + case TREE: + presentationAction.setImageDescriptor(UIIcons.HIERARCHY); + treePresentationAction.setChecked(true); + break; + case COMPACT_TREE: + presentationAction.setImageDescriptor(UIIcons.COMPACT); + compactTreePresentationAction.setChecked(true); + break; + default: + break; + } + presentationAction.update(); + } + private void updateToolbar() { ControlContribution controlContribution = new ControlContribution( @@ -1883,73 +1971,9 @@ public class StagingView extends ViewPart IMenuManager dropdownMenu = actionBars.getMenuManager(); MenuManager presentationMenu = new MenuManager( UIText.StagingView_Presentation); - listPresentationAction = new Action(UIText.StagingView_List, - IAction.AS_RADIO_BUTTON) { - @Override - public void run() { - if (!isChecked()) { - return; - } - switchToListMode(); - refreshViewers(); - } - }; - listPresentationAction.setImageDescriptor(UIIcons.FLAT); presentationMenu.add(listPresentationAction); - - treePresentationAction = new Action(UIText.StagingView_Tree, - IAction.AS_RADIO_BUTTON) { - @Override - public void run() { - if (!isChecked()) { - return; - } - presentation = Presentation.TREE; - setPresentation(presentation, false); - listPresentationAction.setChecked(false); - compactTreePresentationAction.setChecked(false); - setExpandCollapseActionsVisible(false, isExpandAllowed(false), - true); - setExpandCollapseActionsVisible(true, isExpandAllowed(true), - true); - refreshViewers(); - } - }; - treePresentationAction.setImageDescriptor(UIIcons.HIERARCHY); presentationMenu.add(treePresentationAction); - - compactTreePresentationAction = new Action(UIText.StagingView_CompactTree, - IAction.AS_RADIO_BUTTON) { - @Override - public void run() { - if (!isChecked()) { - return; - } - switchToCompactModeInternal(false); - refreshViewers(); - } - - }; - compactTreePresentationAction.setImageDescriptor(UIIcons.COMPACT); presentationMenu.add(compactTreePresentationAction); - - presentation = readPresentation(UIPreferences.STAGING_VIEW_PRESENTATION, - Presentation.LIST); - switch (presentation) { - case LIST: - listPresentationAction.setChecked(true); - setExpandCollapseActionsVisible(false, false, false); - setExpandCollapseActionsVisible(true, false, false); - break; - case TREE: - treePresentationAction.setChecked(true); - break; - case COMPACT_TREE: - compactTreePresentationAction.setChecked(true); - break; - default: - break; - } dropdownMenu.add(presentationMenu); dropdownMenu.add(new Separator()); dropdownMenu.add(openNewCommitsAction); @@ -1970,10 +1994,14 @@ public class StagingView extends ViewPart } private Presentation readPresentation(String key, Presentation def) { - String presentationString = getPreferenceStore().getString(key); - if (presentationString.length() > 0) { + return getPresentation(getPreferenceStore().getString(key), def); + } + + private static Presentation getPresentation(String value, + Presentation def) { + if (!value.isEmpty()) { try { - return Presentation.valueOf(presentationString); + return Presentation.valueOf(value); } catch (IllegalArgumentException e) { // Use given default } @@ -4312,6 +4340,10 @@ public class StagingView extends ViewPart switchRepositoriesAction.dispose(); switchRepositoriesAction = null; } + if (presentationAction != null) { + presentationAction.dispose(); + presentationAction = null; + } getPreferenceStore().removePropertyChangeListener(uiPrefsListener); @@ -4510,4 +4542,70 @@ public class StagingView extends ViewPart } } + + private static class PresentationAction extends ToolbarMenuAction + implements IPropertyChangeListener { + + private ToolBarManager toolbar; + + private final IPreferenceStore store; + + private final @NonNull List<IAction> actions; + + public PresentationAction(IPreferenceStore store, IAction... actions) { + super(UIText.StagingView_Presentation); + @SuppressWarnings("null") + @NonNull + List<IAction> a = actions != null ? Arrays.asList(actions) + : Collections.emptyList(); + this.actions = a; + this.store = store; + store.addPropertyChangeListener(this); + } + + @Override + protected Collection<IAction> getActions() { + return actions; + } + + public void setToolbar(ToolBarManager toolbar) { + this.toolbar = toolbar; + } + + @Override + public void dispose() { + store.removePropertyChangeListener(this); + super.dispose(); + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + if (UIPreferences.STAGING_VIEW_PRESENTATION + .equals(event.getProperty())) { + Presentation current = getPresentation( + event.getNewValue().toString(), Presentation.LIST); + switch (current) { + case LIST: + setImageDescriptor(UIIcons.FLAT); + break; + case TREE: + setImageDescriptor(UIIcons.HIERARCHY); + break; + case COMPACT_TREE: + setImageDescriptor(UIIcons.COMPACT); + break; + default: + return; + } + update(); + } + } + + public void update() { + if (toolbar != null) { + toolbar.update(true); + } + } + + } } |