| /******************************************************************************* |
| * Copyright (c) 2005, 2010 IBM Corporation and others. |
| * |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.team.ui.synchronize; |
| |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IContributionItem; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.team.core.mapping.IMergeContext; |
| import org.eclipse.team.core.mapping.ISynchronizationContext; |
| import org.eclipse.team.internal.ui.Utils; |
| import org.eclipse.team.internal.ui.mapping.CommonMenuManager; |
| import org.eclipse.team.internal.ui.mapping.MergeAction; |
| import org.eclipse.team.internal.ui.mapping.MergeIncomingChangesAction; |
| import org.eclipse.team.internal.ui.mapping.ModelSelectionDropDownAction; |
| import org.eclipse.team.internal.ui.synchronize.SynchronizePageConfiguration; |
| import org.eclipse.team.internal.ui.synchronize.actions.OpenInCompareAction; |
| import org.eclipse.team.internal.ui.synchronize.actions.SyncViewerShowPreferencesAction; |
| import org.eclipse.team.ui.mapping.SynchronizationActionProvider; |
| import org.eclipse.ui.IActionBars; |
| import org.eclipse.ui.IKeyBindingService; |
| import org.eclipse.ui.IViewSite; |
| import org.eclipse.ui.IWorkbenchSite; |
| |
| /** |
| * Action group that contributes the merge actions to the model |
| * synchronize participant. The groups adds the following: |
| * <ul> |
| * <li>A toolbar action for attempting an auto-merge |
| * <li>Context menu merge actions that delegate to the |
| * model's merge action handlers. |
| * <li>TODO a merge all and overwrite all menu item? |
| * </ul> |
| * <p> |
| * Subclasses can configure the label and icons used for the merge actions |
| * by overriding {@link #configureMergeAction(String, Action)} and can |
| * configure where in the context menu the actions appear by overriding |
| * {@link #addToContextMenu(String, Action, IMenuManager)}. |
| * |
| * @since 3.2 |
| **/ |
| public class ModelSynchronizeParticipantActionGroup extends SynchronizePageActionGroup { |
| |
| /** |
| * The id of the merge action group that determines where the merge |
| * actions (e.g. merge and overwrite) appear in the context menu or toolbar. |
| */ |
| public static final String MERGE_ACTION_GROUP = "merge"; //$NON-NLS-1$ |
| |
| /** |
| * The id of the action group that determines where the other |
| * actions (e.g. mark-as-merged) appear in the context menu. |
| */ |
| public static final String OTHER_ACTION_GROUP = "other"; //$NON-NLS-1$ |
| |
| /** |
| * The id used to identify the Merge All action. |
| */ |
| protected static final String MERGE_ALL_ACTION_ID = "org.eclipse.team.ui.mergeAll"; //$NON-NLS-1$ |
| |
| /** |
| * Create a merge action group. |
| */ |
| public ModelSynchronizeParticipantActionGroup() { |
| } |
| |
| private MergeIncomingChangesAction updateToolbarAction; |
| private ModelSelectionDropDownAction modelPicker; |
| private SyncViewerShowPreferencesAction showPreferences; |
| private OpenInCompareAction openInCompareAction; |
| private MergeAction merge; |
| private MergeAction overwrite; |
| private MergeAction markAsMerged; |
| |
| @Override |
| public void initialize(ISynchronizePageConfiguration configuration) { |
| super.initialize(configuration); |
| |
| ModelSynchronizeParticipant participant = ((ModelSynchronizeParticipant)configuration.getParticipant()); |
| if (participant.isMergingEnabled()) { |
| updateToolbarAction = new MergeIncomingChangesAction(configuration); |
| configureMergeAction(MERGE_ALL_ACTION_ID, updateToolbarAction); |
| appendToGroup( |
| ISynchronizePageConfiguration.P_TOOLBAR_MENU, |
| MERGE_ACTION_GROUP, |
| updateToolbarAction); |
| // TODO: Should add a merge all to the context menu as well? |
| } |
| modelPicker = new ModelSelectionDropDownAction(configuration); |
| appendToGroup( |
| ISynchronizePageConfiguration.P_TOOLBAR_MENU, |
| ISynchronizePageConfiguration.NAVIGATE_GROUP, |
| modelPicker); |
| ISynchronizePageSite site = configuration.getSite(); |
| IWorkbenchSite ws = site.getWorkbenchSite(); |
| if (ws instanceof IViewSite) { |
| showPreferences = new SyncViewerShowPreferencesAction(configuration); |
| openInCompareAction = new OpenInCompareAction(configuration); |
| configuration.setProperty(SynchronizePageConfiguration.P_OPEN_ACTION, new Action() { |
| @Override |
| public void run() { |
| openInCompareAction.run(); |
| } |
| }); |
| } |
| } |
| |
| @Override |
| public void fillActionBars(IActionBars actionBars) { |
| super.fillActionBars(actionBars); |
| if (actionBars != null && showPreferences != null) { |
| IMenuManager menu = actionBars.getMenuManager(); |
| appendToGroup(menu, ISynchronizePageConfiguration.PREFERENCES_GROUP, showPreferences); |
| } |
| } |
| |
| @Override |
| public void fillContextMenu(IMenuManager menu) { |
| super.fillContextMenu(menu); |
| if (menu instanceof CommonMenuManager) { |
| CommonMenuManager cmm = (CommonMenuManager) menu; |
| addMergeActions(cmm); |
| } |
| Object[] elements = ((IStructuredSelection)getContext().getSelection()).toArray(); |
| if (elements.length > 0 && openInCompareAction != null) { |
| IContributionItem fileGroup = findGroup(menu, ISynchronizePageConfiguration.FILE_GROUP); |
| if (fileGroup != null) { |
| ModelSynchronizeParticipant msp = ((ModelSynchronizeParticipant)getConfiguration().getParticipant()); |
| boolean allElementsHaveCompareInput = true; |
| for (int i = 0; i < elements.length; i++) { |
| if (!msp.hasCompareInputFor(elements[i])) { |
| allElementsHaveCompareInput = false; |
| break; |
| } |
| } |
| if (allElementsHaveCompareInput) { |
| menu.appendToGroup(fileGroup.getId(), openInCompareAction); |
| } |
| } |
| } |
| } |
| |
| /* |
| * Method to add the merge actions to the context menu. This method |
| * is called by the internal synchronization framework and should not |
| * to be invoked by other clients. Subclasses can configure the |
| * merge actions by overriding {@link #configureMergeAction(String, Action)} |
| * and can control where in the context menu the action appears by |
| * overriding {@link #addToContextMenu(String, Action, IMenuManager)}. |
| * @param cmm the menu manager |
| */ |
| private void addMergeActions(CommonMenuManager cmm) { |
| ModelSynchronizeParticipant participant = ((ModelSynchronizeParticipant)getConfiguration().getParticipant()); |
| if (participant.isMergingEnabled()) { |
| if (!isTwoWayMerge()) { |
| if (merge == null) { |
| merge = new MergeAction(SynchronizationActionProvider.MERGE_ACTION_ID, cmm, getConfiguration()); |
| configureMergeAction(SynchronizationActionProvider.MERGE_ACTION_ID, merge); |
| registerActionWithWorkbench(merge); |
| |
| } |
| merge.update(); |
| addToContextMenu(SynchronizationActionProvider.MERGE_ACTION_ID, merge, cmm); |
| } |
| if (overwrite == null) { |
| overwrite = new MergeAction(SynchronizationActionProvider.OVERWRITE_ACTION_ID, cmm, getConfiguration()); |
| configureMergeAction(SynchronizationActionProvider.OVERWRITE_ACTION_ID, overwrite); |
| registerActionWithWorkbench(overwrite); |
| } |
| overwrite.update(); |
| addToContextMenu(SynchronizationActionProvider.OVERWRITE_ACTION_ID, overwrite, cmm); |
| if (!isTwoWayMerge()) { |
| if (markAsMerged == null) { |
| markAsMerged = new MergeAction(SynchronizationActionProvider.MARK_AS_MERGE_ACTION_ID, cmm, getConfiguration()); |
| configureMergeAction(SynchronizationActionProvider.MARK_AS_MERGE_ACTION_ID, markAsMerged); |
| } |
| markAsMerged.update(); |
| addToContextMenu(SynchronizationActionProvider.MARK_AS_MERGE_ACTION_ID, markAsMerged, cmm); |
| registerActionWithWorkbench(markAsMerged); |
| } |
| } |
| } |
| |
| /** |
| * Register this action with the workbench so that it can participate in keybindings and |
| * retargetable actions. |
| * |
| * @param action the action to register |
| */ |
| private void registerActionWithWorkbench(IAction action) { |
| ISynchronizePageSite site = getConfiguration().getSite(); |
| String id = action.getId(); |
| if (id != null) { |
| site.getActionBars().setGlobalActionHandler(id, action); |
| IKeyBindingService keyBindingService = site.getKeyBindingService(); |
| if(keyBindingService != null) |
| keyBindingService.registerAction(action); |
| } |
| } |
| |
| /** |
| * Configure the merge action to have appropriate label, image, etc. |
| * Subclasses may override but should invoke the overridden |
| * method for unrecognized ids in order to support future additions. |
| * @param mergeActionId the id of the merge action (one of |
| * {@link SynchronizationActionProvider#MERGE_ACTION_ID}, |
| * {@link SynchronizationActionProvider#OVERWRITE_ACTION_ID} or |
| * {@link SynchronizationActionProvider#MARK_AS_MERGE_ACTION_ID}) |
| * @param action the action for the given id |
| */ |
| protected void configureMergeAction(String mergeActionId, Action action) { |
| if (mergeActionId == SynchronizationActionProvider.MERGE_ACTION_ID) { |
| Utils.initAction(action, "action.merge."); //$NON-NLS-1$ |
| } else if (mergeActionId == SynchronizationActionProvider.OVERWRITE_ACTION_ID) { |
| if (isTwoWayMerge()) { |
| Utils.initAction(action, "action.replace."); //$NON-NLS-1$ |
| } else { |
| Utils.initAction(action, "action.overwrite."); //$NON-NLS-1$ |
| } |
| } else if (mergeActionId == SynchronizationActionProvider.MARK_AS_MERGE_ACTION_ID) { |
| Utils.initAction(action, "action.markAsMerged."); //$NON-NLS-1$ |
| } else if (mergeActionId == MERGE_ALL_ACTION_ID) { |
| if (isTwoWayMerge()) { |
| Utils.initAction(action, "action.replaceAll."); //$NON-NLS-1$ |
| } else { |
| Utils.initAction(action, "action.mergeAll."); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private boolean isTwoWayMerge() { |
| ModelSynchronizeParticipant participant = ((ModelSynchronizeParticipant)getConfiguration().getParticipant()); |
| ISynchronizationContext context = participant.getContext(); |
| if (context instanceof IMergeContext) { |
| IMergeContext mc = (IMergeContext) context; |
| return (mc.getMergeType() == ISynchronizationContext.TWO_WAY); |
| } |
| return false; |
| } |
| |
| /** |
| * Add the merge action to the context menu manager. |
| * Subclasses may override but should invoke the overridden |
| * method for unrecognized ids in order to support future additions. |
| * @param mergeActionId the id of the merge action (one of |
| * {@link SynchronizationActionProvider#MERGE_ACTION_ID}, |
| * {@link SynchronizationActionProvider#OVERWRITE_ACTION_ID} or |
| * {@link SynchronizationActionProvider#MARK_AS_MERGE_ACTION_ID}) |
| * @param action the action for the given id |
| * @param manager the context menu manager |
| */ |
| protected void addToContextMenu(String mergeActionId, Action action, IMenuManager manager) { |
| IContributionItem group = null;; |
| if (mergeActionId == SynchronizationActionProvider.MERGE_ACTION_ID) { |
| group = manager.find(MERGE_ACTION_GROUP); |
| } else if (mergeActionId == SynchronizationActionProvider.OVERWRITE_ACTION_ID) { |
| group = manager.find(MERGE_ACTION_GROUP); |
| } else if (mergeActionId == SynchronizationActionProvider.MARK_AS_MERGE_ACTION_ID) { |
| group = manager.find(OTHER_ACTION_GROUP); |
| } |
| if (group != null) { |
| manager.appendToGroup(group.getId(), action); |
| } else { |
| manager.add(action); |
| } |
| } |
| |
| @Override |
| public void dispose() { |
| if (modelPicker != null) |
| modelPicker.dispose(); |
| if (merge != null) |
| merge.dispose(); |
| if (overwrite != null) |
| overwrite.dispose(); |
| if (markAsMerged != null) |
| markAsMerged.dispose(); |
| if (updateToolbarAction != null) |
| updateToolbarAction.dispose(); |
| super.dispose(); |
| } |
| } |