diff options
author | Michael Valenta | 2006-03-08 19:50:09 +0000 |
---|---|---|
committer | Michael Valenta | 2006-03-08 19:50:09 +0000 |
commit | 35629fc3b126c9e46f95710b3616576f010238ed (patch) | |
tree | 0c66a8983e2f273dd55c2520661c883f937fd95d /bundles/org.eclipse.team.cvs.ui/src/org | |
parent | 60ee07ef56bdb19381f15c52c85e49132facf9ae (diff) | |
download | eclipse.platform.team-35629fc3b126c9e46f95710b3616576f010238ed.tar.gz eclipse.platform.team-35629fc3b126c9e46f95710b3616576f010238ed.tar.xz eclipse.platform.team-35629fc3b126c9e46f95710b3616576f010238ed.zip |
Bug 122849 [Model Sync] Support for change sets
Diffstat (limited to 'bundles/org.eclipse.team.cvs.ui/src/org')
7 files changed, 1086 insertions, 3 deletions
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java index 4477ac6f7..cd6deb45f 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java @@ -37,6 +37,7 @@ import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.core.mapping.CVSActiveChangeSetCollector; import org.eclipse.team.internal.ccvs.ui.console.CVSOutputConsole; import org.eclipse.team.internal.ccvs.ui.model.CVSAdapterFactory; import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; @@ -81,7 +82,7 @@ public class CVSUIPlugin extends AbstractUIPlugin { */ private RepositoryManager repositoryManager; - private SubscriberChangeSetCollector changeSetManager; + private CVSActiveChangeSetCollector changeSetManager; /** * CVSUIPlugin constructor @@ -268,7 +269,7 @@ public class CVSUIPlugin extends AbstractUIPlugin { public synchronized SubscriberChangeSetCollector getChangeSetManager() { if (changeSetManager == null) { - changeSetManager = new SubscriberChangeSetCollector(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber()); + changeSetManager = new CVSActiveChangeSetCollector(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber()); } return changeSetManager; } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetActionProvider.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetActionProvider.java new file mode 100644 index 000000000..6e98ed316 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetActionProvider.java @@ -0,0 +1,421 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.mappings; + +import java.util.*; + +import org.eclipse.core.resources.*; +import org.eclipse.core.resources.mapping.ResourceTraversal; +import org.eclipse.jface.action.*; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.*; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Control; +import org.eclipse.team.core.diff.*; +import org.eclipse.team.core.mapping.IResourceDiffTree; +import org.eclipse.team.core.mapping.provider.ResourceDiffTree; +import org.eclipse.team.internal.ccvs.core.mapping.ChangeSetModelProvider; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.internal.core.subscribers.*; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.internal.ui.synchronize.ChangeSetCapability; +import org.eclipse.team.internal.ui.synchronize.IChangeSetProvider; +import org.eclipse.team.ui.mapping.SynchronizationActionProvider; +import org.eclipse.team.ui.synchronize.*; +import org.eclipse.ui.actions.ActionContext; +import org.eclipse.ui.actions.BaseSelectionListenerAction; +import org.eclipse.ui.navigator.INavigatorContentExtension; +import org.eclipse.ui.navigator.INavigatorContentService; + +public class ChangeSetActionProvider extends SynchronizationActionProvider { + + /** + * Menu group that can be added to the context menu + */ + public final static String CHANGE_SET_GROUP = "changeSetActions"; //$NON-NLS-1$ + + private CreateChangeSetAction createChangeSet; + private MenuManager addToChangeSet; + private EditChangeSetAction editChangeSet; + private RemoveChangeSetAction removeChangeSet; + private MakeDefaultChangeSetAction makeDefault; + + private class CreateChangeSetAction extends ModelParticipantAction { + + public CreateChangeSetAction(ISynchronizePageConfiguration configuration) { + super(TeamUIMessages.ChangeLogModelProvider_0, configuration); + } + + public void run() { + final IDiff[] diffs = getLocalChanges(getStructuredSelection()); + syncExec(new Runnable() { + public void run() { + createChangeSet(diffs); + } + }); + } + + private void createChangeSet(IDiff[] diffs) { + ActiveChangeSet set = getChangeSetCapability().createChangeSet(getConfiguration(), diffs); + if (set != null) { + getActiveChangeSetManager().add(set); + } + } + + protected boolean isEnabledForSelection(IStructuredSelection selection) { + return containsLocalChanges(selection); + } + } + + private class AddToChangeSetAction extends ModelParticipantAction { + + private final ActiveChangeSet set; + + public AddToChangeSetAction(ISynchronizePageConfiguration configuration, ActiveChangeSet set, ISelection selection) { + super(set == null ? TeamUIMessages.ChangeSetActionGroup_2 : set.getTitle(), configuration); + this.set = set; + selectionChanged(selection); + } + + public void run() { + IDiff[] diffArray = getLocalChanges(getStructuredSelection()); + if (set != null) { + set.add(diffArray); + } else { + ChangeSet[] sets = getActiveChangeSetManager().getSets(); + IResource[] resources = getResources(diffArray); + for (int i = 0; i < sets.length; i++) { + ActiveChangeSet activeSet = (ActiveChangeSet)sets[i]; + activeSet.remove(resources); + } + } + } + + private IResource[] getResources(IDiff[] diffArray) { + List result = new ArrayList(); + for (int i = 0; i < diffArray.length; i++) { + IDiff diff = diffArray[i]; + IResource resource = ResourceDiffTree.getResourceFor(diff); + if (resource != null) { + result.add(resource); + } + } + return (IResource[]) result.toArray(new IResource[result.size()]); + } + + protected boolean isEnabledForSelection(IStructuredSelection selection) { + return containsLocalChanges(selection); + } + } + + private abstract class ChangeSetAction extends BaseSelectionListenerAction { + + public ChangeSetAction(String title, ISynchronizePageConfiguration configuration) { + super(title); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.actions.BaseSelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection) + */ + protected boolean updateSelection(IStructuredSelection selection) { + return getSelectedSet() != null; + } + + protected ActiveChangeSet getSelectedSet() { + IStructuredSelection selection = getStructuredSelection(); + if (selection.size() == 1) { + Object first = selection.getFirstElement(); + if (first instanceof ActiveChangeSet) { + return (ActiveChangeSet) first; + } + } + return null; + } + } + + private class EditChangeSetAction extends ChangeSetAction { + + public EditChangeSetAction(ISynchronizePageConfiguration configuration) { + super(TeamUIMessages.ChangeLogModelProvider_6, configuration); + } + + public void run() { + ActiveChangeSet set = getSelectedSet(); + if (set == null) return; + getChangeSetCapability().editChangeSet(getSynchronizePageConfiguration(), set); + } + } + + private class RemoveChangeSetAction extends ChangeSetAction { + + public RemoveChangeSetAction(ISynchronizePageConfiguration configuration) { + super("Remove Change Set", configuration); //$NON-NLS-1$ + } + + public void run() { + ActiveChangeSet set = getSelectedSet(); + if (set == null) return; + if (MessageDialog.openConfirm(getSynchronizePageConfiguration().getSite().getShell(), TeamUIMessages.ChangeSetActionGroup_0, NLS.bind(TeamUIMessages.ChangeSetActionGroup_1, new String[] { set.getTitle() }))) { // + getActiveChangeSetManager().remove(set); + } + } + } + + private class MakeDefaultChangeSetAction extends ChangeSetAction { + public MakeDefaultChangeSetAction(ISynchronizePageConfiguration configuration) { + super(TeamUIMessages.ChangeLogModelProvider_9, configuration); + } + + public void run() { + ActiveChangeSet set = getSelectedSet(); + if (set == null) return; + getActiveChangeSetManager().makeDefault(set); + } + } + + public ChangeSetActionProvider() { + super(); + } + + protected void initialize() { + super.initialize(); + if (getChangeSetCapability().supportsActiveChangeSets()) { + addToChangeSet = new MenuManager(TeamUIMessages.ChangeLogModelProvider_12); + addToChangeSet.setRemoveAllWhenShown(true); + addToChangeSet.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + addChangeSets(manager); + } + }); + createChangeSet = new CreateChangeSetAction(getSynchronizePageConfiguration()); + addToChangeSet.add(createChangeSet); + addToChangeSet.add(new Separator()); + editChangeSet = new EditChangeSetAction(getSynchronizePageConfiguration()); + makeDefault = new MakeDefaultChangeSetAction(getSynchronizePageConfiguration()); + removeChangeSet = new RemoveChangeSetAction(getSynchronizePageConfiguration()); + } + } + + public void fillContextMenu(IMenuManager menu) { + super.fillContextMenu(menu); + if (getChangeSetCapability().enableActiveChangeSetsFor(getSynchronizePageConfiguration())) { + appendToGroup( + menu, + CHANGE_SET_GROUP, + addToChangeSet); + appendToGroup( + menu, + CHANGE_SET_GROUP, + editChangeSet); + appendToGroup( + menu, + CHANGE_SET_GROUP, + removeChangeSet); + appendToGroup( + menu, + CHANGE_SET_GROUP, + makeDefault); + } + } + + public void dispose() { + if (addToChangeSet != null) { + addToChangeSet.dispose(); + addToChangeSet.removeAll(); + } + super.dispose(); + } + + protected void addChangeSets(IMenuManager manager) { + ChangeSet[] sets = getActiveChangeSetManager().getSets(); + ISelection selection = getContext().getSelection(); + createChangeSet.selectionChanged(selection); + addToChangeSet.add(createChangeSet); + addToChangeSet.add(new Separator()); + for (int i = 0; i < sets.length; i++) { + ActiveChangeSet set = (ActiveChangeSet)sets[i]; + AddToChangeSetAction action = new AddToChangeSetAction(getSynchronizePageConfiguration(), set, selection); + manager.add(action); + } + addToChangeSet.add(new Separator()); + // Action that removes change set resources + addToChangeSet.add(new AddToChangeSetAction(getSynchronizePageConfiguration(), null, selection)); + } + + private boolean appendToGroup(IContributionManager manager, String groupId, IContributionItem item) { + if (manager == null || item == null) return false; + IContributionItem group = manager.find(groupId); + if (group != null) { + manager.appendToGroup(group.getId(), item); + return true; + } + return false; + } + + private boolean appendToGroup(IContributionManager manager, String groupId, IAction action) { + if (manager == null || action == null) return false; + IContributionItem group = manager.find(groupId); + if (group != null) { + manager.appendToGroup(group.getId(), action); + //registerActionWithWorkbench(action); + return true; + } + return false; + } + + public ChangeSetCapability getChangeSetCapability() { + ISynchronizeParticipant participant = getSynchronizePageConfiguration().getParticipant(); + if (participant instanceof IChangeSetProvider) { + IChangeSetProvider provider = (IChangeSetProvider) participant; + return provider.getChangeSetCapability(); + } + return null; + } + + private void syncExec(final Runnable runnable) { + final Control ctrl = getSynchronizePageConfiguration().getPage().getViewer().getControl(); + Utils.syncExec(runnable, ctrl); + } + + private SubscriberChangeSetCollector getActiveChangeSetManager() { + return CVSUIPlugin.getPlugin().getChangeSetManager(); + } + + + public IDiff[] getLocalChanges(IStructuredSelection selection) { + if (selection instanceof ITreeSelection) { + ITreeSelection ts = (ITreeSelection) selection; + TreePath[] paths = ts.getPaths(); + List result = new ArrayList(); + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + IDiff[] diffs = getLocalChanges(path); + for (int j = 0; j < diffs.length; j++) { + IDiff diff = diffs[j]; + result.add(diff); + } + } + return (IDiff[]) result.toArray(new IDiff[result.size()]); + } + return new IDiff[0]; + } + + private IDiff[] getLocalChanges(TreePath path) { + IResourceDiffTree tree = getDiffTree(path); + if (path.getSegmentCount() == 1) { + return ((ResourceDiffTree)tree).getDiffs(); + } + ResourceTraversal[] traversals = getTraversals(path.getLastSegment()); + return tree.getDiffs(traversals); + } + + private IResourceDiffTree getDiffTree(TreePath path) { + return getContentProvider().getDiffTree(path); + } + + public boolean containsLocalChanges(IStructuredSelection selection) { + if (selection instanceof ITreeSelection) { + ITreeSelection ts = (ITreeSelection) selection; + TreePath[] paths = ts.getPaths(); + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + if (containsLocalChanges(path)) { + return true; + } + } + } + return false; + } + + private boolean containsLocalChanges(TreePath path) { + IResourceDiffTree tree = getDiffTree(path); + ResourceTraversal[] traversals = getTraversals(path.getLastSegment()); + return tree.hasMatchingDiffs(traversals, getVisibleLocalChangesFilter()); + } + + private ResourceTraversal[] getTraversals(Object element) { + if (element instanceof ChangeSet) { + ChangeSet set = (ChangeSet) element; + return new ResourceTraversal[] { new ResourceTraversal(set.getResources(), IResource.DEPTH_ZERO, IResource.NONE) }; + } + if (element instanceof IProject) { + IProject project = (IProject) element; + return new ResourceTraversal[] { new ResourceTraversal(new IResource[] { project }, IResource.DEPTH_INFINITE, IResource.NONE) }; + } + if (element instanceof IFile) { + IFile file = (IFile) element; + return new ResourceTraversal[] { new ResourceTraversal(new IResource[] { file }, IResource.DEPTH_ZERO, IResource.NONE) }; + } + if (element instanceof IFolder) { + IFolder folder = (IFolder) element; + if (getLayout().equals(IPreferenceIds.COMPRESSED_LAYOUT)) { + return new ResourceTraversal[] { new ResourceTraversal(new IResource[] { folder }, IResource.DEPTH_ONE, IResource.NONE) }; + } else if (getLayout().equals(IPreferenceIds.TREE_LAYOUT)) { + return new ResourceTraversal[] { new ResourceTraversal(new IResource[] { folder }, IResource.DEPTH_INFINITE, IResource.NONE) }; + } else if (getLayout().equals(IPreferenceIds.FLAT_LAYOUT)) { + return new ResourceTraversal[] { new ResourceTraversal(new IResource[] { folder }, IResource.DEPTH_ZERO, IResource.NONE) }; + } + } + return null; + } + + private FastDiffFilter getVisibleLocalChangesFilter() { + return new FastDiffFilter() { + public boolean select(IDiff diff) { + if (diff instanceof IThreeWayDiff && isVisible(diff)) { + IThreeWayDiff twd = (IThreeWayDiff) diff; + if (twd.getDirection() == IThreeWayDiff.OUTGOING || twd.getDirection() == IThreeWayDiff.CONFLICTING) { + return true; + } + } + return false; + } + }; + } + + private boolean isVisible(IDiff diff) { + ChangeSetContentProvider provider = getContentProvider(); + return provider.isVisible(diff); + } + + private ChangeSetContentProvider getContentProvider() { + INavigatorContentService service = getActionSite().getContentService(); + Set set = service.findContentExtensionsByTriggerPoint(getModelProvider()); + for (Iterator iter = set.iterator(); iter.hasNext();) { + INavigatorContentExtension extension = (INavigatorContentExtension) iter.next(); + ITreeContentProvider provider = extension.getContentProvider(); + if (provider instanceof ChangeSetContentProvider) { + return (ChangeSetContentProvider) provider; + } + } + throw new IllegalStateException(); + } + + private Object getModelProvider() { + return ChangeSetModelProvider.getProvider(); + } + + private String getLayout() { + return TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCVIEW_DEFAULT_LAYOUT); + } + + public void setContext(ActionContext context) { + super.setContext(context); + if (context != null) { + if (editChangeSet != null) + editChangeSet.selectionChanged((IStructuredSelection)getContext().getSelection()); + if (removeChangeSet != null) + removeChangeSet.selectionChanged((IStructuredSelection)getContext().getSelection()); + if (makeDefault != null) + makeDefault.selectionChanged((IStructuredSelection)getContext().getSelection()); + } + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetContentProvider.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetContentProvider.java new file mode 100644 index 000000000..8e5b53a20 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetContentProvider.java @@ -0,0 +1,465 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.mappings; + +import java.util.*; + +import org.eclipse.core.resources.*; +import org.eclipse.core.resources.mapping.ModelProvider; +import org.eclipse.core.resources.mapping.ResourceTraversal; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.viewers.*; +import org.eclipse.team.core.diff.*; +import org.eclipse.team.core.mapping.IResourceDiffTree; +import org.eclipse.team.core.mapping.ISynchronizationContext; +import org.eclipse.team.core.mapping.provider.ResourceDiffTree; +import org.eclipse.team.internal.ccvs.core.mapping.ChangeSetModelProvider; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.internal.core.subscribers.*; +import org.eclipse.team.internal.ui.IPreferenceIds; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.internal.ui.mapping.ResourceModelContentProvider; +import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; +import org.eclipse.ui.navigator.ICommonContentExtensionSite; + +public class ChangeSetContentProvider extends ResourceModelContentProvider implements ITreePathContentProvider { + + private ResourceDiffTree theRest; + private Map diffTrees = new HashMap(); + + /* + * Listener that reacts to changes made to the active change set collector + */ + private IChangeSetChangeListener activeListener = new IChangeSetChangeListener() { + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.IChangeSetChangeListener#setAdded(org.eclipse.team.internal.core.subscribers.ChangeSet) + */ + public void setAdded(final ChangeSet set) { + // TODO: Should we listen to all sets for changes or just to the collector? + addListener((DiffChangeSet)set); + if (isVisible(set)) { + Utils.syncExec(new Runnable() { + public void run() { + Object input = getViewer().getInput(); + ((AbstractTreeViewer)getViewer()).add(input, set); + } + }, (StructuredViewer)getViewer()); + } + IResource[] resources = set.getResources(); + try { + getTheRest().beginInput(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + getTheRest().remove(resource); + } + } finally { + getTheRest().endInput(null); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.IChangeSetChangeListener#defaultSetChanged(org.eclipse.team.internal.core.subscribers.ChangeSet, org.eclipse.team.internal.core.subscribers.ChangeSet) + */ + public void defaultSetChanged(final ChangeSet previousDefault, final ChangeSet set) { + if (isVisible(set) || isVisible(previousDefault)) { + Utils.asyncExec(new Runnable() { + public void run() { + ((AbstractTreeViewer)getViewer()).update(new Object[] {previousDefault, set}, null); + } + }, (StructuredViewer)getViewer()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.IChangeSetChangeListener#setRemoved(org.eclipse.team.internal.core.subscribers.ChangeSet) + */ + public void setRemoved(final ChangeSet set) { + removeListener((DiffChangeSet)set); + if (isVisible(set)) { + Utils.syncExec(new Runnable() { + public void run() { + ((AbstractTreeViewer)getViewer()).remove(TreePath.EMPTY.createChildPath(set)); + } + }, (StructuredViewer)getViewer()); + } + IResource[] resources = set.getResources(); + try { + getTheRest().beginInput(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + IDiff diff = getContext().getDiffTree().getDiff(resource); + if (diff != null && !isContainedInSet(diff)) + getTheRest().add(diff); + } + } finally { + getTheRest().endInput(null); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.IChangeSetChangeListener#nameChanged(org.eclipse.team.internal.core.subscribers.ChangeSet) + */ + public void nameChanged(final ChangeSet set) { + if (isVisible(set)) { + Utils.asyncExec(new Runnable() { + public void run() { + ((AbstractTreeViewer)getViewer()).update(set, null); + } + }, (StructuredViewer)getViewer()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.IChangeSetChangeListener#resourcesChanged(org.eclipse.team.internal.core.subscribers.ChangeSet, org.eclipse.core.runtime.IPath[]) + */ + public void resourcesChanged(final ChangeSet set, final IPath[] paths) { + if (isVisible(set)) { + Utils.syncExec(new Runnable() { + public void run() { + // TODO: Should we refresh here or in a diff change listener + ((AbstractTreeViewer)getViewer()).refresh(set, true); + } + }, (StructuredViewer)getViewer()); + } + try { + getTheRest().beginInput(); + for (int i = 0; i < paths.length; i++) { + IPath path = paths[i]; + boolean isContained = ((DiffChangeSet)set).contains(path); + if (isContained) { + IDiff diff = ((DiffChangeSet)set).getDiffTree().getDiff(path); + if (diff != null) { + getTheRest().remove(ResourceDiffTree.getResourceFor(diff)); + } + } else { + IDiff diff = getContext().getDiffTree().getDiff(path); + if (diff != null && !isContainedInSet(diff)) { + getTheRest().add(diff); + } + } + } + } finally { + getTheRest().endInput(null); + } + } + }; + + private IDiffChangeListener diffTreeListener = new IDiffChangeListener() { + + /* (non-Javadoc) + * @see org.eclipse.team.core.diff.IDiffChangeListener#propertyChanged(org.eclipse.team.core.diff.IDiffTree, int, org.eclipse.core.runtime.IPath[]) + */ + public void propertyChanged(IDiffTree tree, int property, IPath[] paths) { + // Ignore + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.diff.IDiffChangeListener#diffsChanged(org.eclipse.team.core.diff.IDiffChangeEvent, org.eclipse.core.runtime.IProgressMonitor) + */ + public void diffsChanged(IDiffChangeEvent event, IProgressMonitor monitor) { + Object input = getViewer().getInput(); + if (input instanceof ChangeSetModelProvider) { + Utils.asyncExec(new Runnable() { + public void run() { + // TODO: Need to be a bit more precise + ((AbstractTreeViewer)getViewer()).refresh(); + } + }, (StructuredViewer)getViewer()); + } + } + + }; + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.mapping.ResourceModelContentProvider#getModelProviderId() + */ + protected String getModelProviderId() { + return ChangeSetModelProvider.ID; + } + + protected boolean isVisible(ChangeSet set) { + final Object input = getViewer().getInput(); + if (input instanceof ChangeSetModelProvider) { + if (set instanceof ActiveChangeSet) { + ActiveChangeSet acs = (ActiveChangeSet) set; + // TODO: may nee to be more precise that this + return getConfiguration().getMode() != ISynchronizePageConfiguration.INCOMING_MODE; + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.mapping.ResourceModelContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object parent) { + if (parent instanceof ISynchronizationContext) { + // Do not show change sets when all models are visible because + // model providers that override the resource content may cause + // problems for the change set content provider + return new Object[0]; + } + if (parent == getModelProvider()) { + return getRootElements(); + } + return super.getElements(parent); + } + + private Object[] getRootElements() { + List result = new ArrayList(); + ChangeSet[] sets = getAllSets(); + for (int i = 0; i < sets.length; i++) { + ChangeSet set = sets[i]; + if (hasChildren(TreePath.EMPTY.createChildPath(set))) + result.add(set); + } + // Include resources that are not in a set + ResourceDiffTree tree = getTheRest(); + IPath[] otherRoots = tree.getChildren(ResourcesPlugin.getWorkspace().getRoot().getFullPath()); + for (int i = 0; i < otherRoots.length; i++) { + IPath path = otherRoots[i]; + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.lastSegment()); + if (project.isAccessible()) + result.add(project); + } + return result.toArray(); + } + + private synchronized ResourceDiffTree getTheRest() { + if (theRest == null) { + theRest = new ResourceDiffTree(); + theRest.addDiffChangeListener(diffTreeListener); + IResourceDiffTree allChanges = getContext().getDiffTree(); + allChanges.accept(ResourcesPlugin.getWorkspace().getRoot().getFullPath(), new IDiffVisitor() { + public boolean visit(IDiff diff) { + if (!isContainedInSet(diff)) + theRest.add(diff); + return true; + } + }, IResource.DEPTH_INFINITE); + } + return theRest; + } + + protected boolean isContainedInSet(IDiff diff) { + ChangeSet[] sets = getAllSets(); + for (int i = 0; i < sets.length; i++) { + ChangeSet set = sets[i]; + if (set.contains(ResourceDiffTree.getResourceFor(diff))) { + return true; + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.mapping.ResourceModelContentProvider#getTraversals(org.eclipse.team.core.mapping.ISynchronizationContext, java.lang.Object) + */ + protected ResourceTraversal[] getTraversals( + ISynchronizationContext context, Object object) { + if (object instanceof ChangeSet) { + ChangeSet set = (ChangeSet) object; + IResource[] resources = set.getResources(); + return new ResourceTraversal[] { new ResourceTraversal(resources, IResource.DEPTH_ZERO, IResource.NONE) }; + } + return super.getTraversals(context, object); + } + + public Object[] getChildren(TreePath parentPath) { + if (parentPath.getSegmentCount() == 0) + return getRootElements(); + Object first = parentPath.getFirstSegment(); + IResourceDiffTree diffTree; + Object parent = parentPath.getLastSegment(); + if (first instanceof DiffChangeSet) { + DiffChangeSet set = (DiffChangeSet) first; + diffTree = set.getDiffTree(); + if (parent instanceof DiffChangeSet) { + parent = getModelRoot(); + } + } else { + diffTree = getTheRest(); + if (parent instanceof ModelProvider) { + parent = getModelRoot(); + } + } + Object[] children = getChildren(parent); + Set result = new HashSet(); + for (int i = 0; i < children.length; i++) { + Object child = children[i]; + if (isVisible(child, diffTree)) { + result.add(child); + } + } + return result.toArray(); + } + + private boolean isVisible(Object object, IResourceDiffTree tree) { + if (object instanceof IResource) { + IResource resource = (IResource) object; + if (tree.getDiff(resource) != null) + return true; + switch (resource.getType()) { + case IResource.PROJECT: + return tree.getDiffs(resource, IResource.DEPTH_INFINITE).length > 0; + case IResource.FOLDER: + if (getLayout().equals(IPreferenceIds.COMPRESSED_LAYOUT)) { + return tree.getDiffs(resource, IResource.DEPTH_ONE).length > 0; + } else if (getLayout().equals(IPreferenceIds.TREE_LAYOUT)) { + return tree.getDiffs(resource, IResource.DEPTH_INFINITE).length > 0; + } + } + } + return false; + } + + public boolean hasChildren(TreePath path) { + return getChildren(path).length > 0; + } + + public TreePath[] getParents(Object element) { + if (element instanceof ChangeSet) { + return new TreePath[] { TreePath.EMPTY }; + } + if (element instanceof IResource) { + IResource resource = (IResource) element; + DiffChangeSet[] sets = getSetsContaining(resource); + if (sets.length > 0) { + List result = new ArrayList(); + for (int i = 0; i < sets.length; i++) { + DiffChangeSet set = sets[i]; + TreePath path = getPathForElement(set.getDiffTree(), resource); + if (path != null) + result.add(path); + } + return (TreePath[]) result.toArray(new TreePath[result.size()]); + } else { + TreePath path = getPathForElement(getTheRest(), resource); + if (path != null) + return new TreePath[] { path }; + } + } + + return new TreePath[0]; + } + + private DiffChangeSet[] getSetsContaining(IResource resource) { + List result = new ArrayList(); + DiffChangeSet[] allSets = getAllSets(); + for (int i = 0; i < allSets.length; i++) { + DiffChangeSet set = allSets[i]; + if (isVisible(resource, set.getDiffTree())) { + result.add(set); + } + } + return (DiffChangeSet[]) result.toArray(new DiffChangeSet[result.size()]); + } + + private DiffChangeSet[] getAllSets() { + SubscriberChangeSetCollector collector = CVSUIPlugin.getPlugin().getChangeSetManager(); + ChangeSet[] sets = collector.getSets(); + List result = new ArrayList(); + for (int i = 0; i < sets.length; i++) { + ChangeSet set = sets[i]; + result.add(set); + } + return (DiffChangeSet[]) result.toArray(new DiffChangeSet[result.size()]); + } + + private TreePath getPathForElement(IResourceDiffTree tree, IResource resource) { + // TODO Auto-generated method stub + return null; + } + + public void init(ICommonContentExtensionSite site) { + super.init(site); + SubscriberChangeSetCollector collector = CVSUIPlugin.getPlugin().getChangeSetManager(); + collector.addListener(activeListener); + ChangeSet[] sets = collector.getSets(); + for (int i = 0; i < sets.length; i++) { + DiffChangeSet set = (DiffChangeSet)sets[i]; + set.getDiffTree().addDiffChangeListener(diffTreeListener); + } + } + + public void dispose() { + CVSUIPlugin.getPlugin().getChangeSetManager().removeListener(activeListener); + for (Iterator iter = diffTrees.values().iterator(); iter.hasNext();) { + IDiffTree tree = (IDiffTree) iter.next(); + tree.removeDiffChangeListener(diffTreeListener); + } + if (theRest != null) { + theRest.removeDiffChangeListener(diffTreeListener); + } + super.dispose(); + } + + protected void addListener(DiffChangeSet set) { + IResourceDiffTree tree = set.getDiffTree(); + diffTrees.put(tree, set); + tree.addDiffChangeListener(diffTreeListener); + } + + protected void removeListener(DiffChangeSet set) { + IResourceDiffTree tree = set.getDiffTree(); + diffTrees.remove(tree); + tree.removeDiffChangeListener(diffTreeListener); + } + + public boolean isVisible(IDiff diff) { + return super.isVisible(diff); + } + + public IResourceDiffTree getDiffTree(TreePath path) { + if (path.getSegmentCount() > 0) { + Object first = path.getFirstSegment(); + if (first instanceof DiffChangeSet) { + DiffChangeSet set = (DiffChangeSet) first; + return set.getDiffTree(); + } + } + return getTheRest(); + } + + public void diffsChanged(IDiffChangeEvent event, IProgressMonitor monitor) { + // Override inherited method to reconcile sub-trees + IPath[] removed = event.getRemovals(); + IDiff[] added = event.getAdditions(); + IDiff[] changed = event.getChanges(); + // Only adjust the set of the rest. The others will be handled by the collectors + try { + getTheRest().beginInput(); + for (int i = 0; i < removed.length; i++) { + IPath path = removed[i]; + getTheRest().remove(path); + } + for (int i = 0; i < added.length; i++) { + IDiff diff = added[i]; + // Only add the diff if it is not already in another set + if (!isContainedInSet(diff)) { + getTheRest().add(diff); + } + } + for (int i = 0; i < changed.length; i++) { + IDiff diff = changed[i]; + // Only add the diff if it is already contained in the free set + if (getTheRest().getDiff(diff.getPath()) != null) { + getTheRest().add(diff); + } + } + } finally { + getTheRest().endInput(monitor); + } + } + +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetLabelProvider.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetLabelProvider.java new file mode 100644 index 000000000..c6d383206 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetLabelProvider.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.mappings; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; +import org.eclipse.team.internal.core.subscribers.ActiveChangeSet; +import org.eclipse.team.internal.ui.mapping.ResourceModelLabelProvider; + +public class ChangeSetLabelProvider extends ResourceModelLabelProvider { + + private Image changeSetImage; + + protected String getDelegateText(Object element) { + if (element instanceof ActiveChangeSet) { + ActiveChangeSet set = (ActiveChangeSet) element; + return set.getName(); + } + return super.getDelegateText(element); + } + + protected Image getDelegateImage(Object element) { + if (element instanceof ActiveChangeSet) { + return getChangeSetImage(); + } + return super.getDelegateImage(element); + } + + private Image getChangeSetImage() { + if (changeSetImage == null) { + ImageDescriptor imageDescriptor = CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_CHANGELOG); + if (imageDescriptor != null) + changeSetImage = imageDescriptor.createImage(); + } + return changeSetImage; + } + + public void dispose() { + if (changeSetImage != null) { + changeSetImage.dispose(); + } + super.dispose(); + } + +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetSorter.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetSorter.java new file mode 100644 index 000000000..65bd2419f --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetSorter.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.mappings; + +import org.eclipse.team.internal.ui.mapping.ResourceModelSorter; + +public class ChangeSetSorter extends ResourceModelSorter { + + public ChangeSetSorter() { + super(); + } + +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceChangeSetCapability.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceChangeSetCapability.java new file mode 100644 index 000000000..f7d03a933 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceChangeSetCapability.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.mappings; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.window.Window; +import org.eclipse.team.core.diff.IDiff; +import org.eclipse.team.core.mapping.provider.ResourceDiffTree; +import org.eclipse.team.internal.ccvs.ui.*; +import org.eclipse.team.internal.ccvs.ui.subscriber.CommitSetDialog; +import org.eclipse.team.internal.core.subscribers.ActiveChangeSet; +import org.eclipse.team.internal.core.subscribers.SubscriberChangeSetCollector; +import org.eclipse.team.internal.ui.synchronize.ChangeSetCapability; +import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; + +public class WorkspaceChangeSetCapability extends ChangeSetCapability { + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.ChangeSetCapability#enableChangeSetsByDefault() + */ + public boolean enableChangeSetsByDefault() { + return CVSUIPlugin.getPlugin().getPreferenceStore().getBoolean(ICVSUIConstants.PREF_COMMIT_SET_DEFAULT_ENABLEMENT); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.ChangeSetCapability#supportsActiveChangeSets() + */ + public boolean supportsActiveChangeSets() { + return true; + } + + public boolean enableActiveChangeSetsFor(ISynchronizePageConfiguration configuration) { + return supportsActiveChangeSets() && + configuration.getMode() != ISynchronizePageConfiguration.INCOMING_MODE; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.ChangeSetCapability#createChangeSet(org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration, org.eclipse.team.core.diff.IDiff[]) + */ + public ActiveChangeSet createChangeSet(ISynchronizePageConfiguration configuration, IDiff[] infos) { + ActiveChangeSet set = getActiveChangeSetManager().createSet(CVSUIMessages.WorkspaceChangeSetCapability_1, new IDiff[0]); + CommitSetDialog dialog = new CommitSetDialog(configuration.getSite().getShell(), set, getResources(infos), + CVSUIMessages.WorkspaceChangeSetCapability_2, CVSUIMessages.WorkspaceChangeSetCapability_3); // + dialog.open(); + if (dialog.getReturnCode() != Window.OK) return null; + set.add(infos); + return set; + } + + private IResource[] getResources(IDiff[] diffs) { + Set result = new HashSet(); + for (int i = 0; i < diffs.length; i++) { + IDiff diff = diffs[i]; + IResource resource = ResourceDiffTree.getResourceFor(diff); + if (resource != null) + result.add(resource); + } + return (IResource[]) result.toArray(new IResource[result.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.ChangeSetCapability#editChangeSet(org.eclipse.team.core.subscribers.ActiveChangeSet) + */ + public void editChangeSet(ISynchronizePageConfiguration configuration, ActiveChangeSet set) { + CommitSetDialog dialog = new CommitSetDialog(configuration.getSite().getShell(), set, set.getResources(), + CVSUIMessages.WorkspaceChangeSetCapability_7, CVSUIMessages.WorkspaceChangeSetCapability_8); // + dialog.open(); + if (dialog.getReturnCode() != Window.OK) return; + // Nothing to do here as the set was updated by the dialog + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.ChangeSetCapability#getActiveChangeSetManager() + */ + public SubscriberChangeSetCollector getActiveChangeSetManager() { + return CVSUIPlugin.getPlugin().getChangeSetManager(); + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceModelParticipant.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceModelParticipant.java index 76ee32463..fa1471427 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceModelParticipant.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceModelParticipant.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.ui.mappings; +import org.eclipse.core.resources.mapping.ModelProvider; import org.eclipse.core.resources.mapping.ResourceMapping; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.action.*; @@ -22,19 +23,22 @@ import org.eclipse.team.core.mapping.provider.MergeContext; import org.eclipse.team.core.mapping.provider.SynchronizationContext; import org.eclipse.team.core.subscribers.SubscriberScopeManager; import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; +import org.eclipse.team.internal.ccvs.core.mapping.ChangeSetModelProvider; import org.eclipse.team.internal.ccvs.ui.*; import org.eclipse.team.internal.ccvs.ui.actions.*; import org.eclipse.team.internal.ccvs.ui.subscriber.CVSActionDelegateWrapper; import org.eclipse.team.internal.ui.TeamUIPlugin; import org.eclipse.team.internal.ui.Utils; import org.eclipse.team.internal.ui.mapping.MergeAllActionHandler; +import org.eclipse.team.internal.ui.synchronize.ChangeSetCapability; +import org.eclipse.team.internal.ui.synchronize.IChangeSetProvider; import org.eclipse.team.ui.TeamUI; import org.eclipse.team.ui.mapping.ITeamContentProviderManager; import org.eclipse.team.ui.mapping.SynchronizationActionProvider; import org.eclipse.team.ui.synchronize.*; public class WorkspaceModelParticipant extends - ModelSynchronizeParticipant { + ModelSynchronizeParticipant implements IChangeSetProvider { public static final String VIEWER_ID = "org.eclipse.team.cvs.ui.workspaceSynchronization"; //$NON-NLS-1$ @@ -169,6 +173,8 @@ public class WorkspaceModelParticipant extends } } } + + private WorkspaceChangeSetCapability capability; public WorkspaceModelParticipant() { } @@ -229,5 +235,30 @@ public class WorkspaceModelParticipant extends pages[pages.length - 1].setTitle(CVSUIMessages.CVSParticipant_2); return pages; } + + public ModelProvider[] getEnabledModelProviders() { + ModelProvider[] enabledProviders = super.getEnabledModelProviders(); + for (int i = 0; i < enabledProviders.length; i++) { + ModelProvider provider = enabledProviders[i]; + if (provider.getId().equals(ChangeSetModelProvider.ID)) + return enabledProviders; + } + ModelProvider[] extended = new ModelProvider[enabledProviders.length + 1]; + for (int i = 0; i < enabledProviders.length; i++) { + extended[i] = enabledProviders[i]; + } + ChangeSetModelProvider provider = ChangeSetModelProvider.getProvider(); + if (provider == null) + return enabledProviders; + extended[extended.length - 1] = provider; + return extended; + } + + public ChangeSetCapability getChangeSetCapability() { + if (capability == null) { + capability = new WorkspaceChangeSetCapability(); + } + return capability; + } } |