blob: 1af0550a9d0ee204fd1c45b4facb026df477f385 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.ActionExecuteHelper;
import com.intellij.vcsUtil.ActionStateConsumer;
import com.intellij.vcsUtil.ActionUpdateHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.dialogs.SelectCreateExternalTargetDialog;
import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.internal.wc.SVNExternal;
import org.tmatesoft.svn.core.wc.*;
import java.io.File;
/**
* Created with IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 7/6/12
* Time: 7:21 PM
*/
public class CreateExternalAction extends DumbAwareAction {
public CreateExternalAction() {
super(SvnBundle.message("svn.create.external.below.action"), SvnBundle.message("svn.create.external.below.description"), null);
}
@Override
public void actionPerformed(AnActionEvent e) {
final ActionExecuteHelper helper = new ActionExecuteHelper();
checkState(e, helper);
if (! helper.isOk()) return;
final DataContext dc = e.getDataContext();
final Project project = PlatformDataKeys.PROJECT.getData(dc);
final VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(dc);
//1 select target
final SelectCreateExternalTargetDialog dialog = new SelectCreateExternalTargetDialog(project, vf);
dialog.show();
if (DialogWrapper.OK_EXIT_CODE != dialog.getExitCode()) return;
final String url = dialog.getSelectedURL();
final boolean checkout = dialog.isCheckout();
final String target = dialog.getLocalTarget().trim();
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Creating External", true, null) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
doInBackground(project, vf, url, checkout, target);
}
});
}
private void doInBackground(Project project, VirtualFile vf, String url, boolean checkout, String target) {
final SvnVcs vcs = SvnVcs.getInstance(project);
try {
final File ioFile = new File(vf.getPath());
if (addToExternalProperty(vcs, ioFile, target, url)) return;
final VcsDirtyScopeManager dirtyScopeManager = VcsDirtyScopeManager.getInstance(project);
final FilePathImpl filePath = new FilePathImpl(ioFile, true);
dirtyScopeManager.fileDirty(filePath);
if (checkout) {
// +-
final SVNUpdateClient client = vcs.createUpdateClient();
client.setEventHandler(new ISVNEventHandler() {
@Override
public void handleEvent(SVNEvent event, double progress) throws SVNException {
}
@Override
public void checkCancelled() throws SVNCancelException {
final ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator();
if (pi != null && pi.isCanceled()) throw new SVNCancelException();
}
});
client.doUpdate(ioFile, SVNRevision.HEAD, SVNDepth.UNKNOWN, false, false);
vf.refresh(true, true, new Runnable() {
@Override
public void run() {
dirtyScopeManager.dirDirtyRecursively(filePath);
}
});
}
}
catch (SVNException e1) {
AbstractVcsHelper.getInstance(project).showError(new VcsException(e1), "Create External");
}
}
public static boolean addToExternalProperty(SvnVcs vcs, File ioFile, String target, String url) throws SVNException {
final SVNWCClient wcClient = vcs.createWCClient();
final SVNPropertyData propertyData =
wcClient.doGetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
String newValue;
if (propertyData != null && propertyData.getValue() != null && ! StringUtil.isEmptyOrSpaces(propertyData.getValue().getString())) {
final SVNExternal[] externals = SVNExternal.parseExternals("Create External", propertyData.getValue().getString());
for (SVNExternal external : externals) {
if (Comparing.equal(external.getPath(), target)) {
AbstractVcsHelper
.getInstance(vcs.getProject()).showError(new VcsException("Selected destination conflicts with existing: " + external.toString()), "Create External");
return true;
}
}
final String string = createExternalDefinitionString(url, target);
newValue = propertyData.getValue().getString() + "\n" + string;
} else {
newValue = createExternalDefinitionString(url, target);
}
wcClient.doSetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), false, SVNDepth.EMPTY, null, null);
return false;
}
public static String createExternalDefinitionString(String url, String target) {
return url + " " + target;
}
@Override
public void update(AnActionEvent e) {
final ActionUpdateHelper helper = new ActionUpdateHelper();
checkState(e, helper);
helper.apply(e);
}
private void checkState(AnActionEvent e, final ActionStateConsumer sc) {
final DataContext dc = e.getDataContext();
final Project project = PlatformDataKeys.PROJECT.getData(dc);
final ProjectLevelVcsManager manager = ProjectLevelVcsManager.getInstance(project);
if (project == null || ! manager.checkVcsIsActive(SvnVcs.getKey().getName())) {
sc.hide();
return;
}
final VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(dc);
final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dc);
if (vf == null || files == null || files.length != 1 || ! vf.isDirectory()) {
sc.disable();
return;
}
final AbstractVcs vcsFor = manager.getVcsFor(vf);
if (vcsFor == null || ! SvnVcs.getKey().equals(vcsFor.getKeyInstanceMethod())) {
sc.disable();
return;
}
final FileStatus status = FileStatusManager.getInstance(project).getStatus(vf);
if (status == null || FileStatus.DELETED.equals(status) || FileStatus.IGNORED.equals(status) ||
FileStatus.MERGED_WITH_PROPERTY_CONFLICTS.equals(status) || FileStatus.OBSOLETE.equals(status) || FileStatus.UNKNOWN.equals(status)) {
sc.disable();
return;
}
sc.enable();
}
}