### Eclipse Workspace Patch 1.0 #P org.eclipse.team.ui Index: src/org/eclipse/team/internal/ui/TeamUIMessages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIMessages.java,v retrieving revision 1.86 diff -u -r1.86 TeamUIMessages.java --- src/org/eclipse/team/internal/ui/TeamUIMessages.java 4 Mar 2010 11:30:01 -0000 1.86 +++ src/org/eclipse/team/internal/ui/TeamUIMessages.java 5 Mar 2010 12:15:58 -0000 @@ -718,6 +718,13 @@ public static String PatchParsedPage_description; public static String PatchParsedPage_clickFinishToGoToSynchronizeView; + public static String PatchInaccessibleProjectsPage_title; + public static String PatchInaccessibleProjectsPage_message; + public static String PatchInaccessibleProjectsPage_projectDoesNotExistInWorkspace; + public static String PatchInaccessibleProjectsPage_selectExisting; + public static String PatchInaccessibleProjectsPage_deselectAll; + public static String PatchInaccessibleProjectsPage_openingProjects; + public static String NotFound; } Index: src/org/eclipse/team/internal/ui/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties,v retrieving revision 1.257 diff -u -r1.257 messages.properties --- src/org/eclipse/team/internal/ui/messages.properties 4 Mar 2010 11:30:01 -0000 1.257 +++ src/org/eclipse/team/internal/ui/messages.properties 5 Mar 2010 12:15:58 -0000 @@ -575,4 +575,13 @@ # PatchParsedPage_title=Patch Parsed PatchParsedPage_description=The patch has been processed. -PatchParsedPage_clickFinishToGoToSynchronizeView=Click finish button to go to Synchronize view. \ No newline at end of file +PatchParsedPage_clickFinishToGoToSynchronizeView=Click finish button to go to Synchronize view. +# +# PatchInaccessibleProjectsPage +# +PatchInaccessibleProjectsPage_title=Inaccessible Projects +PatchInaccessibleProjectsPage_message=Select projects to open for applying the patch. Inaccessbile projects will not appear in the Synchronize View. +PatchInaccessibleProjectsPage_projectDoesNotExistInWorkspace={0} (Project does not exist in workspace) +PatchInaccessibleProjectsPage_selectExisting=Select Existing +PatchInaccessibleProjectsPage_deselectAll=Deselect All +PatchInaccessibleProjectsPage_openingProjects=Opening projects \ No newline at end of file Index: src/org/eclipse/team/internal/ui/synchronize/patch/ApplyPatchSubscriber.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/patch/ApplyPatchSubscriber.java,v retrieving revision 1.3 diff -u -r1.3 ApplyPatchSubscriber.java --- src/org/eclipse/team/internal/ui/synchronize/patch/ApplyPatchSubscriber.java 1 Mar 2010 16:24:39 -0000 1.3 +++ src/org/eclipse/team/internal/ui/synchronize/patch/ApplyPatchSubscriber.java 5 Mar 2010 12:15:59 -0000 @@ -101,21 +101,28 @@ } public IResource[] members(IResource resource) throws TeamException { + //XXX: what if there is an addition in the patch that needs to add 3 subfolders? try { if(resource.getType() == IResource.FILE) // file has no IResource members return new IResource[0]; IContainer container = (IContainer) resource; - + // workspace container members - List existingChildren = new ArrayList(Arrays.asList(container.members())); + List existingChildren = new ArrayList(); + + if (container.isAccessible()) + existingChildren.addAll(Arrays.asList(container.members())); // patch members, subscriber location FilePatch2[] diffs = getPatcher().getDiffs(); for (int i = 0; i < diffs.length; i++) { IResource file = PatchModelProvider.getFile(diffs[i], getPatcher()); - if (!container.exists(file.getProjectRelativePath())) { - existingChildren.add(file); + if (container.getFullPath().isPrefixOf(file.getFullPath())) { + // XXX: check segments + if (!container.exists(file.getProjectRelativePath())) { + existingChildren.add(file); + } } } return (IResource[]) existingChildren.toArray(new IResource[existingChildren.size()]); @@ -146,7 +153,8 @@ // return array of projects from the patch DiffProject diffProject = ((PatchProjectDiffNode)children[i]).getDiffProject(); IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(diffProject.getName()); - roots.add(project); + if (project.isAccessible()) + roots.add(project); } } else { roots.add(getPatcher().getTarget()); Index: src/org/eclipse/team/internal/ui/synchronize/patch/ApplyPatchSynchronizationWizard.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/patch/ApplyPatchSynchronizationWizard.java,v retrieving revision 1.3 diff -u -r1.3 ApplyPatchSynchronizationWizard.java --- src/org/eclipse/team/internal/ui/synchronize/patch/ApplyPatchSynchronizationWizard.java 4 Mar 2010 11:30:01 -0000 1.3 +++ src/org/eclipse/team/internal/ui/synchronize/patch/ApplyPatchSynchronizationWizard.java 5 Mar 2010 12:15:59 -0000 @@ -11,13 +11,17 @@ package org.eclipse.team.internal.ui.synchronize.patch; import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.internal.core.patch.DiffProject; import org.eclipse.compare.internal.patch.*; import org.eclipse.core.resources.*; import org.eclipse.core.resources.mapping.ResourceMapping; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.team.core.subscribers.SubscriberMergeContext; import org.eclipse.team.core.subscribers.SubscriberScopeManager; -import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.internal.ui.wizards.PatchInaccessibleProjectsPage; import org.eclipse.team.ui.IConfigurationWizard; import org.eclipse.team.ui.TeamUI; import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; @@ -27,6 +31,8 @@ public class ApplyPatchSynchronizationWizard extends PatchWizard implements IConfigurationWizard { + private PatchInaccessibleProjectsPage fPatchInaccessibleProjectsPage; + public ApplyPatchSynchronizationWizard() { // TODO: get selection, available when launched from toolbar or main // menu @@ -34,6 +40,13 @@ } public boolean performFinish() { + if (fPatchInaccessibleProjectsPage != null) { + IProject[] projects = fPatchInaccessibleProjectsPage + .getSelectedProjects(); + if (projects != null && projects.length != 0) + openSelectedProjects(projects); + } + ApplyPatchSubscriber subscriber = new ApplyPatchSubscriber(getPatcher()); // Get ResourceMappings for root resources from the patch. @@ -72,12 +85,38 @@ if (getPatch() == null) addPage(fPatchWizardPage = new InputPatchPage(this)); if (getPatch() == null || !getPatcher().isWorkspacePatch()) - addPage(fPatchTargetPage = new PatchTargetPage(getPatcher())); + addPage(fPatchTargetPage = new PatchTargetPage(getPatcher()) { + public IWizardPage getNextPage() { + if (!isTargetingInaccessibleProjects()) + return super.getNextPage().getNextPage(); + return super.getNextPage(); + } + }); + if (getPatch() == null || isTargetingInaccessibleProjects()) + addPage(fPatchInaccessibleProjectsPage = new PatchInaccessibleProjectsPage( + getPatcher())); addPage(new PatchParsedPage()); } + private boolean isTargetingInaccessibleProjects() { + DiffProject[] diffProjects = getPatcher().getDiffProjects(); + if (diffProjects != null) { + for (int i = 0; i < diffProjects.length; i++) { + IProject project = ResourcesPlugin.getWorkspace().getRoot() + .getProject(diffProjects[i].getName()); + if (!project.isAccessible()) + return true; + } + } + return false; + } + public boolean canFinish() { IWizardPage currentPage = getContainer().getCurrentPage(); + if (currentPage.getName().equals( + PatchInaccessibleProjectsPage.PATCH_INACCESSIBLE_PROJECTS_NAME)) { + return currentPage.isPageComplete(); + } if (currentPage.getName() .equals(PatchParsedPage.PATCH_PARSED_PAGE_NAME)) { return currentPage.isPageComplete(); @@ -89,4 +128,33 @@ // make the patcher available to other classes in the package return super.getPatcher(); } + + private void openSelectedProjects(final IProject projects[]) { + Job openProjectsJob = new Job( + TeamUIMessages.PatchInaccessibleProjectsPage_openingProjects) { + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask( + TeamUIMessages.PatchInaccessibleProjectsPage_openingProjects, + projects.length); + MultiStatus errorStatus = new MultiStatus( + TeamUIPlugin.ID, + IStatus.ERROR, + TeamUIMessages.PatchInaccessibleProjectsPage_openingProjects, + null); + for (int i = 0; i < projects.length; i++) { + IProject project = (IProject) projects[i]; + try { + project.open(new SubProgressMonitor(monitor, 1)); + } catch (CoreException e) { + errorStatus.add(e.getStatus()); + } + } + monitor.done(); + return errorStatus; + } + }; + openProjectsJob.setUser(true); + openProjectsJob.schedule(); + } + } Index: src/org/eclipse/team/internal/ui/wizards/PatchInaccessibleProjectsPage.java =================================================================== RCS file: src/org/eclipse/team/internal/ui/wizards/PatchInaccessibleProjectsPage.java diff -N src/org/eclipse/team/internal/ui/wizards/PatchInaccessibleProjectsPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/team/internal/ui/wizards/PatchInaccessibleProjectsPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2010 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.ui.wizards; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.compare.internal.core.patch.DiffProject; +import org.eclipse.compare.internal.patch.WorkspacePatcher; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jface.viewers.*; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ui.TeamUIMessages; +import org.eclipse.ui.model.WorkbenchLabelProvider; +import org.eclipse.ui.views.navigator.ResourceComparator; + +public class PatchInaccessibleProjectsPage extends WizardPage { + + private CheckboxTableViewer checkList; + private Button checkAllButton; + private Button uncheckAllButton; + + private WorkspacePatcher fPatcher; + + public final static String PATCH_INACCESSIBLE_PROJECTS_NAME = "PatchInaccessibleProjectsPage"; //$NON-NLS-1$ + + public PatchInaccessibleProjectsPage(WorkspacePatcher patcher) { + super(PATCH_INACCESSIBLE_PROJECTS_NAME, + TeamUIMessages.PatchInaccessibleProjectsPage_title, null); + setMessage(TeamUIMessages.PatchInaccessibleProjectsPage_message); + fPatcher = patcher; + } + + public void createControl(Composite parent) { + initializeDialogUnits(parent); + + Composite composite = new Composite(parent, SWT.NULL); + composite.setLayout(new GridLayout(3, false)); + composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL + | GridData.HORIZONTAL_ALIGN_FILL)); + setControl(composite); + Font parentFont = composite.getFont(); + + checkList = CheckboxTableViewer.newCheckList(composite, SWT.H_SCROLL + | SWT.V_SCROLL | SWT.BORDER); + checkList.setContentProvider(new ArrayContentProvider()); + checkList.setLabelProvider(new WorkbenchLabelProvider() { + public Color getForeground(Object element) { + if (element instanceof IProject + && !((IProject) element).exists()) + return Display.getCurrent().getSystemColor( + SWT.COLOR_WIDGET_NORMAL_SHADOW); + return super.getForeground(element); + } + + protected String decorateText(String input, Object element) { + if (element instanceof IProject + && !((IProject) element).exists()) + return input + + NLS.bind( + TeamUIMessages.PatchInaccessibleProjectsPage_projectDoesNotExistInWorkspace, + ""); //$NON-NLS-1$ + return input; + } + }); + checkList.addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event) { + IProject project = (IProject) event.getElement(); + if (event.getChecked() && !project.exists()) + checkList.setChecked(project, false); + } + }); + checkList + .setComparator(new ResourceComparator(ResourceComparator.NAME)); + + Table table = checkList.getTable(); + GridData data = new GridData(GridData.VERTICAL_ALIGN_FILL + | GridData.HORIZONTAL_ALIGN_FILL); + data.horizontalSpan = 3; + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + table.setLayoutData(data); + + checkAllButton = new Button(composite, SWT.NONE); + checkAllButton + .setText(TeamUIMessages.PatchInaccessibleProjectsPage_selectExisting); + checkAllButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + setAllChecked(true); + } + }); + checkAllButton.setFont(parentFont); + setButtonLayoutData(checkAllButton); + + uncheckAllButton = new Button(composite, SWT.NONE); + uncheckAllButton + .setText(TeamUIMessages.PatchInaccessibleProjectsPage_deselectAll); + uncheckAllButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + setAllChecked(false); + } + }); + uncheckAllButton.setFont(parentFont); + setButtonLayoutData(uncheckAllButton); + + updateControls(); + } + + private void updateControls() { + DiffProject[] diffProjects = fPatcher.getDiffProjects(); + List projects = new ArrayList(); + if (diffProjects != null) { + for (int i = 0; i < diffProjects.length; i++) { + IProject project = ResourcesPlugin.getWorkspace().getRoot() + .getProject(diffProjects[i].getName()); + if (!project.isAccessible()) + projects.add(project); + } + } + checkList.setInput(projects.toArray(new IProject[] {})); + } + + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) + updateControls(); + } + + public IWizardPage getNextPage() { + Object input = checkList.getInput(); + // Skipping the patch parsed page in case this one is displayed + if (input instanceof IProject[] && ((IProject[]) input).length > 0) + return null; + return super.getNextPage(); + } + + public IProject[] getSelectedProjects() { + Object elements[] = checkList.getCheckedElements(); + List projects = new ArrayList(); + for (int i = 0; i < elements.length; i++) + projects.add(elements[i]); + return (IProject[]) projects.toArray(new IProject[] {}); + } + + private void setAllChecked(boolean checked) { + int count = checkList.getTable().getItemCount(); + for (int i = 0; i < count; i++) { + IProject project = (IProject) checkList.getElementAt(i); + if (project.exists()) + checkList.setChecked(project, checked); + } + } + +}