Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Evgeny Pasynkov
2012-12-06 14:39:28 +01:00
52 changed files with 614 additions and 457 deletions
+2 -2
View File
@@ -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;
}
@@ -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);
}
@@ -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 {
@@ -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);
@@ -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();
@@ -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) {
@@ -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) {
@@ -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();
}
@@ -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);
}
}
}
@@ -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"/>
@@ -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);