/******************************************************************************* * Copyright (c) 2005-2008 Polarion Software. * 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: * Sergiy Logvin - Initial API and implementation * Alessandro Nistico - [patch] Change Set's implementation *******************************************************************************/ package org.eclipse.team.svn.ui.panel.local; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.team.internal.ui.Utils; import org.eclipse.team.svn.core.IStateFilter; import org.eclipse.team.svn.core.SVNMessages; import org.eclipse.team.svn.core.connector.SVNProperty; import org.eclipse.team.svn.core.connector.SVNRevision; import org.eclipse.team.svn.core.extension.CoreExtensionsManager; import org.eclipse.team.svn.core.extension.factory.ISVNConnectorFactory; import org.eclipse.team.svn.core.operation.AbstractActionOperation; import org.eclipse.team.svn.core.operation.CompositeOperation; import org.eclipse.team.svn.core.operation.IActionOperation; import org.eclipse.team.svn.core.operation.local.AddToSVNIgnoreOperation; import org.eclipse.team.svn.core.operation.local.CreatePatchOperation; import org.eclipse.team.svn.core.operation.local.ExportOperation; import org.eclipse.team.svn.core.operation.local.MarkAsMergedOperation; import org.eclipse.team.svn.core.operation.local.RefreshResourcesOperation; import org.eclipse.team.svn.core.operation.local.RestoreProjectMetaOperation; import org.eclipse.team.svn.core.operation.local.SaveProjectMetaOperation; import org.eclipse.team.svn.core.operation.local.management.CleanupOperation; import org.eclipse.team.svn.core.operation.local.property.GetPropertiesOperation; import org.eclipse.team.svn.core.operation.local.refactor.DeleteResourceOperation; import org.eclipse.team.svn.core.resource.ILocalResource; import org.eclipse.team.svn.core.resource.IRemoteStorage; import org.eclipse.team.svn.core.resource.IRepositoryResource; import org.eclipse.team.svn.core.resource.events.IResourceStatesListener; import org.eclipse.team.svn.core.resource.events.ResourceStatesChangedEvent; import org.eclipse.team.svn.core.svnstorage.ResourcesParentsProvider; import org.eclipse.team.svn.core.svnstorage.SVNRemoteStorage; import org.eclipse.team.svn.core.utility.FileUtility; import org.eclipse.team.svn.core.utility.ProgressMonitorUtility; import org.eclipse.team.svn.core.utility.SVNUtility; import org.eclipse.team.svn.ui.SVNTeamUIPlugin; import org.eclipse.team.svn.ui.SVNUIMessages; import org.eclipse.team.svn.ui.action.local.AddToSVNIgnoreAction; import org.eclipse.team.svn.ui.action.local.BranchTagAction; import org.eclipse.team.svn.ui.action.local.CompareWithWorkingCopyAction; import org.eclipse.team.svn.ui.action.local.ReplaceWithLatestRevisionAction; import org.eclipse.team.svn.ui.action.local.ReplaceWithRevisionAction; import org.eclipse.team.svn.ui.action.local.RevertAction; import org.eclipse.team.svn.ui.composite.CommentComposite; import org.eclipse.team.svn.ui.composite.ResourceSelectionComposite; import org.eclipse.team.svn.ui.dialog.DefaultDialog; import org.eclipse.team.svn.ui.dialog.DiscardConfirmationDialog; import org.eclipse.team.svn.ui.event.IResourceSelectionChangeListener; import org.eclipse.team.svn.ui.event.ResourceSelectionChangedEvent; import org.eclipse.team.svn.ui.extension.factory.IModifiableCommentDialogPanel; import org.eclipse.team.svn.ui.operation.CompareResourcesOperation; import org.eclipse.team.svn.ui.operation.ShowConflictEditorOperation; import org.eclipse.team.svn.ui.panel.common.CommentPanel; import org.eclipse.team.svn.ui.panel.participant.CommitPaneParticipant; import org.eclipse.team.svn.ui.panel.participant.CommitPaneParticipantHelper; import org.eclipse.team.svn.ui.panel.participant.CommitPaneParticipantHelper.CommitPaneVerifier; import org.eclipse.team.svn.ui.panel.remote.ComparePanel; import org.eclipse.team.svn.ui.preferences.SVNTeamPreferences; import org.eclipse.team.svn.ui.properties.bugtraq.BugtraqModel; import org.eclipse.team.svn.ui.propfind.BugtraqPropFindVisitor; import org.eclipse.team.svn.ui.propfind.CompositePropFindVisitor; import org.eclipse.team.svn.ui.propfind.IPropFindVisitor; import org.eclipse.team.svn.ui.propfind.LogTemplatesPropFindVisitor; import org.eclipse.team.svn.ui.propfind.MaxLogWidthPropFindVisitor; import org.eclipse.team.svn.ui.propfind.MinLockSizePropFindVisitor; import org.eclipse.team.svn.ui.propfind.MinLogSizePropFindVisitor; import org.eclipse.team.svn.ui.utility.LockProposeUtility; import org.eclipse.team.svn.ui.utility.UIMonitorUtility; import org.eclipse.team.svn.ui.verifier.AbstractVerifier; import org.eclipse.team.ui.synchronize.ResourceScope; import org.eclipse.ui.IWorkbenchActionConstants; /** * Commit panel * * @author Sergiy Logvin */ public class CommitPanel extends CommentPanel implements IModifiableCommentDialogPanel { public static final int MSG_COMMIT = 0; public static final int MSG_OVER_AND_COMMIT = 1; public static final int MAXIMUM_CHECKS_SIZE = 100; protected ResourceSelectionComposite selectionComposite; protected Button pasteNamesButton; protected CommitPaneParticipantHelper paneParticipantHelper; /* * Difference between resources and userSelectedResources: * Example: select src folder in Package Explorer * resources: [L/SVNProject/src/existing/otherpack/CC.java, L/SVNProject/src/existing/ZA.java] * userSelectedResources: [F/SVNProject/src]; also it can be null */ protected IResource []resources; protected IResource[] userSelectedResources; protected Button keepLocksButton; protected SashForm sForm; protected boolean keepLocks; protected List changeListenerList; protected int minLogSize; protected int maxLogWidth; protected final String proposedComment; protected IResourceStatesListener resourceStatesListener; protected boolean resourcesChanged; public CommitPanel(IResource []resources, int msgType) { this(resources, msgType, null); } public CommitPanel(IResource []resources, int msgType, String proposedComment) { this(resources, null, msgType, proposedComment); } public CommitPanel(IResource []resources, IResource[] userSelectedResources, int msgType, String proposedComment) { super(SVNUIMessages.CommitPanel_Title); this.proposedComment = proposedComment; this.resources = resources; if (msgType == CommitPanel.MSG_OVER_AND_COMMIT) { this.defaultMessage = SVNUIMessages.CommitPanel_Message; this.dialogDescription = SVNUIMessages.CommitPanel_Description; } this.changeListenerList = new ArrayList(); this.userSelectedResources = userSelectedResources; this.paneParticipantHelper = new CommitPaneParticipantHelper(); } public void createControlsImpl(Composite parent) { GridData data = null; GridLayout layout = null; layout = (GridLayout)parent.getLayout(); layout.marginHeight = 3; this.sForm = new SashForm(parent, SWT.VERTICAL); layout = new GridLayout(); layout.marginHeight = layout.marginWidth = 0; layout.verticalSpacing = 3; this.sForm.setLayout(layout); data = new GridData(GridData.FILL_BOTH); data.heightHint = 400; this.sForm.setLayoutData(data); Composite composite = new Composite(this.sForm, SWT.NONE); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); layout = new GridLayout(); layout.verticalSpacing = 4; layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); Group group = new Group(composite, SWT.NULL); layout = new GridLayout(); group.setLayout(layout); data = new GridData(GridData.FILL_BOTH); group.setLayoutData(data); group.setText(SVNUIMessages.CommitPanel_Comment); CommitPanel.CollectPropertiesOperation op = new CollectPropertiesOperation(this.resources); UIMonitorUtility.doTaskNowDefault(op, true); this.bugtraqModel = op.getBugtraqModel(); this.minLogSize = op.getMinLogSize(); this.maxLogWidth = op.getMaxLogWidth(); this.comment = new CommentComposite(group, this.proposedComment, this, op.getLogTemplates(), this.bugtraqModel, this.minLogSize, this.maxLogWidth); data = new GridData(GridData.FILL_BOTH); this.comment.setLayoutData(data); Composite middleComposite = new Composite(composite, SWT.NULL); data = new GridData(GridData.FILL_HORIZONTAL); layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 2; layout.numColumns = 2; middleComposite.setLayoutData(data); middleComposite.setLayout(layout); this.keepLocks = SVNTeamUIPlugin.instance().getPreferenceStore().getBoolean(SVNTeamPreferences.COMMIT_DIALOG_KEEP_LOCKS); this.keepLocksButton = new Button(middleComposite, SWT.CHECK); data = new GridData(GridData.BEGINNING | GridData.FILL_HORIZONTAL); this.keepLocksButton.setLayoutData(data); this.keepLocksButton.setText(SVNUIMessages.CommitPanel_KeepLocks); this.keepLocksButton.setSelection(false); this.keepLocksButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { CommitPanel.this.keepLocks = CommitPanel.this.keepLocksButton.getSelection(); } }); this.keepLocksButton.setSelection(this.keepLocks); this.pasteNamesButton = new Button(middleComposite, SWT.PUSH | SWT.END); data = new GridData(); this.pasteNamesButton.setLayoutData(data); this.pasteNamesButton.setText(SVNUIMessages.CommitPanel_PasteNames_Button); this.pasteNamesButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { CommitPanel.this.pasteNames(); } }); Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); if (this.paneParticipantHelper.isParticipantPane()) { CommitPaneParticipant participant= new CommitPaneParticipant(new ResourceScope(this.resources), this); this.paneParticipantHelper.init(participant); this.createPaneControls(); } else { this.createResourceSelectionCompositeControls(); } } protected void createResourceSelectionCompositeControls() { this.selectionComposite = new ResourceSelectionComposite(this.sForm, SWT.NONE, this.resources, true, this.userSelectedResources); GridData data = new GridData(GridData.FILL_BOTH); data.heightHint = 175; this.selectionComposite.setLayoutData(data); IPreferenceStore store = SVNTeamUIPlugin.instance().getPreferenceStore(); int first = SVNTeamPreferences.getDialogInt(store, SVNTeamPreferences.COMMIT_DIALOG_WEIGHT_NAME); if (first < 20 || first > 80) // limit saved the value range to something acceptable, since there could be workspace crashes etc. (see bug 375038) { first = 50; } this.sForm.setWeights(new int[] {first, 100 - first}); this.selectionComposite.addResourcesSelectionChangedListener(new IResourceSelectionChangeListener() { public void resourcesSelectionChanged(ResourceSelectionChangedEvent event) { CommitPanel.this.fireResourcesSelectionChanged(event); } }); this.attachTo(this.selectionComposite, new AbstractVerifier() { protected String getErrorMessage(Control input) { IResource []selection = CommitPanel.this.getSelectedResources(); if (selection == null || selection.length == 0) { return SVNUIMessages.ResourceSelectionComposite_Verifier_Error; } if (FileUtility.checkForResourcesPresenceRecursive(selection, new IStateFilter.OrStateFilter(new IStateFilter[]{IStateFilter.SF_CONFLICTING, IStateFilter.SF_TREE_CONFLICTING}))) { return SVNUIMessages.CommitPanel_Conflicting_Error; } return null; } protected String getWarningMessage(Control input) { String message = null; IResource[] selection = CommitPanel.this.getSelectedResources(); if (selection != null && selection.length > 0) { message = CommitPanel.validateResources(selection); } return message; } }); this.addContextMenu(); } protected void createPaneControls() { Composite paneComposite = new Composite(this.sForm, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginWidth = 0; paneComposite.setLayout(layout); GridData data = new GridData(GridData.FILL_BOTH); data.grabExcessHorizontalSpace = true; data.grabExcessVerticalSpace = true; data.heightHint = 175; paneComposite.setLayoutData(data); IPreferenceStore store = SVNTeamUIPlugin.instance().getPreferenceStore(); int first = SVNTeamPreferences.getDialogInt(store, SVNTeamPreferences.COMMIT_DIALOG_WEIGHT_NAME); this.sForm.setWeights(new int[] {first, 100 - first}); Control paneControl = this.paneParticipantHelper.createChangesPage(paneComposite); data = new GridData(GridData.FILL_BOTH); paneControl.setLayoutData(data); this.paneParticipantHelper.initListeners(); //add validator to pane this.attachTo(paneComposite, new CommitPaneVerifier(this.paneParticipantHelper)); } public String getHelpId() { return "org.eclipse.team.svn.help.commitDialogContext"; //$NON-NLS-1$ } public void postInit() { super.postInit(); this.resourceStatesListener = new IResourceStatesListener() { public void resourcesStateChanged(ResourceStatesChangedEvent event) { CommitPanel.this.updateResources(event); } }; SVNRemoteStorage.instance().addResourceStatesListener(ResourceStatesChangedEvent.class, CommitPanel.this.resourceStatesListener); if (this.paneParticipantHelper.isParticipantPane()) { this.paneParticipantHelper.expandPaneTree(); } } protected void saveChangesImpl() { super.saveChangesImpl(); this.savePreferences(); } protected void cancelChangesImpl() { super.cancelChangesImpl(); this.savePreferences(); } public boolean canClose() { final boolean []commit = new boolean[] {true}; if (this.bugtraqModel != null && this.bugtraqModel.getMessage() != null && this.bugtraqModel.isWarnIfNoIssue() && this.comment.getBugID() != null && this.comment.getBugID().trim().length() == 0) { UIMonitorUtility.getDisplay().syncExec(new Runnable() { public void run() { MessageDialog dlg = new MessageDialog( UIMonitorUtility.getShell(), SVNUIMessages.CommitPanel_NoBugId_Title, null, SVNUIMessages.CommitPanel_NoBugId_Message, MessageDialog.WARNING, new String[] {IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL}, 0); commit[0] = dlg.open() == 0; } }); } return commit[0]; } public void pasteNames() { if (!this.paneParticipantHelper.isParticipantPane()) { List selectedResources = this.selectionComposite.getCurrentSelection(); this.pasteNames(selectedResources.toArray(new IResource[0])); } else { ISelection selection = this.paneParticipantHelper.getSyncPageConfiguration().getSite().getSelectionProvider().getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection strSelection = (IStructuredSelection) selection; Object[] elements = strSelection.toArray(); IResource[] resources = Utils.getResources(elements); this.pasteNames(resources); } } } protected void pasteNames(IResource[] resources) { if (resources.length > 0) { String namesString = ""; //$NON-NLS-1$ for (IResource resource : resources) { namesString += resource.getName() + "\n"; //$NON-NLS-1$ } this.comment.insertText(namesString); } } //relates to resource selection composite protected void addContextMenu() { final TableViewer tableViewer = this.selectionComposite.getTableViewer(); MenuManager menuMgr = new MenuManager(); Menu menu = menuMgr.createContextMenu(tableViewer.getTable()); menuMgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); final IStructuredSelection tSelection = (IStructuredSelection)tableViewer.getSelection(); final IResource[] selectedResources = (IResource[])tSelection.toList().toArray(new IResource[tSelection.size()]); Action tAction = null; //paste selected names action manager.add(tAction = new Action(SVNUIMessages.CommitPanel_PasteNames_Action) { public void run() { CommitPanel.this.pasteNames(); } }); tAction.setEnabled(tSelection.size() > 0); //Create Patch File action manager.add(tAction = new Action(SVNUIMessages.CreatePatchCommand_label) { public void run() { FileDialog dlg = new FileDialog(UIMonitorUtility.getShell(), SWT.PRIMARY_MODAL | SWT.SAVE); dlg.setText(SVNUIMessages.SelectPatchFilePage_SavePatchAs); dlg.setFileName(selectedResources[0].getName() + ".patch"); //$NON-NLS-1$ dlg.setFilterExtensions(new String[] {"patch", "*.*"}); //$NON-NLS-1$ //$NON-NLS-2$ String file = dlg.open(); if (file != null) { CreatePatchOperation mainOp = new CreatePatchOperation(new IResource[] {selectedResources[0]}, file, true, true, true, true); UIMonitorUtility.doTaskNowDefault(mainOp, false); } } }); tAction.setEnabled(tSelection.size() == 1 && FileUtility.checkForResourcesPresence(selectedResources, IStateFilter.SF_VERSIONED, IResource.DEPTH_ZERO)); //Create Branch action manager.add(tAction = new Action(SVNUIMessages.BranchAction_label) { public void run() { IResource [] resources = FileUtility.getResourcesRecursive(selectedResources, IStateFilter.SF_EXCLUDE_DELETED, IResource.DEPTH_INFINITE); IActionOperation op = BranchTagAction.getBranchTagOperation(UIMonitorUtility.getShell(), BranchTagAction.BRANCH_ACTION, resources); if (op != null) { UIMonitorUtility.doTaskNowDefault(op, true); } } }); tAction.setEnabled(tSelection.size() > 0 && FileUtility.checkForResourcesPresence(selectedResources, IStateFilter.SF_EXCLUDE_DELETED, IResource.DEPTH_ZERO)); tAction.setImageDescriptor(SVNTeamUIPlugin.instance().getImageDescriptor("icons/common/actions/branch.gif")); //$NON-NLS-1$ manager.add(new Separator()); //Revert action manager.add(tAction = new Action(SVNUIMessages.CommitPanel_Revert_Action) { public void run() { IResource[] changedResources = FileUtility.getResourcesRecursive(selectedResources, RevertAction.SF_REVERTABLE_OR_NEW); CompositeOperation revertOp = RevertAction.getRevertOperation(UIMonitorUtility.getShell(), changedResources, selectedResources); if (revertOp != null) { UIMonitorUtility.doTaskNowDefault(revertOp, true); } } }); tAction.setImageDescriptor(SVNTeamUIPlugin.instance().getImageDescriptor("icons/common/actions/revert.gif")); //$NON-NLS-1$ tAction.setEnabled(tSelection.size() > 0); //Ignore resources group if (tSelection.size() > 0 && selectedResources.length == FileUtility.getResourcesRecursive(selectedResources, AddToSVNIgnoreAction.SF_NEW_AND_PARENT_VERSIONED).length) { MenuManager subMenu = new MenuManager(SVNUIMessages.CommitPanel_Ignore_Group); if (tSelection.size() > 1) { subMenu.add(tAction = new Action(SVNUIMessages.CommitPanel_IgnoreByName_Multiple_Action) { public void run() { CompositeOperation op = new CompositeOperation("Operation_AddToSVNIgnore", SVNMessages.class); //$NON-NLS-1$ op.add(new AddToSVNIgnoreOperation(selectedResources, IRemoteStorage.IGNORE_NAME, null)); op.add(new RefreshResourcesOperation(new ResourcesParentsProvider(CommitPanel.this.resources), IResource.DEPTH_INFINITE, RefreshResourcesOperation.REFRESH_ALL)); UIMonitorUtility.doTaskNowDefault(op, true); } }); tAction.setEnabled(true); subMenu.add(tAction = new Action(SVNUIMessages.CommitPanel_IgnoreByExtension_Multiple_Action) { public void run() { CompositeOperation op = new CompositeOperation("Operation_AddToSVNIgnore", SVNMessages.class); //$NON-NLS-1$ op.add(new AddToSVNIgnoreOperation(selectedResources, IRemoteStorage.IGNORE_EXTENSION, null)); op.add(new RefreshResourcesOperation(new ResourcesParentsProvider(CommitPanel.this.resources), IResource.DEPTH_INFINITE, RefreshResourcesOperation.REFRESH_ALL)); UIMonitorUtility.doTaskNowDefault(op, true); } }); tAction.setEnabled(true); } else { subMenu.add(tAction = new Action(selectedResources[0].getName()) { public void run() { CompositeOperation op = new CompositeOperation("Operation_AddToSVNIgnore", SVNMessages.class); //$NON-NLS-1$ op.add(new AddToSVNIgnoreOperation(selectedResources, IRemoteStorage.IGNORE_NAME, null)); op.add(new RefreshResourcesOperation(new ResourcesParentsProvider(CommitPanel.this.resources), IResource.DEPTH_INFINITE, RefreshResourcesOperation.REFRESH_ALL)); UIMonitorUtility.doTaskNowDefault(op, true); } }); tAction.setEnabled(true); String name = selectedResources[0].getName(); String [] parts = name.split("\\."); //$NON-NLS-1$ if ((parts.length != 0)) { subMenu.add(tAction = new Action("*." + parts[parts.length-1]) { //$NON-NLS-1$ public void run() { CompositeOperation op = new CompositeOperation("Operation_AddToSVNIgnore", SVNMessages.class); //$NON-NLS-1$ op.add(new AddToSVNIgnoreOperation(selectedResources, IRemoteStorage.IGNORE_EXTENSION, null)); op.add(new RefreshResourcesOperation(new ResourcesParentsProvider(CommitPanel.this.resources), IResource.DEPTH_INFINITE, RefreshResourcesOperation.REFRESH_ALL)); UIMonitorUtility.doTaskNowDefault(op, true); } }); tAction.setEnabled(true); } } manager.add(subMenu); } //Edit conflicts action manager.add (tAction = new Action(SVNUIMessages.EditConflictsAction_label) { public void run() { UIMonitorUtility.doTaskScheduledDefault(new ShowConflictEditorOperation(FileUtility.getResourcesRecursive(selectedResources, IStateFilter.SF_CONTENT_CONFLICTING), true)); } }); tAction.setEnabled(FileUtility.checkForResourcesPresenceRecursive(selectedResources, IStateFilter.SF_CONTENT_CONFLICTING)); //Edit tree conflicts action manager.add (tAction = new Action(SVNUIMessages.EditTreeConflictsAction_label) { public void run() { if (selectedResources.length > 0) { ILocalResource local = SVNRemoteStorage.instance().asLocalResource(selectedResources[0]); if (local.hasTreeConflict()) { EditTreeConflictsPanel editConflictsPanel = new EditTreeConflictsPanel(local); DefaultDialog dialog = new DefaultDialog(UIMonitorUtility.getShell(), editConflictsPanel); if (dialog.open() == 0 && editConflictsPanel.getOperation() != null) { UIMonitorUtility.doTaskScheduledDefault(editConflictsPanel.getOperation()); } } } } }); tAction.setEnabled(selectedResources.length == 1 && FileUtility.checkForResourcesPresence(selectedResources, IStateFilter.SF_TREE_CONFLICTING, IResource.DEPTH_ZERO)); //Mark as merged action manager.add (tAction = new Action(SVNUIMessages.CommitPanel_MarkAsMerged_Action) { public void run() { boolean ignoreExternals = SVNTeamPreferences.getBehaviourBoolean(SVNTeamUIPlugin.instance().getPreferenceStore(), SVNTeamPreferences.BEHAVIOUR_IGNORE_EXTERNALS_NAME); MarkAsMergedOperation mainOp = new MarkAsMergedOperation(selectedResources, false, null, ignoreExternals); CompositeOperation op = new CompositeOperation(mainOp.getId(), mainOp.getMessagesClass()); op.add(mainOp); op.add(new RefreshResourcesOperation(FileUtility.getParents(selectedResources, false))); UIMonitorUtility.doTaskNowDefault(op, false); } }); tAction.setEnabled(FileUtility.checkForResourcesPresenceRecursive(selectedResources, IStateFilter.SF_CONFLICTING) && selectedResources.length == 1); manager.add(new Separator()); //Lock action manager.add(tAction = new Action(SVNUIMessages.LockAction_label) { public void run() { IResource[] filteredResources = FileUtility.getResourcesRecursive(selectedResources, IStateFilter.SF_READY_TO_LOCK, IResource.DEPTH_INFINITE); IActionOperation op = LockProposeUtility.performLockAction(filteredResources, false, UIMonitorUtility.getShell()); if (op != null) { UIMonitorUtility.doTaskNowDefault(op, false); } } }); tAction.setImageDescriptor(SVNTeamUIPlugin.instance().getImageDescriptor("icons/common/actions/lock.gif")); //$NON-NLS-1$ tAction.setEnabled(FileUtility.checkForResourcesPresenceRecursive(selectedResources, IStateFilter.SF_READY_TO_LOCK)); //Unlock action manager.add(tAction = new Action(SVNUIMessages.UnlockAction_label) { public void run() { IResource[] filteredResources = FileUtility.getResourcesRecursive(selectedResources, IStateFilter.SF_LOCKED, IResource.DEPTH_INFINITE); IActionOperation op = LockProposeUtility.performUnlockAction(filteredResources, UIMonitorUtility.getShell()); if (op != null) { UIMonitorUtility.doTaskNowDefault(op, false); } } }); tAction.setImageDescriptor(SVNTeamUIPlugin.instance().getImageDescriptor("icons/common/actions/unlock.gif")); //$NON-NLS-1$ tAction.setEnabled(FileUtility.checkForResourcesPresenceRecursive(selectedResources, IStateFilter.SF_LOCKED)); manager.add(new Separator()); //Compare With group MenuManager subMenu = new MenuManager(SVNUIMessages.CommitPanel_CompareWith_Group); subMenu.add(tAction = new Action(SVNUIMessages.CompareWithWorkingCopyAction_label) { public void run() { IResource resource = selectedResources[0]; ILocalResource local = SVNRemoteStorage.instance().asLocalResource(resource); if (!IStateFilter.SF_INTERNAL_INVALID.accept(local)) { IRepositoryResource remote = local.isCopied() ? SVNUtility.getCopiedFrom(resource) : SVNRemoteStorage.instance().asRepositoryResource(resource); remote.setSelectedRevision(SVNRevision.BASE); UIMonitorUtility.doTaskScheduledDefault(new CompareResourcesOperation(local, remote, false, true)); } } }); tAction.setEnabled(tSelection.size() == 1 && FileUtility.checkForResourcesPresence(selectedResources, CompareWithWorkingCopyAction.COMPARE_FILTER, IResource.DEPTH_ZERO)); subMenu.add(tAction = new Action(SVNUIMessages.CompareWithLatestRevisionAction_label) { public void run() { IResource resource = selectedResources[0]; ILocalResource local = SVNRemoteStorage.instance().asLocalResource(resource); if (!IStateFilter.SF_INTERNAL_INVALID.accept(local)) { IRepositoryResource remote = local.isCopied() ? SVNUtility.getCopiedFrom(resource) : SVNRemoteStorage.instance().asRepositoryResource(resource); remote.setSelectedRevision(SVNRevision.HEAD); UIMonitorUtility.doTaskScheduledDefault(new CompareResourcesOperation(local, remote, false, true)); } } }); tAction.setEnabled(tSelection.size() == 1 && (CoreExtensionsManager.instance().getSVNConnectorFactory().getSVNAPIVersion() >= ISVNConnectorFactory.APICompatibility.SVNAPI_1_5_x || selectedResources[0].getType() == IResource.FILE) && FileUtility.checkForResourcesPresenceRecursive(selectedResources, CompareWithWorkingCopyAction.COMPARE_FILTER)); subMenu.add(tAction = new Action(SVNUIMessages.CompareWithRevisionAction_label) { public void run() { IResource resource = selectedResources[0]; ILocalResource local = SVNRemoteStorage.instance().asLocalResource(resource); if (!IStateFilter.SF_INTERNAL_INVALID.accept(local)) { IRepositoryResource remote = local.isCopied() ? SVNUtility.getCopiedFrom(resource) : SVNRemoteStorage.instance().asRepositoryResource(resource); ComparePanel panel = new ComparePanel(remote, local.getRevision()); DefaultDialog dlg = new DefaultDialog(UIMonitorUtility.getShell(), panel); if (dlg.open() == 0) { remote = panel.getSelectedResource(); UIMonitorUtility.doTaskScheduledDefault(new CompareResourcesOperation(local, remote, false, true)); } } } }); tAction.setEnabled(tSelection.size() == 1 && (CoreExtensionsManager.instance().getSVNConnectorFactory().getSVNAPIVersion() >= ISVNConnectorFactory.APICompatibility.SVNAPI_1_5_x || selectedResources[0].getType() == IResource.FILE) && FileUtility.checkForResourcesPresenceRecursive(selectedResources, CompareWithWorkingCopyAction.COMPARE_FILTER)); manager.add(subMenu); //Replace with group subMenu = new MenuManager(SVNUIMessages.CommitPanel_ReplaceWith_Group); subMenu.add(tAction = new Action(SVNUIMessages.ReplaceWithLatestRevisionAction_label) { public void run() { IResource []resources = FileUtility.getResourcesRecursive(selectedResources, IStateFilter.SF_ONREPOSITORY, IResource.DEPTH_ZERO); IActionOperation op = ReplaceWithLatestRevisionAction.getReplaceOperation(resources, UIMonitorUtility.getShell()); if (op != null) { UIMonitorUtility.doTaskNowDefault(op, true); } } }); tAction.setEnabled(FileUtility.checkForResourcesPresenceRecursive(selectedResources, IStateFilter.SF_ONREPOSITORY)); subMenu.add(tAction = new Action(SVNUIMessages.ReplaceWithRevisionAction_label) { public void run() { IActionOperation op = ReplaceWithRevisionAction.getReplaceOperation(selectedResources, UIMonitorUtility.getShell()); if (op != null) { UIMonitorUtility.doTaskNowDefault(op, true); } } }); tAction.setEnabled(tSelection.size() == 1 && FileUtility.checkForResourcesPresence(selectedResources, IStateFilter.SF_ONREPOSITORY, IResource.DEPTH_ZERO)); manager.add(subMenu); manager.add(new Separator()); //Export action manager.add(tAction = new Action(SVNUIMessages.ExportCommand_label) { public void run() { DirectoryDialog fileDialog = new DirectoryDialog(UIMonitorUtility.getShell()); fileDialog.setText(SVNUIMessages.ExportAction_Select_Title); fileDialog.setMessage(SVNUIMessages.ExportAction_Select_Description); String path = fileDialog.open(); if (path != null) { boolean ignoreExternals = SVNTeamPreferences.getBehaviourBoolean(SVNTeamUIPlugin.instance().getPreferenceStore(), SVNTeamPreferences.BEHAVIOUR_IGNORE_EXTERNALS_NAME); UIMonitorUtility.doTaskScheduledDefault(new ExportOperation(FileUtility.getResourcesRecursive(selectedResources, IStateFilter.SF_EXCLUDE_DELETED, IResource.DEPTH_ZERO) , path, SVNRevision.WORKING, ignoreExternals)); } } }); tAction.setImageDescriptor(SVNTeamUIPlugin.instance().getImageDescriptor("icons/common/export.gif")); //$NON-NLS-1$ tAction.setEnabled(tSelection.size() > 0 && FileUtility.checkForResourcesPresence(selectedResources, IStateFilter.SF_EXCLUDE_DELETED, IResource.DEPTH_ZERO)); //Clean-up action manager.add(tAction = new Action(SVNUIMessages.CleanupCommand_label) { public void run() { IResource []resources = FileUtility.getResourcesRecursive(selectedResources, IStateFilter.SF_VERSIONED_FOLDERS, IResource.DEPTH_ZERO); CleanupOperation mainOp = new CleanupOperation(resources); CompositeOperation op = new CompositeOperation(mainOp.getId(), mainOp.getMessagesClass()); op.add(mainOp); op.add(new RefreshResourcesOperation(resources)); UIMonitorUtility.doTaskNowDefault(op, false); } }); tAction.setEnabled(tSelection.size() > 0 && FileUtility.checkForResourcesPresence(selectedResources, IStateFilter.SF_VERSIONED_FOLDERS, IResource.DEPTH_ZERO)); manager.add(new Separator()); //Delete action manager.add(tAction = new Action(SVNUIMessages.CommitPanel_Delete_Action) { public void run() { DiscardConfirmationDialog dialog = new DiscardConfirmationDialog(UIMonitorUtility.getShell(), selectedResources.length == 1, DiscardConfirmationDialog.MSG_RESOURCE); if (dialog.open() == 0) { DeleteResourceOperation deleteOperation = new DeleteResourceOperation(selectedResources); CompositeOperation op = new CompositeOperation(deleteOperation.getId(), deleteOperation.getMessagesClass()); SaveProjectMetaOperation saveOp = new SaveProjectMetaOperation(selectedResources); RestoreProjectMetaOperation restoreOp = new RestoreProjectMetaOperation(saveOp); op.add(saveOp); op.add(deleteOperation); op.add(restoreOp); op.add(new RefreshResourcesOperation(new ResourcesParentsProvider(selectedResources), IResource.DEPTH_INFINITE, RefreshResourcesOperation.REFRESH_CHANGES)); UIMonitorUtility.doTaskNowDefault(op, true); } } }); tAction.setImageDescriptor(SVNTeamUIPlugin.instance().getImageDescriptor("icons/common/delete.gif")); //$NON-NLS-1$ tAction.setEnabled(tSelection.size() > 0 && !FileUtility.checkForResourcesPresence(selectedResources, IStateFilter.SF_DELETED, IResource.DEPTH_ZERO)); } }); menuMgr.setRemoveAllWhenShown(true); tableViewer.getTable().setMenu(menu); } protected void updateResources(ResourceStatesChangedEvent event) { HashSet allResources = new HashSet(Arrays.asList(this.resources)); HashSet toDeleteSet = new HashSet(); toDeleteSet.addAll(Arrays.asList(FileUtility.getResourcesRecursive(event.resources, IStateFilter.SF_NOTMODIFIED, IResource.DEPTH_ZERO))); toDeleteSet.addAll(Arrays.asList(FileUtility.getResourcesRecursive(event.resources, IStateFilter.SF_NOTEXISTS, IResource.DEPTH_ZERO))); toDeleteSet.addAll(Arrays.asList(FileUtility.getResourcesRecursive(event.resources, IStateFilter.SF_IGNORED, IResource.DEPTH_ZERO))); allResources.removeAll(toDeleteSet); final IResource[] newResources = allResources.toArray(new IResource[allResources.size()]); if (!this.paneParticipantHelper.isParticipantPane()) { UIMonitorUtility.getDisplay().syncExec(new Runnable() { public void run() { //FIXME isDisposed() test is necessary as dispose() method is not called from FastTrack Commit Dialog if (!CommitPanel.this.selectionComposite.isDisposed()) { CommitPanel.this.selectionComposite.setResources(newResources); CommitPanel.this.selectionComposite.fireSelectionChanged(); } } }); } this.resources = newResources; this.resourcesChanged = true; } public boolean getResourcesChanged() { return this.resourcesChanged; } public IResource []getSelectedResources() { if (this.paneParticipantHelper.isParticipantPane()) { return this.paneParticipantHelper.getSelectedResources(); } else { return this.selectionComposite.getSelectedResources(); } } public IResource []getNotSelectedResources() { if (this.paneParticipantHelper.isParticipantPane()) { return this.paneParticipantHelper.getNotSelectedResources(); } else { return this.selectionComposite.getNotSelectedResources(); } } public void addResourcesSelectionChangedListener(IResourceSelectionChangeListener listener) { this.changeListenerList.add(listener); } public void removeResourcesSelectionChangedListener(IResourceSelectionChangeListener listener) { this.changeListenerList.remove(listener); } public void fireResourcesSelectionChanged(ResourceSelectionChangedEvent event) { this.validateContent(); IResourceSelectionChangeListener []listeners = this.changeListenerList.toArray(new IResourceSelectionChangeListener[this.changeListenerList.size()]); for (int i = 0; i < listeners.length; i++) { listeners[i].resourcesSelectionChanged(event); } } public boolean getKeepLocks() { return this.keepLocks; } protected Point getPrefferedSizeImpl() { return new Point(600, SWT.DEFAULT); } protected void savePreferences() { int []weights = this.sForm.getWeights(); IPreferenceStore store = SVNTeamUIPlugin.instance().getPreferenceStore(); SVNTeamPreferences.setDialogInt(store, SVNTeamPreferences.COMMIT_DIALOG_WEIGHT_NAME, weights[0] / 10); store.setValue(SVNTeamPreferences.COMMIT_DIALOG_KEEP_LOCKS, this.keepLocks); } public void dispose() { super.dispose(); SVNRemoteStorage.instance().removeResourceStatesListener(ResourceStatesChangedEvent.class, this.resourceStatesListener); if (this.paneParticipantHelper.isParticipantPane()) { this.paneParticipantHelper.dispose(); } } public static class CollectPropertiesOperation extends AbstractActionOperation { protected IResource []resources; protected MinLogSizePropFindVisitor minLogVisitor; protected LogTemplatesPropFindVisitor logTemplateVisitor; protected BugtraqPropFindVisitor bugtraqVisitor; protected MaxLogWidthPropFindVisitor maxWidthVisitor; protected MinLockSizePropFindVisitor minLockVisitor; protected CompositePropFindVisitor compositeVisitor; public CollectPropertiesOperation(IResource []resources) { super("Operation_CollectProperties", SVNUIMessages.class); //$NON-NLS-1$ this.resources = resources; this.logTemplateVisitor = new LogTemplatesPropFindVisitor(); this.bugtraqVisitor = new BugtraqPropFindVisitor(); this.minLogVisitor = new MinLogSizePropFindVisitor(); this.maxWidthVisitor = new MaxLogWidthPropFindVisitor(); this.minLockVisitor = new MinLockSizePropFindVisitor(); if (SVNTeamPreferences.getCommentTemplatesBoolean(SVNTeamUIPlugin.instance().getPreferenceStore(), SVNTeamPreferences.COMMENT_LOG_TEMPLATES_ENABLED_NAME)) { this.compositeVisitor = new CompositePropFindVisitor(new IPropFindVisitor [] {this.logTemplateVisitor, this.bugtraqVisitor, this.minLogVisitor, this.maxWidthVisitor, this.minLockVisitor}); } else { this.compositeVisitor = new CompositePropFindVisitor(new IPropFindVisitor [] {this.bugtraqVisitor, this.minLogVisitor, this.maxWidthVisitor, this.minLockVisitor}); } } protected void runImpl(IProgressMonitor monitor) throws Exception { ArrayList parentProperties = new ArrayList(); int length = this.resources.length < CommitPanel.MAXIMUM_CHECKS_SIZE ? this.resources.length : CommitPanel.MAXIMUM_CHECKS_SIZE; for (int i = 0; i < length && !monitor.isCanceled(); i++) { ProgressMonitorUtility.setTaskInfo(monitor, this, this.resources[i].getFullPath().toString()); ILocalResource local = SVNRemoteStorage.instance().asLocalResourceAccessible(this.resources[i]); IResource resourceToProcess = this.resources[i]; while (IStateFilter.SF_UNVERSIONED.accept(local) || IStateFilter.SF_TREE_CONFLICTING.accept(local) && !IStateFilter.SF_TREE_CONFLICTING_REPOSITORY_EXIST.accept(local)) { resourceToProcess = resourceToProcess.getParent(); local = SVNRemoteStorage.instance().asLocalResourceAccessible(resourceToProcess); } if (!this.processProperty(resourceToProcess, parentProperties, monitor)) { break; } ProgressMonitorUtility.progress(monitor, i, length); } } protected boolean processProperty(IResource resource, ArrayList parentProperties, IProgressMonitor monitor) { if (parentProperties.contains(resource) || monitor.isCanceled()) { return true; } GetPropertiesOperation op = new GetPropertiesOperation(resource); ProgressMonitorUtility.doTaskExternalDefault(op, monitor); if (op.getExecutionState() == IStatus.OK) { SVNProperty []properties = op.getProperties(); if (properties != null) { for (int i = 0; i < properties.length; i++) { if (!this.compositeVisitor.visit(properties[i])) { return false; } } } } parentProperties.add(resource); IResource parent = resource.getParent(); if (parent != null && !(parent instanceof IWorkspaceRoot) && !monitor.isCanceled() && !IStateFilter.SF_UNVERSIONED.accept(SVNRemoteStorage.instance().asLocalResource(parent))) { return this.processProperty(parent, parentProperties, monitor); } return true; } public HashSet getLogTemplates() { return this.logTemplateVisitor.getLogTemplates(); } public BugtraqModel getBugtraqModel() { return this.bugtraqVisitor.getBugtraqModel(); } public int getMinLogSize() { return this.minLogVisitor.getMinLogSize(); } public int getMinLockSize() { return this.minLockVisitor.getMinLockSize(); } public int getMaxLogWidth() { return this.maxWidthVisitor.getMaxLogWidth(); } } /** * Check if resources have errors or warnings * * @param resources * @return */ public static String validateResources(IResource[] resources) { String message = null; int highestProblemSeverity = CommitPanel.getHighestProblemSeverity(resources); switch (highestProblemSeverity) { case IMarker.SEVERITY_WARNING: message = SVNUIMessages.CommitPanel_Resource_Validation_Warning_Message; break; case IMarker.SEVERITY_ERROR: message = SVNUIMessages.CommitPanel_Resource_Validation_Error_Message; break; } return message; } public static int getHighestProblemSeverity(IResource[] resources) { int res = -1; for (IResource resource : resources) { try { int problemSeverity = resource.findMaxProblemSeverity(IMarker.PROBLEM, true, IResource.DEPTH_ZERO); res = problemSeverity > res ? problemSeverity : res; } catch (CoreException e) { //ignore } } return res; } }