diff options
4 files changed, 479 insertions, 0 deletions
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SubscriberParticipantPage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SubscriberParticipantPage.java new file mode 100644 index 000000000..120261ebf --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SubscriberParticipantPage.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.core.subscribers.SubscriberSyncInfoCollector; +import org.eclipse.team.internal.core.subscribers.WorkingSetFilteredSyncInfoCollector; +import org.eclipse.team.internal.ui.synchronize.actions.SubscriberActionContribution; +import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; +import org.eclipse.team.ui.synchronize.SubscriberParticipant; + +/** + * A synchronize view page that works with participants that are subclasses of + * {@link SubscriberParticipant}. It shows changes in the tree or table view + * and supports navigation, opening, and filtering changes. + * <p> + * Clients can subclass to extend the label decoration or add action bar + * contributions. For more extensive modifications, clients should create + * their own custom page. + * </p> + * @since 3.0 + */ +public final class SubscriberParticipantPage extends SyncInfoSetSynchronizePage implements IAdaptable { + + private SubscriberParticipant participant; + + private final static int[] INCOMING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.INCOMING}; + private final static int[] OUTGOING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.OUTGOING}; + private final static int[] BOTH_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.INCOMING, SyncInfo.OUTGOING}; + private final static int[] CONFLICTING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING}; + + /** + * Filters out-of-sync resources by working set and mode + */ + private WorkingSetFilteredSyncInfoCollector collector; + + /** + * Constructs a new SynchronizeView. + */ + public SubscriberParticipantPage(ISynchronizePageConfiguration configuration, SubscriberSyncInfoCollector subscriberCollector) { + super(configuration); + this.participant = (SubscriberParticipant)configuration.getParticipant(); + configuration.setComparisonType(isThreeWay() + ? ISynchronizePageConfiguration.THREE_WAY + : ISynchronizePageConfiguration.TWO_WAY); + configuration.addActionContribution(new SubscriberActionContribution()); + initializeCollector(configuration, subscriberCollector); + } + + /** + * @return Returns the participant. + */ + public SubscriberParticipant getParticipant() { + return participant; + } + + /* + * This method is invoked from <code>setMode</code> when the mode has changed. + * It sets the filter on the collector to show the <code>SyncInfo</code> + * appropriate for the mode. + * @param mode the new mode (one of <code>INCOMING_MODE_FILTER</code>, + * <code>OUTGOING_MODE_FILTER</code>, <code>CONFLICTING_MODE_FILTER</code> + * or <code>BOTH_MODE_FILTER</code>) + */ + protected void updateMode(int mode) { + if(collector != null && isThreeWay()) { + + int[] modeFilter = BOTH_MODE_FILTER; + switch(mode) { + case ISynchronizePageConfiguration.INCOMING_MODE: + modeFilter = INCOMING_MODE_FILTER; break; + case ISynchronizePageConfiguration.OUTGOING_MODE: + modeFilter = OUTGOING_MODE_FILTER; break; + case ISynchronizePageConfiguration.BOTH_MODE: + modeFilter = BOTH_MODE_FILTER; break; + case ISynchronizePageConfiguration.CONFLICTING_MODE: + modeFilter = CONFLICTING_MODE_FILTER; break; + } + + collector.setFilter( + new FastSyncInfoFilter.AndSyncInfoFilter( + new FastSyncInfoFilter[] { + new FastSyncInfoFilter.SyncInfoDirectionFilter(modeFilter) + })); + } + } + + private void initializeCollector(ISynchronizePageConfiguration configuration, SubscriberSyncInfoCollector subscriberCollector) { + SubscriberParticipant participant = getParticipant(); + collector = new WorkingSetFilteredSyncInfoCollector(subscriberCollector, participant.getSubscriber().roots()); + updateMode(configuration.getMode()); + collector.reset(); + configuration.setProperty(ISynchronizePageConfiguration.P_SYNC_INFO_SET, collector.getSyncInfoTree()); + configuration.setProperty(SynchronizePageConfiguration.P_WORKING_SET_SYNC_INFO_SET, collector.getWorkingSetSyncInfoSet()); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoSetSynchronizePage#isThreeWay() + */ + protected boolean isThreeWay() { + return getParticipant().getSubscriber().getResourceComparator().isThreeWay(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.SyncInfoSetSynchronizePage#reset() + */ + public void reset() { + getParticipant().reset(); + } + + /* + * Provide internal access to the collector + * @return Returns the collector. + */ + public WorkingSetFilteredSyncInfoCollector getCollector() { + return collector; + } + + public void dispose() { + super.dispose(); + collector.dispose(); + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/CopyToClipboardAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/CopyToClipboardAction.java new file mode 100644 index 000000000..70c54f17d --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/CopyToClipboardAction.java @@ -0,0 +1,152 @@ +/* + * Created on Aug 26, 2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package org.eclipse.team.internal.ui.synchronize.actions; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWTError; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.FileTransfer; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.ui.actions.SelectionListenerAction; +import org.eclipse.ui.part.ResourceTransfer; + + +/** + * Based on org.eclipse.ui.views.navigator.CopyAction. + */ + +class CopyToClipboardAction extends SelectionListenerAction { + + private final static String ID= TeamUIPlugin.PLUGIN_ID + ".synchronize.action.copy"; //$NON-NLS-1$ + + private final Shell fShell; + private final Clipboard fClipboard; + + protected CopyToClipboardAction(Shell shell) { + super(Policy.bind("CopyToClipboardAction.1")); //$NON-NLS-1$ + Assert.isNotNull(shell); + fShell= shell; + fClipboard= new Clipboard(shell.getDisplay()); + setToolTipText(Policy.bind("CopyToClipboardAction.2")); //$NON-NLS-1$ + setId(ID); + } + + + public void run() { + List selectedResources = getSelectedResources(); + IResource[] resources = (IResource[]) selectedResources.toArray(new IResource[selectedResources.size()]); + + // Get the file names and a string representation + final int length = resources.length; + int actualLength = 0; + String[] fileNames = new String[length]; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < length; i++) { + final IPath location = resources[i].getLocation(); + // location may be null. See bug 29491. + if (location != null) + fileNames[actualLength++] = location.toOSString(); + if (i > 0) + buf.append("\n"); //$NON-NLS-1$ + buf.append(resources[i].getName()); + } + // was one or more of the locations null? + if (actualLength < length) { + String[] tempFileNames = fileNames; + fileNames = new String[actualLength]; + for (int i = 0; i < actualLength; i++) + fileNames[i] = tempFileNames[i]; + } + setClipboard(resources, fileNames, buf.toString()); + } + + /** + * Set the clipboard contents. Prompt to retry if clipboard is busy. + * + * @param resources the resources to copy to the clipboard + * @param fileNames file names of the resources to copy to the clipboard + * @param names string representation of all names + */ + private void setClipboard(IResource[] resources, String[] fileNames, String names) { + try { + // set the clipboard contents + if (fileNames.length > 0) { + fClipboard.setContents(new Object[] { resources, fileNames, + names }, + new Transfer[] { ResourceTransfer.getInstance(), + FileTransfer.getInstance(), + TextTransfer.getInstance() }); + } else { + fClipboard.setContents(new Object[] { resources, names }, + new Transfer[] { ResourceTransfer.getInstance(), + TextTransfer.getInstance() }); + } + } catch (SWTError e) { + if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) + throw e; + if (MessageDialog.openQuestion(fShell, Policy.bind("CopyToClipboardAction.3"), Policy.bind("CopyToClipboardAction.4"))) //$NON-NLS-1$//$NON-NLS-2$ + setClipboard(resources, fileNames, names); + } + } + + protected boolean updateSelection(IStructuredSelection selection) { + if (!super.updateSelection(selection)) + return false; + + if (getSelectedNonResources().size() > 0) + return false; + + List selectedResources = getSelectedResources(); + if (selectedResources.size() == 0) + return false; + + boolean projSelected = selectionIsOfType(IResource.PROJECT); + boolean fileFoldersSelected = selectionIsOfType(IResource.FILE + | IResource.FOLDER); + if (!projSelected && !fileFoldersSelected) + return false; + + // selection must be homogeneous + if (projSelected && fileFoldersSelected) + return false; + + // must have a common parent + IContainer firstParent = ((IResource) selectedResources.get(0)) + .getParent(); + if (firstParent == null) + return false; + + Iterator resourcesEnum = selectedResources.iterator(); + while (resourcesEnum.hasNext()) { + IResource currentResource = (IResource) resourcesEnum.next(); + if (!currentResource.getParent().equals(firstParent)) + return false; + // resource location must exist + if (currentResource.getLocation() == null) + return false; + } + + return true; + } + + public void dispose() { + fClipboard.dispose(); + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefactorActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefactorActionGroup.java new file mode 100644 index 000000000..90e7f11b1 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefactorActionGroup.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize.actions; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.ui.synchronize.ISynchronizePageSite; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionGroup; +import org.eclipse.ui.actions.DeleteResourceAction; +import org.eclipse.ui.actions.MoveResourceAction; +import org.eclipse.ui.actions.RenameResourceAction; + +/** + * This action group is modeled after the class of the same name in + * the org.eclipse.ui.workbench plugin. We couldn't reuse that class + * because of a hard dependency on the navigator. + */ +public class RefactorActionGroup extends ActionGroup { + + private CopyToClipboardAction copyAction; + private MoveResourceAction moveAction; + private RenameResourceAction renameAction; + private ISynchronizePageSite site; + private DeleteResourceAction deleteAction; + + public RefactorActionGroup(ISynchronizePageSite site) { + this.site = site; + makeActions(); + } + + public void fillContextMenu(IMenuManager parentMenu, String groupId) { + + final MenuManager menu = new MenuManager(Policy.bind("RefactorActionGroup.0")); //$NON-NLS-1$ + + final IStructuredSelection selection= getSelection(); + final boolean anyResourceSelected = !selection.isEmpty() && allResourcesAreOfType(selection, IResource.PROJECT | IResource.FOLDER | IResource.FILE); + + if (anyResourceSelected) { + copyAction.selectionChanged(selection); + deleteAction.selectionChanged(selection); + moveAction.selectionChanged(selection); + renameAction.selectionChanged(selection); + + menu.add(copyAction); + menu.add(deleteAction); + menu.add(moveAction); + menu.add(renameAction); + } + parentMenu.appendToGroup(groupId, menu); + } + + public void fillActionBars(IActionBars actionBars) { + actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction); + actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), deleteAction); + actionBars.setGlobalActionHandler(ActionFactory.RENAME.getId(), renameAction); + actionBars.setGlobalActionHandler(ActionFactory.MOVE.getId(), moveAction); + } + + public void updateActionBars() { + final IStructuredSelection structuredSelection= getSelection(); + copyAction.selectionChanged(structuredSelection); + deleteAction.selectionChanged(structuredSelection); + moveAction.selectionChanged(structuredSelection); + renameAction.selectionChanged(structuredSelection); + } + + protected void makeActions() { + + final Shell shell = site.getShell(); + final ISharedImages images = PlatformUI.getWorkbench().getSharedImages(); + + copyAction= new CopyToClipboardAction(shell); + moveAction= new MoveResourceAction(shell); + renameAction= new RenameResourceAction(shell); + deleteAction = new DeleteResourceAction(shell) { + protected List getSelectedResources() { + return getSelection().toList();//Arrays.asList(Utils.getResources(getSelection().toArray())); + } + }; + + copyAction.setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); + copyAction.setDisabledImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED)); + + deleteAction.setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)); + deleteAction.setDisabledImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE_DISABLED)); + } + + private IStructuredSelection getSelection() { + final ISelection selection= getContext().getSelection(); + + if (!(selection instanceof IStructuredSelection)) + return new StructuredSelection(); + + return new StructuredSelection(Utils.getResources(((IStructuredSelection)selection).toArray())); + } + + private boolean allResourcesAreOfType(IStructuredSelection selection, int resourceMask) { + Iterator resources = selection.iterator(); + while (resources.hasNext()) { + Object next = resources.next(); + IResource resource = null; + if (next instanceof IResource) { + resource = (IResource)next; + } else if (next instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable)next; + resource = (IResource)adaptable.getAdapter(IResource.class); + } + if(resource == null) { + IResource[] r = Utils.getResources(new Object[] {next}); + if(r.length == 1) { + resource = r[0]; + } + } + if (resource == null || (resource.getType() & resourceMask) == 0) { + return false; + } + } + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.actions.ActionGroup#dispose() + */ + public void dispose() { + super.dispose(); + copyAction.dispose(); + } +} diff --git a/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestTreeViewerAdvisor.java b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestTreeViewerAdvisor.java new file mode 100644 index 000000000..60ea66af8 --- /dev/null +++ b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestTreeViewerAdvisor.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.tests.ui.synchronize; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.team.core.synchronize.SyncInfoTree; +import org.eclipse.team.internal.ui.synchronize.*; +import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; + +public class TestTreeViewerAdvisor extends TreeViewerAdvisor { + + public TestTreeViewerAdvisor(Composite parent, ISynchronizePageConfiguration configuration) { + super(parent, configuration); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.TreeViewerAdvisor#createModelManager(org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration) + */ + protected SynchronizeModelManager createModelManager(ISynchronizePageConfiguration configuration) { + SynchronizeModelManager manager = new SynchronizeModelManager(configuration) { + protected ISynchronizeModelProvider createModelProvider(String id) { + return new HierarchicalModelProvider(getConfiguration(), getSyncInfoSet()); + } + protected ISynchronizeModelProviderDescriptor[] getSupportedModelProviders() { + return new ISynchronizeModelProviderDescriptor[] { + new HierarchicalModelProvider.HierarchicalModelProviderDescriptor()}; + } + private SyncInfoTree getSyncInfoSet() { + return (SyncInfoTree)getConfiguration().getProperty(ISynchronizePageConfiguration.P_SYNC_INFO_SET); + } + }; + manager.setViewerAdvisor(this); + return manager; + } +} |