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

This commit is contained in:
irengrig
2011-02-15 19:37:02 +03:00
29 changed files with 353 additions and 219 deletions
@@ -0,0 +1,70 @@
/*
* 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.roots.ui.configuration.libraries.impl;
import com.intellij.internal.statistic.UsagesCollector;
import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryKind;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author nik
*/
public class LibraryUsageCollector extends UsagesCollector {
@NonNls private static final String GROUP_ID = "libraries";
@NotNull
@Override
public Set<UsageDescriptor> getUsages(@Nullable Project project) {
if (project == null) return Collections.emptySet();
final Set<LibraryKind<?>> usedKinds = new HashSet<LibraryKind<?>>();
final Processor<Library> processor = new Processor<Library>() {
@Override
public boolean process(Library library) {
usedKinds.addAll(LibraryPresentationManagerImpl.getLibraryKinds(library, null));
return true;
}
};
for (Module module : ModuleManager.getInstance(project).getModules()) {
ModuleRootManager.getInstance(module).orderEntries().librariesOnly().forEachLibrary(processor);
}
final HashSet<UsageDescriptor> usageDescriptors = new HashSet<UsageDescriptor>();
for (LibraryKind<?> kind : usedKinds) {
final GroupDescriptor group = GroupDescriptor.create(GROUP_ID);
usageDescriptors.add(new UsageDescriptor(group, kind.getKindId(), 1));
}
return usageDescriptors;
}
@NotNull
@Override
public String getGroupId() {
return GROUP_ID;
}
}
@@ -21,7 +21,10 @@ import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
@@ -107,7 +110,7 @@ public class IconLineMarkerProvider implements LineMarkerProvider {
@Nullable
private LineMarkerInfo<PsiElement> resolveIconInfo(PsiType type, PsiExpression initializer, PsiElement bindingElement) {
if (initializer != null && initializer.isValid() && isIconClassType(type)) {
final Project project = initializer.getProject();
final List<FileReference> refs = new ArrayList<FileReference>();
initializer.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
@@ -146,9 +149,10 @@ public class IconLineMarkerProvider implements LineMarkerProvider {
final Icon icon = getIcon(file);
if (icon != null) {
final Ref<VirtualFile> f = Ref.create(file);
final GutterIconNavigationHandler<PsiElement> navHandler = new GutterIconNavigationHandler<PsiElement>() {
public void navigate(MouseEvent e, PsiElement elt) {
psiFileSystemItem.navigate(true);
FileEditorManager.getInstance(project).openFile(f.get(), true);
}
};
return new LineMarkerInfo<PsiElement>(bindingElement, bindingElement.getTextRange(), icon,
@@ -117,7 +117,7 @@ public class StatementParser {
final PsiBuilder.Marker codeBlock = builder.mark();
builder.advanceLexer();
parseStatements(builder, (parseUntilEof ? BraceMode.TILL_LAST : BraceMode.TILL_FIRST));
parseStatements(builder, parseUntilEof ? BraceMode.TILL_LAST : BraceMode.TILL_FIRST);
final boolean greedyBlock = !expectOrError(builder, JavaTokenType.RBRACE, JavaErrorMessages.message("expected.rbrace"));
builder.getTokenType(); // eat spaces
@@ -185,7 +185,7 @@ public class ExecutionHelper {
public static void executeExternalProcess(@Nullable final Project myProject,
@NotNull final OSProcessHandler processHandler,
@NotNull final ExecutionMode mode) {
final String title = mode.getTitle() != null ? mode.getTitle() : "Running. Please wait...";
final String title = mode.getTitle() != null ? mode.getTitle() : "Please wait...";
assert title != null;
final Runnable process;
@@ -275,7 +275,7 @@ public class ExecutionHelper {
public void run() {
myProgressIndicator = ProgressManager.getInstance().getProgressIndicator();
if (myProgressIndicator != null && StringUtil.isEmpty(myProgressIndicator.getText())) {
myProgressIndicator.setText("Please wait");
myProgressIndicator.setText("Please wait...");
}
LOG.assertTrue(myProgressIndicator != null || cancelableFun != null,
@@ -27,7 +27,7 @@ import java.util.List;
/**
* @author Roman.Chernyatchik
*/
public abstract class ExecutionMode {
public class ExecutionMode {
private final boolean myCancelable;
private final String myTitle;
private final String myTitle2;
@@ -107,4 +107,4 @@ public abstract class ExecutionMode {
public List<ProcessListener> getProcessListeners() {
return myListeners;
}
}
}
@@ -19,8 +19,6 @@
*/
package com.intellij.find;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInsight.highlighting.HighlightManagerImpl;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.find.impl.LiveOccurrence;
@@ -34,13 +32,13 @@ import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.editor.event.SelectionEvent;
import com.intellij.openapi.editor.event.SelectionListener;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
@@ -72,6 +70,7 @@ import java.util.Set;
import java.util.regex.Pattern;
public class EditorSearchComponent extends JPanel implements DataProvider, LivePreview.CursorListener, SelectionListener {
private static final int MATCHES_LIMIT = 100;
private final JLabel myMatchInfoLabel;
private final LinkLabel myClickToHighlightLabel;
private final Project myProject;
@@ -90,9 +89,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
private static final Color FOCUS_CATCHER_COLOR = new Color(0x9999ff);
private final JComponent myToolbarComponent;
private com.intellij.openapi.editor.event.DocumentAdapter myDocumentListener;
private ArrayList<RangeHighlighter> myHighlighters = new ArrayList<RangeHighlighter>();
private int myMatchesLimit = 100;
private final JCheckBox myCbRegexp;
private final JCheckBox myCbWholeWords;
private final JCheckBox myCbInComments;
@@ -104,13 +101,37 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
mySearchField.requestFocus();
}
public void notFound() {
setNotFoundBackground();
@Override
public Editor getEditor(Ref<Boolean> needToUpdate) {
needToUpdate.set(true);
return myEditor;
}
@Override
protected void tooManyMatches() {
myMatchInfoLabel.setText("More than " + myMatchesLimit + " matches");
public void searchEndsWith(int count) {
if (count <= getMatchesLimit()) {
myClickToHighlightLabel.setVisible(false);
if (count > 0) {
setRegularBackground();
if (count > 1) {
myMatchInfoLabel.setText(count + " matches");
}
else {
myMatchInfoLabel.setText("1 match");
}
}
else {
setNotFoundBackground();
myMatchInfoLabel.setText("No matches");
}
}
else {
setRegularBackground();
myMatchInfoLabel.setText("More than 100 matches");
myClickToHighlightLabel.setVisible(true);
boldMatchInfo();
}
}
};
private final LivePreview myLivePreview;
@@ -118,6 +139,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
private boolean myIsReplace;
private boolean myListeningSelection = false;
private boolean myToChangeSelection = true;
@Nullable
public Object getData(@NonNls final String dataId) {
@@ -136,12 +158,18 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
myIsReplace = isReplace;
setMatchesLimit(MATCHES_LIMIT);
GRADIENT_C1 = getBackground();
GRADIENT_C2 = new Color(Math.max(0, GRADIENT_C1.getRed() - 0x18), Math.max(0, GRADIENT_C1.getGreen() - 0x18), Math.max(0, GRADIENT_C1.getBlue() - 0x18));
myProject = project;
myEditor = editor;
myLivePreview = new LivePreview(myEditor.getProject());
myLivePreview.addCursorListener(this);
myLivePreview.setDelegate(myLivePreviewController);
JPanel leadPanel = createLeadPane();
add(leadPanel, BorderLayout.WEST);
@@ -258,7 +286,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
myClickToHighlightLabel = new LinkLabel("Click to highlight", null, new LinkListener() {
@Override
public void linkSelected(LinkLabel aSource, Object aLinkData) {
myMatchesLimit = Integer.MAX_VALUE;
setMatchesLimit(Integer.MAX_VALUE);
updateResults(true);
}
});
@@ -306,9 +334,11 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
new VariantsCompletionAction(); // It registers a shortcut set automatically on construction
myLivePreview = new LivePreview(myEditor.getProject());
myLivePreview.addCursorListener(this);
myLivePreview.setDelegate(myLivePreviewController);
}
private void setMatchesLimit(int value) {
myLivePreviewController.setMatchesLimit(value);
}
private void configureReplacementPane() {
@@ -399,7 +429,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
searchField.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(final DocumentEvent e) {
myMatchesLimit = 100;
setMatchesLimit(MATCHES_LIMIT);
updateResults(true);
}
});
@@ -437,13 +467,13 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
}
private void searchBackward() {
myLivePreview.prevOccurrence();
moveCursor(false);
addCurrentTextToRecents();
}
private void searchForward() {
myLivePreview.nextOccurrence();
moveCursor(true);
addCurrentTextToRecents();
}
@@ -457,7 +487,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
@Override
public void cursorMoved() {
if (mySelectionOnly == null || !mySelectionOnly.isSelected()) {
if (myToChangeSelection && (mySelectionOnly == null || !mySelectionOnly.isSelected())) {
LiveOccurrence cursor = myLivePreview.getCursor();
if (cursor != null) {
TextRange range = cursor.getPrimaryRange();
@@ -469,6 +499,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
myEditor.getCaretModel().moveToOffset(range.getStartOffset());
myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
myToChangeSelection = false;
}
}
@@ -478,6 +509,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
}
public void moveCursor(boolean forwardOrBackward) {
myToChangeSelection = true;
if (forwardOrBackward) {
myLivePreview.nextOccurrence();
} else {
@@ -502,13 +534,12 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
}
private void close() {
removeCurrentHighlights();
if (myEditor.getSelectionModel().hasSelection()) {
myEditor.getCaretModel().moveToOffset(myEditor.getSelectionModel().getSelectionStart());
myEditor.getSelectionModel().removeSelection();
}
IdeFocusManager.getInstance(myProject).requestFocus(myEditor.getContentComponent(), false);
myLivePreview.cleanUp();
myEditor.setHeaderComponent(null);
addCurrentTextToRecents();
}
@@ -544,14 +575,15 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
}
private void updateResults(final boolean allowedToChangedEditorSelection) {
removeCurrentHighlights();
myMatchInfoLabel.setFont(myMatchInfoLabel.getFont().deriveFont(Font.PLAIN));
final String text = mySearchField.getText();
if (text.length() == 0) {
setRegularBackground();
myMatchInfoLabel.setText("");
myClickToHighlightLabel.setVisible(false);
myLivePreview.cleanUp();
if (myLivePreview != null) {
myLivePreview.cleanUp();
}
}
else {
final FindModel model = new FindModel();
@@ -597,41 +629,10 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
model.setGlobal(!mySelectionOnly.isSelected());
model.setPreserveCase(myPreserveCase.isEnabled() && myPreserveCase.isSelected());
}
myToChangeSelection = allowedToChangedEditorSelection;
myLivePreviewController.setFindModel(model);
myLivePreview.update();
myLivePreview.setContinuation(new Runnable() {
@Override
public void run() {
final int count = myLivePreview.getSearchResults().size();
if (count <= myMatchesLimit) {
myClickToHighlightLabel.setVisible(false);
if (count > 0) {
setRegularBackground();
if (count > 1) {
myMatchInfoLabel.setText(count + " matches");
}
else {
myMatchInfoLabel.setText("1 match");
}
}
else {
setNotFoundBackground();
myMatchInfoLabel.setText("No matches");
}
}
else {
setRegularBackground();
myMatchInfoLabel.setText("More than 100 matches");
myClickToHighlightLabel.setVisible(true);
boldMatchInfo();
}
}
});
}
}
@@ -677,13 +678,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, LiveP
updateResults(false);
}
private void removeCurrentHighlights() {
final HighlightManagerImpl highlightManager = (HighlightManagerImpl)HighlightManager.getInstance(myProject);
for (RangeHighlighter highlighter : myHighlighters) {
highlightManager.removeSegmentHighlighter(myEditor, highlighter);
}
}
public void setTextInField(final String text) {
mySearchField.setText(text);
updateResults(true);
@@ -24,4 +24,14 @@ public class LiveOccurrence {
public void setSecondaryRanges(Collection<TextRange> secondaryRanges) {
this.mySecondaryRanges = secondaryRanges;
}
@Override
public boolean equals(Object o) {
if (o instanceof LiveOccurrence) {
if (myPrimaryRange.equals(((LiveOccurrence)o).getPrimaryRange())) {
return true;
}
}
return false;
}
}
@@ -29,15 +29,12 @@ import com.intellij.openapi.editor.event.VisibleAreaListener;
import com.intellij.openapi.editor.markup.CustomHighlighterRenderer;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Alarm;
import com.intellij.util.containers.HashSet;
@@ -105,6 +102,14 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
return myCursor;
}
public Project getProject() {
return myProject;
}
public Editor getEditor() {
return myEditor;
}
public interface CursorListener {
void cursorMoved();
}
@@ -131,6 +136,8 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
void performReplaceAll(Editor e);
void getFocusBack();
Editor getEditor(Ref<Boolean> needToUpdate);
}
private static final int USER_ACTIVITY_TRIGGERING_DELAY = 300;
@@ -167,7 +174,7 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
public LivePreview(Project project) {
myProject = project;
updateEditorReference();
// updateEditorReference();
}
public Delegate getDelegate() {
@@ -179,51 +186,29 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
}
@Nullable
public Editor updateEditorReference() {
private Editor updateEditorReference() {
if (myProject == null) return null;
FileEditorManagerEx instanceEx = FileEditorManagerEx.getInstanceEx(myProject);
if (instanceEx != null) {
VirtualFile currentFile = instanceEx.getCurrentFile();
if (currentFile != null) {
FileEditor[] editors = instanceEx.getEditors(currentFile);
if (editors.length > 0) {
FileEditor fileEditor = editors[0];
boolean focusedFound = false;
for (FileEditor e : editors) {
if (e instanceof TextEditor && ((TextEditor)e).getEditor().getContentComponent().hasFocus()) {
fileEditor = e;
focusedFound = true;
}
}
boolean needToUpdate = true;
if (!focusedFound) {
for (FileEditor e : editors) {
if (e instanceof TextEditor && ((TextEditor)e).getEditor() == myEditor) {
needToUpdate = false;
}
}
}
if (needToUpdate && fileEditor instanceof TextEditor) {
Editor editor1 = ((TextEditor) fileEditor).getEditor();
if (editor1 != myEditor) {
doInternalCleanUp();
}
if (myEditor != null) {
myEditor.getDocument().removeDocumentListener(this);
}
myEditor = editor1;
myEditor.getDocument().addDocumentListener(this);
}
} else {
myEditor = null;
}
} else {
myEditor = null;
}
Ref<Boolean> needToUpdate = new Ref<Boolean>();
Editor result = myDelegate.getEditor(needToUpdate);
if (!needToUpdate.isNull() && needToUpdate.get()) {
setEditor(result);
}
return myEditor;
}
private void setEditor(Editor editor) {
if (editor != myEditor) {
doInternalCleanUp();
}
if (myEditor != null) {
myEditor.getDocument().removeDocumentListener(this);
}
myEditor = editor;
if (myEditor != null) {
myEditor.getDocument().addDocumentListener(this);
}
}
@Override
public void documentChanged(DocumentEvent e) {
doInternalCleanUp();
@@ -399,16 +384,9 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
}
}
private static void drawMatch(Graphics2D g2d, Point start, Point end, int lineHeight, int horizontalGap, int verticalGap) {
g2d.setColor(new Color(50, 50, 50));
g2d.translate(0, start.y-verticalGap);
UIUtil.drawSearchMatch(g2d, start.x-horizontalGap, end.x+horizontalGap, lineHeight+2*verticalGap);
g2d.translate(0, -start.y+verticalGap);
}
private void setCursor(LiveOccurrence liveOccurrence) {
hideBalloon();
boolean toNotify = myCursor != null && !myCursor.equals(liveOccurrence);
boolean toNotify = myCursor == null || !myCursor.equals(liveOccurrence);
myCursor = liveOccurrence;
@@ -421,17 +399,7 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
highlightRange(myCursor.getPrimaryRange(), new TextAttributes(null, null, null, null, 0), dummy);
if (!dummy.isEmpty()) {
myCursorHighlighter = dummy.get(0);
myCursorHighlighter.setCustomRenderer(new CustomHighlighterRenderer() {
@Override
public void paint(Editor editor, RangeHighlighter highlighter, Graphics g) {
Graphics2D g2d = (Graphics2D)g;
VisualPosition startVp = editor.offsetToVisualPosition(highlighter.getStartOffset());
VisualPosition endVp = editor.offsetToVisualPosition(highlighter.getEndOffset());
Point start = editor.visualPositionToXY(startVp);
Point end = editor.visualPositionToXY(endVp);
drawMatch(g2d, start, end, editor.getLineHeight(), 1, 4);
}
});
myCursorHighlighter.setCustomRenderer(new MyCustomCursorRenderer());
}
if (!insideVisibleArea(myEditor, myCursor.getPrimaryRange())) {
@@ -449,7 +417,9 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
}
if (toNotify) {
for (CursorListener l : myListeners) {
l.cursorMoved();
if (l!= null) {
l.cursorMoved();
}
}
}
}
@@ -536,4 +506,21 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
return visibleArea.contains(point);
}
private static class MyCustomCursorRenderer implements CustomHighlighterRenderer {
@Override
public void paint(Editor editor, RangeHighlighter highlighter, Graphics g) {
Graphics2D g2d = (Graphics2D)g;
VisualPosition startVp = editor.offsetToVisualPosition(highlighter.getStartOffset());
VisualPosition endVp = editor.offsetToVisualPosition(highlighter.getEndOffset());
Point start = editor.visualPositionToXY(startVp);
Point end = editor.visualPositionToXY(endVp);
g2d.setColor(new Color(50, 50, 50));
g2d.translate(0, start.y - 4);
Color c1 = new Color(220, 200, 130);
Color c2 = new Color(220, 170, 30);
UIUtil.drawSearchMatch(g2d, start.x- 1, end.x+ 1, editor.getLineHeight() +2* 4, c1, c2);
g2d.translate(0, -start.y + 4);
}
}
}
@@ -4,7 +4,12 @@ import com.intellij.find.FindModel;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.UserActivityListener;
import com.intellij.ui.UserActivityWatcher;
import org.jetbrains.annotations.NotNull;
@@ -88,6 +93,40 @@ public class LivePreviewController implements LivePreview.Delegate, UserActivity
myFindDialog.getContentPane().requestFocus();
}
@Override
public Editor getEditor(Ref<Boolean> needToUpdate) {
Editor result = null;
FileEditorManagerEx instanceEx = FileEditorManagerEx.getInstanceEx(myLivePreview.getProject());
if (instanceEx != null) {
VirtualFile currentFile = instanceEx.getCurrentFile();
if (currentFile != null) {
FileEditor[] editors = instanceEx.getEditors(currentFile);
if (editors.length > 0) {
FileEditor fileEditor = editors[0];
boolean focusedFound = false;
for (FileEditor e : editors) {
if (e instanceof TextEditor && ((TextEditor)e).getEditor().getContentComponent().hasFocus()) {
fileEditor = e;
focusedFound = true;
}
}
needToUpdate.set(true);
if (!focusedFound) {
for (FileEditor e : editors) {
if (e instanceof TextEditor && ((TextEditor)e).getEditor() == myLivePreview.getEditor()) {
needToUpdate.set(false);
}
}
}
if(needToUpdate.get() && fileEditor instanceof TextEditor) {
result = ((TextEditor)fileEditor).getEditor();
}
}
}
}
return result;
}
@Override
public TextRange performReplace(final LiveOccurrence occurrence, final String replacement, final Editor editor) {
updateDelegatesFindModel();
@@ -8,6 +8,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -62,7 +63,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate {
}
int offset = r.getStartOffset();
VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(editor.getDocument());
ArrayList<FindResult> results = new ArrayList<FindResult>();
final ArrayList<FindResult> results = new ArrayList<FindResult>();
while (true) {
FindManager findManager = FindManager.getInstance(editor.getProject());
@@ -76,28 +77,24 @@ public class LivePreviewControllerBase implements LivePreview.Delegate {
if (results.size() > myMatchesLimit) break;
}
if (results.size() < myMatchesLimit) {
if (results.isEmpty()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
notFound();
}
});
}
findResultsToOccurrences(results, occurrences);
} else {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
tooManyMatches();
}
});
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
searchEndsWith(results.size());
}
});
}
return occurrences;
}
protected void tooManyMatches() { }
protected void searchEndsWith(int size) {
}
@Override
public String getReplacementPreviewText(Editor editor, LiveOccurrence liveOccurrence) {
@@ -145,5 +142,9 @@ public class LivePreviewControllerBase implements LivePreview.Delegate {
@Override
public void getFocusBack() {}
public void notFound() {}
@Override
public Editor getEditor(Ref<Boolean> needToUpdate) {
return null;
}
}
@@ -186,14 +186,16 @@ public class TreeChangeEventImpl implements TreeChangeEvent{
}
private void insertAtList(ASTNode node){
final int[] nodeRoute = getRoute(node);
int index = 0;
while(index < myChangedInOrder.size()){
final ASTNode current = myChangedInOrder.get(index++);
final int[] route = getRoute(current);
if(compareRouts(nodeRoute, route) < 0) {
myChangedInOrder.add(index, node);
return;
if (!myChangedInOrder.isEmpty()) {
final int[] nodeRoute = getRoute(node);
int index = 0;
while(index < myChangedInOrder.size()){
final ASTNode current = myChangedInOrder.get(index++);
final int[] route = getRoute(current);
if(compareRouts(nodeRoute, route) < 0) {
myChangedInOrder.add(index, node);
return;
}
}
}
myChangedInOrder.add(node);
@@ -155,7 +155,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
}
@Nullable
public FileViewProvider getCachedViewProvider(Document document) {
public FileViewProvider getCachedViewProvider(@NotNull Document document) {
final VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
if (virtualFile == null || !virtualFile.isValid()) return null;
return ((PsiManagerEx)myPsiManager).getFileManager().findCachedViewProvider(virtualFile);
@@ -521,13 +521,14 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
public void beforeDocumentChange(DocumentEvent event) {
final Document document = event.getDocument();
final FileViewProvider provider = getCachedViewProvider(document);
if (provider == null) return;
final FileViewProvider viewProvider = getCachedViewProvider(document);
if (viewProvider == null) return;
if (!isRelevant(viewProvider)) return;
VirtualFile virtualFile = provider.getVirtualFile();
VirtualFile virtualFile = viewProvider.getVirtualFile();
if (virtualFile.getFileType().isBinary()) return;
final List<PsiFile> files = provider.getAllFiles();
final List<PsiFile> files = viewProvider.getAllFiles();
boolean hasLockedBlocks = false;
for (PsiFile file : files) {
if (file == null) continue;
@@ -556,7 +557,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
}
if (!hasLockedBlocks) {
((SingleRootFileViewProvider)provider).beforeDocumentChanged();
((SingleRootFileViewProvider)viewProvider).beforeDocumentChanged();
}
}
@@ -564,9 +565,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
final Document document = event.getDocument();
final FileViewProvider viewProvider = getCachedViewProvider(document);
if (viewProvider == null) return;
VirtualFile virtualFile = viewProvider.getVirtualFile();
if (virtualFile.getFileType().isBinary()) return;
if (viewProvider.getManager() != myPsiManager) return;
if (!isRelevant(viewProvider)) return;
final List<PsiFile> files = viewProvider.getAllFiles();
boolean commitNecessary = false;
@@ -597,6 +596,11 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
}
}
private boolean isRelevant(FileViewProvider viewProvider) {
VirtualFile virtualFile = viewProvider.getVirtualFile();
return !virtualFile.getFileType().isBinary() && viewProvider.getManager() == myPsiManager && !myPsiManager.getProject().isDisposed();
}
public TextBlock getTextBlock(Document document, PsiFile file) {
TextBlock textBlock = file.getUserData(KEY_TEXT_BLOCK);
if (textBlock == null){
@@ -619,20 +619,11 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
final StubTree derefdOnLock = derefStub();
if (derefdOnLock != null) return derefdOnLock;
setStubTree(stubHolder);
return derefStub();
}
}
public void setStubTree(StubTree stubHolder) {
synchronized (myStubLock) {
assert getTreeElementNoLock() == null;
myStub = new SoftReference<StubTree>(stubHolder);
StubBase<PsiFile> base = (StubBase)stubHolder.getRoot();
base.setPsi(this);
base.putUserData(STUB_TREE_IN_PARSED_TREE, stubHolder); // This will prevent soft reference myStub to be collected before all of the stubs are collected.
return stubHolder;
}
}
@@ -890,7 +881,11 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
final FileElement fileElement = calcTreeElement();
StubTree tree = fileElement.getUserData(STUB_TREE_IN_PARSED_TREE);
if (tree == null) {
final StubElement currentStubTree = ((IStubFileElementType)getContentElementType()).getBuilder().buildStubTree(this);
IElementType contentElementType = getContentElementType();
if (!(contentElementType instanceof IStubFileElementType)) {
LOG.error("ContentElementType: "+contentElementType+"; file: "+this);
}
final StubElement currentStubTree = ((IStubFileElementType)contentElementType).getBuilder().buildStubTree(this);
tree = new StubTree((PsiFileStub)currentStubTree);
bindFakeStubsToTree(tree);
fileElement.putUserData(STUB_TREE_IN_PARSED_TREE, tree);
@@ -87,11 +87,11 @@ public class BlockSupportImpl extends BlockSupport {
file.getViewProvider().beforeContentsSynchronized();
final PsiFileImpl fileImpl = (PsiFileImpl)file;
Project project = fileImpl.getProject();
final CharTable charTable = fileImpl.getTreeElement().getCharTable();
final FileElement treeFileElement = fileImpl.getTreeElement();
final CharTable charTable = treeFileElement.getCharTable();
// hack
final int textLength = file.getTextLength() + lengthShift;
final FileElement treeFileElement = fileImpl.getTreeElement();
if (treeFileElement.getElementType() instanceof ITemplateDataElementType || isTooDeep(file)) {
// unable to perform incremental reparse for template data in JSP, or in exceptionally deep trees
@@ -59,6 +59,8 @@ public abstract class LocalFileSystem extends NewVirtualFileSystem {
*/
public abstract void refreshIoFiles(Iterable<File> files);
public abstract void refreshIoFiles(Iterable<File> files, boolean async, boolean recursive, @Nullable Runnable onFinish);
/**
* Performs a nonrecursive synchronous refresh of specified files
* @param files files to refresh
@@ -66,6 +68,7 @@ public abstract class LocalFileSystem extends NewVirtualFileSystem {
*/
public abstract void refreshFiles(Iterable<VirtualFile> files);
public abstract void refreshFiles(Iterable<VirtualFile> files, boolean async, boolean recursive, @Nullable Runnable onFinish);
public abstract byte[] physicalContentsToByteArray(final VirtualFile virtualFile) throws IOException;
public abstract long physicalLength(final VirtualFile virtualFile) throws IOException;
@@ -151,7 +151,7 @@ public class StartupManagerImpl extends StartupManagerEx {
VirtualFileManager.getInstance().refresh(!app.isHeadlessEnvironment());
}
if (SystemInfo.isMac && SystemInfo.is64Bit && "10.6".compareTo(SystemInfo.OS_VERSION) <= 0) {
if (SystemInfo.isMac && SystemInfo.isMacIntel64 && "10.6".compareTo(SystemInfo.OS_VERSION) <= 0) {
if (Registry.is("ide.firstStartup")) {
String productName = ApplicationNamesInfo.getInstance().getProductName();
Notification n =
@@ -164,9 +164,10 @@ public class StartupManagerImpl extends StartupManagerEx {
}
});
Notifications.Bus.notify(n, NotificationDisplayType.STICKY_BALLOON, null);
Registry.get("ide.firstStartup").setValue(false);
}
}
Registry.get("ide.firstStartup").setValue(false);
}
private void startCacheUpdate() {
@@ -192,7 +192,12 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
return refreshAndFindFileByPath(path.replace(File.separatorChar, '/'));
}
@Override
public void refreshIoFiles(Iterable<File> files) {
refreshIoFiles(files, false, false, null);
}
public void refreshIoFiles(Iterable<File> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
final VirtualFileManagerEx manager = (VirtualFileManagerEx)VirtualFileManager.getInstance();
Application app = ApplicationManager.getApplication();
@@ -209,7 +214,7 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
}
}
RefreshQueue.getInstance().refresh(false, false, null, VfsUtil.toVirtualFileArray(filesToRefresh));
RefreshQueue.getInstance().refresh(async, recursive, onFinish, VfsUtil.toVirtualFileArray(filesToRefresh));
}
finally {
if (fireCommonRefreshSession) manager.fireAfterRefreshFinish(false);
@@ -217,16 +222,16 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
}
public void refreshFiles(Iterable<VirtualFile> files) {
refreshFiles(files, false, false);
refreshFiles(files, false, false, null);
}
protected static void refreshFiles(final Iterable<VirtualFile> files, final boolean recursive, final boolean async) {
public void refreshFiles(Iterable<VirtualFile> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
List<VirtualFile> list = new ArrayList<VirtualFile>();
for (VirtualFile file : files) {
list.add(file);
}
RefreshQueue.getInstance().refresh(async, recursive, null, VfsUtil.toVirtualFileArray(list));
RefreshQueue.getInstance().refresh(async, recursive, onFinish, VfsUtil.toVirtualFileArray(list));
}
public byte[] physicalContentsToByteArray(final VirtualFile virtualFile) throws IOException {
@@ -388,7 +388,7 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
((NewVirtualFile)file).markDirtyRecursively();
}
}
refreshFiles(filesToSynchronize, toWatchRecursively, true);
refreshFiles(filesToSynchronize, true, toWatchRecursively, null);
}
return result;
@@ -72,6 +72,14 @@ public class MockLocalFileSystem extends LocalFileSystem {
public void refreshFiles(final Iterable<VirtualFile> files) {
}
@Override
public void refreshIoFiles(Iterable<File> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
}
@Override
public void refreshFiles(Iterable<VirtualFile> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
}
@Override
public byte[] physicalContentsToByteArray(final VirtualFile virtualFile) throws IOException {
throw new UnsupportedOperationException("'physicalContentsToByteArray' not implemented in " + getClass().getName());
@@ -110,6 +118,7 @@ public class MockLocalFileSystem extends LocalFileSystem {
public void unregisterAuxiliaryFileOperationsHandler(final LocalFileOperationsHandler handler) {
}
@Override
public boolean processCachedFilesInSubtree(final VirtualFile file, final Processor<VirtualFile> processor) {
throw new UnsupportedOperationException("'processCachedFilesInSubtree' not implemented in " + getClass().getName());
@@ -16,6 +16,7 @@
package com.intellij.openapi.util;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -89,35 +90,36 @@ public class ShutDownTracker implements Runnable {
}
}
private synchronized boolean isRegistered(Thread thread) {
private synchronized boolean isRegistered(@NotNull Thread thread) {
return myThreads.contains(thread);
}
@NotNull
private synchronized Thread[] getStopperThreads() {
return myThreads.toArray(new Thread[myThreads.size()]);
}
public synchronized void registerStopperThread(Thread thread) {
public synchronized void registerStopperThread(@NotNull Thread thread) {
myThreads.add(thread);
}
public synchronized void unregisterStopperThread(Thread thread) {
public synchronized void unregisterStopperThread(@NotNull Thread thread) {
myThreads.remove(thread);
}
public synchronized void registerShutdownThread(final Thread thread) {
public synchronized void registerShutdownThread(@NotNull Thread thread) {
myShutdownThreads.addLast(thread);
}
public synchronized void registerShutdownThread(int index, final Thread thread) {
public synchronized void registerShutdownThread(int index, @NotNull Thread thread) {
myShutdownThreads.add(index, thread);
}
public synchronized void registerShutdownTask(Runnable task) {
public synchronized void registerShutdownTask(@NotNull Runnable task) {
myShutdownTasks.addLast(task);
}
public synchronized void unregisterShutdownTask(Runnable task) {
public synchronized void unregisterShutdownTask(@NotNull Runnable task) {
myShutdownTasks.remove(task);
}
@@ -125,8 +127,4 @@ public class ShutDownTracker implements Runnable {
private synchronized <T> T removeLast(LinkedList<T> list) {
return list.isEmpty()? null : list.removeLast();
}
private synchronized <T> boolean isEmpty(LinkedList<T> list) {
return list.isEmpty();
}
}
@@ -53,6 +53,8 @@ public class SystemInfo {
public static final boolean is64Bit = !is32Bit;
public static final boolean isAMD64 = "amd64".equals(OS_ARCH);
public static final boolean isMacIntel64 = isMac && "x86_64".equals(OS_ARCH);
/**
* Whether IDEA is running under MacOS X version 10.4 or later.
*
@@ -120,7 +120,6 @@ public class DiffTree<OT, NT> {
NT newChild2 = newIndex < newSize-1 ? newChildren[newIndex+1] : null;
CompareResult c11 = looksEqual(comparator, oldChild1, newChild1);
if (c11 == CompareResult.EQUAL || c11 == CompareResult.DRILL_DOWN_NEEDED) {
if (c11 == CompareResult.DRILL_DOWN_NEEDED) {
build(oldChild1, newChild1, level+1);
@@ -129,32 +128,32 @@ public class DiffTree<OT, NT> {
newIndex++;
continue;
}
CompareResult c12 = looksEqual(comparator, oldChild1, newChild2);
CompareResult c21 = looksEqual(comparator, oldChild2, newChild1);
if (c11 == CompareResult.TYPE_ONLY) {
CompareResult c21 = looksEqual(comparator, oldChild2, newChild1);
if (c21 == CompareResult.EQUAL || c21 == CompareResult.DRILL_DOWN_NEEDED) {
myConsumer.nodeDeleted(oldNode, oldChild1);
oldIndex++;
continue;
}
else if (c12 == CompareResult.EQUAL || c12 == CompareResult.DRILL_DOWN_NEEDED) {
CompareResult c12 = looksEqual(comparator, oldChild1, newChild2);
if (c12 == CompareResult.EQUAL || c12 == CompareResult.DRILL_DOWN_NEEDED) {
myConsumer.nodeInserted(oldNode, newChild1, newIndex);
newIndex++;
continue;
}
else {
myConsumer.nodeReplaced(oldChild1, newChild1);
oldIndex++;
newIndex++;
continue;
}
myConsumer.nodeReplaced(oldChild1, newChild1);
oldIndex++;
newIndex++;
continue;
}
CompareResult c12 = looksEqual(comparator, oldChild1, newChild2);
if (c12 == CompareResult.EQUAL || c12 == CompareResult.DRILL_DOWN_NEEDED || c12 == CompareResult.TYPE_ONLY) {
myConsumer.nodeInserted(oldNode, newChild1, newIndex);
newIndex++;
continue;
}
CompareResult c21 = looksEqual(comparator, oldChild2, newChild1);
if (c21 == CompareResult.EQUAL || c21 == CompareResult.DRILL_DOWN_NEEDED || c21 == CompareResult.TYPE_ONLY) {
myConsumer.nodeDeleted(oldNode, oldChild1);
oldIndex++;
@@ -20,6 +20,7 @@
package com.intellij.util.messages.impl;
import com.intellij.util.messages.Topic;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Method;
@@ -28,7 +29,7 @@ public final class Message {
private final Method myListenerMethod;
private final Object[] myArgs;
public Message(final Topic topic, final Method listenerMethod, final Object[] args) {
public Message(@NotNull Topic topic, @NotNull Method listenerMethod, Object[] args) {
myTopic = topic;
myListenerMethod = listenerMethod;
myArgs = args;
@@ -49,4 +50,4 @@ public final class Message {
public String toString() {
return myTopic.toString() + ":" + myListenerMethod.getName();
}
}
}
@@ -20,6 +20,7 @@ import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.messages.Topic;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
@@ -32,18 +33,18 @@ public class MessageListenerList<T> {
private final Topic<T> myTopic;
private final Map<T, MessageBusConnection> myListenerToConnectionMap = new HashMap<T, MessageBusConnection>();
public MessageListenerList(MessageBus messageBus, Topic<T> topic) {
public MessageListenerList(@NotNull MessageBus messageBus, @NotNull Topic<T> topic) {
myTopic = topic;
myMessageBus = messageBus;
}
public void add(T listener) {
public void add(@NotNull T listener) {
final MessageBusConnection connection = myMessageBus.connect();
connection.subscribe(myTopic, listener);
myListenerToConnectionMap.put(listener, connection);
}
public void add(final T listener, Disposable parentDisposable) {
public void add(@NotNull final T listener, @NotNull Disposable parentDisposable) {
Disposer.register(parentDisposable, new Disposable() {
public void dispose() {
myListenerToConnectionMap.remove(listener);
@@ -54,7 +55,7 @@ public class MessageListenerList<T> {
myListenerToConnectionMap.put(listener, connection);
}
public void remove(T listener) {
public void remove(@NotNull T listener) {
final MessageBusConnection connection = myListenerToConnectionMap.remove(listener);
if (connection != null) {
connection.disconnect();
@@ -761,9 +761,15 @@ public class UIUtil {
final int startX,
final int endX,
final int height) {
Color c1 = new Color(255, 234, 162);
Color c2 = new Color(255, 208, 66);
drawSearchMatch(g, startX, endX, height, c1, c2);
}
public static void drawSearchMatch(Graphics2D g, int startX, int endX, int height, Color c1, Color c2) {
final boolean drawRound = endX - startX > 4;
g.setPaint(new GradientPaint(startX, 2, new Color(255, 234, 162), startX, height - 5, new Color(255, 208, 66)));
g.setPaint(new GradientPaint(startX, 2, c1, startX, height - 5, c2));
g.fillRect(startX, 3, endX - startX, height - 5);
if (drawRound) {
@@ -129,6 +129,7 @@ public class PluginRunConfiguration extends RunConfigurationBase implements Modu
params.getClassPath().addFirst(libPath + File.separator + "log4j.jar");
params.getClassPath().addFirst(libPath + File.separator + "jdom.jar");
params.getClassPath().addFirst(libPath + File.separator + "trove4j.jar");
params.getClassPath().addFirst(libPath + File.separator + "openapi.jar");
params.getClassPath().addFirst(libPath + File.separator + "util.jar");
params.getClassPath().addFirst(libPath + File.separator + "extensions.jar");
@@ -759,12 +759,12 @@ public class GitPushActiveBranchesDialog extends DialogWrapper {
}
if (postUiTask != null) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
postUiTask.run(roots);
}
}, ModalityState.stateForComponent(getRootPane()));
});
}
}
};
@@ -32,7 +32,7 @@ public class GithubCheckoutProvider implements CheckoutProvider {
return;
}
if (availableRepos.isEmpty()){
Messages.showErrorDialog(project, "You don't have any repository available on GitHub.", "Cannot clone");
Messages.showErrorDialog(project, "You don't have any repository available on GitHub.\nOnly your own or watched repositories can be cloned.", "Cannot clone");
return;
}
Collections.sort(availableRepos, new Comparator<RepositoryInfo>() {
+2
View File
@@ -868,6 +868,8 @@
implementationClass="com.intellij.openapi.roots.ui.configuration.libraryEditor.SourcesOrderRootTypeUIFactory"/>
<OrderRootTypeUI key="DOCUMENTATION"
implementationClass="com.intellij.openapi.roots.ui.configuration.libraryEditor.DocumentationOrderRootTypeUIFactory"/>
<statistics.usagesCollector implementation="com.intellij.openapi.roots.ui.configuration.libraries.impl.LibraryUsageCollector"/>
<getDataRule key="analysisScope" implementationClass="com.intellij.analysis.AnalysisScopeRule"/>
<getDataRule key="context.ProjectFileDirectory" implementationClass="com.intellij.ide.impl.dataRules.ProjectFileDirectoryRule"/>