mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
@@ -50,7 +50,8 @@ import com.intellij.execution.configurations.CommandLineState;
|
||||
import com.intellij.execution.configurations.RemoteConnection;
|
||||
import com.intellij.execution.configurations.RunProfile;
|
||||
import com.intellij.execution.configurations.RunProfileState;
|
||||
import com.intellij.execution.filters.ExceptionFilter;
|
||||
import com.intellij.execution.filters.ExceptionFilters;
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.filters.TextConsoleBuilder;
|
||||
import com.intellij.execution.process.ProcessAdapter;
|
||||
import com.intellij.execution.process.ProcessEvent;
|
||||
@@ -1669,7 +1670,10 @@ public abstract class DebugProcessImpl implements DebugProcess {
|
||||
if (state instanceof CommandLineState) {
|
||||
final TextConsoleBuilder consoleBuilder = ((CommandLineState)state).getConsoleBuilder();
|
||||
if (consoleBuilder != null) {
|
||||
consoleBuilder.addFilter(new ExceptionFilter(session.getSearchScope()));
|
||||
List<Filter> filters = ExceptionFilters.getFilters(session.getSearchScope());
|
||||
for (Filter filter : filters) {
|
||||
consoleBuilder.addFilter(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
myExecutionResult = state.execute(executor, runner);
|
||||
|
||||
@@ -33,7 +33,8 @@ import com.intellij.debugger.ui.impl.watch.*;
|
||||
import com.intellij.execution.*;
|
||||
import com.intellij.execution.configurations.RunProfile;
|
||||
import com.intellij.execution.executors.DefaultDebugExecutor;
|
||||
import com.intellij.execution.filters.ExceptionFilter;
|
||||
import com.intellij.execution.filters.ExceptionFilters;
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.filters.TextConsoleBuilder;
|
||||
import com.intellij.execution.filters.TextConsoleBuilderFactory;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
@@ -498,7 +499,10 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos
|
||||
public void addThreadDump(List<ThreadState> threads) {
|
||||
final Project project = getProject();
|
||||
final TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
|
||||
consoleBuilder.addFilter(new ExceptionFilter(myDebuggerSession.getSearchScope()));
|
||||
List<Filter> filters = ExceptionFilters.getFilters(myDebuggerSession.getSearchScope());
|
||||
for (Filter filter : filters) {
|
||||
consoleBuilder.addFilter(filter);
|
||||
}
|
||||
final ConsoleView consoleView = consoleBuilder.getConsole();
|
||||
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
|
||||
final ThreadDumpPanel panel = new ThreadDumpPanel(project, consoleView, toolbarActions, threads);
|
||||
|
||||
+6
-2
@@ -24,12 +24,16 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultConsoleFiltersProvider implements ConsoleFilterProviderEx {
|
||||
public Filter[] getDefaultFilters(@NotNull Project project) {
|
||||
return new Filter[]{new ExceptionFilter(project), new YourkitFilter(project)};
|
||||
return getDefaultFilters(project, GlobalSearchScope.allScope(project));
|
||||
}
|
||||
|
||||
public Filter[] getDefaultFilters(@NotNull Project project, @NotNull GlobalSearchScope scope) {
|
||||
return new Filter[]{new ExceptionFilter(scope), new YourkitFilter(project)};
|
||||
List<Filter> filters = ExceptionFilters.getFilters(scope);
|
||||
filters.add(new YourkitFilter(project));
|
||||
return filters.toArray(new Filter[filters.size()]);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.execution.filters;
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/8/11
|
||||
* Time: 12:11 PM
|
||||
*/
|
||||
public class ExceptionBaseFilterFactory implements ExceptionFilterFactory {
|
||||
@Override
|
||||
public Filter create(GlobalSearchScope searchScope) {
|
||||
return new ExceptionFilter(searchScope);
|
||||
}
|
||||
}
|
||||
@@ -15,135 +15,20 @@
|
||||
*/
|
||||
package com.intellij.execution.filters;
|
||||
|
||||
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.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class ExceptionFilter implements Filter, DumbAware {
|
||||
private final Project myProject;
|
||||
@NonNls private static final String AT = "at";
|
||||
private static final String AT_PREFIX = AT + " ";
|
||||
private static final String STANDALONE_AT = " " + AT + " ";
|
||||
private static final TextAttributes HYPERLINK_ATTRIBUTES = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES);
|
||||
private final GlobalSearchScope mySearchScope;
|
||||
|
||||
public ExceptionFilter(@NotNull final Project project) {
|
||||
myProject = project;
|
||||
mySearchScope = GlobalSearchScope.allScope(myProject);
|
||||
}
|
||||
private final GlobalSearchScope myScope;
|
||||
|
||||
public ExceptionFilter(@NotNull final GlobalSearchScope scope) {
|
||||
myProject = scope.getProject();
|
||||
mySearchScope = scope;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Trinity<String, String, TextRange> parseExceptionLine(final String line) {
|
||||
int atIndex;
|
||||
if (line.startsWith(AT_PREFIX)){
|
||||
atIndex = 0;
|
||||
}
|
||||
else{
|
||||
atIndex = line.indexOf(STANDALONE_AT);
|
||||
if (atIndex < 0) {
|
||||
atIndex = line.indexOf(AT_PREFIX);
|
||||
}
|
||||
if (atIndex < 0) return null;
|
||||
}
|
||||
|
||||
final int lparenthIndex = line.indexOf('(', atIndex);
|
||||
if (lparenthIndex < 0) return null;
|
||||
final int lastDotIndex = line.lastIndexOf('.', lparenthIndex);
|
||||
if (lastDotIndex < 0 || lastDotIndex < atIndex) return null;
|
||||
String className = line.substring(atIndex + AT.length() + 1, lastDotIndex).trim();
|
||||
|
||||
String methodName = line.substring(lastDotIndex + 1, lparenthIndex).trim();
|
||||
|
||||
final int rparenthIndex = line.indexOf(')', lparenthIndex);
|
||||
if (rparenthIndex < 0) return null;
|
||||
|
||||
return Trinity.create(className, methodName, new TextRange(lparenthIndex, rparenthIndex));
|
||||
myScope = scope;
|
||||
}
|
||||
|
||||
public Result applyFilter(final String line, final int textEndOffset) {
|
||||
final Trinity<String, String, TextRange> info = parseExceptionLine(line);
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String className = info.first;
|
||||
final int dollarIndex = className.indexOf('$');
|
||||
if (dollarIndex >= 0){
|
||||
className = className.substring(0, dollarIndex);
|
||||
}
|
||||
|
||||
final int lparenthIndex = info.third.getStartOffset();
|
||||
final int rparenthIndex = info.third.getEndOffset();
|
||||
final String fileAndLine = line.substring(lparenthIndex + 1, rparenthIndex).trim();
|
||||
|
||||
final int colonIndex = fileAndLine.lastIndexOf(':');
|
||||
if (colonIndex < 0) return null;
|
||||
|
||||
final String lineString = fileAndLine.substring(colonIndex + 1);
|
||||
try{
|
||||
final int lineNumber = Integer.parseInt(lineString);
|
||||
final PsiManager manager = PsiManager.getInstance(myProject);
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(manager.getProject());
|
||||
PsiClass aClass = psiFacade.findClass(className, mySearchScope);
|
||||
if (aClass == null) {
|
||||
aClass = psiFacade.findClass(className, GlobalSearchScope.allScope(myProject));
|
||||
if (aClass == null) {//try to find class according to all dollars in package name
|
||||
aClass = psiFacade.findClass(info.first, GlobalSearchScope.allScope(myProject));
|
||||
}
|
||||
if (aClass == null) return null;
|
||||
}
|
||||
final PsiFile file = (PsiFile) aClass.getContainingFile().getNavigationElement();
|
||||
if (file == null) return null;
|
||||
|
||||
/*
|
||||
IDEADEV-4976: Some scramblers put something like SourceFile mock instead of real class name.
|
||||
final String filePath = fileAndLine.substring(0, colonIndex).replace('/', File.separatorChar);
|
||||
final int slashIndex = filePath.lastIndexOf(File.separatorChar);
|
||||
final String shortFileName = slashIndex < 0 ? filePath : filePath.substring(slashIndex + 1);
|
||||
if (!file.getName().equalsIgnoreCase(shortFileName)) return null;
|
||||
*/
|
||||
|
||||
final int textStartOffset = textEndOffset - line.length();
|
||||
|
||||
final int highlightStartOffset = textStartOffset + lparenthIndex + 1;
|
||||
final int highlightEndOffset = textStartOffset + rparenthIndex;
|
||||
VirtualFile virtualFile = file.getVirtualFile();
|
||||
final OpenFileHyperlinkInfo linkInfo = new OpenFileHyperlinkInfo(myProject, virtualFile, lineNumber - 1);
|
||||
TextAttributes attributes = HYPERLINK_ATTRIBUTES.clone();
|
||||
if (!ProjectRootManager.getInstance(myProject).getFileIndex().isInContent(virtualFile)) {
|
||||
Color color = UIUtil.getInactiveTextColor();
|
||||
attributes.setForegroundColor(color);
|
||||
attributes.setEffectColor(color);
|
||||
}
|
||||
return new Result(highlightStartOffset, highlightEndOffset, linkInfo, attributes);
|
||||
}
|
||||
catch(NumberFormatException e){
|
||||
return null;
|
||||
}
|
||||
ExceptionWorker worker = new ExceptionWorker(myScope.getProject(), myScope);
|
||||
worker.execute(line, textEndOffset);
|
||||
return worker.getResult();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.execution.filters;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/5/11
|
||||
* Time: 7:46 PM
|
||||
*/
|
||||
public interface ExceptionFilterFactory {
|
||||
ExtensionPointName<ExceptionFilterFactory> EP_NAME = ExtensionPointName.create("com.intellij.exceptionFilter");
|
||||
|
||||
Filter create(final GlobalSearchScope searchScope);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.execution.filters;
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/5/11
|
||||
* Time: 7:54 PM
|
||||
*/
|
||||
public class ExceptionFilters {
|
||||
private ExceptionFilters() {
|
||||
}
|
||||
|
||||
public static List<Filter> getFilters(final GlobalSearchScope searchScope) {
|
||||
List<Filter> filters = new ArrayList<Filter>();
|
||||
ExceptionFilterFactory[] extensions = ExceptionFilterFactory.EP_NAME.getExtensions();
|
||||
for (ExceptionFilterFactory extension : extensions) {
|
||||
filters.add(extension.create(searchScope));
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
}
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.contentAnnotation;
|
||||
|
||||
import com.intellij.execution.filters.ExceptionWorker;
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.filters.FilterMixin;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.DiffColors;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.localVcs.UpToDateLineNumberProvider;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.impl.UpToDateLineNumberProviderImpl;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/5/11
|
||||
* Time: 8:39 PM
|
||||
*/
|
||||
public class VcsContentAnnotationExceptionFilter implements Filter, FilterMixin {
|
||||
private final Project myProject;
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationExceptionFilter");
|
||||
private final GlobalSearchScope myScope;
|
||||
|
||||
public VcsContentAnnotationExceptionFilter(GlobalSearchScope scope) {
|
||||
myScope = scope;
|
||||
myProject = scope.getProject();
|
||||
}
|
||||
|
||||
private static class MyAdditionalHighlight extends AdditionalHighlight {
|
||||
private MyAdditionalHighlight(int start, int end) {
|
||||
super(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextAttributes getTextAttributes(@Nullable TextAttributes source) {
|
||||
EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
final TextAttributes changedColor = globalScheme.getAttributes(DiffColors.DIFF_MODIFIED);
|
||||
if (source == null) {
|
||||
TextAttributes atts =
|
||||
globalScheme.getAttributes(CodeInsightColors.CLASS_NAME_ATTRIBUTES).clone();
|
||||
atts.setBackgroundColor(changedColor.getBackgroundColor());
|
||||
return atts;
|
||||
}
|
||||
TextAttributes clone = source.clone();
|
||||
clone.setBackgroundColor(changedColor.getBackgroundColor());
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyHeavyFilter(final Document copiedFragment,
|
||||
int startOffset,
|
||||
int startLineNumber,
|
||||
Consumer<AdditionalHighlight> consumer) {
|
||||
VcsContentAnnotation vcsContentAnnotation = VcsContentAnnotationImpl.getInstance(myProject);
|
||||
final LocalChangesCorrector localChangesCorrector = new LocalChangesCorrector(myProject);
|
||||
Trinity<PsiClass, PsiFile, String> previousLineResult = null;
|
||||
|
||||
for (int i = 0; i < copiedFragment.getLineCount(); i++) {
|
||||
final int lineStartOffset = copiedFragment.getLineStartOffset(i);
|
||||
final int lineEndOffset = copiedFragment.getLineEndOffset(i);
|
||||
final ExceptionWorker worker = new ExceptionWorker(myProject, myScope);
|
||||
final String[] lineText = new String[1];
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
lineText[0] = copiedFragment.getText(new TextRange(lineStartOffset, lineEndOffset));
|
||||
worker.execute(lineText[0], lineEndOffset);
|
||||
}
|
||||
});
|
||||
if (worker.getResult() != null) {
|
||||
VirtualFile vf = worker.getFile().getVirtualFile();
|
||||
if (localChangesCorrector.isFileAlreadyIdentifiedAsChanged(vf) || ChangeListManager.isFileChanged(myProject, vf) ||
|
||||
vcsContentAnnotation.fileRecentlyChanged(vf)) {
|
||||
final Document document = getDocumentForFile(worker);
|
||||
if (document == null) return;
|
||||
|
||||
int startFileOffset = worker.getInfo().getThird().getStartOffset();
|
||||
int idx = lineText[0].indexOf(':', startFileOffset);
|
||||
int endIdx = idx == -1 ? worker.getInfo().getThird().getEndOffset() : idx;
|
||||
consumer.consume(new MyAdditionalHighlight(startOffset + lineStartOffset + startFileOffset + 1, startOffset + lineStartOffset + endIdx));
|
||||
|
||||
// also check method
|
||||
final List<TextRange> ranges = findMethodRange(worker, document, previousLineResult);
|
||||
if (ranges != null) {
|
||||
boolean methodChanged = false;
|
||||
for (TextRange range : ranges) {
|
||||
if (localChangesCorrector.isRangeChangedLocally(vf, document, range)) {
|
||||
methodChanged = true;
|
||||
break;
|
||||
}
|
||||
final TextRange correctedRange = localChangesCorrector.getCorrectedRange(vf, document, range);
|
||||
if (vcsContentAnnotation.intervalRecentlyChanged(vf, correctedRange)) {
|
||||
methodChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (methodChanged) {
|
||||
consumer.consume(new MyAdditionalHighlight(startOffset + lineStartOffset + worker.getInfo().getSecond().getStartOffset(),
|
||||
startOffset + lineStartOffset + worker.getInfo().getSecond().getEndOffset()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
previousLineResult = worker.getResult() == null ? null :
|
||||
new Trinity<PsiClass, PsiFile, String>(worker.getPsiClass(), worker.getFile(), worker.getMethod());
|
||||
}
|
||||
}
|
||||
|
||||
private static class LocalChangesCorrector {
|
||||
private final Map<VirtualFile, UpToDateLineNumberProvider> myRecentlyChanged;
|
||||
private final Project myProject;
|
||||
|
||||
private LocalChangesCorrector(final Project project) {
|
||||
myProject = project;
|
||||
myRecentlyChanged = new HashMap<VirtualFile, UpToDateLineNumberProvider>();
|
||||
}
|
||||
|
||||
public boolean isFileAlreadyIdentifiedAsChanged(final VirtualFile vf) {
|
||||
return myRecentlyChanged.containsKey(vf);
|
||||
}
|
||||
|
||||
public boolean isRangeChangedLocally(final VirtualFile vf, final Document document, final TextRange range) {
|
||||
final UpToDateLineNumberProvider provider = getProvider(vf, document);
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return provider.isRangeChanged(range.getStartOffset(), range.getEndOffset());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public TextRange getCorrectedRange(final VirtualFile vf, final Document document, final TextRange range) {
|
||||
final UpToDateLineNumberProvider provider = getProvider(vf, document);
|
||||
if (provider == null) return range;
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<TextRange>() {
|
||||
@Override
|
||||
public TextRange compute() {
|
||||
return new TextRange(provider.getLineNumber(range.getStartOffset()), provider.getLineNumber(range.getEndOffset()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private UpToDateLineNumberProvider getProvider(VirtualFile vf, Document document) {
|
||||
UpToDateLineNumberProvider provider = myRecentlyChanged.get(vf);
|
||||
if (provider == null) {
|
||||
provider = new UpToDateLineNumberProviderImpl(document, myProject);
|
||||
myRecentlyChanged.put(vf, provider);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
|
||||
private Document getDocumentForFile(final ExceptionWorker worker) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Document>() {
|
||||
@Override
|
||||
public Document compute() {
|
||||
final Document document = FileDocumentManager.getInstance().getDocument(worker.getFile().getVirtualFile());
|
||||
if (document == null) {
|
||||
LOG.info("can not get document for file: " + worker.getFile().getVirtualFile());
|
||||
return null;
|
||||
}
|
||||
return document;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* final UpToDateLineNumberProvider getUpToDateLineNumber = new UpToDateLineNumberProviderImpl(editor.getDocument(), project, upToDateContent);
|
||||
/**/
|
||||
|
||||
// line numbers
|
||||
private List<TextRange> findMethodRange(final ExceptionWorker worker, final Document document, final Trinity<PsiClass, PsiFile, String> previousLineResult) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<List<TextRange>>() {
|
||||
@Override
|
||||
public List<TextRange> compute() {
|
||||
List<TextRange> ranges = getTextRangeForMethod(worker, previousLineResult);
|
||||
if (ranges == null) return null;
|
||||
final List<TextRange> result = new ArrayList<TextRange>();
|
||||
for (TextRange range : ranges) {
|
||||
result.add(new TextRange(document.getLineNumber(range.getStartOffset()),
|
||||
document.getLineNumber(range.getEndOffset())));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// null - check all
|
||||
@Nullable
|
||||
private List<PsiMethod> selectMethod(final PsiMethod[] methods, final Trinity<PsiClass, PsiFile, String> previousLineResult) {
|
||||
if (previousLineResult == null || previousLineResult.getThird() == null) return null;
|
||||
|
||||
final List<PsiMethod> result = new SmartList<PsiMethod>();
|
||||
for (final PsiMethod method : methods) {
|
||||
method.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitCallExpression(PsiCallExpression callExpression) {
|
||||
final PsiMethod resolved = callExpression.resolveMethod();
|
||||
if (resolved != null) {
|
||||
if (resolved.getName().equals(previousLineResult.getThird())) {
|
||||
result.add(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<TextRange> getTextRangeForMethod(final ExceptionWorker worker, Trinity<PsiClass, PsiFile, String> previousLineResult) {
|
||||
String method = worker.getMethod();
|
||||
PsiClass psiClass = worker.getPsiClass();
|
||||
PsiMethod[] methods;
|
||||
if (method.contains("<init>")) {
|
||||
// constructor
|
||||
methods = psiClass.getConstructors();
|
||||
} else if (method.contains("$")) {
|
||||
// access$100
|
||||
return null;
|
||||
} else {
|
||||
methods = psiClass.findMethodsByName(method, false);
|
||||
}
|
||||
if (methods.length > 0) {
|
||||
if (methods.length == 1) {
|
||||
final TextRange range = methods[0].getTextRange();
|
||||
return Collections.singletonList(range);
|
||||
} else {
|
||||
List<PsiMethod> selectedMethods = selectMethod(methods, previousLineResult);
|
||||
final List<PsiMethod> toIterate = selectedMethods == null ? Arrays.asList(methods) : selectedMethods;
|
||||
final List<TextRange> result = new ArrayList<TextRange>();
|
||||
for (PsiMethod psiMethod : toIterate) {
|
||||
result.add(psiMethod.getTextRange());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result applyFilter(String line, int entireLength) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.contentAnnotation;
|
||||
|
||||
import com.intellij.execution.filters.ExceptionFilterFactory;
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/5/11
|
||||
* Time: 8:03 PM
|
||||
*/
|
||||
public class VcsContentAnnotationExceptionFilterFactory implements ExceptionFilterFactory {
|
||||
@Override
|
||||
public Filter create(GlobalSearchScope searchScope) {
|
||||
return new VcsContentAnnotationExceptionFilter(searchScope);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,8 @@ public class ThreadDumpPanel extends JPanel {
|
||||
});
|
||||
toolbarActions.add(new CopyToClipboardAction(threadDump, project));
|
||||
toolbarActions.add(new SortThreadsAction());
|
||||
add(ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions,false).getComponent(), BorderLayout.WEST);
|
||||
//toolbarActions.add(new ShowRecentlyChanged());
|
||||
add(ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false).getComponent(), BorderLayout.WEST);
|
||||
|
||||
final Splitter splitter = new Splitter(false, 0.3f);
|
||||
splitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myThreadList));
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.execution.filters;
|
||||
|
||||
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.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/5/11
|
||||
* Time: 8:36 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class ExceptionWorker {
|
||||
@NonNls private static final String AT = "at";
|
||||
private static final String AT_PREFIX = AT + " ";
|
||||
private static final String STANDALONE_AT = " " + AT + " ";
|
||||
|
||||
private static final TextAttributes HYPERLINK_ATTRIBUTES = EditorColorsManager
|
||||
.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES);
|
||||
|
||||
private final Project myProject;
|
||||
private final GlobalSearchScope mySearchScope;
|
||||
private Filter.Result myResult;
|
||||
private PsiClass myClass;
|
||||
private PsiFile myFile;
|
||||
private String myMethod;
|
||||
private Trinity<TextRange,TextRange,TextRange> myInfo;
|
||||
|
||||
public ExceptionWorker(Project project, final GlobalSearchScope searchScope) {
|
||||
myProject = project;
|
||||
mySearchScope = searchScope;
|
||||
}
|
||||
|
||||
public void execute(final String line, final int textEndOffset) {
|
||||
myInfo = parseExceptionLine(line);
|
||||
if (myInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
myMethod = myInfo.getSecond().substring(line);
|
||||
String className = myInfo.first.substring(line).trim();
|
||||
final int dollarIndex = className.indexOf('$');
|
||||
if (dollarIndex >= 0){
|
||||
className = className.substring(0, dollarIndex);
|
||||
}
|
||||
|
||||
final int lparenthIndex = myInfo.third.getStartOffset();
|
||||
final int rparenthIndex = myInfo.third.getEndOffset();
|
||||
final String fileAndLine = line.substring(lparenthIndex + 1, rparenthIndex).trim();
|
||||
|
||||
final int colonIndex = fileAndLine.lastIndexOf(':');
|
||||
if (colonIndex < 0) return;
|
||||
|
||||
final String lineString = fileAndLine.substring(colonIndex + 1);
|
||||
try{
|
||||
final int lineNumber = Integer.parseInt(lineString);
|
||||
final PsiManager manager = PsiManager.getInstance(myProject);
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(manager.getProject());
|
||||
myClass = psiFacade.findClass(className, mySearchScope);
|
||||
if (myClass == null) {
|
||||
myClass = psiFacade.findClass(className, GlobalSearchScope.allScope(myProject));
|
||||
if (myClass == null) {//try to find class according to all dollars in package name
|
||||
myClass = psiFacade.findClass(className, GlobalSearchScope.allScope(myProject));
|
||||
}
|
||||
if (myClass == null) return;
|
||||
}
|
||||
myFile = (PsiFile) myClass.getContainingFile().getNavigationElement();
|
||||
if (myFile == null) return;
|
||||
|
||||
/*
|
||||
IDEADEV-4976: Some scramblers put something like SourceFile mock instead of real class name.
|
||||
final String filePath = fileAndLine.substring(0, colonIndex).replace('/', File.separatorChar);
|
||||
final int slashIndex = filePath.lastIndexOf(File.separatorChar);
|
||||
final String shortFileName = slashIndex < 0 ? filePath : filePath.substring(slashIndex + 1);
|
||||
if (!file.getName().equalsIgnoreCase(shortFileName)) return null;
|
||||
*/
|
||||
|
||||
final int textStartOffset = textEndOffset - line.length();
|
||||
|
||||
final int highlightStartOffset = textStartOffset + lparenthIndex + 1;
|
||||
final int highlightEndOffset = textStartOffset + rparenthIndex;
|
||||
VirtualFile virtualFile = myFile.getVirtualFile();
|
||||
final OpenFileHyperlinkInfo linkInfo = new OpenFileHyperlinkInfo(myProject, virtualFile, lineNumber - 1);
|
||||
TextAttributes attributes = HYPERLINK_ATTRIBUTES.clone();
|
||||
if (!ProjectRootManager.getInstance(myProject).getFileIndex().isInContent(virtualFile)) {
|
||||
Color color = UIUtil.getInactiveTextColor();
|
||||
attributes.setForegroundColor(color);
|
||||
attributes.setEffectColor(color);
|
||||
}
|
||||
myResult = new Filter.Result(highlightStartOffset, highlightEndOffset, linkInfo, attributes);
|
||||
}
|
||||
catch(NumberFormatException e){
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
public Filter.Result getResult() {
|
||||
return myResult;
|
||||
}
|
||||
|
||||
public PsiClass getPsiClass() {
|
||||
return myClass;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return myMethod;
|
||||
}
|
||||
|
||||
public PsiFile getFile() {
|
||||
return myFile;
|
||||
}
|
||||
|
||||
public Trinity<TextRange, TextRange, TextRange> getInfo() {
|
||||
return myInfo;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Trinity<TextRange, TextRange, TextRange> parseExceptionLine(final String line) {
|
||||
int atIndex;
|
||||
if (line.startsWith(AT_PREFIX)){
|
||||
atIndex = 0;
|
||||
}
|
||||
else{
|
||||
atIndex = line.indexOf(STANDALONE_AT);
|
||||
if (atIndex < 0) {
|
||||
atIndex = line.indexOf(AT_PREFIX);
|
||||
}
|
||||
if (atIndex < 0) return null;
|
||||
}
|
||||
|
||||
final int lparenthIndex = line.indexOf('(', atIndex);
|
||||
if (lparenthIndex < 0) return null;
|
||||
final int lastDotIndex = line.lastIndexOf('.', lparenthIndex);
|
||||
if (lastDotIndex < 0 || lastDotIndex < atIndex) return null;
|
||||
|
||||
final int rparenthIndex = line.indexOf(')', lparenthIndex);
|
||||
if (rparenthIndex < 0) return null;
|
||||
|
||||
// class, method, link
|
||||
return Trinity.create(adjustedRange(line, atIndex + AT.length() + 1, lastDotIndex),
|
||||
adjustedRange(line, lastDotIndex + 1, lparenthIndex), new TextRange(lparenthIndex, rparenthIndex));
|
||||
}
|
||||
|
||||
private static TextRange adjustedRange(final String line, final int start, final int end) {
|
||||
String sub = line.substring(start, end);
|
||||
return new TextRange(start, end - spacesEnd(sub));
|
||||
}
|
||||
|
||||
private static int spacesStart(final String s) {
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
final char c = s.charAt(i);
|
||||
if (! Character.isSpaceChar(c)) return cnt;
|
||||
++ cnt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
private static int spacesEnd(final String s) {
|
||||
int cnt = 0;
|
||||
for (int i = s.length() - 1; i >= 0; i--) {
|
||||
final char c = s.charAt(i);
|
||||
if (! Character.isSpaceChar(c)) return cnt;
|
||||
++ cnt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -15,15 +15,18 @@
|
||||
*/
|
||||
package com.intellij.execution.filters;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CompositeFilter implements Filter {
|
||||
public class CompositeFilter implements Filter, FilterMixin {
|
||||
private final List<Filter> myFilters = new ArrayList<Filter>();
|
||||
private boolean myIsAnyHeavy;
|
||||
private final DumbService myDumbService;
|
||||
|
||||
public CompositeFilter(Project project) {
|
||||
@@ -48,11 +51,34 @@ public class CompositeFilter implements Filter {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyHeavyFilter(Document copiedFragment,
|
||||
int startOffset,
|
||||
int startLineNumber,
|
||||
Consumer<AdditionalHighlight> consumer) {
|
||||
final boolean dumb = myDumbService.isDumb();
|
||||
List<Filter> filters = myFilters;
|
||||
int count = filters.size();
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < count; i++) {
|
||||
Filter filter = filters.get(i);
|
||||
if (! (filter instanceof FilterMixin)) continue;
|
||||
if (!dumb || DumbService.isDumbAware(filter)) {
|
||||
((FilterMixin) filter).applyHeavyFilter(copiedFragment, startOffset, startLineNumber, consumer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return myFilters.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isAnyHeavy() {
|
||||
return myIsAnyHeavy;
|
||||
}
|
||||
|
||||
public void addFilter(final Filter filter) {
|
||||
myFilters.add(filter);
|
||||
myIsAnyHeavy |= filter instanceof FilterMixin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ public interface Filter {
|
||||
/**
|
||||
* Filters line by creating an instance of {@link Result}.
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
* The line to be filtered. Note that the line must contain a line
|
||||
* separator at the end.
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.execution.filters;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/3/11
|
||||
* Time: 4:50 PM
|
||||
*/
|
||||
public interface FilterMixin {
|
||||
@Nullable
|
||||
void applyHeavyFilter(Document copiedFragment, int startOffset, int startLineNumber, Consumer<AdditionalHighlight> consumer);
|
||||
|
||||
abstract class AdditionalHighlight {
|
||||
private final int myStart;
|
||||
private final int myEnd;
|
||||
|
||||
public AdditionalHighlight(int start, int end) {
|
||||
myStart = start;
|
||||
myEnd = end;
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return myStart;
|
||||
}
|
||||
|
||||
public int getEnd() {
|
||||
return myEnd;
|
||||
}
|
||||
|
||||
public abstract TextAttributes getTextAttributes(@Nullable final TextAttributes source);
|
||||
}
|
||||
}
|
||||
@@ -41,11 +41,11 @@ import com.intellij.openapi.editor.actions.ToggleUseSoftWrapsToolbarAction;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.event.*;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.FoldingModelEx;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterClient;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
|
||||
import com.intellij.openapi.editor.markup.HighlighterLayer;
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
||||
@@ -60,10 +60,7 @@ import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.LineTokenizer;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -91,7 +88,7 @@ import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableConsoleView, DataProvider, OccurenceNavigator {
|
||||
public class ConsoleViewImpl implements ConsoleView, ObservableConsoleView, DataProvider, OccurenceNavigator {
|
||||
@NonNls private static final String CONSOLE_VIEW_POPUP_MENU = "ConsoleView.PopupMenu";
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.ConsoleViewImpl");
|
||||
|
||||
@@ -115,12 +112,17 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
private Computable<ModalityState> myStateForUpdate;
|
||||
|
||||
private final Alarm mySpareTimeAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this);
|
||||
@Nullable
|
||||
private final Alarm myHeavyAlarm;
|
||||
|
||||
private final CopyOnWriteArraySet<ChangeListener> myListeners = new CopyOnWriteArraySet<ChangeListener>();
|
||||
private final ArrayList<AnAction> customActions = new ArrayList<AnAction>();
|
||||
private final ConsoleBuffer myBuffer = new ConsoleBuffer();
|
||||
private boolean myUpdateFoldingsEnabled = true;
|
||||
private EditorHyperlinkSupport myHyperlinks;
|
||||
private MyDiffContainer myJLayeredPane;
|
||||
private JPanel myMainPanel;
|
||||
private final Runnable myFinishProgress;
|
||||
|
||||
@TestOnly
|
||||
public Editor getEditor() {
|
||||
@@ -272,7 +274,6 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
|
||||
protected ConsoleViewImpl(final Project project, GlobalSearchScope searchScope, boolean viewer, FileType fileType,
|
||||
@NotNull final ConsoleState initialState) {
|
||||
super(new BorderLayout());
|
||||
isViewer = viewer;
|
||||
myState = initialState;
|
||||
myPsiDisposedCheck = new DisposedPsiManagerCheck(project);
|
||||
@@ -289,8 +290,19 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
myPredefinedMessageFilter.addFilter(filter);
|
||||
}
|
||||
}
|
||||
if (myPredefinedMessageFilter.isAnyHeavy()) {
|
||||
myHeavyAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, this);
|
||||
} else {
|
||||
myHeavyAlarm = null;
|
||||
}
|
||||
|
||||
Disposer.register(project, this);
|
||||
myFinishProgress = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myJLayeredPane.finishUpdating();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void attachToProcess(final ProcessHandler processHandler) {
|
||||
@@ -368,17 +380,27 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
}
|
||||
},
|
||||
100,
|
||||
ModalityState.stateForComponent(this)
|
||||
ModalityState.stateForComponent(myJLayeredPane)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void addToolbar(JComponent component, String constraint) {
|
||||
myMainPanel.add(component, constraint);
|
||||
}
|
||||
|
||||
public JComponent getComponent() {
|
||||
if (myMainPanel == null) {
|
||||
myMainPanel = new JPanel(new BorderLayout());
|
||||
myJLayeredPane = new MyDiffContainer(myMainPanel, "Checking recent changes...");
|
||||
}
|
||||
|
||||
if (myEditor == null) {
|
||||
myEditor = createEditor();
|
||||
myHyperlinks = new EditorHyperlinkSupport(myEditor, myProject);
|
||||
requestFlushImmediately();
|
||||
add(createCenterComponent(), BorderLayout.CENTER);
|
||||
myMainPanel.add(createCenterComponent(), BorderLayout.CENTER);
|
||||
|
||||
|
||||
myEditor.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
@@ -412,7 +434,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
}
|
||||
});
|
||||
}
|
||||
return this;
|
||||
return myJLayeredPane;
|
||||
}
|
||||
|
||||
protected JComponent createCenterComponent() {
|
||||
@@ -436,6 +458,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
myEditor = null;
|
||||
myHyperlinks = null;
|
||||
}
|
||||
myJLayeredPane.dispose();
|
||||
}
|
||||
|
||||
protected void disposeEditor() {
|
||||
@@ -476,7 +499,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
}
|
||||
|
||||
private ModalityState getStateForUpdate() {
|
||||
return myStateForUpdate != null ? myStateForUpdate.compute() : ModalityState.stateForComponent(this);
|
||||
return myStateForUpdate != null ? myStateForUpdate.compute() : ModalityState.stateForComponent(myJLayeredPane);
|
||||
}
|
||||
|
||||
private void requestFlushImmediately() {
|
||||
@@ -789,6 +812,43 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
if (canHighlightHyperlinks) {
|
||||
myHyperlinks.highlightHyperlinks(myCustomFilter, myPredefinedMessageFilter, line1, endLine);
|
||||
}
|
||||
|
||||
if (myPredefinedMessageFilter.isAnyHeavy()) {
|
||||
final int startLine = Math.max(0, line1);
|
||||
|
||||
final Document document = getEditor().getDocument();
|
||||
final Document documentCopy = new DocumentImpl(true);
|
||||
final int startOffset = document.getLineStartOffset(startLine);
|
||||
documentCopy.setText(new String(document.getText(new TextRange(startOffset, document.getLineEndOffset(endLine)))));
|
||||
documentCopy.setReadOnly(true);
|
||||
|
||||
myJLayeredPane.startUpdating();
|
||||
myHeavyAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myPredefinedMessageFilter.applyHeavyFilter(documentCopy, startOffset, startLine, new Consumer<FilterMixin.AdditionalHighlight>() {
|
||||
@Override
|
||||
public void consume(final FilterMixin.AdditionalHighlight additionalHighlight) {
|
||||
SwingUtilities.invokeLater(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myFlushAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myHyperlinks.adjustHighlighters(Collections.singletonList(additionalHighlight));
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (myHeavyAlarm.getActiveRequestCount() == 0) {
|
||||
SwingUtilities.invokeLater(myFinishProgress);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
if (myUpdateFoldingsEnabled) {
|
||||
updateFoldings(line1, endLine, true);
|
||||
}
|
||||
@@ -1066,7 +1126,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
s = (String)content.getTransferData(DataFlavor.stringFlavor);
|
||||
}
|
||||
catch (Exception e) {
|
||||
consoleView.getToolkit().beep();
|
||||
consoleView.getComponent().getToolkit().beep();
|
||||
}
|
||||
if (s == null) return;
|
||||
Editor editor = consoleView.myEditor;
|
||||
@@ -1279,6 +1339,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
consoleActions[1] = nextAction;
|
||||
consoleActions[2] = switchSoftWrapsAction;
|
||||
consoleActions[3] = autoScrollToTheEndAction;
|
||||
//consoleActions[4] = new ShowRecentlyChanged();
|
||||
for (int i = 0; i < customActions.size(); ++i) {
|
||||
consoleActions[i + 4] = customActions.get(i);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.execution.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.util.ui.AbstractLayoutManager;
|
||||
import com.intellij.util.ui.AnimatedIcon;
|
||||
import com.intellij.util.ui.AsyncProcessIcon;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* @author amakeev
|
||||
* @author Irina.Chernushina
|
||||
* Date: 8/8/11
|
||||
* Time: 3:13 PM
|
||||
*/
|
||||
public class MyDiffContainer extends JLayeredPane implements Disposable {
|
||||
private AnimatedIcon myIcon = new AsyncProcessIcon(this.getClass().getName());
|
||||
|
||||
private JComponent myContent;
|
||||
private JComponent myLoadingPanel;
|
||||
private final JLabel myJLabel;
|
||||
|
||||
public MyDiffContainer(JComponent content, final String text) {
|
||||
setLayout(new MyOverlayLayout());
|
||||
myContent = content;
|
||||
myLoadingPanel = new JPanel(new MyPanelLayout());
|
||||
myLoadingPanel.setOpaque(false);
|
||||
myLoadingPanel.add(myIcon);
|
||||
myJLabel = new JLabel(text);
|
||||
myJLabel.setForeground(UIUtil.getInactiveTextColor());
|
||||
myLoadingPanel.add(myJLabel);
|
||||
|
||||
add(myContent);
|
||||
add(myLoadingPanel, JLayeredPane.POPUP_LAYER);
|
||||
|
||||
finishUpdating();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
myIcon.dispose();
|
||||
}
|
||||
|
||||
public void startUpdating() {
|
||||
myLoadingPanel.setVisible(true);
|
||||
myIcon.resume();
|
||||
}
|
||||
|
||||
public void finishUpdating() {
|
||||
myIcon.suspend();
|
||||
myLoadingPanel.setVisible(false);
|
||||
}
|
||||
|
||||
private class MyOverlayLayout extends AbstractLayoutManager {
|
||||
public void layoutContainer(Container parent) {
|
||||
myContent.setBounds(0, 0, getWidth(), getHeight());
|
||||
myLoadingPanel.setBounds(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
return myContent.getPreferredSize();
|
||||
}
|
||||
}
|
||||
|
||||
private class MyPanelLayout extends AbstractLayoutManager {
|
||||
public void layoutContainer(Container parent) {
|
||||
Dimension size = myIcon.getPreferredSize();
|
||||
Dimension preferredSize = myJLabel.getPreferredSize();
|
||||
int width = getWidth();
|
||||
int offset = width - size.width - 15 - preferredSize.width;
|
||||
myIcon.setBounds(offset, 0, size.width, size.height);
|
||||
myJLabel.setBounds(offset + size.width + 3, 0, preferredSize.width, size.height);
|
||||
}
|
||||
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
return myContent.getPreferredSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.unscramble;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
|
||||
import com.intellij.openapi.vcs.configurable.VcsContentAnnotationConfigurable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/4/11
|
||||
* Time: 2:29 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class ShowRecentlyChanged extends DumbAwareAction {
|
||||
public ShowRecentlyChanged() {
|
||||
super("Show recently changed", "Show recently changed", IconLoader.getIcon("/general/copy.png"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (! enabled(e)) return;
|
||||
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
|
||||
VcsContentAnnotationConfigurable configurable = new VcsContentAnnotationConfigurable(project);
|
||||
ShowSettingsUtil.getInstance().editConfigurable(project, configurable);
|
||||
// todo recalculate highlight
|
||||
}
|
||||
|
||||
private boolean enabled(AnActionEvent e) {
|
||||
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
|
||||
if (project == null) return false;
|
||||
ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project);
|
||||
if (! vcsManager.hasActiveVcss()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(enabled(e));
|
||||
}
|
||||
}
|
||||
@@ -258,16 +258,4 @@ public class LoadingDecorator {
|
||||
frame.setBounds(300, 300, 300, 300);
|
||||
frame.show();
|
||||
}
|
||||
|
||||
|
||||
private static class MyLayeredPane extends JLayeredPane {
|
||||
@Override
|
||||
public void doLayout() {
|
||||
super.doLayout();
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
final Component each = getComponent(i);
|
||||
each.setBounds(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.ui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/4/11
|
||||
* Time: 3:59 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class MyLayeredPane extends JLayeredPane {
|
||||
@Override
|
||||
public void doLayout() {
|
||||
super.doLayout();
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
final Component each = getComponent(i);
|
||||
if (each instanceof Icon) {
|
||||
each.setBounds(0, 0, each.getWidth(), each.getHeight());
|
||||
} else {
|
||||
each.setBounds(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class SimpleColoredComponent extends JComponent implements Accessible {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.SimpleColoredComponent");
|
||||
public static final Color STYLE_SEARCH_MATCH_BACKGROUND = new Color(250, 250, 250, 140);
|
||||
|
||||
private final ArrayList<String> myFragments;
|
||||
private final ArrayList<SimpleTextAttributes> myAttributes;
|
||||
@@ -439,7 +440,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
|
||||
|
||||
if (!attributes.isSearchMatch()) {
|
||||
if (shouldDrawMacShadow()) {
|
||||
g.setColor(new Color(250, 250, 250, 140));
|
||||
g.setColor(STYLE_SEARCH_MATCH_BACKGROUND);
|
||||
g.drawString(fragment, xOffset, textBaseline + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.execution.impl;
|
||||
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.filters.FilterMixin;
|
||||
import com.intellij.execution.filters.HyperlinkInfo;
|
||||
import com.intellij.ide.OccurenceNavigator;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -33,7 +34,9 @@ import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.util.BeforeAfter;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -50,14 +53,18 @@ import java.util.List;
|
||||
public class EditorHyperlinkSupport {
|
||||
public static final Key<TextAttributes> OLD_HYPERLINK_TEXT_ATTRIBUTES = Key.create("OLD_HYPERLINK_TEXT_ATTRIBUTES");
|
||||
private static final int HYPERLINK_LAYER = HighlighterLayer.SELECTION - 123;
|
||||
private static final int HIGHLIGHT_LAYER = HighlighterLayer.SELECTION - 111;
|
||||
private static final int NO_INDEX = Integer.MIN_VALUE;
|
||||
|
||||
private final Editor myEditor;
|
||||
private final Map<RangeHighlighter, HyperlinkInfo> myHighlighterToMessageInfoMap = new HashMap<RangeHighlighter, HyperlinkInfo>();
|
||||
private int myLastIndex = NO_INDEX;
|
||||
private final Consumer<BeforeAfter<Filter.Result>> myRefresher;
|
||||
private final List<RangeHighlighter> myHighlighters;
|
||||
|
||||
public EditorHyperlinkSupport(@NotNull final Editor editor, @NotNull final Project project) {
|
||||
myEditor = editor;
|
||||
myHighlighters = new SmartList<RangeHighlighter>();
|
||||
|
||||
editor.addEditorMouseListener(new EditorMouseAdapter() {
|
||||
public void mouseReleased(final EditorMouseEvent e) {
|
||||
@@ -86,10 +93,78 @@ public class EditorHyperlinkSupport {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
myRefresher = new Consumer<BeforeAfter<Filter.Result>>() {
|
||||
@Override
|
||||
public void consume(BeforeAfter<Filter.Result> resultBeforeAfter) {
|
||||
if (resultBeforeAfter.getBefore() == null) return;
|
||||
final RangeHighlighter hyperlinkRange = findHyperlinkRange(resultBeforeAfter.getBefore().hyperlinkInfo);
|
||||
if (hyperlinkRange != null) {
|
||||
myHighlighterToMessageInfoMap.remove(hyperlinkRange);
|
||||
} else {
|
||||
final Iterator<RangeHighlighter> iterator = myHighlighters.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final RangeHighlighter highlighter = iterator.next();
|
||||
if (highlighter.isValid() && containsOffset(resultBeforeAfter.getBefore().highlightStartOffset, highlighter)) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resultBeforeAfter.getAfter() != null) {
|
||||
if (resultBeforeAfter.getAfter().hyperlinkInfo != null) {
|
||||
addHyperlink(resultBeforeAfter.getAfter().highlightStartOffset, resultBeforeAfter.getAfter().highlightEndOffset,
|
||||
resultBeforeAfter.getAfter().highlightAttributes, resultBeforeAfter.getAfter().hyperlinkInfo);
|
||||
} else if (resultBeforeAfter.getAfter().highlightAttributes != null) {
|
||||
addHighlighter(resultBeforeAfter.getAfter().highlightStartOffset, resultBeforeAfter.getAfter().highlightEndOffset,
|
||||
resultBeforeAfter.getAfter().highlightAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void adjustHighlighters(final List<FilterMixin.AdditionalHighlight> highlights) {
|
||||
for (FilterMixin.AdditionalHighlight highlight : highlights) {
|
||||
RangeHighlighter found = null;
|
||||
for (RangeHighlighter rangeHighlighter : myHighlighterToMessageInfoMap.keySet()) {
|
||||
if (rangeHighlighter.getStartOffset() <= highlight.getStart() && rangeHighlighter.getEndOffset() >= highlight.getEnd()) {
|
||||
found = rangeHighlighter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found != null) {
|
||||
TextAttributes textAttributes = highlight.getTextAttributes(found.getTextAttributes());
|
||||
final HyperlinkInfo hyperlinkInfo = myHighlighterToMessageInfoMap.remove(found);
|
||||
if (found.getStartOffset() != highlight.getStart()) {
|
||||
addHyperlink(found.getStartOffset(), highlight.getEnd(), found.getTextAttributes(), hyperlinkInfo);
|
||||
}
|
||||
if (found.getEndOffset() != highlight.getEnd()) {
|
||||
addHyperlink(highlight.getEnd(), found.getEndOffset(), found.getTextAttributes(), hyperlinkInfo);
|
||||
}
|
||||
addHyperlink(highlight.getStart(), highlight.getEnd(), textAttributes, hyperlinkInfo);
|
||||
myEditor.getMarkupModel().removeHighlighter(found);
|
||||
return;
|
||||
}
|
||||
final Iterator<RangeHighlighter> iterator = myHighlighters.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final RangeHighlighter highlighter = iterator.next();
|
||||
if (highlighter.getStartOffset() == highlight.getStart() && highlighter.getEndOffset() == highlight.getEnd()) {
|
||||
iterator.remove();
|
||||
final TextAttributes textAttributes = highlight.getTextAttributes(highlighter.getTextAttributes());
|
||||
addHighlighter(highlight.getStart(), highlight.getEnd(), textAttributes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
final TextAttributes textAttributes = highlight.getTextAttributes(null);
|
||||
addHighlighter(highlight.getStart(), highlight.getEnd(), textAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearHyperlinks() {
|
||||
myHighlighterToMessageInfoMap.clear();
|
||||
myHighlighters.clear();
|
||||
myLastIndex = NO_INDEX;
|
||||
}
|
||||
|
||||
@@ -171,12 +246,25 @@ public class EditorHyperlinkSupport {
|
||||
if (result == null) {
|
||||
result = predefinedMessageFilter.applyFilter(text, endOffset);
|
||||
}
|
||||
if (result != null && result.hyperlinkInfo != null) {
|
||||
addHyperlink(result.highlightStartOffset, result.highlightEndOffset, result.highlightAttributes, result.hyperlinkInfo);
|
||||
if (result != null) {
|
||||
if (result.hyperlinkInfo != null) {
|
||||
addHyperlink(result.highlightStartOffset, result.highlightEndOffset, result.highlightAttributes, result.hyperlinkInfo);
|
||||
} else if (result.highlightAttributes != null) {
|
||||
addHighlighter(result.highlightStartOffset, result.highlightEndOffset, result.highlightAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addHighlighter(int highlightStartOffset, int highlightEndOffset, TextAttributes highlightAttributes) {
|
||||
final RangeHighlighter highlighter = myEditor.getMarkupModel().addRangeHighlighter(highlightStartOffset,
|
||||
highlightEndOffset,
|
||||
HIGHLIGHT_LAYER,
|
||||
highlightAttributes,
|
||||
HighlighterTargetArea.EXACT_RANGE);
|
||||
myHighlighters.add(highlighter);
|
||||
}
|
||||
|
||||
private static TextAttributes getHyperlinkAttributes() {
|
||||
return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES);
|
||||
}
|
||||
@@ -220,6 +308,7 @@ public class EditorHyperlinkSupport {
|
||||
}, i, ranges.size());
|
||||
}
|
||||
|
||||
// todo fix link followed here!
|
||||
private static void linkFollowed(Editor editor, Collection<RangeHighlighter> ranges, final RangeHighlighter link) {
|
||||
MarkupModelEx markupModel = (MarkupModelEx)editor.getMarkupModel();
|
||||
for (RangeHighlighter range : ranges) {
|
||||
@@ -237,6 +326,7 @@ public class EditorHyperlinkSupport {
|
||||
attributes.setEffectType(oldAttributes.getEffectType());
|
||||
attributes.setEffectColor(oldAttributes.getEffectColor());
|
||||
attributes.setForegroundColor(oldAttributes.getForegroundColor());
|
||||
attributes.setBackgroundColor(oldAttributes.getBackgroundColor());
|
||||
markupModel.setRangeHighlighterAttributes(range, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -384,19 +384,20 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
|
||||
if (clip.height == 0) return;
|
||||
|
||||
final Rectangle componentBounds = c.getBounds();
|
||||
final TextRange docRange = TextRange.create(0, getEditor().getDocument().getTextLength());
|
||||
if (myCachedTrack == null || myCachedTrack.getHeight() != componentBounds.getHeight()) {
|
||||
myCachedTrack = new BufferedImage(componentBounds.width, componentBounds.height, BufferedImage.TYPE_INT_ARGB);
|
||||
myDirtyRange = TextRange.create(0, getEditor().getDocument().getTextLength());
|
||||
myDirtyRange = docRange;
|
||||
paintTrackBasement(myCachedTrack.getGraphics(), new Rectangle(0, 0, componentBounds.width, componentBounds.height));
|
||||
}
|
||||
|
||||
if (myDirtyRange != null) {
|
||||
final Graphics2D imageGraphics = myCachedTrack.createGraphics();
|
||||
|
||||
|
||||
((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart();
|
||||
|
||||
try {
|
||||
myDirtyRange = myDirtyRange.intersection(docRange);
|
||||
repaint(imageGraphics, componentBounds.width, ERROR_ICON_WIDTH - 1, myDirtyRange.getStartOffset(), myDirtyRange.getEndOffset());
|
||||
myDirtyRange = null;
|
||||
}
|
||||
|
||||
@@ -119,5 +119,6 @@
|
||||
<extensionPoint name="xmlRpcHandler" beanClass="com.intellij.ide.XmlRpcHandlerBean"/>
|
||||
|
||||
<extensionPoint name="editorHighlighterProvider" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint"/>
|
||||
<extensionPoint name="fileDocumentManagerListener" interface="com.intellij.openapi.fileEditor.FileDocumentManagerListener"/>
|
||||
<extensionPoint name="fileDocumentManagerListener" interface="com.intellij.openapi.fileEditor.FileDocumentManagerListener"/>
|
||||
<extensionPoint name="exceptionFilter" interface="com.intellij.execution.filters.ExceptionFilterFactory"/>
|
||||
</extensionPoints>
|
||||
|
||||
@@ -226,4 +226,7 @@
|
||||
|
||||
<projectService serviceInterface="com.intellij.openapi.wm.impl.ProjectFrameBounds"
|
||||
serviceImplementation="com.intellij.openapi.wm.impl.ProjectFrameBounds"/>
|
||||
<exceptionFilter implementation="com.intellij.execution.filters.ExceptionBaseFilterFactory"/>
|
||||
<exceptionFilter implementation="com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationExceptionFilterFactory"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
@@ -106,5 +106,10 @@
|
||||
<component><interface-class>com.intellij.openapi.vcs.impl.VcsBaseContentProvider</interface-class>
|
||||
<implementation-class>com.intellij.openapi.vcs.impl.VcsFileStatusProvider</implementation-class>
|
||||
</component>
|
||||
<component><interface-class>com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationSettings</interface-class>
|
||||
<implementation-class>com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationSettings</implementation-class>
|
||||
</component>
|
||||
<component><interface-class>com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotation</interface-class>
|
||||
<implementation-class>com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationImpl</implementation-class></component>
|
||||
</project-components>
|
||||
</components>
|
||||
|
||||
@@ -19,4 +19,6 @@ public interface UpToDateLineNumberProvider {
|
||||
int ABSENT_LINE_NUMBER = -1;
|
||||
|
||||
int getLineNumber(int currentNumber);
|
||||
boolean isLineChanged(int currentNumber);
|
||||
boolean isRangeChanged(final int start, final int end);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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;
|
||||
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/3/11
|
||||
* Time: 12:56 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class RichTextItem {
|
||||
private final String myText;
|
||||
private final SimpleTextAttributes myTextAttributes;
|
||||
|
||||
public RichTextItem(String text, SimpleTextAttributes textAttributes) {
|
||||
myText = text;
|
||||
myTextAttributes = textAttributes;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return myText;
|
||||
}
|
||||
|
||||
public SimpleTextAttributes getTextAttributes() {
|
||||
return myTextAttributes;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -81,6 +82,9 @@ public interface FileAnnotation {
|
||||
@Nullable
|
||||
VcsRevisionNumber getLineRevisionNumber(int lineNumber);
|
||||
|
||||
@Nullable
|
||||
Date getLineDate(int lineNumber);
|
||||
|
||||
/**
|
||||
* Get revision number for the line.
|
||||
*/
|
||||
|
||||
@@ -150,4 +150,12 @@ public abstract class ChangeListManager implements ChangeListModification {
|
||||
public abstract void letGo();
|
||||
public abstract String isFreezed();
|
||||
public abstract boolean isFreezedWithNotification(@Nullable String modalTitle);
|
||||
|
||||
public static boolean isFileChanged(final Project project, final VirtualFile vf) {
|
||||
FileStatus status = getInstance(project).getStatus(vf);
|
||||
if (status == null || FileStatus.NOT_CHANGED.equals(status) || FileStatus.UNKNOWN.equals(status) || FileStatus.IGNORED.equals(status)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.contentAnnotation;
|
||||
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vcs.RichTextItem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/3/11
|
||||
* Time: 12:50 PM
|
||||
*/
|
||||
public interface VcsContentAnnotation {
|
||||
boolean fileRecentlyChanged(final VirtualFile vf);
|
||||
|
||||
boolean intervalRecentlyChanged(VirtualFile file, final TextRange lineInterval);
|
||||
|
||||
@Nullable
|
||||
Details annotateLine(final VirtualFile vf, final Getter<TextRange> enclosingRange, final int lineNumber);
|
||||
|
||||
class Details {
|
||||
private final boolean myLineChanged;
|
||||
// meaningful enclosing structure
|
||||
private final boolean myMethodChanged;
|
||||
private final boolean myFileChanged;
|
||||
@Nullable
|
||||
private final List<RichTextItem> myDetails;
|
||||
|
||||
public Details(boolean lineChanged, boolean methodChanged, boolean fileChanged, List<RichTextItem> details) {
|
||||
myLineChanged = lineChanged;
|
||||
myMethodChanged = methodChanged;
|
||||
myFileChanged = fileChanged;
|
||||
myDetails = details;
|
||||
}
|
||||
|
||||
public boolean isLineChanged() {
|
||||
return myLineChanged;
|
||||
}
|
||||
|
||||
public boolean isMethodChanged() {
|
||||
return myMethodChanged;
|
||||
}
|
||||
|
||||
public boolean isFileChanged() {
|
||||
return myFileChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.contentAnnotation;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.diff.DiffMixin;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionDescription;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/3/11
|
||||
* Time: 1:04 PM
|
||||
*/
|
||||
public class VcsContentAnnotationImpl implements VcsContentAnnotation {
|
||||
private final Project myProject;
|
||||
private final VcsContentAnnotationSettings mySettings;
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationImpl");
|
||||
|
||||
public static VcsContentAnnotation getInstance(final Project project) {
|
||||
return ServiceManager.getService(project, VcsContentAnnotation.class);
|
||||
}
|
||||
|
||||
public VcsContentAnnotationImpl(Project project, VcsContentAnnotationSettings settings) {
|
||||
myProject = project;
|
||||
mySettings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fileRecentlyChanged(VirtualFile vf) {
|
||||
final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject);
|
||||
final AbstractVcs vcs = vcsManager.getVcsFor(vf);
|
||||
if (vcs == null) return false;
|
||||
if (vcs.getDiffProvider() instanceof DiffMixin) {
|
||||
final VcsRevisionDescription description = ((DiffMixin)vcs.getDiffProvider()).getCurrentRevisionDescription(vf);
|
||||
final Date date = description.getRevisionDate();
|
||||
return isRecent(date);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isRecent(Date date) {
|
||||
return date.getTime() > (System.currentTimeMillis() - mySettings.getLimit());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intervalRecentlyChanged(VirtualFile file, TextRange lineInterval) {
|
||||
final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject);
|
||||
final AbstractVcs vcs = vcsManager.getVcsFor(file);
|
||||
if (vcs == null) return false;
|
||||
final FileAnnotation fileAnnotation;
|
||||
try {
|
||||
fileAnnotation = vcs.getCachingAnnotationProvider().annotate(file);
|
||||
}
|
||||
catch (VcsException e) {
|
||||
LOG.info(e);
|
||||
return false;
|
||||
}
|
||||
for (int i = lineInterval.getStartOffset(); i <= lineInterval.getEndOffset(); i++) {
|
||||
Date lineDate = fileAnnotation.getLineDate(i);
|
||||
if (lineDate != null && isRecent(lineDate)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Details annotateLine(final VirtualFile vf, final Getter<TextRange> enclosingRange, final int lineNumber) {
|
||||
final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject);
|
||||
final AbstractVcs vcs = vcsManager.getVcsFor(vf);
|
||||
if (vcs == null) return null;
|
||||
if (vcs.getDiffProvider() instanceof DiffMixin) {
|
||||
boolean fileRecent = false;
|
||||
final VcsRevisionDescription description = ((DiffMixin)vcs.getDiffProvider()).getCurrentRevisionDescription(vf);
|
||||
final Date date = description.getRevisionDate();
|
||||
if (isRecent(date)) {
|
||||
fileRecent = true;
|
||||
enclosingRange.get();
|
||||
}
|
||||
return new Details(false, false, fileRecent, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.contentAnnotation;
|
||||
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/3/11
|
||||
* Time: 1:13 PM
|
||||
*/
|
||||
@State(
|
||||
name = "VcsContentAnnotationSettings",
|
||||
storages = {@Storage( file = "$WORKSPACE_FILE$")})
|
||||
public class VcsContentAnnotationSettings implements PersistentStateComponent<VcsContentAnnotationSettings.State> {
|
||||
// approx
|
||||
public static final int ourMaxDays = 31;
|
||||
public final static long ourAbsoluteLimit = ourMaxDays * 24 * 60 * 60 * 1000L;
|
||||
private State myState = new State();
|
||||
|
||||
{
|
||||
myState.myLimit = ourAbsoluteLimit;
|
||||
}
|
||||
|
||||
public static VcsContentAnnotationSettings getInstance(final Project project) {
|
||||
return ServiceManager.getService(project, VcsContentAnnotationSettings.class);
|
||||
}
|
||||
|
||||
public static class State {
|
||||
public boolean myShow = true;
|
||||
public long myLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return myState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(State state) {
|
||||
myState = state;
|
||||
}
|
||||
|
||||
public long getLimit() {
|
||||
return myState.myLimit;
|
||||
}
|
||||
|
||||
public long getLimitDays() {
|
||||
return myState.myLimit / (24 * 60 * 60 * 1000L);
|
||||
}
|
||||
|
||||
public void setLimit(long limit) {
|
||||
myState.myLimit = limit * 24 * 60 * 60 * 1000L;
|
||||
}
|
||||
|
||||
public boolean isShow() {
|
||||
return myState.myShow;
|
||||
}
|
||||
|
||||
public void setShow(final boolean value) {
|
||||
myState.myShow = value;
|
||||
}
|
||||
}
|
||||
@@ -188,7 +188,7 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware, Ann
|
||||
final AbstractVcs vcs) {
|
||||
final String upToDateContent = fileAnnotation.getAnnotatedContent();
|
||||
|
||||
final UpToDateLineNumberProvider getUpToDateLineNumber = new UpToDateLineNumberProviderImpl(editor.getDocument(), project, upToDateContent);
|
||||
final UpToDateLineNumberProvider getUpToDateLineNumber = new UpToDateLineNumberProviderImpl(editor.getDocument(), project);
|
||||
editor.getGutter().closeAllAnnotations();
|
||||
|
||||
// be careful, not proxies but original items are put there (since only their presence not behaviour is important)
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.configurable;
|
||||
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationSettings;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 8/4/11
|
||||
* Time: 2:05 PM
|
||||
*/
|
||||
public class VcsContentAnnotationConfigurable implements Configurable {
|
||||
private final Project myProject;
|
||||
private JCheckBox myHighlightRecentlyChanged;
|
||||
private JSpinner myHighlightInterval;
|
||||
|
||||
public VcsContentAnnotationConfigurable(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Show recently changed";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpTopic() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
JPanel wrapper = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
myHighlightRecentlyChanged = new JCheckBox("Show changed in last");
|
||||
myHighlightRecentlyChanged.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
|
||||
myHighlightInterval = new JSpinner(new SpinnerNumberModel(1, 1, VcsContentAnnotationSettings.ourMaxDays, 1));
|
||||
wrapper.add(myHighlightRecentlyChanged);
|
||||
wrapper.add(myHighlightInterval);
|
||||
wrapper.add(new JLabel("days"));
|
||||
|
||||
myHighlightRecentlyChanged.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
myHighlightInterval.setEnabled(myHighlightRecentlyChanged.isSelected());
|
||||
}
|
||||
});
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
VcsContentAnnotationSettings settings = VcsContentAnnotationSettings.getInstance(myProject);
|
||||
if (myHighlightRecentlyChanged.isSelected() != settings.isShow()) return true;
|
||||
if (! Comparing.equal(myHighlightInterval.getValue(), settings.getLimitDays())) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
VcsContentAnnotationSettings settings = VcsContentAnnotationSettings.getInstance(myProject);
|
||||
settings.setShow(myHighlightRecentlyChanged.isSelected());
|
||||
settings.setLimit(((Number) myHighlightInterval.getValue()).intValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
VcsContentAnnotationSettings settings = VcsContentAnnotationSettings.getInstance(myProject);
|
||||
myHighlightRecentlyChanged.setSelected(settings.isShow());
|
||||
myHighlightInterval.setValue(settings.getLimitDays());
|
||||
myHighlightInterval.setEnabled(myHighlightRecentlyChanged.isSelected());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
}
|
||||
}
|
||||
+14
-3
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.configurable;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
@@ -134,6 +135,7 @@ public class VcsDirectoryConfigurationPanel extends PanelWithButtons implements
|
||||
private JButton myEditButton;
|
||||
private JButton myRemoveButton;
|
||||
private final Map<String, VcsDescriptor> myAllVcss;
|
||||
private VcsContentAnnotationConfigurable myRecentlyChangedConfigurable;
|
||||
private final boolean myIsDisabled;
|
||||
|
||||
public VcsDirectoryConfigurationPanel(final Project project) {
|
||||
@@ -147,6 +149,7 @@ public class VcsDirectoryConfigurationPanel extends PanelWithButtons implements
|
||||
}
|
||||
|
||||
myDirectoryMappingTable = new TableView<VcsDirectoryMapping>();
|
||||
initPanel();
|
||||
initializeModel();
|
||||
|
||||
final JComboBox comboBox = myVcsComboBox.getComboBox();
|
||||
@@ -172,7 +175,6 @@ public class VcsDirectoryConfigurationPanel extends PanelWithButtons implements
|
||||
updateButtons();
|
||||
}
|
||||
});
|
||||
initPanel();
|
||||
updateButtons();
|
||||
if (myIsDisabled) {
|
||||
myDirectoryMappingTable.setEnabled(false);
|
||||
@@ -187,6 +189,8 @@ public class VcsDirectoryConfigurationPanel extends PanelWithButtons implements
|
||||
}
|
||||
myModel = new ListTableModel<VcsDirectoryMapping>(new ColumnInfo[]{DIRECTORY, VCS_SETTING}, mappings, 0);
|
||||
myDirectoryMappingTable.setModel(myModel);
|
||||
|
||||
myRecentlyChangedConfigurable.reset();
|
||||
}
|
||||
|
||||
private void updateButtons() {
|
||||
@@ -273,19 +277,26 @@ public class VcsDirectoryConfigurationPanel extends PanelWithButtons implements
|
||||
}
|
||||
|
||||
protected JComponent createMainComponent() {
|
||||
return ScrollPaneFactory.createScrollPane(myDirectoryMappingTable);
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
final JScrollPane scroll = ScrollPaneFactory.createScrollPane(myDirectoryMappingTable);
|
||||
panel.add(scroll, BorderLayout.CENTER);
|
||||
myRecentlyChangedConfigurable = new VcsContentAnnotationConfigurable(myProject);
|
||||
panel.add(myRecentlyChangedConfigurable.createComponent(), BorderLayout.SOUTH);
|
||||
return panel;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
initializeModel();
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
public void apply() throws ConfigurationException {
|
||||
myVcsManager.setDirectoryMappings(myModel.getItems());
|
||||
myRecentlyChangedConfigurable.apply();
|
||||
initializeModel();
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
if (myRecentlyChangedConfigurable.isModified()) return true;
|
||||
return !myModel.getItems().equals(myVcsManager.getDirectoryMappings());
|
||||
}
|
||||
|
||||
|
||||
+38
-4
@@ -29,21 +29,55 @@ import java.util.List;
|
||||
public class UpToDateLineNumberProviderImpl implements UpToDateLineNumberProvider {
|
||||
private final Document myDocument;
|
||||
private final Project myProject;
|
||||
private final String myUpToDateContent;
|
||||
private final LineStatusTrackerManagerI myLineStatusTrackerManagerI;
|
||||
|
||||
public UpToDateLineNumberProviderImpl(Document document, Project project, String upToDateContent) {
|
||||
public UpToDateLineNumberProviderImpl(Document document, Project project) {
|
||||
myDocument = document;
|
||||
myProject = project;
|
||||
myUpToDateContent = upToDateContent;
|
||||
myLineStatusTrackerManagerI = LineStatusTrackerManager.getInstance(myProject);
|
||||
}
|
||||
|
||||
public int getLineNumber(int currentNumber) {
|
||||
LineStatusTracker tracker = LineStatusTrackerManager.getInstance(myProject).getLineStatusTracker(myDocument);
|
||||
LineStatusTracker tracker = myLineStatusTrackerManagerI.getLineStatusTracker(myDocument);
|
||||
if (tracker == null) {
|
||||
return currentNumber;
|
||||
}
|
||||
return calcLineNumber(tracker, currentNumber);
|
||||
}
|
||||
|
||||
public boolean isRangeChanged(final int start, final int end) {
|
||||
LineStatusTracker tracker = LineStatusTrackerManager.getInstance(myProject).getLineStatusTracker(myDocument);
|
||||
if (tracker == null) {
|
||||
return false;
|
||||
}
|
||||
for (Range range : tracker.getRanges()) {
|
||||
if (lineInRange(range, start) || lineInRange(range, end)) {
|
||||
return true;
|
||||
}
|
||||
if (range.getOffset1() > start) {
|
||||
return range.getOffset1() < end;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean lineInRange(final Range range, final int currentNumber) {
|
||||
return range.getOffset1() <= currentNumber && range.getOffset2() >= currentNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLineChanged(int currentNumber) {
|
||||
LineStatusTracker tracker = LineStatusTrackerManager.getInstance(myProject).getLineStatusTracker(myDocument);
|
||||
if (tracker == null) {
|
||||
return false;
|
||||
}
|
||||
for (Range range : tracker.getRanges()) {
|
||||
if (range.getOffset1() <= currentNumber && range.getOffset2() >= currentNumber) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean endsWithSeparator(final CharSequence string) {
|
||||
if ((string == null) || (string.length() == 0)) {
|
||||
|
||||
@@ -155,6 +155,14 @@ public class CvsFileAnnotation implements FileAnnotation{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLineDate(int lineNumber) {
|
||||
if (lineNumber < 0 || lineNumber >= myAnnotations.length) {
|
||||
return null;
|
||||
}
|
||||
return myAnnotations[lineNumber].getDate();
|
||||
}
|
||||
|
||||
public VcsRevisionNumber originalRevision(int lineNumber) {
|
||||
return getLineRevisionNumber(lineNumber);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,6 @@
|
||||
serviceImplementation="git4idea.DialogManager"/>
|
||||
<projectService serviceInterface="git4idea.history.wholeTree.GitLogSettings"
|
||||
serviceImplementation="git4idea.history.wholeTree.GitLogSettings"/>
|
||||
|
||||
<applicationService
|
||||
serviceInterface="git4idea.config.GitVcsApplicationSettings"
|
||||
serviceImplementation="git4idea.config.GitVcsApplicationSettings"/>
|
||||
|
||||
@@ -237,13 +237,26 @@ public class GitFileAnnotation implements FileAnnotation {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public VcsRevisionNumber getLineRevisionNumber(final int lineNumber) {
|
||||
if (myLines.size() <= lineNumber || lineNumber < 0 || myLines.get(lineNumber) == null) {
|
||||
if (lineNumberCheck(lineNumber)) {
|
||||
return null;
|
||||
}
|
||||
final LineInfo lineInfo = myLines.get(lineNumber);
|
||||
return lineInfo == null ? null : lineInfo.getRevision();
|
||||
}
|
||||
|
||||
private boolean lineNumberCheck(int lineNumber) {
|
||||
return myLines.size() <= lineNumber || lineNumber < 0 || myLines.get(lineNumber) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLineDate(int lineNumber) {
|
||||
if (lineNumberCheck(lineNumber)) {
|
||||
return null;
|
||||
}
|
||||
final LineInfo lineInfo = myLines.get(lineNumber);
|
||||
return lineInfo == null ? null : lineInfo.getDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get revision number for the line.
|
||||
*/
|
||||
@@ -287,7 +300,7 @@ public class GitFileAnnotation implements FileAnnotation {
|
||||
}
|
||||
|
||||
public String getValue(int lineNumber) {
|
||||
if (myLines.size() <= lineNumber || lineNumber < 0 || myLines.get(lineNumber) == null) {
|
||||
if (lineNumberCheck(lineNumber)) {
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.apache.commons.lang.StringUtils;
|
||||
import org.zmlx.hg4idea.HgFile;
|
||||
import org.zmlx.hg4idea.HgFileRevision;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -99,6 +100,16 @@ public class HgAnnotation implements FileAnnotation {
|
||||
return annotationLine.getVcsRevisionNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLineDate(int lineNumber) {
|
||||
if (lineNumber >= lines.size() || lineNumber < 0) {
|
||||
return null;
|
||||
}
|
||||
//lines.get(lineNumber).get(HgAnnotation.FIELD.DATE)
|
||||
// todo : parse date
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<VcsFileRevision> getRevisions() {
|
||||
List<VcsFileRevision> result = new LinkedList<VcsFileRevision>();
|
||||
result.addAll(vcsFileRevisions);
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentFactory;
|
||||
import com.intellij.ui.content.MessageView;
|
||||
@@ -34,6 +35,7 @@ import org.jetbrains.idea.maven.execution.MavenRunnerParameters;
|
||||
import org.jetbrains.idea.maven.execution.MavenRunnerSettings;
|
||||
import org.jetbrains.idea.maven.utils.MavenUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class MavenConsoleImpl extends MavenConsole {
|
||||
@@ -73,10 +75,11 @@ public class MavenConsoleImpl extends MavenConsole {
|
||||
public static TextConsoleBuilder createConsoleBuilder(Project project) {
|
||||
TextConsoleBuilder builder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
|
||||
|
||||
Filter[] filters = {new ExceptionFilter(project), new RegexpFilter(project, CONSOLE_FILTER_REGEXP)};
|
||||
List<Filter> filters = ExceptionFilters.getFilters(GlobalSearchScope.allScope(project));
|
||||
for (Filter filter : filters) {
|
||||
builder.addFilter(filter);
|
||||
}
|
||||
builder.addFilter(new RegexpFilter(project, CONSOLE_FILTER_REGEXP));
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
@@ -246,6 +246,16 @@ public class SvnFileAnnotation implements FileAnnotation {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLineDate(int lineNumber) {
|
||||
if (myInfos.size() <= lineNumber || lineNumber < 0) {
|
||||
return null;
|
||||
}
|
||||
final LineInfo info = myInfos.get(lineNumber);
|
||||
if (info == null) return null;
|
||||
return info.getDate();
|
||||
}
|
||||
|
||||
public List<VcsFileRevision> getRevisions() {
|
||||
final List<VcsFileRevision> result = new ArrayList<VcsFileRevision>(myRevisionMap.values());
|
||||
Collections.sort(result, new Comparator<VcsFileRevision>() {
|
||||
|
||||
Reference in New Issue
Block a user