mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
@@ -140,7 +140,7 @@
|
||||
<option name="BREAKPOINT_ATTRIBUTES">
|
||||
<value>
|
||||
<option name="FOREGROUND" />
|
||||
<option name="BACKGROUND" value="88382d" />
|
||||
<option name="BACKGROUND" value="3a2323" />
|
||||
<option name="FONT_TYPE" value="0" />
|
||||
<option name="EFFECT_COLOR" />
|
||||
<option name="EFFECT_TYPE" value="0" />
|
||||
@@ -630,7 +630,7 @@
|
||||
<option name="EXECUTIONPOINT_ATTRIBUTES">
|
||||
<value>
|
||||
<option name="FOREGROUND" />
|
||||
<option name="BACKGROUND" value="313f7f" />
|
||||
<option name="BACKGROUND" value="2d6099" />
|
||||
<option name="FONT_TYPE" value="0" />
|
||||
<option name="EFFECT_COLOR" />
|
||||
<option name="EFFECT_TYPE" value="0" />
|
||||
|
||||
@@ -770,11 +770,16 @@ public class BuildManager implements ApplicationComponent{
|
||||
}
|
||||
cmdLine.addParameter("-D"+ GlobalOptions.COMPILE_PARALLEL_OPTION +"=" + Boolean.toString(config.PARALLEL_COMPILATION));
|
||||
|
||||
boolean isProfilingMode = false;
|
||||
final String additionalOptions = config.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS;
|
||||
if (!StringUtil.isEmpty(additionalOptions)) {
|
||||
final StringTokenizer tokenizer = new StringTokenizer(additionalOptions, " ", false);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
cmdLine.addParameter(tokenizer.nextToken());
|
||||
final String option = tokenizer.nextToken();
|
||||
if ("-Dprofiling.mode=true".equals(option)) {
|
||||
isProfilingMode = true;
|
||||
}
|
||||
cmdLine.addParameter(option);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,9 +808,17 @@ public class BuildManager implements ApplicationComponent{
|
||||
}
|
||||
}
|
||||
|
||||
final File workDirectory = getBuildSystemDirectory();
|
||||
workDirectory.mkdirs();
|
||||
ensureLogConfigExists(workDirectory);
|
||||
|
||||
final List<String> cp = ClasspathBootstrap.getBuildProcessApplicationClasspath();
|
||||
cp.add(compilerPath);
|
||||
cp.addAll(myClasspathManager.getCompileServerPluginsClasspath(project));
|
||||
if (isProfilingMode) {
|
||||
cp.add(new File(workDirectory, "yjp-controller-api-redist.jar").getPath());
|
||||
cmdLine.addParameter("-agentlib:yjpagent=disablej2ee,disablealloc,sessionname=ExternalBuild");
|
||||
}
|
||||
|
||||
cmdLine.addParameter("-classpath");
|
||||
cmdLine.addParameter(classpathToString(cp));
|
||||
@@ -815,10 +828,6 @@ public class BuildManager implements ApplicationComponent{
|
||||
cmdLine.addParameter(Integer.toString(port));
|
||||
cmdLine.addParameter(sessionId.toString());
|
||||
|
||||
final File workDirectory = getBuildSystemDirectory();
|
||||
workDirectory.mkdirs();
|
||||
ensureLogConfigExists(workDirectory);
|
||||
|
||||
cmdLine.addParameter(FileUtil.toSystemIndependentName(workDirectory.getPath()));
|
||||
|
||||
cmdLine.setWorkDirectory(workDirectory);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -208,7 +209,7 @@ public class ExceptionWorker {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class MyHyperlinkInfo implements HyperlinkInfo {
|
||||
private static class MyHyperlinkInfo implements FileHyperlinkInfo {
|
||||
private final VirtualFile myVirtualFile;
|
||||
private final int myLineNumber;
|
||||
private final Project myProject;
|
||||
@@ -246,5 +247,11 @@ public class ExceptionWorker {
|
||||
|
||||
new OpenFileHyperlinkInfo(myProject, currentVirtualFile, myLineNumber - 1).navigate(project);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public OpenFileDescriptor getDescriptor() {
|
||||
return new OpenFileDescriptor(myProject, myVirtualFile, myLineNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,11 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
final Ref<Boolean> hasErrors = new Ref<Boolean>(false);
|
||||
final Ref<Boolean> doneSomething = new Ref<Boolean>(false);
|
||||
try {
|
||||
ProfilingHelper profilingHelper = null;
|
||||
if (Utils.IS_PROFILING_MODE) {
|
||||
profilingHelper = new ProfilingHelper();
|
||||
}
|
||||
|
||||
runBuild(new MessageHandler() {
|
||||
public void processMessage(BuildMessage buildMessage) {
|
||||
final CmdlineRemoteProto.Message.BuilderMessage response;
|
||||
@@ -132,6 +137,10 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (profilingHelper != null) {
|
||||
profilingHelper.stopProfiling();
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.info(e);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.jetbrains.jps.cmdline;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 12/6/12
|
||||
*/
|
||||
class ProfilingHelper {
|
||||
|
||||
private final Class<?> myControllerClass;
|
||||
private final Object myController;
|
||||
|
||||
ProfilingHelper() throws Exception {
|
||||
myControllerClass = Class.forName("com.yourkit.api.Controller");
|
||||
myController = myControllerClass.newInstance();
|
||||
}
|
||||
|
||||
public void startProfiling() {
|
||||
try {
|
||||
final Method startMethod = myControllerClass.getDeclaredMethod("startCPUProfiling", long.class, String.class);
|
||||
if (startMethod != null) {
|
||||
startMethod.invoke(myController, 4L/*ProfilingModes.CPU_SAMPLING*/, null);
|
||||
}
|
||||
else {
|
||||
System.err.println("Cannot find method 'startCPUProfiling' in class " + myControllerClass.getName());
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopProfiling() {
|
||||
try {
|
||||
final Method captureMethod = myControllerClass.getDeclaredMethod("captureSnapshot", long.class);
|
||||
if (captureMethod != null) {
|
||||
final String path = (String)captureMethod.invoke(myController, 0L/*ProfilingModes.SNAPSHOT_WITHOUT_HEAP*/);
|
||||
System.err.println("CPU Snapshot captured: " + path);
|
||||
final Method stopMethod = myControllerClass.getDeclaredMethod("stopCPUProfiling");
|
||||
if (stopMethod != null) {
|
||||
stopMethod.invoke(myController);
|
||||
}
|
||||
else {
|
||||
System.err.println("Cannot find method 'stopCPUProfiling' in class " + myControllerClass.getName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.err.println("Cannot find method 'captureSnapshot' in class " + myControllerClass.getName());
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ public class Utils {
|
||||
public static final Key<Boolean> ERRORS_DETECTED_KEY = Key.create("_errors_detected_");
|
||||
private static volatile File ourSystemRoot = new File(System.getProperty("user.home"), ".idea-build");
|
||||
public static final boolean IS_TEST_MODE = Boolean.parseBoolean(System.getProperty("test.mode", "false"));
|
||||
public static final boolean IS_PROFILING_MODE = Boolean.parseBoolean(System.getProperty("profiling.mode", "false"));
|
||||
|
||||
private Utils() {
|
||||
}
|
||||
|
||||
@@ -476,14 +476,20 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
return cached;
|
||||
}
|
||||
|
||||
public static List<String> getCompilationOptions(CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) {
|
||||
private static List<String> getCompilationOptions(CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) {
|
||||
List<String> cached = JAVAC_OPTIONS.get(context);
|
||||
if (cached == null) {
|
||||
loadCommonJavacOptions(context);
|
||||
cached = JAVAC_OPTIONS.get(context);
|
||||
assert cached != null : context;
|
||||
}
|
||||
|
||||
final List<String> options = new ArrayList<String>(cached);
|
||||
List<String> options = new ArrayList<String>(cached);
|
||||
addCompilationOptions(options, context, chunk, profile);
|
||||
return options;
|
||||
}
|
||||
|
||||
public static void addCompilationOptions(List<String> options, CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) {
|
||||
if (!isEncodingSet(options)) {
|
||||
final CompilerEncodingConfiguration config = context.getProjectDescriptor().getEncodingConfiguration();
|
||||
final String encoding = config.getPreferredModuleChunkEncoding(chunk);
|
||||
@@ -574,8 +580,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
else {
|
||||
options.add("-proc:none");
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private static String getLanguageLevel(JpsModule module) {
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.CommitExecutor;
|
||||
import com.intellij.openapi.vcs.changes.CommitResultHandler;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsHistoryProvider;
|
||||
@@ -185,10 +185,22 @@ public class MockVcsHelper extends AbstractVcsHelper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitChanges(@NotNull List<Change> changes, @NotNull LocalChangeList initialChangeList,
|
||||
@NotNull String commitMessage, @Nullable CommitExecutor executor) {
|
||||
public boolean commitChanges(@NotNull Collection<Change> changes, @NotNull LocalChangeList initialChangeList,
|
||||
@NotNull String commitMessage, @Nullable CommitResultHandler customResultHandler) {
|
||||
if (myCommitHandler != null) {
|
||||
return myCommitHandler.commit(commitMessage);
|
||||
boolean success = myCommitHandler.commit(commitMessage);
|
||||
if (customResultHandler != null) {
|
||||
if (success) {
|
||||
customResultHandler.onSuccess(commitMessage);
|
||||
}
|
||||
else {
|
||||
customResultHandler.onFailure();
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
if (customResultHandler != null) {
|
||||
customResultHandler.onFailure();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+5
-2
@@ -25,12 +25,14 @@ import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.NavigatablePsiElement;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.CollectionListModel;
|
||||
import com.intellij.ui.JBListWithHintProvider;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.popup.AbstractPopup;
|
||||
import com.intellij.usages.UsageView;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -113,12 +115,13 @@ public class PsiElementListNavigator {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
final Ref<UsageView> usageView = new Ref<UsageView>();
|
||||
if (findUsagesTitle != null) {
|
||||
popupChooserBuilder = popupChooserBuilder.setCouldPin(new Processor<JBPopup>() {
|
||||
@Override
|
||||
public boolean process(JBPopup popup) {
|
||||
final List<NavigatablePsiElement> items = model.getItems();
|
||||
FindUtil.showInUsageView(null, items.toArray(new PsiElement[items.size()]), findUsagesTitle, targets[0].getProject());
|
||||
usageView.set(FindUtil.showInUsageView(null, items.toArray(new PsiElement[items.size()]), findUsagesTitle, targets[0].getProject()));
|
||||
popup.cancel();
|
||||
return false;
|
||||
}
|
||||
@@ -127,7 +130,7 @@ public class PsiElementListNavigator {
|
||||
|
||||
final JBPopup popup = popupChooserBuilder.createPopup();
|
||||
if (listUpdaterTask != null) {
|
||||
listUpdaterTask.init((AbstractPopup)popup, list);
|
||||
listUpdaterTask.init((AbstractPopup)popup, list, usageView);
|
||||
|
||||
ProgressManager.getInstance().run(listUpdaterTask);
|
||||
}
|
||||
|
||||
+5
-7
@@ -45,6 +45,7 @@ import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ui.SideBorder;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.usages.UsageView;
|
||||
import com.intellij.util.PairFunction;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -337,7 +338,7 @@ public class ImplementationViewComponent extends JPanel {
|
||||
if (file == null) continue;
|
||||
final PsiElement parent = element.getParent();
|
||||
files.add(new FileDescriptor(file, names.size() > 1 || parent == file ? element : parent));
|
||||
candidates.add(element.getNavigationElement());
|
||||
candidates.add(element);
|
||||
}
|
||||
|
||||
fun.fun(PsiUtilCore.toPsiElementArray(candidates), files);
|
||||
@@ -367,7 +368,7 @@ public class ImplementationViewComponent extends JPanel {
|
||||
private void updateEditorText() {
|
||||
disposeNonTextEditor();
|
||||
|
||||
final PsiElement elt = myElements[myIndex];
|
||||
final PsiElement elt = myElements[myIndex].getNavigationElement();
|
||||
Project project = elt.getProject();
|
||||
PsiFile psiFile = getContainingFile(elt);
|
||||
final VirtualFile vFile = psiFile.getVirtualFile();
|
||||
@@ -498,11 +499,8 @@ public class ImplementationViewComponent extends JPanel {
|
||||
return myElements;
|
||||
}
|
||||
|
||||
public void showInUsageView() {
|
||||
FindUtil.showInUsageView(null, collectNonBinaryElements(), myTitle, myEditor.getProject());
|
||||
if (myHint.isVisible()) {
|
||||
myHint.cancel();
|
||||
}
|
||||
public UsageView showInUsageView() {
|
||||
return FindUtil.showInUsageView(null, collectNonBinaryElements(), myTitle, myEditor.getProject());
|
||||
}
|
||||
|
||||
private class BackAction extends AnAction implements HintManagerImpl.ActionToIgnore {
|
||||
|
||||
+9
-5
@@ -36,6 +36,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.PomTargetPsiElement;
|
||||
import com.intellij.psi.*;
|
||||
@@ -46,6 +47,7 @@ import com.intellij.ui.popup.AbstractPopup;
|
||||
import com.intellij.ui.popup.NotLookupOrSearchCondition;
|
||||
import com.intellij.ui.popup.PopupPositionManager;
|
||||
import com.intellij.ui.popup.PopupUpdateProcessor;
|
||||
import com.intellij.usages.UsageView;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -204,6 +206,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
|
||||
}
|
||||
}
|
||||
|
||||
final Ref<UsageView> usageView = new Ref<UsageView>();
|
||||
final String title = CodeInsightBundle.message("implementation.view.title", text);
|
||||
if (myPopupRef != null) {
|
||||
final JBPopup popup = myPopupRef.get();
|
||||
@@ -211,7 +214,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
|
||||
final ImplementationViewComponent component = (ImplementationViewComponent) ((AbstractPopup)popup).getComponent();
|
||||
((AbstractPopup)popup).setCaption(title);
|
||||
component.update(impls, index);
|
||||
updateInBackground(editor, element, component, title, (AbstractPopup)popup);
|
||||
updateInBackground(editor, element, component, title, (AbstractPopup)popup, usageView);
|
||||
if (invokedByShortcut) {
|
||||
((AbstractPopup)popup).focusPreferredComponent();
|
||||
}
|
||||
@@ -242,13 +245,14 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
|
||||
.setCouldPin(new Processor<JBPopup>() {
|
||||
@Override
|
||||
public boolean process(JBPopup popup) {
|
||||
component.showInUsageView();
|
||||
usageView.set(component.showInUsageView());
|
||||
popup.cancel();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.createPopup();
|
||||
|
||||
updateInBackground(editor, element, component, title, (AbstractPopup)popup);
|
||||
updateInBackground(editor, element, component, title, (AbstractPopup)popup, usageView);
|
||||
|
||||
PopupPositionManager.positionPopupInBestPosition(popup, editor, DataManager.getInstance().getDataContext());
|
||||
component.setHint(popup, title);
|
||||
@@ -261,7 +265,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
|
||||
@Nullable PsiElement element,
|
||||
ImplementationViewComponent component,
|
||||
String title,
|
||||
AbstractPopup popup) {
|
||||
AbstractPopup popup, Ref<UsageView> usageView) {
|
||||
if (myTaskRef != null) {
|
||||
final BackgroundUpdaterTask updaterTask = myTaskRef.get();
|
||||
if (updaterTask != null) {
|
||||
@@ -271,7 +275,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
|
||||
|
||||
if (element == null) return; //already found
|
||||
final ImplementationsUpdaterTask task = new ImplementationsUpdaterTask(element, editor, title);
|
||||
task.init(popup, component);
|
||||
task.init(popup, component, usageView);
|
||||
|
||||
myTaskRef = new WeakReference<BackgroundUpdaterTask>(task);
|
||||
ProgressManager.getInstance().run(task);
|
||||
|
||||
+20
-2
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.navigation;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.progress.PerformInBackgroundOption;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
@@ -22,8 +23,13 @@ import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupAdapter;
|
||||
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.popup.AbstractPopup;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usages.UsageInfo2UsageAdapter;
|
||||
import com.intellij.usages.UsageView;
|
||||
import com.intellij.usages.impl.UsageViewImpl;
|
||||
import com.intellij.util.Alarm;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -39,6 +45,7 @@ import java.util.List;
|
||||
public abstract class BackgroundUpdaterTask<T> extends Task.Backgroundable {
|
||||
protected AbstractPopup myPopup;
|
||||
protected T myComponent;
|
||||
private Ref<UsageView> myUsageView;
|
||||
private final List<PsiElement> myData = new ArrayList<PsiElement>();
|
||||
|
||||
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
@@ -61,9 +68,10 @@ public abstract class BackgroundUpdaterTask<T> extends Task.Backgroundable {
|
||||
super(project, title, canBeCancelled, backgroundOption);
|
||||
}
|
||||
|
||||
public void init(@NotNull AbstractPopup popup, T component) {
|
||||
public void init(@NotNull AbstractPopup popup, T component, Ref<UsageView> usageView) {
|
||||
myPopup = popup;
|
||||
myComponent = component;
|
||||
myUsageView = usageView;
|
||||
|
||||
myPopup.addPopupListener(new JBPopupAdapter() {
|
||||
@Override
|
||||
@@ -83,7 +91,17 @@ public abstract class BackgroundUpdaterTask<T> extends Task.Backgroundable {
|
||||
return canceled;
|
||||
}
|
||||
|
||||
public boolean updateComponent(PsiElement element, @Nullable final Comparator comparator) {
|
||||
public boolean updateComponent(final PsiElement element, @Nullable final Comparator comparator) {
|
||||
final UsageView view = myUsageView.get();
|
||||
if (view != null && !((UsageViewImpl)view).isDisposed()) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
view.appendUsage(new UsageInfo2UsageAdapter(new UsageInfo(element)));
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
if (myCanceled) return false;
|
||||
if (myPopup.isDisposed()) return false;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -41,6 +42,7 @@ import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.ui.CollectionListModel;
|
||||
import com.intellij.ui.JBListWithHintProvider;
|
||||
import com.intellij.ui.popup.AbstractPopup;
|
||||
import com.intellij.usages.UsageView;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Processor;
|
||||
@@ -169,6 +171,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
|
||||
}
|
||||
});
|
||||
|
||||
final Ref<UsageView> usageView = new Ref<UsageView>();
|
||||
final JBPopup popup = builder.
|
||||
setTitle(title).
|
||||
setItemChoosenCallback(runnable).
|
||||
@@ -183,8 +186,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
|
||||
setCouldPin(new Processor<JBPopup>() {
|
||||
@Override
|
||||
public boolean process(JBPopup popup) {
|
||||
FindUtil.showInUsageView(gotoData.source, gotoData.targets,
|
||||
getFindUsagesTitle(gotoData.source, name, gotoData.targets.length), project);
|
||||
usageView.set(FindUtil.showInUsageView(gotoData.source, gotoData.targets, getFindUsagesTitle(gotoData.source, name, gotoData.targets.length), project));
|
||||
popup.cancel();
|
||||
return false;
|
||||
}
|
||||
@@ -192,7 +194,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
|
||||
setAdText(getAdText(gotoData.source, targets.length)).
|
||||
createPopup();
|
||||
if (gotoData.listUpdaterTask != null) {
|
||||
gotoData.listUpdaterTask.init((AbstractPopup)popup, list);
|
||||
gotoData.listUpdaterTask.init((AbstractPopup)popup, list, usageView);
|
||||
ProgressManager.getInstance().run(gotoData.listUpdaterTask);
|
||||
}
|
||||
popup.showInBestPositionFor(editor);
|
||||
|
||||
@@ -46,6 +46,9 @@ import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.TextEditor;
|
||||
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
@@ -60,6 +63,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usages.*;
|
||||
import com.intellij.usages.impl.UsageViewImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -910,19 +914,36 @@ public class FindUtil {
|
||||
boolean shouldReplace(TextRange range, String replace);
|
||||
}
|
||||
|
||||
public static void showInUsageView(PsiElement sourceElement, PsiElement[] targets, String title, Project project) {
|
||||
public static UsageView showInUsageView(PsiElement sourceElement, final PsiElement[] targets, String title, Project project) {
|
||||
final UsageViewPresentation presentation = new UsageViewPresentation();
|
||||
presentation.setCodeUsagesString(title);
|
||||
presentation.setTabName(title);
|
||||
presentation.setTabText(title);
|
||||
final UsageInfo[] usages = new UsageInfo[targets.length];
|
||||
for (int i = 0; i < targets.length; i++) {
|
||||
usages[i] = new UsageInfo(targets[i]);
|
||||
}
|
||||
final UsageTarget[] usageTargets =
|
||||
sourceElement == null ? UsageTarget.EMPTY_ARRAY : new UsageTarget[]{new PsiElement2UsageTargetAdapter(sourceElement)};
|
||||
final Usage[] foundUsages = UsageInfoToUsageConverter.convert(
|
||||
new UsageInfoToUsageConverter.TargetElementsDescriptor(targets), usages);
|
||||
UsageViewManager.getInstance(project).showUsages(usageTargets, foundUsages, presentation);
|
||||
|
||||
final UsageInfoToUsageConverter.TargetElementsDescriptor targetElementsDescriptor =
|
||||
sourceElement != null ? new UsageInfoToUsageConverter.TargetElementsDescriptor(sourceElement)
|
||||
: new UsageInfoToUsageConverter.TargetElementsDescriptor(PsiElement.EMPTY_ARRAY);
|
||||
final Usage[] usages = {UsageInfoToUsageConverter.convert(targetElementsDescriptor, new UsageInfo(targets[0]))};
|
||||
final UsageView view =
|
||||
UsageViewManager.getInstance(project).showUsages(usageTargets, usages, presentation);
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Updating Usage View ...") {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
|
||||
for (int i = 1; i < targets.length; i++) {
|
||||
if (((UsageViewImpl)view).isDisposed()) break;
|
||||
final PsiElement target = targets[i];
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final Usage usage = UsageInfoToUsageConverter.convert(targetElementsDescriptor, new UsageInfo(target));
|
||||
view.appendUsage(usage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +110,10 @@ public abstract class GotoActionBase extends AnAction {
|
||||
}
|
||||
|
||||
protected static Pair<String, Integer> getInitialText(boolean useEditorSelection, AnActionEvent e) {
|
||||
final String predefined = e.getData(PlatformDataKeys.PREDEFINED_TEXT);
|
||||
if (!StringUtil.isEmpty(predefined)) {
|
||||
return Pair.create(predefined, 0);
|
||||
}
|
||||
if (useEditorSelection) {
|
||||
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
|
||||
if (editor != null) {
|
||||
|
||||
@@ -72,7 +72,7 @@ class AnnotateStackTraceAction extends AnAction {
|
||||
private HashMap<VirtualFile, List<Integer>> files2lines = new HashMap<VirtualFile, List<Integer>>();
|
||||
|
||||
AnnotateStackTraceAction(ConsoleViewImpl consoleView) {
|
||||
super("Annotate", null, AllIcons.Actions.Annotate);
|
||||
super("Show files modification info", null, AllIcons.Actions.Annotate);
|
||||
myHyperlinks = consoleView.getHyperlinks();
|
||||
myEditor = consoleView.getEditor();
|
||||
myEditor.getColorsScheme().setColor(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -93,6 +93,8 @@ public class PlatformDataKeys {
|
||||
public static final DataKey<ModalityState> MODALITY_STATE = DataKey.create("ModalityState");
|
||||
public static final DataKey<Boolean> SOURCE_NAVIGATION_LOCKED = DataKey.create("sourceNavigationLocked");
|
||||
|
||||
public static final DataKey<String> PREDEFINED_TEXT = DataKey.create("predefined.text.value");
|
||||
|
||||
/**
|
||||
* Returns java.awt.Point to guess where to show context menu invoked by key.
|
||||
* This point should be relative to the currently focused component
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.impl.PresentationFactory;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.markup.EffectType;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
@@ -33,10 +35,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.GraphicsConfig;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
@@ -57,6 +56,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IconUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.StatusText;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -908,11 +908,48 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processKeyEvent(KeyEvent e) {
|
||||
protected void processKeyEvent(final KeyEvent e) {
|
||||
final int keyCode = e.getKeyCode();
|
||||
if (keyCode == VK_LEFT || keyCode == VK_RIGHT) {
|
||||
return;
|
||||
}
|
||||
if (keyCode == VK_ENTER && files.getModel().getSize() + toolWindows.getModel().getSize() == 0) {
|
||||
AnAction gotoAction = ActionManager.getInstance().getAction("GotoClass");
|
||||
if (gotoAction == null) {
|
||||
gotoAction = ActionManager.getInstance().getAction("GotoFile");
|
||||
}
|
||||
if (gotoAction != null) {
|
||||
final String search = mySpeedSearch.getEnteredPrefix();
|
||||
myPopup.cancel();
|
||||
final AnAction action = gotoAction;
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
DataManager.getInstance().getDataContextFromFocus().doWhenDone(new AsyncResult.Handler<DataContext>() {
|
||||
@Override
|
||||
public void run(final DataContext context) {
|
||||
final DataContext dataContext = new DataContext() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (PlatformDataKeys.PREDEFINED_TEXT.is(dataId)) {
|
||||
return search;
|
||||
}
|
||||
return context.getData(dataId);
|
||||
}
|
||||
};
|
||||
final AnActionEvent event =
|
||||
new AnActionEvent(e, dataContext, ActionPlaces.EDITOR_POPUP, new PresentationFactory().getPresentation(action),
|
||||
ActionManager.getInstance(), 0);
|
||||
action.actionPerformed(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.processKeyEvent(e);
|
||||
}
|
||||
|
||||
@@ -983,6 +1020,13 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
final Object value = list.getSelectedValue();
|
||||
((NameFilteringListModel)files.getModel()).refilter();
|
||||
((NameFilteringListModel)toolWindows.getModel()).refilter();
|
||||
if (files.getModel().getSize() + toolWindows.getModel().getSize() == 0) {
|
||||
toolWindows.getEmptyText().setText("");
|
||||
files.getEmptyText().setText("Press 'Enter' to search in Project");
|
||||
} else {
|
||||
files.getEmptyText().setText(StatusText.DEFAULT_EMPTY_TEXT);
|
||||
toolWindows.getEmptyText().setText(StatusText.DEFAULT_EMPTY_TEXT);
|
||||
}
|
||||
files.repaint();
|
||||
toolWindows.repaint();
|
||||
getSelectedList(list).setSelectedValue(value, true);
|
||||
|
||||
@@ -133,17 +133,8 @@ public class IdeaApplication {
|
||||
LOG.info("WM detected: " + wmName);
|
||||
if (wmName == null) return;
|
||||
|
||||
if ("Mutter".equals(wmName)) {
|
||||
if (wmName.startsWith("Mutter") || "Muffin".equals(wmName) || "GNOME Shell".equals(wmName)) {
|
||||
try {
|
||||
xwmClass.getDeclaredField("MUTTER_WM");
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
setWM(xwm, "METACITY_WM"); // Mutter support absent - mimic Metacity
|
||||
}
|
||||
}
|
||||
else if ("Muffin".equals(wmName) || "GNOME Shell".equals(wmName)) {
|
||||
try {
|
||||
xwmClass.getDeclaredField("MUTTER_WM");
|
||||
setWM(xwm, "MUTTER_WM");
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
|
||||
@@ -335,13 +335,13 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
|
||||
public SearchPopup(String initialString) {
|
||||
final Color foregroundColor = UIUtil.getToolTipForeground();
|
||||
Color color1 = UIUtil.getToolTipBackground();
|
||||
Color color1 = new JBColor(UIUtil.getToolTipBackground().brighter(), Gray._111);
|
||||
mySearchField = new SearchField();
|
||||
final JLabel searchLabel = new JLabel(" " + UIBundle.message("search.popup.search.for.label") + " ");
|
||||
searchLabel.setFont(searchLabel.getFont().deriveFont(Font.BOLD));
|
||||
searchLabel.setForeground(foregroundColor);
|
||||
mySearchField.setBorder(null);
|
||||
mySearchField.setBackground(color1.brighter());
|
||||
mySearchField.setBackground(color1);
|
||||
mySearchField.setForeground(foregroundColor);
|
||||
|
||||
mySearchField.setDocument(new PlainDocument() {
|
||||
@@ -358,7 +358,7 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
String newText = oldText.substring(0, offs) + str + oldText.substring(offs);
|
||||
super.insertString(offs, str, a);
|
||||
if (findElement(newText) == null) {
|
||||
mySearchField.setForeground(Color.RED);
|
||||
mySearchField.setForeground(JBColor.RED);
|
||||
}
|
||||
else {
|
||||
mySearchField.setForeground(foregroundColor);
|
||||
@@ -368,7 +368,7 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
mySearchField.setText(initialString);
|
||||
|
||||
setBorder(BorderFactory.createLineBorder(Color.gray, 1));
|
||||
setBackground(color1.brighter());
|
||||
setBackground(color1);
|
||||
setLayout(new BorderLayout());
|
||||
add(searchLabel, BorderLayout.WEST);
|
||||
add(mySearchField, BorderLayout.EAST);
|
||||
@@ -421,10 +421,10 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
private void updateSelection(Object element) {
|
||||
if (element != null) {
|
||||
selectElement(element, mySearchField.getText());
|
||||
mySearchField.setForeground(Color.black);
|
||||
mySearchField.setForeground(UIUtil.getLabelForeground());
|
||||
}
|
||||
else {
|
||||
mySearchField.setForeground(Color.red);
|
||||
mySearchField.setForeground(JBColor.red);
|
||||
}
|
||||
if (mySearchPopup != null) {
|
||||
mySearchPopup.setSize(mySearchPopup.getPreferredSize());
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.testFramework.vcs;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -79,6 +80,12 @@ public class MockChangeList extends LocalChangeList {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalChangeList copy() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
+4
@@ -365,4 +365,8 @@ public class MockChangeListManager extends ChangeListManagerEx {
|
||||
public void freezeImmediately(@Nullable String reason) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalChangeList addChangeList(@NotNull String name, @Nullable String comment, @Nullable Object data) {
|
||||
return addChangeList(name, comment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -67,10 +68,13 @@ public class UsageInfoToUsageConverter {
|
||||
|
||||
@NotNull
|
||||
private static List<SmartPsiElementPointer<PsiElement>> convertToSmartPointers(@NotNull PsiElement[] primaryElements) {
|
||||
if (primaryElements.length == 0) return Collections.emptyList();
|
||||
|
||||
final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(primaryElements[0].getProject());
|
||||
return ContainerUtil.mapNotNull(primaryElements, new Function<PsiElement, SmartPsiElementPointer<PsiElement>>() {
|
||||
@Override
|
||||
public SmartPsiElementPointer<PsiElement> fun(final PsiElement s) {
|
||||
return SmartPointerManager.getInstance(s.getProject()).createSmartPsiElementPointer(s);
|
||||
return smartPointerManager.createSmartPsiElementPointer(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -985,6 +985,10 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDisposed() {
|
||||
return isDisposed;
|
||||
}
|
||||
|
||||
private void showNode(@NotNull final UsageNode node) {
|
||||
if (!myPresentation.isDetachedMode()) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.CommitExecutor;
|
||||
import com.intellij.openapi.vcs.changes.CommitResultHandler;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsHistoryProvider;
|
||||
@@ -167,11 +167,11 @@ public abstract class AbstractVcsHelper {
|
||||
|
||||
|
||||
/**
|
||||
* Shows commit dialog, fills it with the given changes and given commit message, initially selects the given changelist.
|
||||
* @return true if user commits the changes, and commit succeeds; false if user presses Cancel or commit fails with errors.
|
||||
* <p>Shows commit dialog, fills it with the given changes and given commit message, initially selects the given changelist.</p>
|
||||
* <p>Note that the method is asynchronous: it returns right after user presses "Commit" or "Cancel" and after all pre-commit handlers
|
||||
* have been called. It doesn't wait for commit itself to succeed or fail - for this use the {@code customResultHandler}.</p>
|
||||
* @return true if user decides to commit the changes, false if user presses Cancel.
|
||||
*/
|
||||
public abstract boolean commitChanges(@NotNull List<Change> changes, @NotNull LocalChangeList initialChangeList,
|
||||
@NotNull String commitMessage, @Nullable CommitExecutor executor);
|
||||
|
||||
|
||||
public abstract boolean commitChanges(@NotNull Collection<Change> changes, @NotNull LocalChangeList initialChangeList,
|
||||
@NotNull String commitMessage, @Nullable CommitResultHandler customResultHandler);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 com.intellij.openapi.vcs.changes;
|
||||
|
||||
import com.intellij.openapi.vcs.AbstractVcsHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* CommitResultHandler may be passed to {@link AbstractVcsHelper#commitChanges(Collection, LocalChangeList, String, CommitResultHandler)}.
|
||||
* It is called after commit is performed: successful or failed.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public interface CommitResultHandler {
|
||||
|
||||
void onSuccess(@NotNull String commitMessage);
|
||||
|
||||
void onFailure();
|
||||
|
||||
}
|
||||
@@ -63,6 +63,12 @@ public abstract class LocalChangeList implements Cloneable, ChangeList {
|
||||
|
||||
public abstract void setReadOnly(boolean isReadOnly);
|
||||
|
||||
/**
|
||||
* Get additional data associated with this changelist.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract Object getData();
|
||||
|
||||
public abstract LocalChangeList copy();
|
||||
|
||||
public boolean hasDefaultName() {
|
||||
|
||||
@@ -46,12 +46,12 @@ public class FilePathImpl implements FilePath {
|
||||
private boolean myIsDirectory;
|
||||
private final boolean myLocal;
|
||||
|
||||
private FilePathImpl(VirtualFile virtualParent,
|
||||
private FilePathImpl(@NotNull VirtualFile virtualParent,
|
||||
@NotNull String name,
|
||||
final boolean isDirectory,
|
||||
VirtualFile child,
|
||||
final boolean forDeleted) {
|
||||
this(virtualParent == null ? new File(name) : new File(new File(virtualParent.getPath()), name), isDirectory, true);
|
||||
this(new File(virtualParent.getPath(), name), isDirectory, true);
|
||||
myVirtualParent = virtualParent;
|
||||
|
||||
if (!forDeleted) {
|
||||
@@ -88,6 +88,7 @@ public class FilePathImpl implements FilePath {
|
||||
}
|
||||
private FilePathImpl(@NotNull File file, final boolean isDirectory, boolean local) {
|
||||
myFile = file;
|
||||
assert myFile.isAbsolute();
|
||||
myName = file.getName();
|
||||
myIsDirectory = isDirectory;
|
||||
myLocal = local;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.vcs.changes;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -31,4 +32,6 @@ public abstract class ChangeListManagerEx extends ChangeListManager {
|
||||
|
||||
|
||||
public abstract void freezeImmediately(@Nullable String reason);
|
||||
|
||||
public abstract LocalChangeList addChangeList(@NotNull String name, @Nullable final String comment, @Nullable Object data);
|
||||
}
|
||||
@@ -230,7 +230,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
|
||||
public void run() {
|
||||
synchronized (myDataLock) {
|
||||
if (myWorker.isEmpty()) {
|
||||
final LocalChangeList list = myWorker.addChangeList(VcsBundle.message("changes.default.changlist.name"), null);
|
||||
final LocalChangeList list = myWorker.addChangeList(VcsBundle.message("changes.default.changlist.name"), null, null);
|
||||
setDefaultChangeList(list);
|
||||
|
||||
if (myIgnoredIdeaLevel.isEmpty()) {
|
||||
@@ -829,11 +829,16 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
|
||||
}
|
||||
|
||||
public LocalChangeList addChangeList(@NotNull final String name, @Nullable final String comment) {
|
||||
return addChangeList(name, comment, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalChangeList addChangeList(@NotNull final String name, @Nullable final String comment, @Nullable final Object data) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<LocalChangeList>() {
|
||||
@Override
|
||||
public LocalChangeList compute() {
|
||||
synchronized (myDataLock) {
|
||||
final LocalChangeList changeList = myModifier.addChangeList(name, comment);
|
||||
final LocalChangeList changeList = myModifier.addChangeList(name, comment, data);
|
||||
myChangesViewManager.scheduleRefresh();
|
||||
return changeList;
|
||||
}
|
||||
@@ -841,6 +846,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void removeChangeList(final String name) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
@@ -1158,7 +1164,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
|
||||
|
||||
private boolean doCommit(final LocalChangeList changeList, final List<Change> changes, final boolean synchronously) {
|
||||
return new CommitHelper(myProject, changeList, changes, changeList.getName(),
|
||||
changeList.getComment(), new ArrayList<CheckinHandler>(), false, synchronously, NullableFunction.NULL).doCommit();
|
||||
changeList.getComment(), new ArrayList<CheckinHandler>(), false, synchronously, NullableFunction.NULL, null).doCommit();
|
||||
}
|
||||
|
||||
public void commitChangesSynchronously(LocalChangeList changeList, List<Change> changes) {
|
||||
|
||||
+2
-1
@@ -70,7 +70,8 @@ class ChangeListManagerSerialization {
|
||||
final String changeListName = listNode.getAttributeValue(ATT_NAME);
|
||||
LocalChangeList list = myWorker.getCopyByName(changeListName);
|
||||
if (list == null) {
|
||||
list = myWorker.addChangeList(listNode.getAttributeValue(ATT_ID), changeListName, listNode.getAttributeValue(ATT_COMMENT), false);
|
||||
list = myWorker.addChangeList(listNode.getAttributeValue(ATT_ID), changeListName, listNode.getAttributeValue(ATT_COMMENT), false,
|
||||
null);
|
||||
}
|
||||
//noinspection unchecked
|
||||
final List<Element> changeNodes = (List<Element>)listNode.getChildren(NODE_CHANGE);
|
||||
|
||||
@@ -198,14 +198,16 @@ public class ChangeListWorker implements ChangeListsWriteOperations {
|
||||
return list != null;
|
||||
}
|
||||
|
||||
public LocalChangeList addChangeList(@NotNull final String name, @Nullable final String description) {
|
||||
return addChangeList(null, name, description, false);
|
||||
public LocalChangeList addChangeList(@NotNull final String name, @Nullable final String comment, @Nullable Object data) {
|
||||
return addChangeList(null, name, comment, false, data);
|
||||
}
|
||||
|
||||
LocalChangeList addChangeList(String id, @NotNull final String name, @Nullable final String description, final boolean inUpdate) {
|
||||
LocalChangeList addChangeList(String id, @NotNull final String name, @Nullable final String description, final boolean inUpdate,
|
||||
@Nullable Object data) {
|
||||
final boolean contains = myMap.containsKey(name);
|
||||
LOG.assertTrue(! contains, "Attempt to create duplicate changelist " + name);
|
||||
final LocalChangeListImpl newList = (LocalChangeListImpl) LocalChangeList.createEmptyChangeList(myProject, name);
|
||||
newList.setData(data);
|
||||
|
||||
if (description != null) {
|
||||
newList.setCommentImpl(description);
|
||||
@@ -751,7 +753,7 @@ public class ChangeListWorker implements ChangeListsWriteOperations {
|
||||
}
|
||||
|
||||
public LocalChangeList addChangeList(final String name, final String comment) {
|
||||
return myWorker.addChangeList(null, name, comment, true);
|
||||
return myWorker.addChangeList(null, name, comment, true, null);
|
||||
}
|
||||
|
||||
public LocalChangeList findOrCreateList(final String name, final String comment) {
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ public interface ChangeListsWriteOperations {
|
||||
@Nullable
|
||||
String setDefault(String name);
|
||||
boolean setReadOnly(String name, boolean value);
|
||||
LocalChangeList addChangeList(@NotNull String name, @Nullable String description);
|
||||
LocalChangeList addChangeList(@NotNull String name, @Nullable String comment, @Nullable Object data);
|
||||
boolean removeChangeList(@NotNull String name);
|
||||
@Nullable
|
||||
MultiMap<LocalChangeList, Change> moveChangesTo(String name, Change[] changes);
|
||||
|
||||
@@ -29,6 +29,7 @@ public class LocalChangeListImpl extends LocalChangeList {
|
||||
private String myId;
|
||||
@NotNull private String myName;
|
||||
private String myComment = "";
|
||||
@Nullable private Object myData;
|
||||
|
||||
private boolean myIsDefault = false;
|
||||
private boolean myIsReadOnly = false;
|
||||
@@ -116,6 +117,16 @@ public class LocalChangeListImpl extends LocalChangeList {
|
||||
myIsReadOnly = isReadOnly;
|
||||
}
|
||||
|
||||
void setData(@Nullable Object data) {
|
||||
myData = data;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData() {
|
||||
return myData;
|
||||
}
|
||||
|
||||
void addChange(Change change) {
|
||||
if (ChangeListManagerImpl.DEBUG) {
|
||||
ChangeListManagerImpl.log("LocalChangeListImpl.addChange: this = " + this + ", change = " + change);
|
||||
@@ -260,6 +271,7 @@ public class LocalChangeListImpl extends LocalChangeList {
|
||||
copy.myComment = myComment;
|
||||
copy.myIsDefault = myIsDefault;
|
||||
copy.myIsReadOnly = myIsReadOnly;
|
||||
copy.myData = myData;
|
||||
|
||||
if (myChanges != null) {
|
||||
copy.myChanges = new HashSet<Change>(myChanges);
|
||||
|
||||
@@ -39,8 +39,8 @@ public class Modifier implements ChangeListsWriteOperations {
|
||||
myCommandQueue = new LinkedList<ChangeListCommand>();
|
||||
}
|
||||
|
||||
public LocalChangeList addChangeList(@NotNull final String name, @Nullable final String comment) {
|
||||
final AddList command = new AddList(name, comment);
|
||||
public LocalChangeList addChangeList(@NotNull final String name, @Nullable final String comment, @Nullable Object data) {
|
||||
final AddList command = new AddList(name, comment, data);
|
||||
impl(command);
|
||||
return command.getNewListCopy();
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ public class UpdateRequestsQueue {
|
||||
myWaitingUpdateCompletionQueue.removeAll(copy);
|
||||
}
|
||||
|
||||
if (! myWaitingUpdateCompletionQueue.isEmpty() && ! myRequestSubmitted) {
|
||||
if (! myWaitingUpdateCompletionQueue.isEmpty() && ! myRequestSubmitted && ! myStopped) {
|
||||
LOG.error("No update task to handle request(s)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
checkIfDisposed();
|
||||
return myIndex.isExcludedFile(file);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -25,17 +25,19 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class AddList implements ChangeListCommand {
|
||||
@NotNull private final String myName;
|
||||
@Nullable private final String myComment;
|
||||
@Nullable private final Object myData;
|
||||
|
||||
private LocalChangeList myNewListCopy;
|
||||
|
||||
public AddList(@NotNull final String name, @Nullable final String comment) {
|
||||
public AddList(@NotNull final String name, @Nullable final String comment, @Nullable Object data) {
|
||||
myName = name;
|
||||
myComment = comment;
|
||||
myData = data;
|
||||
}
|
||||
|
||||
public void apply(final ChangeListWorker worker) {
|
||||
if (! worker.findListByName(myName)) {
|
||||
myNewListCopy = worker.addChangeList(myName, myComment);
|
||||
myNewListCopy = worker.addChangeList(myName, myComment, myData);
|
||||
} else {
|
||||
worker.editComment(myName, myComment);
|
||||
myNewListCopy = worker.getCopyByName(myName);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.changes.ui;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -67,6 +68,12 @@ public class AlienLocalChangeList extends LocalChangeList {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public LocalChangeList copy() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
+21
-11
@@ -111,6 +111,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
private final ZipperUpdater myZipperUpdater;
|
||||
private final Runnable myRefreshDetails;
|
||||
private CommitAction myCommitAction;
|
||||
@Nullable private CommitResultHandler myResultHandler;
|
||||
|
||||
private static class MyUpdateButtonsRunnable implements Runnable {
|
||||
private CommitChangeListDialog myDialog;
|
||||
@@ -139,7 +140,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
private final MyUpdateButtonsRunnable myUpdateButtonsRunnable = new MyUpdateButtonsRunnable(this);
|
||||
|
||||
private static boolean commit(final Project project, final List<Change> changes, final LocalChangeList initialSelection,
|
||||
final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment) {
|
||||
final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment,
|
||||
@Nullable CommitResultHandler customResultHandler) {
|
||||
final AbstractVcs[] allActiveVcss = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss();
|
||||
final List<VcsCheckinHandlerFactory> factoryList =
|
||||
CheckinHandlersManager.getInstance().getMatchingVcsFactories(Arrays.<AbstractVcs>asList(allActiveVcss));
|
||||
@@ -155,7 +157,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
final ArrayList<LocalChangeList> changeLists = new ArrayList<LocalChangeList>(manager.getChangeListsCopy());
|
||||
CommitChangeListDialog dialog =
|
||||
new CommitChangeListDialog(project, changes, initialSelection, executors, showVcsCommit, defaultList, changeLists, null, false,
|
||||
comment);
|
||||
comment, customResultHandler);
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
dialog.show();
|
||||
}
|
||||
@@ -179,10 +181,10 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
public static boolean commitChanges(final Project project, final Collection<Change> changes, final LocalChangeList initialSelection,
|
||||
@Nullable final CommitExecutor executor, final String comment) {
|
||||
if (executor == null) {
|
||||
return commitChanges(project, changes, initialSelection, collectExecutors(project, changes), true, comment);
|
||||
return commitChanges(project, changes, initialSelection, collectExecutors(project, changes), true, comment, null);
|
||||
}
|
||||
else {
|
||||
return commitChanges(project, changes, initialSelection, Collections.singletonList(executor), false, comment);
|
||||
return commitChanges(project, changes, initialSelection, Collections.singletonList(executor), false, comment, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,22 +199,29 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the commit dialog, and performs the selected action: commit, commit & push, create patch, etc.
|
||||
* @param customResultHandler If this is not null, after commit is completed, custom result handler is called instead of
|
||||
* showing the default notification in case of commit or failure.
|
||||
* @return true if user agreed to commit, false if he pressed "Cancel".
|
||||
*/
|
||||
public static boolean commitChanges(final Project project, final Collection<Change> changes, final LocalChangeList initialSelection,
|
||||
final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment) {
|
||||
final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment,
|
||||
@Nullable CommitResultHandler customResultHandler) {
|
||||
if (changes.isEmpty() && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
Messages.showInfoMessage(project, VcsBundle.message("commit.dialog.no.changes.detected.text") ,
|
||||
VcsBundle.message("commit.dialog.no.changes.detected.title"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return commit(project, new ArrayList<Change>(changes), initialSelection, executors, showVcsCommit, comment);
|
||||
return commit(project, new ArrayList<Change>(changes), initialSelection, executors, showVcsCommit, comment, customResultHandler);
|
||||
}
|
||||
|
||||
public static void commitAlienChanges(final Project project, final List<Change> changes, final AbstractVcs vcs,
|
||||
final String changelistName, final String comment) {
|
||||
final LocalChangeList lcl = new AlienLocalChangeList(changes, changelistName);
|
||||
new CommitChangeListDialog(project, changes, null, null, true, AlienLocalChangeList.DEFAULT_ALIEN, Collections.singletonList(lcl), vcs,
|
||||
true, comment).show();
|
||||
true, comment, null).show();
|
||||
}
|
||||
|
||||
private CommitChangeListDialog(final Project project,
|
||||
@@ -221,13 +230,14 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
final List<CommitExecutor> executors,
|
||||
final boolean showVcsCommit, final LocalChangeList defaultChangeList,
|
||||
final List<LocalChangeList> changeLists, final AbstractVcs singleVcs, final boolean isAlien,
|
||||
final String comment) {
|
||||
final String comment, @Nullable CommitResultHandler customResultHandler) {
|
||||
super(project, true);
|
||||
myCommitContext = new CommitContext();
|
||||
myProject = project;
|
||||
myExecutors = executors;
|
||||
myShowVcsCommit = showVcsCommit;
|
||||
myVcs = singleVcs;
|
||||
myResultHandler = customResultHandler;
|
||||
myListComments = new HashMap<String, String>();
|
||||
myAdditionalData = new PseudoMap<Object, Object>();
|
||||
myDiffDetails = new ShortDiffDetails(myProject, new Getter<Change[]>() {
|
||||
@@ -570,7 +580,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
runBeforeCommitHandlers(new Runnable() {
|
||||
public void run() {
|
||||
CommitChangeListDialog.super.doOKAction();
|
||||
doCommit();
|
||||
doCommit(myResultHandler);
|
||||
}
|
||||
}, null);
|
||||
|
||||
@@ -925,7 +935,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
super.doCancelAction();
|
||||
}
|
||||
|
||||
private void doCommit() {
|
||||
private void doCommit(@Nullable CommitResultHandler customResultHandler) {
|
||||
final CommitHelper helper = new CommitHelper(
|
||||
myProject,
|
||||
myBrowser.getSelectedChangeList(),
|
||||
@@ -933,7 +943,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
|
||||
myActionName,
|
||||
getCommitMessage(),
|
||||
myHandlers,
|
||||
myAllOfDefaultChangeListChangesIncluded, false, myAdditionalData);
|
||||
myAllOfDefaultChangeListChangesIncluded, false, myAdditionalData, customResultHandler);
|
||||
|
||||
if (myIsAlien) {
|
||||
helper.doAlienCommit(myVcs);
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.WaitForProgressToShow;
|
||||
import com.intellij.util.ui.ConfirmationDialog;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -66,6 +67,7 @@ public class CommitHelper {
|
||||
private final boolean myAllOfDefaultChangeListChangesIncluded;
|
||||
private final boolean myForceSyncCommit;
|
||||
private final NullableFunction<Object, Object> myAdditionalData;
|
||||
@Nullable private final CommitResultHandler myCustomResultHandler;
|
||||
private final List<Document> myCommittingDocuments = new ArrayList<Document>();
|
||||
private final VcsConfiguration myConfiguration;
|
||||
private final VcsDirtyScopeManager myDirtyScopeManager;
|
||||
@@ -78,7 +80,8 @@ public class CommitHelper {
|
||||
final String commitMessage,
|
||||
final List<CheckinHandler> handlers,
|
||||
final boolean allOfDefaultChangeListChangesIncluded,
|
||||
final boolean synchronously, final NullableFunction<Object, Object> additionalDataHolder) {
|
||||
final boolean synchronously, final NullableFunction<Object, Object> additionalDataHolder,
|
||||
@Nullable CommitResultHandler customResultHandler) {
|
||||
myProject = project;
|
||||
myChangeList = changeList;
|
||||
myIncludedChanges = includedChanges;
|
||||
@@ -88,6 +91,7 @@ public class CommitHelper {
|
||||
myAllOfDefaultChangeListChangesIncluded = allOfDefaultChangeListChangesIncluded;
|
||||
myForceSyncCommit = synchronously;
|
||||
myAdditionalData = additionalDataHolder;
|
||||
myCustomResultHandler = customResultHandler;
|
||||
myConfiguration = VcsConfiguration.getInstance(myProject);
|
||||
myDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
|
||||
myFeedback = new HashSet<String>();
|
||||
@@ -133,8 +137,11 @@ public class CommitHelper {
|
||||
|
||||
@Override
|
||||
public NotificationInfo notifyFinished() {
|
||||
String text = reportSuccess(processor);
|
||||
return new NotificationInfo("VCS Commit", "VCS Commit Finished", text, true);
|
||||
if (myCustomResultHandler == null) {
|
||||
String text = reportSuccess(processor);
|
||||
return new NotificationInfo("VCS Commit", "VCS Commit Finished", text, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
ProgressManager.getInstance().run(task);
|
||||
@@ -202,14 +209,18 @@ public class CommitHelper {
|
||||
processor.doBeforeRefresh();
|
||||
|
||||
AbstractVcsHelper.getInstance(myProject).showErrors(processor.getVcsExceptions(), myActionName);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
LOG.error(e);
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} finally {
|
||||
processor.myVcsExceptions.add(new VcsException(e));
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
processor.myVcsExceptions.add(new VcsException(e));
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
commitCompleted(processor.getVcsExceptions(), processor);
|
||||
processor.customRefresh();
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
@@ -511,6 +522,9 @@ public class CommitHelper {
|
||||
}
|
||||
|
||||
processor.afterSuccessfulCheckIn();
|
||||
if (myCustomResultHandler != null) {
|
||||
myCustomResultHandler.onSuccess(myCommitMessage);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (CheckinHandler handler : myHandlers) {
|
||||
@@ -523,28 +537,38 @@ public class CommitHelper {
|
||||
if (indicator != null) {
|
||||
indicator.setText(VcsBundle.message("commit.dialog.completed.successfully"));
|
||||
}
|
||||
} else {
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
public void run() {
|
||||
final String message;
|
||||
if (errorsSize > 0 && warningsSize > 0) {
|
||||
message = VcsBundle.message("message.text.commit.failed.with.errors.and.warnings");
|
||||
}
|
||||
else if (errorsSize > 0) {
|
||||
message = VcsBundle.message("message.text.commit.failed.with.errors");
|
||||
}
|
||||
else {
|
||||
message = VcsBundle.message("message.text.commit.finished.with.warnings");
|
||||
}
|
||||
//new VcsBalloonProblemNotifier(myProject, message, MessageType.ERROR).run();
|
||||
Messages.showErrorDialog(message, VcsBundle.message("message.title.commit"));
|
||||
|
||||
if (errorsSize > 0) {
|
||||
processor.afterFailedCheckIn();
|
||||
}
|
||||
}
|
||||
}, null, myProject);
|
||||
}
|
||||
else {
|
||||
if (myCustomResultHandler == null) {
|
||||
showErrorDialogAndMoveToAnotherList(processor, errorsSize, warningsSize);
|
||||
}
|
||||
else {
|
||||
myCustomResultHandler.onFailure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showErrorDialogAndMoveToAnotherList(final GeneralCommitProcessor processor, final int errorsSize, final int warningsSize) {
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
public void run() {
|
||||
final String message;
|
||||
if (errorsSize > 0 && warningsSize > 0) {
|
||||
message = VcsBundle.message("message.text.commit.failed.with.errors.and.warnings");
|
||||
}
|
||||
else if (errorsSize > 0) {
|
||||
message = VcsBundle.message("message.text.commit.failed.with.errors");
|
||||
}
|
||||
else {
|
||||
message = VcsBundle.message("message.text.commit.finished.with.warnings");
|
||||
}
|
||||
//new VcsBalloonProblemNotifier(myProject, message, MessageType.ERROR).run();
|
||||
Messages.showErrorDialog(message, VcsBundle.message("message.title.commit"));
|
||||
|
||||
if (errorsSize > 0) {
|
||||
processor.afterFailedCheckIn();
|
||||
}
|
||||
}
|
||||
}, null, myProject);
|
||||
}
|
||||
|
||||
public static void moveToFailedList(final ChangeList changeList,
|
||||
|
||||
@@ -47,10 +47,7 @@ import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.actions.AnnotateToggleAction;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.CommitExecutor;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vcs.changes.*;
|
||||
import com.intellij.openapi.vcs.changes.committed.*;
|
||||
import com.intellij.openapi.vcs.changes.ui.*;
|
||||
import com.intellij.openapi.vcs.history.*;
|
||||
@@ -225,9 +222,11 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitChanges(@NotNull List<Change> changes, @NotNull LocalChangeList initialChangeList,
|
||||
@NotNull String commitMessage, @Nullable CommitExecutor executor) {
|
||||
return CommitChangeListDialog.commitChanges(myProject, changes, initialChangeList, executor, commitMessage);
|
||||
public boolean commitChanges(@NotNull Collection<Change> changes, @NotNull LocalChangeList initialChangeList,
|
||||
@NotNull String commitMessage, @Nullable CommitResultHandler customResultHandler) {
|
||||
return CommitChangeListDialog.commitChanges(myProject, changes, initialChangeList,
|
||||
CommitChangeListDialog.collectExecutors(myProject, changes), true, commitMessage,
|
||||
customResultHandler);
|
||||
}
|
||||
|
||||
private static void addDirectMessages(VcsErrorViewPanel vcsErrorViewPanel, List<VcsException> abstractVcsExceptions) {
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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 git4idea.changes;
|
||||
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Git change list
|
||||
*/
|
||||
public class GitChangeList extends LocalChangeList {
|
||||
private String name;
|
||||
private String comment;
|
||||
private final Collection<Change> changes;
|
||||
|
||||
public GitChangeList(@NotNull String name, String comment, Collection<Change> changes) {
|
||||
super();
|
||||
setName(name);
|
||||
setComment(comment);
|
||||
this.changes = changes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(@NotNull String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setReadOnly(boolean isReadOnly) {
|
||||
}
|
||||
|
||||
public Collection<Change> getChanges() {
|
||||
return changes;
|
||||
}
|
||||
|
||||
public LocalChangeList copy() {
|
||||
return new GitChangeList(name, comment, changes);
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,8 @@ import com.intellij.openapi.vcs.CheckinProjectPanel;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.ObjectsConvertor;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ChangeList;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
|
||||
import com.intellij.openapi.vcs.changes.*;
|
||||
import com.intellij.openapi.vcs.checkin.CheckinChangeListSpecificComponent;
|
||||
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
|
||||
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -49,6 +47,7 @@ import git4idea.commands.GitSimpleHandler;
|
||||
import git4idea.config.GitConfigUtil;
|
||||
import git4idea.config.GitVcsSettings;
|
||||
import git4idea.history.NewGitUsersComponent;
|
||||
import git4idea.history.browser.GitCommit;
|
||||
import git4idea.i18n.GitBundle;
|
||||
import git4idea.push.GitPusher;
|
||||
import git4idea.repo.GitRepositoryFiles;
|
||||
@@ -61,6 +60,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
@@ -73,13 +73,14 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
@NonNls private static final String GIT_COMMIT_MSG_FILE_EXT = ".txt"; // the file extension for commit message file
|
||||
|
||||
private final Project myProject;
|
||||
public static final SimpleDateFormat COMMIT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
private final VcsDirtyScopeManager myDirtyScopeManager;
|
||||
private final GitVcsSettings mySettings;
|
||||
|
||||
private String myNextCommitAuthor = null; // The author for the next commit
|
||||
private boolean myNextCommitAmend; // If true, the next commit is amended
|
||||
private Boolean myNextCommitIsPushed = null; // The push option of the next commit
|
||||
|
||||
private Date myNextCommitAuthorDate;
|
||||
|
||||
public GitCheckinEnvironment(@NotNull Project project, @NotNull final VcsDirtyScopeManager dirtyScopeManager, final GitVcsSettings settings) {
|
||||
myProject = project;
|
||||
@@ -178,7 +179,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
Set<FilePath> files = new HashSet<FilePath>();
|
||||
files.addAll(added);
|
||||
files.addAll(removed);
|
||||
commit(myProject, root, files, messageFile, myNextCommitAuthor, myNextCommitAmend);
|
||||
commit(myProject, root, files, messageFile, myNextCommitAuthor, myNextCommitAmend, myNextCommitAuthorDate);
|
||||
}
|
||||
catch (VcsException ex) {
|
||||
if (!isMergeCommit(ex)) {
|
||||
@@ -440,12 +441,15 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
/**
|
||||
* Prepare delete files handler.
|
||||
*
|
||||
* @param project the project
|
||||
* @param root a vcs root
|
||||
* @param files a files to commit
|
||||
* @param message a message file to use
|
||||
* @param nextCommitAuthor a author for the next commit
|
||||
* @param nextCommitAmend true, if the commit should be amended
|
||||
*
|
||||
*
|
||||
* @param project the project
|
||||
* @param root a vcs root
|
||||
* @param files a files to commit
|
||||
* @param message a message file to use
|
||||
* @param nextCommitAuthor a author for the next commit
|
||||
* @param nextCommitAmend true, if the commit should be amended
|
||||
* @param nextCommitAuthorDate Author date timestamp to override the date of the commit or null if this overriding is not needed.
|
||||
* @return a simple handler that does the task
|
||||
* @throws VcsException in case of git problem
|
||||
*/
|
||||
@@ -454,7 +458,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
Collection<FilePath> files,
|
||||
File message,
|
||||
final String nextCommitAuthor,
|
||||
boolean nextCommitAmend)
|
||||
boolean nextCommitAmend, Date nextCommitAuthorDate)
|
||||
throws VcsException {
|
||||
boolean amend = nextCommitAmend;
|
||||
for (List<String> paths : VcsFileUtil.chunkPaths(root, files)) {
|
||||
@@ -470,6 +474,9 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
if (nextCommitAuthor != null) {
|
||||
handler.addParameters("--author=" + nextCommitAuthor);
|
||||
}
|
||||
if (nextCommitAuthorDate != null) {
|
||||
handler.addParameters("--date", COMMIT_DATE_FORMAT.format(nextCommitAuthorDate));
|
||||
}
|
||||
handler.endOptions();
|
||||
handler.addParameters(paths);
|
||||
handler.run();
|
||||
@@ -559,12 +566,13 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
myNextCommitAmend = false;
|
||||
myNextCommitAuthor = null;
|
||||
myNextCommitIsPushed = null;
|
||||
myNextCommitAuthorDate = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkin options for git
|
||||
*/
|
||||
private class GitCheckinOptions implements RefreshableOnComponent {
|
||||
private class GitCheckinOptions implements CheckinChangeListSpecificComponent {
|
||||
/**
|
||||
* A container panel
|
||||
*/
|
||||
@@ -577,6 +585,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
* The amend checkbox
|
||||
*/
|
||||
private final JCheckBox myAmend;
|
||||
private Date myAuthorDate;
|
||||
|
||||
/**
|
||||
* A constructor
|
||||
@@ -661,7 +670,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void saveState() {
|
||||
String author = (String)myAuthor.getSelectedItem();
|
||||
String author = (String)myAuthor.getEditor().getItem();
|
||||
myNextCommitAuthor = author.length() == 0 ? null : author;
|
||||
if (author.length() == 0) {
|
||||
myNextCommitAuthor = null;
|
||||
@@ -671,6 +680,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
mySettings.saveCommitAuthor(author);
|
||||
}
|
||||
myNextCommitAmend = myAmend.isSelected();
|
||||
myNextCommitAuthorDate = myAuthorDate;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -679,6 +689,17 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
public void restoreState() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeListSelected(LocalChangeList list) {
|
||||
Object data = list.getData();
|
||||
if (data instanceof GitCommit) {
|
||||
GitCommit commit = (GitCommit)data;
|
||||
String author = String.format("%s <%s>", commit.getAuthor(), commit.getAuthorEmail());
|
||||
myAuthor.getEditor().setItem(author);
|
||||
myAuthorDate = new Date(commit.getAuthorTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setNextCommitIsPushed(Boolean nextCommitIsPushed) {
|
||||
|
||||
@@ -18,24 +18,17 @@ package git4idea.history.browser;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.*;
|
||||
import com.intellij.openapi.vcs.changes.ui.CommitHelper;
|
||||
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.WaitForProgressToShow;
|
||||
import git4idea.GitPlatformFacade;
|
||||
import git4idea.checkin.GitCheckinEnvironment;
|
||||
import git4idea.commands.Git;
|
||||
import git4idea.commands.GitCommandResult;
|
||||
import git4idea.commands.GitSimpleEventDetector;
|
||||
@@ -43,15 +36,13 @@ import git4idea.commands.GitUntrackedFilesOverwrittenByOperationDetector;
|
||||
import git4idea.merge.GitConflictResolver;
|
||||
import git4idea.repo.GitRepository;
|
||||
import git4idea.util.UntrackedFilesNotifier;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -163,7 +154,7 @@ public class GitCherryPicker {
|
||||
@NotNull GitCommitWrapper commit,
|
||||
@NotNull List<GitCommitWrapper> successfulCommits) {
|
||||
CherryPickData data = updateChangeListManager(commit.getCommit());
|
||||
boolean committed = showCommitDialog(repository, commit, data.myChangeList, data.myCommitMessage);
|
||||
boolean committed = showCommitDialogAndWaitForCommit(repository, commit, data.myChangeList, data.myCommitMessage);
|
||||
if (committed) {
|
||||
removeChangeList(data);
|
||||
successfulCommits.add(commit);
|
||||
@@ -206,12 +197,12 @@ public class GitCherryPicker {
|
||||
refreshChangedFiles(paths);
|
||||
final String commitMessage = createCommitMessage(commit, paths);
|
||||
LocalChangeList previouslyDefaultChangeList = myChangeListManager.getDefaultChangeList();
|
||||
LocalChangeList changeList = createChangeListAfterUpdate(commit.getChanges(), paths, commitMessage);
|
||||
LocalChangeList changeList = createChangeListAfterUpdate(commit, paths, commitMessage);
|
||||
return new CherryPickData(changeList, commitMessage, previouslyDefaultChangeList);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LocalChangeList createChangeListAfterUpdate(@NotNull final List<Change> changes, @NotNull final Collection<FilePath> paths,
|
||||
private LocalChangeList createChangeListAfterUpdate(@NotNull final GitCommit commit, @NotNull final Collection<FilePath> paths,
|
||||
@NotNull final String commitMessage) {
|
||||
final AtomicReference<LocalChangeList> changeList = new AtomicReference<LocalChangeList>();
|
||||
myPlatformFacade.invokeAndWait(new Runnable() {
|
||||
@@ -219,7 +210,7 @@ public class GitCherryPicker {
|
||||
public void run() {
|
||||
myChangeListManager.invokeAfterUpdate(new Runnable() {
|
||||
public void run() {
|
||||
changeList.set(createChangeList(changes, commitMessage));
|
||||
changeList.set(createChangeList(commit, commitMessage));
|
||||
}
|
||||
}, InvokeAfterUpdateMode.SYNCHRONOUS_NOT_CANCELLABLE, "Cherry-pick",
|
||||
new Consumer<VcsDirtyScopeManager>() {
|
||||
@@ -243,29 +234,53 @@ public class GitCherryPicker {
|
||||
return message;
|
||||
}
|
||||
|
||||
private boolean showCommitDialog(@NotNull final GitRepository repository, @NotNull final GitCommitWrapper commit,
|
||||
@NotNull final LocalChangeList changeList, @NotNull final String commitMessage) {
|
||||
private boolean showCommitDialogAndWaitForCommit(@NotNull final GitRepository repository, @NotNull final GitCommitWrapper commit,
|
||||
@NotNull final LocalChangeList changeList, @NotNull final String commitMessage) {
|
||||
final AtomicBoolean commitSucceeded = new AtomicBoolean();
|
||||
final Semaphore sem = new Semaphore(0);
|
||||
myPlatformFacade.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cancelCherryPick(repository);
|
||||
List<Change> changes = commit.getCommit().getChanges();
|
||||
CherryPickCommitExecutor executor = new CherryPickCommitExecutor(myProject, myPlatformFacade, changes, commitMessage);
|
||||
boolean commitNotCancelled = myPlatformFacade.getVcsHelper(myProject).commitChanges(changes, changeList, commitMessage, executor);
|
||||
boolean success = commitNotCancelled && !executor.hasCommitFailed();
|
||||
if (success) {
|
||||
commit.setActualSubject(getSubjectFromCommitMessage(executor.getActualCommitMessage()));
|
||||
try {
|
||||
cancelCherryPick(repository);
|
||||
List<Change> changes = commit.getCommit().getChanges();
|
||||
boolean commitNotCancelled = myPlatformFacade.getVcsHelper(myProject).commitChanges(changes, changeList, commitMessage,
|
||||
new CommitResultHandler() {
|
||||
@Override
|
||||
public void onSuccess(@NotNull String commitMessage) {
|
||||
commit.setActualSubject(commitMessage);
|
||||
commitSucceeded.set(true);
|
||||
sem.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure() {
|
||||
commitSucceeded.set(false);
|
||||
sem.release();
|
||||
}
|
||||
});
|
||||
|
||||
if (!commitNotCancelled) {
|
||||
commitSucceeded.set(false);
|
||||
sem.release();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOG.error(t);
|
||||
commitSucceeded.set(false);
|
||||
sem.release();
|
||||
}
|
||||
commitSucceeded.set(success);
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
return commitSucceeded.get();
|
||||
}
|
||||
|
||||
private static String getSubjectFromCommitMessage(String commitMessage) {
|
||||
int newLine = commitMessage.indexOf("\n");
|
||||
return newLine < 0 ? commitMessage : commitMessage.substring(0, newLine);
|
||||
// need additional waiting, because commitChanges is asynchronous
|
||||
try {
|
||||
sem.acquire();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
LOG.error(e);
|
||||
return false;
|
||||
}
|
||||
return commitSucceeded.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,7 +349,7 @@ public class GitCherryPicker {
|
||||
|
||||
@NotNull
|
||||
private static String commitDetails(@NotNull GitCommitWrapper commit) {
|
||||
return commit.getCommit().getShortHash().toString() + " \"" + commit.getSubject() + "\"";
|
||||
return commit.getCommit().getShortHash().toString() + " \"" + commit.getOriginalSubject() + "\"";
|
||||
}
|
||||
|
||||
private void refreshChangedFiles(@NotNull Collection<FilePath> filePaths) {
|
||||
@@ -347,9 +362,10 @@ public class GitCherryPicker {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LocalChangeList createChangeList(@NotNull List<Change> changes, @NotNull String commitMessage) {
|
||||
private LocalChangeList createChangeList(@NotNull GitCommit commit, @NotNull String commitMessage) {
|
||||
List<Change> changes = commit.getChanges();
|
||||
if (!changes.isEmpty()) {
|
||||
final LocalChangeList changeList = myChangeListManager.addChangeList(commitMessage, commitMessage);
|
||||
final LocalChangeList changeList = ((ChangeListManagerEx)myChangeListManager).addChangeList(commitMessage, commitMessage, commit);
|
||||
myChangeListManager.moveChangesTo(changeList, changes.toArray(new Change[changes.size()]));
|
||||
myChangeListManager.setDefaultChangeList(changeList);
|
||||
return changeList;
|
||||
@@ -451,142 +467,6 @@ public class GitCherryPicker {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Commit procedure is overridden by the executor with its own CommitSession.
|
||||
The reason of that is the asynchronous nature of the CommitHelper: it returns, we continue cherry-picking and occasionally pick
|
||||
the next commit in the queue, and only then Git is called for commit. Thus it commits two cherry-picks at once, which is wrong.
|
||||
|
||||
Here we call GitCheckinEnvironment manually
|
||||
*/
|
||||
private static class CherryPickCommitExecutor implements CommitExecutor {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final GitPlatformFacade myPlatformFacade;
|
||||
@NotNull private final List<Change> myChanges;
|
||||
@NotNull private final String myOriginalCommitMessage;
|
||||
private boolean myCommitFailed;
|
||||
|
||||
@Nullable private CherryPickCommitExecutor.CherryPickCommitSession myCommitSession;
|
||||
|
||||
CherryPickCommitExecutor(@NotNull Project project, @NotNull GitPlatformFacade platformFacade,
|
||||
@NotNull List<Change> changes, @NotNull String originalCommitMessage) {
|
||||
myProject = project;
|
||||
myPlatformFacade = platformFacade;
|
||||
myChanges = changes;
|
||||
myOriginalCommitMessage = originalCommitMessage;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@Override
|
||||
public String getActionText() {
|
||||
return "Commit";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CommitSession createCommitSession() {
|
||||
myCommitSession = new CherryPickCommitSession();
|
||||
return myCommitSession;
|
||||
}
|
||||
|
||||
public boolean hasCommitFailed() {
|
||||
return myCommitFailed;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getActualCommitMessage() {
|
||||
return myCommitSession == null ? myOriginalCommitMessage : myCommitSession.getActualCommitMessage();
|
||||
}
|
||||
|
||||
private class CherryPickCommitSession implements CommitSession {
|
||||
private String myActualCommitMessage;
|
||||
|
||||
@Override
|
||||
public JComponent getAdditionalConfigurationUI() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getAdditionalConfigurationUI(Collection<Change> changes, String commitMessage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute(Collection<Change> changes, String commitMessage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Collection<Change> changes, String commitMessage) {
|
||||
final Collection<Document> committingDocs = markCommittingDocs();
|
||||
try {
|
||||
GitCheckinEnvironment ce = ServiceManager.getService(myProject, GitCheckinEnvironment.class);
|
||||
try {
|
||||
ce.reset();
|
||||
List<VcsException> exceptions = ce.commit(myChanges, commitMessage);
|
||||
VcsDirtyScopeManager.getInstance(myProject).filePathsDirty(ChangesUtil.getPaths(myChanges), null);
|
||||
if (exceptions != null && !exceptions.isEmpty()) {
|
||||
VcsException exception = exceptions.get(0);
|
||||
handleError(exception);
|
||||
}
|
||||
myActualCommitMessage = commitMessage;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
handleError(e);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
unmarkCommittingDocs(committingDocs);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleError(Throwable exception) {
|
||||
myCommitFailed = true;
|
||||
final String errorMessage = exception.getMessage();
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showErrorDialog(myProject, errorMessage, "Commit Failed");
|
||||
}
|
||||
}, null, myProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executionCanceled() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void unmarkCommittingDocs(final Collection<Document> committingDocs) {
|
||||
myPlatformFacade.runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CommitHelper.unmarkCommittingDocuments(committingDocs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<Document> markCommittingDocs() {
|
||||
final Collection<Document> committingDocs = new ArrayList<Document>();
|
||||
myPlatformFacade.runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
committingDocs.addAll(CommitHelper.markCommittingDocuments(myProject, myChanges));
|
||||
}
|
||||
});
|
||||
return committingDocs;
|
||||
}
|
||||
|
||||
public String getActualCommitMessage() {
|
||||
return myActualCommitMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is needed to hold both the original GitCommit, and the commit message which could be changed by the user.
|
||||
* Only the subject of the commit message is needed.
|
||||
@@ -613,6 +493,10 @@ public class GitCherryPicker {
|
||||
public GitCommit getCommit() {
|
||||
return myOriginalCommit;
|
||||
}
|
||||
|
||||
public String getOriginalSubject() {
|
||||
return myOriginalCommit.getSubject();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.CommitExecutor;
|
||||
import com.intellij.openapi.vcs.changes.CommitResultHandler;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsHistoryProvider;
|
||||
@@ -171,8 +171,8 @@ public class HgMockVcsHelper extends AbstractVcsHelper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitChanges(@NotNull List<Change> changes, @NotNull LocalChangeList initialChangeList,
|
||||
@NotNull String commitMessage, @Nullable CommitExecutor executor) {
|
||||
public boolean commitChanges(@NotNull Collection<Change> changes, @NotNull LocalChangeList initialChangeList,
|
||||
@NotNull String commitMessage, @Nullable CommitResultHandler customResultHandler) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.maven.execution;
|
||||
|
||||
import com.intellij.execution.JUnitPatcher;
|
||||
import com.intellij.execution.configurations.JavaParameters;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.dom.MavenDomUtil;
|
||||
import org.jetbrains.idea.maven.dom.MavenPropertyResolver;
|
||||
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
|
||||
import org.jetbrains.idea.maven.project.MavenProject;
|
||||
import org.jetbrains.idea.maven.project.MavenProjectsManager;
|
||||
import org.jetbrains.idea.maven.utils.MavenJDOMUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Sergey Evdokimov
|
||||
*/
|
||||
public class MavenJUnitPatcher extends JUnitPatcher {
|
||||
|
||||
@Override
|
||||
public void patchJavaParameters(@Nullable Module module, JavaParameters javaParameters) {
|
||||
if (module == null) return;
|
||||
|
||||
MavenProject mavenProject = MavenProjectsManager.getInstance(module.getProject()).findProject(module);
|
||||
if (mavenProject == null) return;
|
||||
|
||||
Element config = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-surefire-plugin");
|
||||
List<String> paths = MavenJDOMUtil.findChildrenValuesByPath(config, "additionalClasspathElements", "additionalClasspathElement");
|
||||
|
||||
if (paths.isEmpty()) return;
|
||||
|
||||
MavenDomProjectModel domModel = MavenDomUtil.getMavenDomProjectModel(module.getProject(), mavenProject.getFile());;
|
||||
|
||||
for (String path : paths) {
|
||||
if (domModel != null) {
|
||||
path = MavenPropertyResolver.resolve(path, domModel);
|
||||
}
|
||||
|
||||
javaParameters.getClassPath().add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-55
@@ -220,65 +220,14 @@ public class MavenModuleImporter {
|
||||
}
|
||||
|
||||
private void configSurefirePlugin() {
|
||||
List<String> urls = new ArrayList<String>();
|
||||
|
||||
AccessToken accessToken = ReadAction.start();
|
||||
try {
|
||||
MavenDomProjectModel domModel = null;
|
||||
|
||||
Element config = myMavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-surefire-plugin");
|
||||
for (String each : MavenJDOMUtil.findChildrenValuesByPath(config, "additionalClasspathElements", "additionalClasspathElement")) {
|
||||
String url = VfsUtil.pathToUrl(each);
|
||||
|
||||
if (domModel == null) {
|
||||
domModel = MavenDomUtil.getMavenDomProjectModel(myModule.getProject(), myMavenProject.getFile());
|
||||
}
|
||||
|
||||
if (domModel != null) {
|
||||
url = MavenPropertyResolver.resolve(url, domModel);
|
||||
}
|
||||
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
}
|
||||
|
||||
// Remove "maven-surefire-plugin urls" library created by previous version of IDEA.
|
||||
// todo remove this code after 01.06.2013
|
||||
LibraryTable moduleLibraryTable = myRootModelAdapter.getRootModel().getModuleLibraryTable();
|
||||
|
||||
Library library = moduleLibraryTable.getLibraryByName(SUREFIRE_PLUGIN_LIBRARY_NAME);
|
||||
if (library == null) {
|
||||
if (urls.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
library = moduleLibraryTable.createLibrary(SUREFIRE_PLUGIN_LIBRARY_NAME);
|
||||
LibraryOrderEntry orderEntry = myRootModelAdapter.getRootModel().findLibraryOrderEntry(library);
|
||||
orderEntry.setScope(DependencyScope.TEST);
|
||||
if (library != null) {
|
||||
moduleLibraryTable.removeLibrary(library);
|
||||
}
|
||||
else {
|
||||
if (urls.isEmpty()) {
|
||||
moduleLibraryTable.removeLibrary(library);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String[] oldUrls = library.getUrls(OrderRootType.CLASSES);
|
||||
if (!urls.equals(Arrays.asList(oldUrls))) {
|
||||
Library.ModifiableModel modifiableModel = library.getModifiableModel();
|
||||
|
||||
for (String url : oldUrls) {
|
||||
modifiableModel.removeRoot(url, OrderRootType.CLASSES);
|
||||
}
|
||||
|
||||
for (String url : urls) {
|
||||
modifiableModel.addRoot(url, OrderRootType.CLASSES);
|
||||
}
|
||||
|
||||
modifiableModel.commit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addAttachArtifactDependency(@NotNull Element buildHelperCfg,
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
<configurationProducer implementation="org.jetbrains.idea.maven.execution.MavenConfigurationProducer"/>
|
||||
<orderEnumerationHandlerFactory implementation="org.jetbrains.idea.maven.execution.MavenOrderEnumeratorHandler$FactoryImpl"/>
|
||||
|
||||
<junitPatcher implementation="org.jetbrains.idea.maven.execution.MavenJUnitPatcher" />
|
||||
|
||||
<compiler implementation="org.jetbrains.idea.maven.compiler.MavenResourceCompiler" order="last"/>
|
||||
<compileServer.plugin classpath="jps/maven-jps-plugin.jar"/>
|
||||
|
||||
|
||||
+1
-1
@@ -774,7 +774,7 @@ public class MavenClasspathsAndSearchScopesTest extends MavenImportingTestCase {
|
||||
getProjectPath() + "/m3/target/classes");
|
||||
}
|
||||
|
||||
public void testAdditionalClasspathElementsInTests() throws Exception {
|
||||
public void _testAdditionalClasspathElementsInTests() throws Exception {
|
||||
File iof1 = new File(myDir, "foo/bar1");
|
||||
File iof2 = new File(myDir, "foo/bar2");
|
||||
iof1.mkdirs();
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.jetbrains.idea.svn;
|
||||
|
||||
import com.intellij.lifecycle.PeriodicalTasksCloser;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
@@ -74,6 +75,7 @@ public class StatusWalkerPartnerImpl implements StatusWalkerPartner {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
if (myVcs.getProject().isDisposed()) throw new ProcessCanceledException();
|
||||
return myExcludedFileIndex.isExcludedFile(vFile);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
@@ -91,7 +92,7 @@ public class SvnMapping {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getRootForPath(final String path) {
|
||||
public String getRootForPath(@NotNull final String path) {
|
||||
String floor = myFile2UrlMap.floorKey(path);
|
||||
if (floor == null) return null;
|
||||
NavigableMap<String, RootUrlInfo> head = myFile2UrlMap.headMap(floor, true);
|
||||
|
||||
Reference in New Issue
Block a user