() {
- public boolean process(VirtualFile file, Integer value) {
- ProgressManager.checkCanceled();
- if (!IndexCacheManagerImpl.shouldBeFound(file, index)) {
+ public boolean process(VirtualFile file, Integer value) {
+ if (progress != null) progress.checkCanceled();
+ if (!IndexCacheManagerImpl.shouldBeFound(file, index)) {
+ return true;
+ }
+ int mask = value.intValue();
+ for (RequestWithProcessor single : data) {
+ final PsiSearchRequest request = single.request;
+ if ((mask & request.searchContext) != 0 && ((GlobalSearchScope)request.searchScope).contains(file)) {
+ local.putValue(file, single);
+ }
+ }
return true;
}
- int mask = value.intValue();
- for (RequestWithProcessor single : data) {
- final PsiSearchRequest request = single.request;
- if ((mask & request.searchContext) != 0 && ((GlobalSearchScope)request.searchScope).contains(file)) {
- local.putValue(file, single);
- }
- }
- return true;
- }
- }, commonScope);
+ }, commonScope);
}
});
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java
index 0237d6756ade..f3f17275ffb5 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java
@@ -406,8 +406,7 @@ public class CodeEditUtil {
public static void setOldIndentation(final TreeElement treeElement, final int oldIndentation) {
if(treeElement == null) return;
- if(oldIndentation >= 0) treeElement.putCopyableUserData(INDENT_INFO, oldIndentation);
- else treeElement.putCopyableUserData(INDENT_INFO, null);
+ treeElement.putCopyableUserData(INDENT_INFO, oldIndentation >= 0 ? oldIndentation : null);
}
public static boolean isMarkedToReformatBefore(final TreeElement element) {
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
index 52323e3a37f6..5946b573b5b1 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
@@ -83,7 +83,7 @@ public abstract class LeafElement extends TreeElement {
return leafTextMatches(text, buffer, start);
}
- public static int leafTextMatches(CharSequence text, CharSequence buffer, int start) {
+ public static int leafTextMatches(@NotNull CharSequence text, @NotNull CharSequence buffer, int start) {
final int length = text.length();
if(buffer.length() - start < length) return -1;
for(int i = 0; i < length; i++){
diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java
index 7fa8c3b2e7fb..47a892abfbe6 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java
@@ -100,7 +100,11 @@ public abstract class ParameterTableModelBase extends L
int column) {
Component component = original.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (!table.isCellEditable(row, table.convertColumnIndexToModel(column))) {
- component.setBackground(table.getBackground().darker());
+ Color bg = table.getBackground().darker();
+ component.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), 230));
+ if (component instanceof EditorTextField) {
+ ((EditorTextField)component).setCenterByHeight(false);
+ }
}
return component;
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellEditorBase.java b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellEditorBase.java
index e0ff09e3c3e1..fa06d4aae1db 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellEditorBase.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellEditorBase.java
@@ -23,6 +23,8 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.ui.EditorTextField;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
import javax.swing.table.TableCellEditor;
import java.awt.*;
@@ -50,11 +52,13 @@ public class CodeFragmentTableCellEditorBase extends AbstractCellEditor implemen
}
protected EditorTextField createEditorField(Document document) {
- return new EditorTextField(document, myProject, myFileType) {
+ EditorTextField field = new EditorTextField(document, myProject, myFileType) {
protected boolean shouldHaveBorder() {
return false;
}
};
+ field.setBorder(new EmptyBorder(1, 1, 1, 1));
+ return field;
}
public PsiCodeFragment getCellEditorValue() {
diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java
index df8e9f67b44b..f76582636804 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java
@@ -24,6 +24,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.ui.EditorTextField;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
@@ -62,7 +63,7 @@ public class CodeFragmentTableCellRenderer implements TableCellRenderer {
}
};
}
- editorTextField.setBorder(hasFocus ? BorderFactory.createLineBorder(table.getForeground()): null);
+ editorTextField.setBorder(hasFocus ? BorderFactory.createLineBorder(table.getForeground()): new EmptyBorder(1, 1, 1, 1));
return editorTextField;
}
}
diff --git a/platform/platform-api/src/com/intellij/lang/LanguageExtension.java b/platform/platform-api/src/com/intellij/lang/LanguageExtension.java
index fdec618383c6..9b36627f81aa 100644
--- a/platform/platform-api/src/com/intellij/lang/LanguageExtension.java
+++ b/platform/platform-api/src/com/intellij/lang/LanguageExtension.java
@@ -43,27 +43,21 @@ public class LanguageExtension extends KeyedExtensionCollector {
return key.getID();
}
- public T forLanguage(Language l) {
+ public T forLanguage(@NotNull Language l) {
T cached = l.getUserData(IN_LANGUAGE_CACHE);
if (cached != null) return cached;
List extensions = forKey(l);
T result;
if (extensions.isEmpty()) {
-
Language base = l.getBaseLanguage();
- if (base != null) {
- result = forLanguage(base);
- }
- else {
- result = myDefaultImplementation;
- }
+ result = base == null ? myDefaultImplementation : forLanguage(base);
}
else {
result = extensions.get(0);
}
-
- l.putUserData(IN_LANGUAGE_CACHE, result);
+ if (result == null) return result;
+ l.putUserDataIfAbsent(IN_LANGUAGE_CACHE, result);
return result;
}
diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
index 5d5e8dd98731..74daf6527798 100644
--- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
+++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
@@ -95,6 +95,11 @@ public class JBScrollPane extends JScrollPane {
public boolean canBePreprocessed(MouseEvent e) {
return JBScrollPane.canBePreprocessed(e, this);
}
+
+ @Override
+ public Dimension getPreferredSize() {
+ return super.getPreferredSize(); //To change body of overridden methods use File | Settings | File Templates.
+ }
}
diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
index b4c83c0cd66b..f4a93cc54492 100644
--- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java
+++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
@@ -45,6 +45,10 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
private MyCellEditorRemover myEditorRemover;
private boolean myEnableAntialiasing;
+ private int myRowHeight = -1;
+ private boolean myRowHeightIsExplicitlySet;
+ private boolean myRowHeightIsComputing;
+
public JBTable() {
this(new DefaultTableModel());
}
@@ -86,6 +90,9 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
final TableModelListener modelListener = new TableModelListener() {
@Override
public void tableChanged(final TableModelEvent e) {
+ if (!myRowHeightIsExplicitlySet) {
+ myRowHeight = -1;
+ }
if ((e.getType() == TableModelEvent.DELETE && isEmpty())
|| (e.getType() == TableModelEvent.INSERT && !isEmpty())) {
repaintViewport();
@@ -113,6 +120,36 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
boolean marker = Patches.SUN_BUG_ID_4503845; // Don't remove. It's a marker for find usages
}
+ @Override
+ public int getRowHeight() {
+ if (myRowHeightIsComputing) return super.getRowHeight();
+
+ if (myRowHeight < 0) {
+ try {
+ myRowHeightIsComputing = true;
+ TableModel model = getModel();
+ for (int row = 0; row < model.getRowCount(); row++) {
+ for (int column = 0; column < model.getColumnCount(); column++) {
+ Dimension size =
+ getCellRenderer(row, column).getTableCellRendererComponent(this, model.getValueAt(row, column), true, true, row, column)
+ .getPreferredSize();
+ myRowHeight = Math.max(size.height, myRowHeight);
+ }
+ }
+ }
+ finally {
+ myRowHeightIsComputing = false;
+ }
+ }
+ return myRowHeight;
+ }
+
+ @Override
+ public void setRowHeight(int rowHeight) {
+ myRowHeight = rowHeight;
+ myRowHeightIsExplicitlySet = true;
+ }
+
private void repaintViewport() {
if (!isDisplayable() || !isVisible()) return;
diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java
index f36e3b33eba9..1df1f86a9e8d 100644
--- a/platform/platform-api/src/com/intellij/ui/table/TableView.java
+++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java
@@ -15,6 +15,10 @@
*/
package com.intellij.ui.table;
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.TableUtil;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
@@ -26,9 +30,8 @@ import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.table.*;
import java.awt.*;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
+import java.awt.event.KeyEvent;
+import java.util.*;
import java.util.List;
public class TableView- extends BaseTableView implements ItemsProvider, SelectionProvider {
@@ -55,6 +58,57 @@ public class TableView
- extends BaseTableView implements ItemsProvider, Sel
return (ListTableModel
- )super.getModel();
}
+
+ @Override
+ public boolean editCellAt(final int row, final int column, final EventObject e) {
+ boolean started = super.editCellAt(row, column, e);
+ if (started && e instanceof KeyEvent) {
+ final Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ if (getEditingColumn() != row && getEditingColumn() != column) return;
+ Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+ if (focusOwner == null || !SwingUtilities.isDescendingFrom(focusOwner, TableView.this)) return;
+
+ KeyEvent keyEvent = (KeyEvent)e;
+ if (Character.isDefined(keyEvent.getKeyChar())) {
+ try {
+ selectAll(focusOwner);
+
+ Robot r = new Robot();
+ r.keyPress(keyEvent.getKeyCode());
+ r.keyRelease(keyEvent.getKeyCode());
+ }
+ catch (AWTException e1) {
+ return;
+ }
+ } else {
+ selectAll(focusOwner);
+ }
+ }
+ };
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ r.run();
+ }
+ });
+ }
+ return started;
+ }
+
+ private void selectAll(Component focusOwner) {
+ if (focusOwner instanceof TextComponent) {
+ ((TextComponent)focusOwner).selectAll();
+ } else {
+ Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(focusOwner));
+ if (editor != null) {
+ editor.getSelectionModel().setSelection(0, editor.getDocument().getTextLength());
+ }
+ }
+ }
+
public TableCellRenderer getCellRenderer(int row, int column) {
final ColumnInfo
- columnInfo = getListTableModel().getColumnInfos()[convertColumnIndexToModel(column)];
final Item item = getListTableModel().getItems().get(convertRowIndexToModel(row));
diff --git a/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java b/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java
index 65e97cca94fc..1cfc6661df48 100644
--- a/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java
+++ b/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java
@@ -19,6 +19,8 @@ import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Application;
@@ -29,12 +31,20 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.FocusManager;
import javax.swing.*;
+import javax.swing.event.CaretListener;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentListener;
import javax.swing.plaf.basic.BasicPopupMenuUI;
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.dnd.DragGestureRecognizer;
+import java.awt.event.AWTEventListener;
+import java.awt.event.HierarchyEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.EventListener;
/**
* This class listens event from ProjectManager and cleanup some
@@ -181,6 +191,60 @@ public final class SwingCleanuper implements ApplicationComponent{
}
}
);
+
+ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+ @Override
+ public void eventDispatched(AWTEvent event) {
+ if (!SystemInfo.isMac || !Registry.is("jvmbugfix.mac.caccessibleLeak")) return;
+
+ HierarchyEvent he = (HierarchyEvent)event;
+ if ((he.getChangeFlags() & (HierarchyEvent.SHOWING_CHANGED)) > 0) {
+ if (he.getComponent() != null && !he.getComponent().isShowing()) {
+ Component c = he.getComponent();
+ if (c instanceof JTextComponent) {
+ JTextComponent textComponent = (JTextComponent)c;
+
+ CaretListener[] carets = textComponent.getListeners(CaretListener.class);
+ for (CaretListener each : carets) {
+ if (isCAccessibleListener(each)) {
+ textComponent.removeCaretListener(each);
+ }
+ }
+
+ Document document = textComponent.getDocument();
+ if (document instanceof AbstractDocument) {
+ DocumentListener[] documentListeners = ((AbstractDocument)document).getDocumentListeners();
+ for (DocumentListener each : documentListeners) {
+ if (isCAccessibleListener(each)) {
+ document.removeDocumentListener(each);
+ }
+ }
+ }
+ } else if (c instanceof JProgressBar) {
+ JProgressBar bar = (JProgressBar)c;
+ ChangeListener[] changeListeners = bar.getChangeListeners();
+ for (ChangeListener each : changeListeners) {
+ if (isCAccessibleListener(each)) {
+ bar.removeChangeListener(each);
+ }
+ }
+ } else if (c instanceof JSlider) {
+ JSlider slider = (JSlider)c;
+ ChangeListener[] changeListeners = slider.getChangeListeners();
+ for (ChangeListener each : changeListeners) {
+ if (isCAccessibleListener(each)) {
+ slider.removeChangeListener(each);
+ }
+ }
+ }
+ }
+ }
+ }
+ }, HierarchyEvent.HIERARCHY_EVENT_MASK);
+ }
+
+ private boolean isCAccessibleListener(EventListener listener) {
+ return listener != null && listener.toString().contains("AXTextChangeNotifier");
}
private static void resetField(Object object, Class type, @NonNls String name) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java
index 75f62da8b6eb..4ea4bf781df4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java
@@ -28,6 +28,7 @@ import com.intellij.util.containers.FilteringIterator;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
public class ApplyNonConflicts extends AnAction implements DumbAware {
public ApplyNonConflicts() {
@@ -36,7 +37,7 @@ public class ApplyNonConflicts extends AnAction implements DumbAware {
public void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
- ArrayList notConflicts = ContainerUtil.collect(getNotConflicts(dataContext));
+ List notConflicts = ContainerUtil.collect(getNotConflicts(dataContext));
for (Change change : notConflicts) {
Change.apply(change, MergeList.BRANCH_SIDE);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index 699c7ff1eb09..b71ce84d2def 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -228,7 +228,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private boolean myGutterNeedsUpdate = false;
private Alarm myAppleRepaintAlarm;
- private Alarm myMouseSelectionStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
+ private final Alarm myMouseSelectionStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
private Runnable myMouseSelectionStateResetRunnable;
private boolean myEmbeddedIntoDialogWrapper;
@@ -1721,6 +1721,19 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (attributes.getEffectType() == EffectType.WAVE_UNDERSCORE) {
drawWave(g, end.x, end.x + charWidth - 1, y);
}
+ else if (attributes.getEffectType() == EffectType.BOLD_DOTTED_LINE) {
+ final int dottedAt = SystemInfo.isMac ? y - 1 : y;
+ UIUtil.drawBoldDottedLine((Graphics2D)g, end.x, end.x + charWidth - 1, dottedAt,
+ getBackgroundColor(attributes), attributes.getEffectColor(), false);
+ }
+ else if (attributes.getEffectType() == EffectType.STRIKEOUT) {
+ int y1 = y - getCharHeight() / 2 - 1;
+ UIUtil.drawLine(g, end.x, y1, end.x + charWidth - 1, y1);
+ }
+ else if (attributes.getEffectType() == EffectType.BOLD_LINE_UNDERSCORE) {
+ UIUtil.drawLine(g, end.x, y - 1, end.x + charWidth - 1, y - 1);
+ UIUtil.drawLine(g, end.x, y, end.x + charWidth - 1, y);
+ }
else if (attributes.getEffectType() != EffectType.BOXED) {
UIUtil.drawLine(g, end.x, y, end.x + charWidth - 1, y);
}
@@ -4682,8 +4695,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private boolean processMousePressed(MouseEvent e) {
- boolean isNavigation = false;
-
myInitialMouseEvent = e;
if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE && System.currentTimeMillis() - myMouseSelectionChangeTimestamp > Registry.intValue(
@@ -4698,6 +4709,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (y < 0) y = 0;
final EditorMouseEventArea eventArea = getMouseEventArea(e);
+ boolean isNavigation = false;
if (eventArea == EditorMouseEventArea.FOLDING_OUTLINE_AREA) {
final FoldRegion range = myGutterComponent.findFoldingAnchorAt(x, y);
if (range != null) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java
index c5f7460f6616..c025221f4fe4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java
@@ -25,7 +25,10 @@ import gnu.trove.TLongHashSet;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.ReferenceQueue;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -36,40 +39,44 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
public abstract class IntervalTreeImpl extends RedBlackTree implements IntervalTree {
protected int keySize; // number of all keys
protected final ReadWriteLock l = new ReentrantReadWriteLock();
+ private IntervalNode minNode; // left most node in the tree
protected abstract EqualStartIntervalComparator getComparator();
private final ReferenceQueue myReferenceQueue = new ReferenceQueue();
private int deadReferenceCount;
- public abstract class IntervalNode extends RedBlackTree.Node implements MutableInterval {
- protected int maxEnd; // max of all intervalEnd()s among all children.
- protected int delta; // delta of startOffset. getStartOffset() = myStartOffset + Sum of deltas up to root
- protected abstract int computeDeltaUpToRoot();
- @Override
- public IntervalNode getLeft() {
- return (IntervalNode)super.getLeft();
- }
- @Override
- public IntervalNode getRight() {
- return (IntervalNode)super.getRight();
- }
- @Override
- public IntervalNode getParent() {
- return (IntervalNode)super.getParent();
- }
- }
-
- protected class MyNode extends IntervalNode {
+ protected class IntervalNode extends Node implements MutableInterval/*, Iterable, Iterator*/ {
private volatile int myStart;
private volatile int myEnd;
private volatile boolean isValid = true;
- protected final List> intervals;
- public MyNode(@NotNull T key, int start, int end) {
+ protected final SmartList> intervals;
+ protected int maxEnd; // max of all intervalEnd()s among all children.
+ protected int delta; // delta of startOffset. getStartOffset() = myStartOffset + Sum of deltas up to root
+ IntervalNode next; // node following this in the in-order tree traversal. used for optimised tree iteration
+
+ public IntervalNode(@NotNull T key, int start, int end) {
// maxEnd == 0 so to not disrupt existing maxes
intervals = new SmartList>(createGetable(key));
myStart = start;
myEnd = end;
}
+
+
+ @Override
+ public IntervalNode getLeft() {
+ return (IntervalNode)left;
+ }
+
+ @Override
+ public IntervalNode getRight() {
+ return (IntervalNode)right;
+ }
+
+ @Override
+ public IntervalNode getParent() {
+ return (IntervalNode)parent;
+ }
+
@Override
public boolean processAliveKeys(@NotNull Processor super T> processor) {
for (Getable interval : intervals) {
@@ -79,21 +86,6 @@ public abstract class IntervalTreeImpl extends RedBla
return true;
}
- @NotNull
- @Override
- public List getAliveKeys() {
- List result = null;
- for (Getable ref : intervals) {
- T interval = ref.get();
- if (interval == null) continue;
- if (result == null) {
- result = new ArrayList(intervals.size());
- }
- result.add(interval);
- }
- return result == null ? Collections.emptyList() : result;
- }
-
public boolean hasAliveKey(boolean purgeDead) {
for (int i = intervals.size() - 1; i >= 0; i--) {
Getable interval = intervals.get(i);
@@ -126,8 +118,7 @@ public abstract class IntervalTreeImpl extends RedBla
return false;
}
}
- List aliveKeys = getAliveKeys();
- assert false: "not found interval: "+key +"; "+ aliveKeys;
+ assert false: "interval not found: "+key +"; "+ intervals;
return false;
}
@@ -147,7 +138,6 @@ public abstract class IntervalTreeImpl extends RedBla
return new WeakReferencedGetable(interval, myReferenceQueue);
}
- @Override
protected int computeDeltaUpToRoot() {
if (normalized) return 0;
int delta = 0;
@@ -205,8 +195,8 @@ public abstract class IntervalTreeImpl extends RedBla
}
@NotNull
- protected abstract MyNode createNewNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer);
- protected abstract MyNode lookupNode(@NotNull T key);
+ protected abstract IntervalNode createNewNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer);
+ protected abstract IntervalNode lookupNode(@NotNull T key);
private int compareNodes(@NotNull IntervalNode i1, int delta1, @NotNull IntervalNode i2, int delta2, @NotNull List invalid) {
if (!i2.hasAliveKey(false)) {
@@ -339,7 +329,7 @@ public abstract class IntervalTreeImpl extends RedBla
return processOverlapping(root.getRight(), offset, processor, modCountBefore, delta);
}
- protected MyNode findOrInsert(@NotNull IntervalNode node) {
+ protected IntervalNode findOrInsert(@NotNull IntervalNode node) {
node.color = Color.RED;
node.setParent(null);
node.setValid(true);
@@ -353,14 +343,14 @@ public abstract class IntervalTreeImpl extends RedBla
root = node;
}
else {
- IntervalNode current = (IntervalNode)root;
+ IntervalNode current = getRoot();
int delta = 0;
loop:
while (true) {
delta += current.delta;
int compResult = compareNodes(node, 0, current, delta, gced);
if (compResult == 0) {
- return (MyNode)current;
+ return current;
}
if (compResult < 0) {
if (current.getLeft() == null) {
@@ -380,14 +370,56 @@ public abstract class IntervalTreeImpl extends RedBla
node.delta = -delta;
node.setParent(current);
}
+ linkNode(node);
correctMaxUp(node);
onInsertNode();
- keySize += ((MyNode)node).intervals.size();
+ keySize += node.intervals.size();
insertCase1(node);
verifyProperties();
deleteNodes(gced);
- return (MyNode)node;
+ return node;
+ }
+
+ private void linkNode(@NotNull IntervalNode node) {
+ IntervalNode previous = previous(node);
+ if (previous == null) {
+ node.next = minNode;
+ minNode = node;
+ }
+ else {
+ node.next = previous.next;
+ previous.next = node;
+ }
+ }
+
+ private void unlinkNode(@NotNull IntervalNode node) {
+ IntervalNode previous = previous(node);
+ if (previous == null) {
+ minNode = node.next;
+ }
+ else {
+ previous.next = node.next;
+ }
+ node.next = null;
+ }
+
+ // finds previous in the in-order traversal
+ private IntervalNode previous(@NotNull IntervalNode node) {
+ IntervalNode left = node.getLeft();
+ if (left != null) {
+ while (left.getRight() != null) {
+ left = left.getRight();
+ }
+ return left;
+ }
+ IntervalNode parent = node.getParent();
+ while (parent != null) {
+ if (parent.getRight() == node) break;
+ node = parent;
+ parent = parent.getParent();
+ }
+ return parent;
}
private void deleteNodes(List collectedAway) {
@@ -405,14 +437,14 @@ public abstract class IntervalTreeImpl extends RedBla
}
}
- public MyNode addInterval(@NotNull T interval, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
+ public IntervalNode addInterval(@NotNull T interval, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
try {
l.writeLock().lock();
checkMax(true);
processReferenceQueue();
modCount++;
IntervalNode newNode = createNewNode(interval, start, end, greedyToLeft, greedyToRight, layer);
- MyNode insertedNode = findOrInsert(newNode);
+ IntervalNode insertedNode = findOrInsert(newNode);
if (insertedNode != newNode) {
// merged
insertedNode.addInterval(interval);
@@ -442,19 +474,22 @@ public abstract class IntervalTreeImpl extends RedBla
}
// returns real (minStart, maxStart, maxEnd)
- protected Trinity checkMax(IntervalNode root,
- int deltaUpToRootExclusive,
- boolean assertInvalid,
- Ref allValid,
- AtomicInteger keyCounter,
- AtomicInteger nodeCounter,
- TLongHashSet ids) {
+ private Trinity checkMax(IntervalNode root,
+ int deltaUpToRootExclusive,
+ boolean assertInvalid,
+ Ref allValid,
+ AtomicInteger keyCounter,
+ AtomicInteger nodeCounter,
+ TLongHashSet ids) {
if (root == null) return Trinity.create(Integer.MAX_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE);
- for (T t : root.getAliveKeys()) {
+ for (int i = root.intervals.size() - 1; i >= 0; i--) {
+ T t = root.intervals.get(i).get();
+ if (t == null) continue;
checkBelongsToTheTree(t, assertInvalid);
assert ids.add(((RangeMarkerImpl)t).getId()) : t;
}
- keyCounter.addAndGet(((MyNode)root).intervals.size());
+
+ keyCounter.addAndGet(root.intervals.size());
nodeCounter.incrementAndGet();
int delta = deltaUpToRootExclusive + (root.isValid() ? root.delta : 0);
Trinity l = checkMax(root.getLeft(), delta, assertInvalid, allValid, keyCounter, nodeCounter, ids);
@@ -503,22 +538,26 @@ public abstract class IntervalTreeImpl extends RedBla
protected void checkBelongsToTheTree(T interval, boolean assertInvalid) {
if (!VERIFY) return;
- MyNode root = lookupNode(interval);
+ IntervalNode root = lookupNode(interval);
if (root == null) return;
assert !root.intervals.isEmpty();
assert root.getTree() == this;
- List keys = root.getAliveKeys();
- assert keys.contains(interval) : keys + "; " + interval;
- for (T key : keys) {
- MyNode node = lookupNode(key);
+ boolean contains = false;
+ for (int i = root.intervals.size() - 1; i >= 0; i--) {
+ T key = root.intervals.get(i).get();
+ if (key == null) continue;
+ contains |= key == interval;
+ IntervalNode node = lookupNode(key);
assert assertInvalid && node == root || !assertInvalid && (node == null || node == root) : node;
assert assertInvalid && node.getTree() == this || !assertInvalid && (node == null || node.getTree() == this) : node;
}
+ assert contains : root.intervals + "; " + interval;
+
IntervalNode e = root;
while (e.getParent() != null) e = e.getParent();
- assert e == this.root; // assert the node belongs to our tree
+ assert e == getRoot(); // assert the node belongs to our tree
}
@Override
@@ -530,7 +569,7 @@ public abstract class IntervalTreeImpl extends RedBla
checkMax(true);
processReferenceQueue();
- MyNode node = lookupNode(interval);
+ IntervalNode node = lookupNode(interval);
if (node == null) return false;
node.removeInterval(interval);
@@ -543,7 +582,7 @@ public abstract class IntervalTreeImpl extends RedBla
}
// run under write lock
- public void removeNode(@NotNull IntervalNode node) {
+ void removeNode(@NotNull IntervalNode node) {
deleteNode(node);
IntervalNode parent = node.getParent();
correctMaxUp(parent);
@@ -551,8 +590,10 @@ public abstract class IntervalTreeImpl extends RedBla
@Override
protected void deleteNode(Node n) {
- MyNode node = (MyNode)n;
+ IntervalNode node = (IntervalNode)n;
pushDeltaFromRoot(node);
+ unlinkNode(node);
+
super.deleteNode(n);
keySize -= node.intervals.size();
@@ -564,9 +605,9 @@ public abstract class IntervalTreeImpl extends RedBla
return keySize;
}
- // returns true if some delta was or became not null
+ // returns true if all deltas involved are still 0
protected boolean pushDelta(IntervalNode root) {
- if (root == null || !root.isValid()) return false;
+ if (root == null || !root.isValid()) return true;
int delta = root.delta;
if (delta != 0) {
root.setIntervalStart(root.intervalStart() + delta);
@@ -575,23 +616,23 @@ public abstract class IntervalTreeImpl extends RedBla
root.delta = 0;
//noinspection NonShortCircuitBooleanExpression
return
- incDelta(root.getLeft(), delta) |
+ incDelta(root.getLeft(), delta) &
incDelta(root.getRight(), delta);
}
- return false;
+ return true;
}
- // returns true if some delta was or became not null
+ // returns true if all deltas involved are still 0
private boolean incDelta(IntervalNode root, int delta) {
- if (root == null) return false;
+ if (root == null) return true;
if (root.isValid()) {
int newDelta = root.delta += delta;
- return newDelta != 0;
+ return newDelta == 0;
}
else {
//noinspection NonShortCircuitBooleanExpression
return
- incDelta(root.getLeft(), delta) |
+ incDelta(root.getLeft(), delta) &
incDelta(root.getRight(), delta);
}
}
@@ -743,10 +784,7 @@ public abstract class IntervalTreeImpl extends RedBla
}
public Iterator iterator() {
- IntervalNode firstNode = getRoot();
- while (firstNode != null && firstNode.getLeft() != null) {
- firstNode = firstNode.getLeft();
- }
+ IntervalNode firstNode = minNode;
if (firstNode == null) {
return ContainerUtil.emptyIterator();
}
@@ -795,58 +833,37 @@ public abstract class IntervalTreeImpl extends RedBla
final int modCountBefore = modCount;
return new Iterator() {
private IntervalNode node = firstNode;
- private Iterator iteratorInCurrentList = firstNode.getAliveKeys().iterator();
-
- {
- // find first non-null key
- while (!iteratorInCurrentList.hasNext()) {
- moveNext();
- if (node == null) break;
- }
- }
+ private int indexInCurrentList = 0;
+ T current;
public boolean hasNext() {
- Iterator it = iteratorInCurrentList;
- return it != null && it.hasNext();
+ if (current != null) return true;
+ while (node != null) {
+ while (indexInCurrentList != node.intervals.size()) {
+ current = node.intervals.get(indexInCurrentList).get();
+ if (current != null) return true;
+ indexInCurrentList++;
+ }
+ indexInCurrentList = 0;
+ node = getNextNode(node);
+ }
+ return false;
}
public T next() {
assert modCount == modCountBefore : "Must not modify range markers during iterate";
- if (node == null || iteratorInCurrentList == null || !iteratorInCurrentList.hasNext()) throw new NoSuchElementException();
- T current = iteratorInCurrentList.next();
- moveNext();
- return current;
+ if (!hasNext()) throw new NoSuchElementException();
+
+ T t = current;
+ current = null;
+
+ indexInCurrentList++;
+ return t;
}
- private void moveNext() {
- if (iteratorInCurrentList != null && iteratorInCurrentList.hasNext()) return;
- while (true) {
- node = getNextNode();
- if (node == null) {
- iteratorInCurrentList = null;
- break;
- }
- iteratorInCurrentList = node.getAliveKeys().iterator();
- if (iteratorInCurrentList.hasNext()) break;
- }
- }
- private IntervalNode getNextNode() {
- IntervalNode n = node.getRight();
- if (n != null) {
- while (n.getLeft()!= null) {
- n = n.getLeft();
- }
- return n;
- }
- IntervalNode parent = node.getParent();
- IntervalNode current = node;
- while (parent != null) {
- if (parent.getLeft() == current) return parent;
- current = parent;
- parent = parent.getParent();
- }
- return null;
+ private IntervalNode getNextNode(IntervalNode node) {
+ return node.next;
}
public void remove() {
@@ -881,13 +898,13 @@ public abstract class IntervalTreeImpl extends RedBla
try {
l.writeLock().lock();
- MyNode node = lookupNode(interval);
+ IntervalNode node = lookupNode(interval);
if (node == null) return;
int before = size();
boolean nodeRemoved = node.removeInterval(interval);
assert nodeRemoved || !node.intervals.isEmpty();
- MyNode insertedNode = addInterval(interval, start, end, greedyToLeft, greedyToRight, layer);
+ IntervalNode insertedNode = addInterval(interval, start, end, greedyToLeft, greedyToRight, layer);
assert node != insertedNode;
int after = size();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java
index c3efa8a61aed..8337e9b0ea35 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java
@@ -141,7 +141,7 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx
}
}
- IntervalTreeImpl.IntervalNode addRangeHighlighter(RangeHighlighterEx marker,
+ IntervalTreeImpl.IntervalNode addRangeHighlighter(RangeHighlighterEx marker,
int start,
int end,
boolean greedyToLeft,
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeHighlighterTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeHighlighterTree.java
index f8fa6ff69c4d..b9ceb3307bdf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeHighlighterTree.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeHighlighterTree.java
@@ -74,7 +74,7 @@ public class RangeHighlighterTree extends RangeMarkerTree {
myLayer = layer;
}
- // range highlighters are strongly referenced
+ //range highlighters are strongly referenced
@Override
protected Getable createGetable(@NotNull RangeHighlighterEx interval) {
return (Getable)interval;
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
index 65e4ba599d06..d2eb1cbc9ed1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
@@ -82,7 +82,7 @@ public class RangeMarkerTree extends IntervalTreeImpl extends IntervalTreeImpl extends IntervalTreeImpl extends IntervalTreeImpl affected = new ArrayList();
- normalized &= !collectAffectedMarkers(getRoot(), e, affected);
+ normalized &= collectAffectedMarkers(getRoot(), e, affected);
checkMax(false);
if (!affected.isEmpty()) {
@@ -180,9 +177,15 @@ public class RangeMarkerTree extends IntervalTreeImpl aliveKeys = node.getAliveKeys();
- if (aliveKeys.isEmpty()) continue; // collected
- RangeMarkerImpl marker = (RangeMarkerImpl)aliveKeys.get(0);
+ List> keys = node.intervals;
+ if (keys.isEmpty()) continue; // collected away
+
+ RangeMarkerImpl marker = null;
+ for (Getable key : keys) {
+ marker = (RangeMarkerImpl)key.get();
+ if (marker != null) break;
+ }
+ if (marker == null) continue;
marker.setValid(true);
//marker.myNode = null;
marker.documentChanged(e);
@@ -191,7 +194,9 @@ public class RangeMarkerTree extends IntervalTreeImpl key : keys) {
+ T interval = key.get();
+ if (interval == null) continue;
insertedNode.addInterval(interval);
}
}
@@ -206,15 +211,14 @@ public class RangeMarkerTree extends IntervalTreeImpl affected) {
- if (root == null) return false;
- boolean denorm = pushDelta(root);
+ // returns true if all deltas involved are still 0
+ private boolean collectAffectedMarkers(IntervalNode root, @NotNull DocumentEvent e, @NotNull List affected) {
+ if (root == null) return true;
+ boolean norm = pushDelta(root);
int maxEnd = root.maxEnd;
assert root.isValid();
@@ -227,19 +231,19 @@ public class RangeMarkerTree extends IntervalTreeImpl maxEnd) {
-
+ // no need to bother
}
else if (affectedEndOffset < root.intervalStart()) {
int lengthDelta = e.getNewLength() - e.getOldLength();
int newD = root.delta += lengthDelta;
- denorm |= newD != 0;
+ norm &= newD == 0;
IntervalNode left = root.getLeft();
if (left != null) {
int newL = left.delta -= lengthDelta;
- denorm |= newL != 0;
+ norm &= newL == 0;
}
- denorm |= pushDelta(root);
- denorm |= collectAffectedMarkers(left, e, affected);
+ norm &= pushDelta(root);
+ norm &= collectAffectedMarkers(left, e, affected);
correctMax(root, 0);
}
else {
@@ -249,11 +253,11 @@ public class RangeMarkerTree extends IntervalTreeImpl sweepProcessor) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java
index 88919cc518b9..a0ced136790a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java
@@ -18,8 +18,6 @@ package com.intellij.openapi.editor.impl;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
-import java.util.List;
-
/**
* User: cdr
@@ -296,9 +294,9 @@ public abstract class RedBlackTree {
}
public abstract static class Node {
- private Node left;
- private Node right;
- private Node parent = null;
+ protected Node left;
+ protected Node right;
+ protected Node parent = null;
protected Color color = Color.RED;
public Node() {
@@ -347,8 +345,7 @@ public abstract class RedBlackTree {
}
public abstract boolean processAliveKeys(@NotNull Processor super K> processor);
- @NotNull
- public abstract List getAliveKeys();
+
public abstract boolean hasAliveKey(boolean purgeDead);
}
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
index a55f9f7f19bc..6e217d4d1beb 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
@@ -73,6 +73,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
private boolean myInheritSwingFont = true;
private Color myEnforcedBgColor = null;
private boolean myOneLineMode; // use getter to access this field! It is allowed to override getter and change initial behaviour
+ private boolean myCenterByHeight = true;
public EditorTextField() {
this("");
@@ -100,7 +101,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
setDocument(document);
myProject = project;
myFileType = fileType;
- setLayout(new BorderLayout());
+ setLayout(null);
enableEvents(AWTEvent.KEY_EVENT_MASK);
// todo[dsl,max]
setFocusable(true);
@@ -207,7 +208,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
Editor editor = myEditor;
myEditor = createEditor();
releaseEditor(editor);
- add(myEditor.getComponent(), BorderLayout.CENTER);
+ add(myEditor.getComponent());
validate();
if (isFocused) {
@@ -307,7 +308,8 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
boolean isFocused = isFocusOwner();
myEditor = createEditor();
- add(myEditor.getComponent(), BorderLayout.CENTER);
+ final JComponent component = myEditor.getComponent();
+ add(component);
super.addNotify();
@@ -393,6 +395,8 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
editor.setBackgroundColor(getBackgroundColor(!myIsViewer, colorsScheme));
}
+
+
public void setOneLineMode(boolean oneLineMode) {
myOneLineMode = oneLineMode;
}
@@ -527,7 +531,10 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
Editor editor = myEditor;
releaseEditor(editor);
myEditor = createEditor();
- add(myEditor.getComponent(), BorderLayout.CENTER);
+ add(myEditor.getComponent()
+
+
+ );
revalidate();
}
}
@@ -539,7 +546,25 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
: UIUtil.getInactiveTextFieldBackgroundColor();
}
+ @Override
+ public void doLayout() {
+ if (getComponentCount() != 1) return;
+
+ Component c = getComponent(0);
+ Insets insets = getInsets() != null ? getInsets() : new Insets(0, 0, 0, 0);
+ int prefHeight = c.getPreferredSize().height;
+ if (myOneLineMode && getSize().height > prefHeight && myCenterByHeight) {
+ int y = insets.top + getSize().height / 2 - prefHeight / 2;
+ c.setBounds(insets.left, y - 1, getSize().width - insets.left - insets.right, prefHeight);
+ } else {
+ c.setBounds(insets.left, insets.top, getSize().width - insets.left - insets.right, getSize().height - insets.top - insets.bottom);
+ }
+ }
+
public Dimension getPreferredSize() {
+ if (super.isPreferredSizeSet()) {
+ return super.getPreferredSize();
+ }
if (myEditor != null) {
final Dimension preferredSize = new Dimension(myEditor.getComponent().getPreferredSize());
final Insets insets = getInsets();
@@ -624,6 +649,10 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
setDocument(document);
}
+ public void setCenterByHeight(boolean centerByHeight) {
+ myCenterByHeight = centerByHeight;
+ }
+
private static class DelegatingToRootTraversalPolicy extends FocusTraversalPolicy {
@Override
public Component getComponentAfter(final Container aContainer, final Component aComponent) {
diff --git a/platform/platform-impl/src/com/intellij/util/ui/ChangesTrackingTableView.java b/platform/platform-impl/src/com/intellij/util/ui/ChangesTrackingTableView.java
index 5e205b9bf462..0b89e21798a6 100644
--- a/platform/platform-impl/src/com/intellij/util/ui/ChangesTrackingTableView.java
+++ b/platform/platform-impl/src/com/intellij/util/ui/ChangesTrackingTableView.java
@@ -39,15 +39,6 @@ public abstract class ChangesTrackingTableView extends TableView {
protected abstract void onEditingStopped();
- @Override
- public TableCellEditor getCellEditor(int row, int column) {
- final TableCellEditor editor = super.getCellEditor(row, column);
- if (column == 0 && editor instanceof DefaultCellEditor) {
- //((DefaultCellEditor)editor).setClickCountToStart(1);
- }
- return editor;
- }
-
@Override
public boolean editCellAt(final int row, final int column, EventObject e) {
if (super.editCellAt(row, column, e)) {
@@ -58,16 +49,25 @@ public abstract class ChangesTrackingTableView extends TableView {
}
};
addChangeListener(getEditorComponent(), new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- onCellValueChanged(row, column, getValue(getEditorComponent()));
- }
- }, myEditorListenerDisposable);
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ onCellValueChanged(row, column, getValue(getEditorComponent()));
+ }
+ }, myEditorListenerDisposable);
return true;
}
return false;
}
+ @Override
+ public TableCellEditor getCellEditor(int row, int column) {
+ final TableCellEditor editor = super.getCellEditor(row, column);
+ if (column == 0 && editor instanceof DefaultCellEditor) {
+ //((DefaultCellEditor)editor).setClickCountToStart(1);
+ }
+ return editor;
+ }
+
@Override
public void removeEditor() {
if (myEditorListenerDisposable != null) {
diff --git a/platform/platform-impl/testSrc/com/intellij/util/IJSwingUtilitiesTest.java b/platform/platform-impl/testSrc/com/intellij/util/IJSwingUtilitiesTest.java
index 3ac0465a6e91..16a52883fcab 100644
--- a/platform/platform-impl/testSrc/com/intellij/util/IJSwingUtilitiesTest.java
+++ b/platform/platform-impl/testSrc/com/intellij/util/IJSwingUtilitiesTest.java
@@ -20,7 +20,7 @@ import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
-import java.util.ArrayList;
+import java.util.List;
public class IJSwingUtilitiesTest extends TestCase {
private final JPanel myPanel = new JPanel();
@@ -52,7 +52,7 @@ public class IJSwingUtilitiesTest extends TestCase {
CHECK.compareAll(new JComponent[]{label1, subPanel, label2, label3, label4}, getChildren());
}
- private ArrayList getChildren() {
+ private List getChildren() {
return ContainerUtil.collect(IJSwingUtilities.getChildren(myPanel));
}
diff --git a/platform/platform-resources-en/src/messages/XmlErrorMessages.properties b/platform/platform-resources-en/src/messages/XmlErrorMessages.properties
index c88534f96060..7a375eae8ebe 100644
--- a/platform/platform-resources-en/src/messages/XmlErrorMessages.properties
+++ b/platform/platform-resources-en/src/messages/XmlErrorMessages.properties
@@ -11,7 +11,7 @@ element.is.not.allowed.here=Element {0} is not allowed here
element.must.be.declared=Element {0} must be declared
element.doesnt.have.required.attribute=Element {0} doesn''t have required attribute {1}
wrong.root.element=Wrong root element
-unbound.namespace=Namespace {0} is not bound
+unbound.namespace=Namespace ''{0}'' is not bound
unbound.namespace.no.param=Namespace is not bound
attribute.is.not.allowed.here=Attribute {0} is not allowed here
empty.attribute.is.not.allowed=Empty attribute {0} is not allowed
diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties
index 474e36f5ba89..64f450c97174 100644
--- a/platform/platform-resources-en/src/misc/registry.properties
+++ b/platform/platform-resources-en/src/misc/registry.properties
@@ -123,3 +123,5 @@ navbar.newpopup=true
inspectionGadgets.telemetry.enabled=false
minuscule.humps.matching=false
minuscule.humps.matching.description=Camel Case without holding Shift in Ctrl+N/Ctrl+Shift+N etc
+
+jvmbugfix.mac.caccessibleLeak=true
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index b009446fd8ba..5fb1d1d608aa 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -28,6 +28,9 @@
+
+
availableIntentions = fixture.getAvailableIntentions();
+ final IntentionAction intentionAction = findIntentionByText(availableIntentions, action);
+ Assert.assertTrue("Action not found: " + action + " among " + availableIntentions, intentionAction != null);
new WriteCommandAction(fixture.getProject()) {
@Override
protected void run(Result result) throws Throwable {
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java
new file mode 100644
index 000000000000..a8f9a8366b8d
--- /dev/null
+++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java
@@ -0,0 +1,110 @@
+package com.intellij.execution.testframework.autotest;
+
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.execution.ui.RunContentManagerImpl;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.event.DocumentAdapter;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.content.Content;
+import com.intellij.util.Alarm;
+import com.intellij.util.containers.WeakList;
+
+import java.util.Collection;
+
+/**
+ * @author yole
+ */
+public class AutoTestManager {
+ private final Project myProject;
+ private final Alarm myAutoTestAlarm;
+
+ private static final int AUTOTEST_DELAY = 2000;
+ private final Runnable myRunTestsRunnable;
+ private boolean myListenerAttached;
+ private final MyDocumentAdapter myListener;
+
+ public static AutoTestManager getInstance(Project project) {
+ return ServiceManager.getService(project, AutoTestManager.class);
+ }
+
+ private final Collection myEnabledDescriptors = new WeakList();
+
+ public AutoTestManager(Project project) {
+ myProject = project;
+ myAutoTestAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, project);
+ myRunTestsRunnable = new Runnable() {
+ public void run() {
+ runAutoTests();
+ }
+ };
+ myListener = new MyDocumentAdapter();
+ }
+
+ public void setAutoTestEnabled(RunContentDescriptor descriptor, boolean enabled) {
+ Content content = descriptor.getAttachedContent();
+ if (enabled) {
+ if (!myEnabledDescriptors.contains(content)) {
+ myEnabledDescriptors.add(content);
+ }
+ if (!myListenerAttached) {
+ myListenerAttached = true;
+ EditorFactory.getInstance().getEventMulticaster().addDocumentListener(myListener, myProject);
+ }
+ }
+ else {
+ myEnabledDescriptors.remove(content);
+ if (myEnabledDescriptors.isEmpty() && myListenerAttached) {
+ myListenerAttached = false;
+ EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(myListener);
+ }
+ }
+ }
+
+ public boolean isAutoTestEnabled(RunContentDescriptor descriptor) {
+ return myEnabledDescriptors.contains(descriptor.getAttachedContent());
+ }
+
+ public void runAutoTests() {
+ for (Content content : myEnabledDescriptors) {
+ runAutoTest(content);
+ }
+ }
+
+ private static void runAutoTest(Content content) {
+ RunContentDescriptor descriptor = RunContentManagerImpl.getRunContentDescriptorByContent(content);
+ if (descriptor == null) {
+ return;
+ }
+ Runnable restarter = descriptor.getRestarter();
+ if (restarter == null) {
+ return;
+ }
+ final ProcessHandler processHandler = descriptor.getProcessHandler();
+ if (processHandler != null && !processHandler.isProcessTerminated()) {
+ return;
+ }
+ restarter.run();
+ }
+
+ private class MyDocumentAdapter extends DocumentAdapter {
+ public void documentChanged(DocumentEvent event) {
+ final Document document = event.getDocument();
+ final VirtualFile vFile = FileDocumentManager.getInstance().getFile(document);
+ if (vFile != null) {
+ final FileEditor[] editors = FileEditorManager.getInstance(myProject).getEditors(vFile);
+ if (editors.length > 0) {
+ myAutoTestAlarm.cancelAllRequests();
+ myAutoTestAlarm.addRequest(myRunTestsRunnable, AUTOTEST_DELAY);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/ToggleAutoTestAction.java b/platform/testRunner/src/com/intellij/execution/testframework/autotest/ToggleAutoTestAction.java
new file mode 100644
index 000000000000..e900bda821a8
--- /dev/null
+++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/ToggleAutoTestAction.java
@@ -0,0 +1,37 @@
+package com.intellij.execution.testframework.autotest;
+
+import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.execution.ui.RunContentManager;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.actionSystem.ToggleAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.IconLoader;
+
+/**
+ * @author yole
+ */
+public class ToggleAutoTestAction extends ToggleAction {
+ public ToggleAutoTestAction() {
+ super("Toggle auto-test", "Toggle automatic rerun of tests on code changes",
+ IconLoader.getIcon("/actions/swapPanels.png"));
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ Project project = e.getData(PlatformDataKeys.PROJECT);
+ RunContentDescriptor descriptor = e.getData(RunContentManager.RUN_CONTENT_DESCRIPTOR);
+ return project == null || descriptor == null
+ ? false
+ : AutoTestManager.getInstance(project).isAutoTestEnabled(descriptor);
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ Project project = e.getData(PlatformDataKeys.PROJECT);
+ RunContentDescriptor descriptor = e.getData(RunContentManager.RUN_CONTENT_DESCRIPTOR);
+ if (project != null && descriptor != null) {
+ AutoTestManager.getInstance(project).setAutoTestEnabled(descriptor, state);
+ }
+ }
+}
diff --git a/platform/util/src/com/intellij/ide/ui/ListCellRendererWrapper.java b/platform/util/src/com/intellij/ide/ui/ListCellRendererWrapper.java
index 943f13cefc79..9c83b38427b6 100644
--- a/platform/util/src/com/intellij/ide/ui/ListCellRendererWrapper.java
+++ b/platform/util/src/com/intellij/ide/ui/ListCellRendererWrapper.java
@@ -32,6 +32,7 @@ public abstract class ListCellRendererWrapper implements ListCellRenderer {
private Icon myIcon;
private String myText;
private String myToolTipText;
+ private Color myForeground;
/**
* A combo box for which this cell renderer is created should be passed here.
@@ -62,6 +63,7 @@ public abstract class ListCellRendererWrapper implements ListCellRenderer {
final JLabel label = (JLabel)component;
label.setIcon(myIcon);
if (myText != null) label.setText(myText);
+ if (myForeground != null) label.setForeground(myForeground);
label.setToolTipText(myToolTipText);
}
return component;
@@ -97,4 +99,7 @@ public abstract class ListCellRendererWrapper implements ListCellRenderer {
myToolTipText = toolTipText;
}
+ public void setForeground(final Color foreground) {
+ myForeground = foreground;
+ }
}
diff --git a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java
index 033038071288..af407dd2b031 100644
--- a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java
+++ b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java
@@ -82,7 +82,6 @@ public class NameUtil {
}
index++;
}
- if (upperCaseCount == 0 && lowerCaseCount == 0 && digitCount == 0) continue;
String word = name.substring(wordStart, index);
array.add(word);
}
@@ -290,7 +289,7 @@ public class NameUtil {
String prevWord = words[i - 1];
if (upperCaseStyle) {
word = word.toUpperCase();
- if (prevWord.charAt(prevWord.length() - 1) != '_') {
+ if (prevWord.charAt(prevWord.length() - 1) != '_' && word.charAt(0) != '_') {
word = "_" + word;
}
}
diff --git a/platform/util/src/com/intellij/util/CommonProcessors.java b/platform/util/src/com/intellij/util/CommonProcessors.java
index 7fd83237f459..f8f26a6a2dd0 100644
--- a/platform/util/src/com/intellij/util/CommonProcessors.java
+++ b/platform/util/src/com/intellij/util/CommonProcessors.java
@@ -40,7 +40,13 @@ public class CommonProcessors {
}
public boolean process(T t) {
- myCollection.add(t);
+ if (accept(t)) {
+ myCollection.add(t);
+ }
+ return true;
+ }
+
+ protected boolean accept(T t) {
return true;
}
diff --git a/platform/util/src/com/intellij/util/SmartList.java b/platform/util/src/com/intellij/util/SmartList.java
index 0bace9c96651..a97da1721993 100644
--- a/platform/util/src/com/intellij/util/SmartList.java
+++ b/platform/util/src/com/intellij/util/SmartList.java
@@ -140,7 +140,38 @@ public class SmartList extends AbstractList {
}
public Iterator iterator() {
- return mySize == 0 ? EmptyIterator.getInstance() : super.iterator();
+ if (mySize == 0) {
+ return EmptyIterator.getInstance();
+ }
+ if (mySize == 1) {
+ return new SingletonIterator();
+ }
+ return super.iterator();
+ }
+
+ private class SingletonIterator implements Iterator {
+ private boolean myVisited;
+ private final int myInitialModCount;
+
+ public SingletonIterator() {
+ myInitialModCount = modCount;
+ }
+
+ public boolean hasNext() {
+ return !myVisited;
+ }
+
+ public E next() {
+ if (myVisited) throw new NoSuchElementException();
+ myVisited = true;
+ if (modCount != myInitialModCount) throw new ConcurrentModificationException("ModCount: "+modCount+"; expected: "+myInitialModCount);
+ return (E)myElem;
+ }
+
+ public void remove() {
+ if (modCount != myInitialModCount) throw new ConcurrentModificationException("ModCount: "+modCount+"; expected: "+myInitialModCount);
+ clear();
+ }
}
public boolean isEmpty() {
@@ -161,5 +192,9 @@ public class SmartList extends AbstractList {
ContainerUtil.sort((List)myElem, comparator);
}
}
+
+ public int getModificationCount() {
+ return modCount;
+ }
}
diff --git a/platform/util/src/com/intellij/util/concurrency/Semaphore.java b/platform/util/src/com/intellij/util/concurrency/Semaphore.java
index 76d6620d67f5..b3992716d4be 100644
--- a/platform/util/src/com/intellij/util/concurrency/Semaphore.java
+++ b/platform/util/src/com/intellij/util/concurrency/Semaphore.java
@@ -72,18 +72,18 @@ public class Semaphore {
sync.acquireSharedInterruptibly(1);
}
- public boolean waitFor(final long timeout) {
+ public boolean waitFor(final long msTimeout) {
try {
- return waitForUnsafe(timeout);
+ return waitForUnsafe(msTimeout);
}
catch (InterruptedException e) {
throw new ProcessCanceledException(e);
}
}
- public boolean waitForUnsafe(long timeout) throws InterruptedException {
+ public boolean waitForUnsafe(long msTimeout) throws InterruptedException {
if (sync.tryAcquireShared(1) >= 0) return true;
- return sync.tryAcquireSharedNanos(1, TimeUnit.MILLISECONDS.toNanos(timeout));
+ return sync.tryAcquireSharedNanos(1, TimeUnit.MILLISECONDS.toNanos(msTimeout));
}
}
diff --git a/platform/util/src/com/intellij/util/containers/CollectUtil.java b/platform/util/src/com/intellij/util/containers/CollectUtil.java
index 87387804bfa3..b72ce8006c6d 100644
--- a/platform/util/src/com/intellij/util/containers/CollectUtil.java
+++ b/platform/util/src/com/intellij/util/containers/CollectUtil.java
@@ -17,22 +17,22 @@ package com.intellij.util.containers;
import com.intellij.openapi.util.Condition;
-import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
/**
* @deprecated use {@link ContainerUtil}
*/
@Deprecated
public abstract class CollectUtil {
- public abstract HashSet toSet(Iterator iterator);
+ public abstract Set toSet(Iterator iterator);
- public HashSet toSet(Iterator iterator, Convertor convertor) {
+ public