summaryrefslogtreecommitdiff
path: root/platform/platform-impl/src/com/intellij/ui
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-impl/src/com/intellij/ui')
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java1
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AppUIUtil.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ui/BalloonImpl.java5
-rw-r--r--platform/platform-impl/src/com/intellij/ui/CheckboxTree.java9
-rw-r--r--platform/platform-impl/src/com/intellij/ui/CheckboxTreeTable.java47
-rw-r--r--platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java45
-rw-r--r--platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java7
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java68
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java35
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java9
10 files changed, 200 insertions, 32 deletions
diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
index 4e65063e7939..d8b204cfd76c 100644
--- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
+++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
@@ -223,6 +223,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
if (selected == null
|| !myComponent.isEnabled()
|| !myComponent.isShowing()
+ || !myComponent.getVisibleRect().intersects(getVisibleRect(selected))
|| !myComponent.isFocusOwner() && !processIfUnfocused
|| isPopup()) {
hideHint();
diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
index 50a7ebbca92b..2a7d44d017bd 100644
--- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.PlatformUtils;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -38,7 +39,6 @@ import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.InputStream;
-import java.lang.reflect.Field;
import java.net.URL;
import java.util.List;
import java.util.Locale;
@@ -111,9 +111,7 @@ public class AppUIUtil {
final Toolkit toolkit = Toolkit.getDefaultToolkit();
final Class<? extends Toolkit> aClass = toolkit.getClass();
if ("sun.awt.X11.XToolkit".equals(aClass.getName())) {
- final Field awtAppClassName = aClass.getDeclaredField("awtAppClassName");
- awtAppClassName.setAccessible(true);
- awtAppClassName.set(toolkit, getFrameClass());
+ ReflectionUtil.setField(aClass, toolkit, null, "awtAppClassName", getFrameClass());
}
}
catch (Exception ignore) { }
diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java
index c6c209ed4b88..513d5cedb2ab 100644
--- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java
@@ -200,8 +200,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
if (cmp == myCloseRec) return true;
if (UIUtil.isDescendingFrom(cmp, myComp)) return true;
if (myComp == null || !myComp.isShowing()) return false;
- Rectangle rectangleOnScreen = new Rectangle(myComp.getLocationOnScreen(), myComp.getSize());
- return rectangleOnScreen.contains(target.getScreenPoint());
+ return myComp.contains(target.getScreenPoint().x, target.getScreenPoint().y);
}
public boolean isMovingForward(RelativePoint target) {
@@ -614,7 +613,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
myComp.setBorder(new EmptyBorder(borderSize, borderSize, borderSize, borderSize));
myLayeredPane.add(myComp);
- myLayeredPane.setLayer(myComp, getLayer());
+ myLayeredPane.setLayer(myComp, getLayer(), 0); // the second balloon must be over the first one
myPosition.updateBounds(this);
if (myBlockClicks) {
myComp.addMouseListener(new MouseAdapter() {
diff --git a/platform/platform-impl/src/com/intellij/ui/CheckboxTree.java b/platform/platform-impl/src/com/intellij/ui/CheckboxTree.java
index c91be65978c1..1443a9303e39 100644
--- a/platform/platform-impl/src/com/intellij/ui/CheckboxTree.java
+++ b/platform/platform-impl/src/com/intellij/ui/CheckboxTree.java
@@ -15,8 +15,6 @@
*/
package com.intellij.ui;
-import java.awt.event.KeyEvent;
-
/**
* User: lex
* Date: Sep 18, 2003
@@ -56,11 +54,4 @@ public class CheckboxTree extends CheckboxTreeBase {
protected void installSpeedSearch() {
new TreeSpeedSearch(this);
}
-
-
- protected boolean isToggleEvent(KeyEvent e) {
- return super.isToggleEvent(e) && !SpeedSearchBase.hasActiveSpeedSearch(this);
- }
-
-
}
diff --git a/platform/platform-impl/src/com/intellij/ui/CheckboxTreeTable.java b/platform/platform-impl/src/com/intellij/ui/CheckboxTreeTable.java
new file mode 100644
index 000000000000..369dd0cc1803
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/CheckboxTreeTable.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import com.intellij.ui.dualView.TreeTableView;
+import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
+import com.intellij.ui.treeStructure.treetable.TreeTableTree;
+import com.intellij.util.EventDispatcher;
+import com.intellij.util.ui.ColumnInfo;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class CheckboxTreeTable extends TreeTableView {
+ private final EventDispatcher<CheckboxTreeListener> myEventDispatcher;
+
+ public CheckboxTreeTable(CheckedTreeNode root, CheckboxTree.CheckboxTreeCellRenderer renderer, final ColumnInfo[] columns) {
+ super(new ListTreeTableModelOnColumns(root, columns));
+ final TreeTableTree tree = getTree();
+ myEventDispatcher = EventDispatcher.create(CheckboxTreeListener.class);
+ CheckboxTreeHelper helper = new CheckboxTreeHelper(CheckboxTreeHelper.DEFAULT_POLICY, myEventDispatcher);
+ helper.initTree(tree, this, renderer);
+ tree.setSelectionRow(0);
+ }
+
+ public void addCheckboxTreeListener(@NotNull CheckboxTreeListener listener) {
+ myEventDispatcher.addListener(listener);
+ }
+
+ public <T> T[] getCheckedNodes(final Class<T> nodeType) {
+ return CheckboxTreeHelper.getCheckedNodes(nodeType, null, getTree().getModel());
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java b/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
index 39c8aaf41ace..d5fc8dcca1ba 100644
--- a/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,8 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.tabs.*;
-import com.intellij.ui.tabs.impl.JBTabsImpl;
+import com.intellij.ui.tabs.impl.JBEditorTabs;
+import com.intellij.ui.tabs.impl.TabLabel;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +39,45 @@ public class JBTabsPaneImpl implements TabbedPane, SwingConstants {
private final CopyOnWriteArraySet<ChangeListener> myListeners = new CopyOnWriteArraySet<ChangeListener>();
public JBTabsPaneImpl(@Nullable Project project, int tabPlacement, @NotNull Disposable parent) {
- myTabs = new JBTabsImpl(project, ActionManager.getInstance(), project == null ? null : IdeFocusManager.getInstance(project), parent);
+ myTabs = new JBEditorTabs(project, ActionManager.getInstance(), project == null ? null : IdeFocusManager.getInstance(project), parent) {
+ @Override
+ public boolean isAlphabeticalMode() {
+ return false;
+ }
+
+ @Override
+ protected void doPaintBackground(Graphics2D g2d, Rectangle clip) {
+ super.doPaintBackground(g2d, clip);
+ if (getTabsPosition() == JBTabsPosition.top && isSingleRow()) {
+ int maxOffset = 0;
+ int maxLength = 0;
+
+ for (int i = getVisibleInfos().size() - 1; i >= 0; i--) {
+ TabInfo visibleInfo = getVisibleInfos().get(i);
+ TabLabel tabLabel = myInfo2Label.get(visibleInfo);
+ Rectangle r = tabLabel.getBounds();
+ if (r.width == 0 || r.height == 0) continue;
+ maxOffset = r.x + r.width;
+ maxLength = r.height;
+ break;
+ }
+
+ maxOffset++;
+ g2d.setPaint(UIUtil.getPanelBackground());
+ g2d.fillRect(clip.x + maxOffset, clip.y, clip.width - maxOffset, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT);
+ g2d.setPaint(new JBColor(Gray._181, UIUtil.getPanelBackground()));
+ g2d.drawLine(clip.x + maxOffset, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT, clip.x + clip.width, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT);
+ g2d.setPaint(UIUtil.getPanelBackground());
+ g2d.drawLine(clip.x, clip.y + maxLength, clip.width, clip.y + maxLength);
+ }
+ }
+
+ @Override
+ protected void paintSelectionAndBorder(Graphics2D g2d) {
+ super.paintSelectionAndBorder(g2d);
+ }
+ };
+
myTabs.addListener(new TabsListener.Adapter() {
@Override
public void selectionChanged(TabInfo oldSelection, TabInfo newSelection) {
diff --git a/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java b/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java
index 99c41b52cbea..e219b778f44d 100644
--- a/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java
+++ b/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,6 +16,7 @@
package com.intellij.ui;
import com.intellij.icons.AllIcons;
+import com.intellij.openapi.ui.Divider;
import com.intellij.openapi.ui.PseudoSplitter;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.vcs.changes.RefreshablePanel;
@@ -41,7 +42,7 @@ public abstract class SplitterWithSecondHideable {
private final boolean myVertical;
private final OnOffListener<Integer> myListener;
private final JPanel myFictivePanel;
- private Splitter.Divider mySuperDivider;
+ private Splitter.DividerImpl mySuperDivider;
private float myPreviousProportion;
public SplitterWithSecondHideable(final boolean vertical,
@@ -185,7 +186,7 @@ public abstract class SplitterWithSecondHideable {
return vertical ? myTitledSeparator.getHeight() : myTitledSeparator.getWidth();
}
- class MyDivider extends Divider {
+ class MyDivider extends DividerImpl {
@Override
public void processMouseMotionEvent(MouseEvent e) {
super.processMouseMotionEvent(e);
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
index 78802ccdf6bb..e50403abef45 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
@@ -162,6 +162,25 @@ public class AbstractPopup implements JBPopup {
private UiActivity myActivityKey;
private Disposable myProjectDisposable;
+ private volatile State myState = State.NEW;
+
+ private enum State {NEW, INIT, SHOWING, SHOWN, CANCEL, DISPOSE}
+
+ private void debugState(String message, State... states) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(hashCode() + " - " + message);
+ if (!ApplicationManager.getApplication().isDispatchThread()) {
+ LOG.debug("unexpected thread");
+ }
+ for (State state : states) {
+ if (state == myState) {
+ return;
+ }
+ }
+ LOG.debug(new IllegalStateException("myState=" + myState));
+ }
+ }
+
AbstractPopup() { }
AbstractPopup init(Project project,
@@ -302,6 +321,8 @@ public class AbstractPopup implements JBPopup {
}
myKeyEventHandler = keyEventHandler;
+ debugState("popup initialized", State.NEW);
+ myState = State.INIT;
return this;
}
@@ -582,10 +603,18 @@ public class AbstractPopup implements JBPopup {
@Override
public void cancel(InputEvent e) {
+ if (myState == State.CANCEL || myState == State.DISPOSE) {
+ return;
+ }
+ debugState("cancel popup", State.SHOWN);
+ myState = State.CANCEL;
+
if (isDisposed()) return;
if (myPopup != null) {
if (!canClose()) {
+ debugState("cannot cancel popup", State.CANCEL);
+ myState = State.SHOWN;
return;
}
storeDimensionSize(myContent.getSize());
@@ -610,8 +639,13 @@ public class AbstractPopup implements JBPopup {
}
if (myInStack) {
- myFocusTrackback.setForcedRestore(!myOk && myFocusable);
- myFocusTrackback.restoreFocus();
+ if (myFocusTrackback != null) {
+ myFocusTrackback.setForcedRestore(!myOk && myFocusable);
+ myFocusTrackback.restoreFocus();
+ }
+ else if (LOG.isDebugEnabled()) {
+ LOG.debug("cancel before show @ " + Thread.currentThread());
+ }
}
@@ -664,6 +698,9 @@ public class AbstractPopup implements JBPopup {
assert ApplicationManager.getApplication().isDispatchThread();
+ debugState("show popup", State.INIT);
+ myState = State.SHOWING;
+
installWindowHook(this);
installProjectDisposer();
addActivity();
@@ -673,6 +710,8 @@ public class AbstractPopup implements JBPopup {
final boolean shouldShow = beforeShow();
if (!shouldShow) {
removeActivity();
+ debugState("rejected to show popup", State.SHOWING);
+ myState = State.INIT;
return;
}
@@ -758,10 +797,11 @@ public class AbstractPopup implements JBPopup {
PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog);
myNativePopup = factory.isNativePopup();
Component popupOwner = myOwner;
- if (popupOwner instanceof RootPaneContainer) {
+ if (popupOwner instanceof RootPaneContainer && !(popupOwner instanceof IdeFrame && !Registry.is("popup.fix.ide.frame.owner"))) {
// JDK uses cached heavyweight popup for a window ancestor
RootPaneContainer root = (RootPaneContainer)popupOwner;
popupOwner = root.getRootPane();
+ LOG.debug("popup owner fixed for JDK cache");
}
if (LOG.isDebugEnabled()) {
LOG.debug("expected preferred size: " + myContent.getPreferredSize());
@@ -957,6 +997,8 @@ public class AbstractPopup implements JBPopup {
}
});
}
+ debugState("popup shown", State.SHOWING);
+ myState = State.SHOWN;
}
public void focusPreferredComponent() {
@@ -1232,6 +1274,16 @@ public class AbstractPopup implements JBPopup {
@Override
public void dispose() {
+ if (myState == State.SHOWN) {
+ LOG.debug("shown popup must be cancelled");
+ cancel();
+ }
+ if (myState == State.DISPOSE) {
+ return;
+ }
+ debugState("dispose popup", State.INIT, State.CANCEL);
+ myState = State.DISPOSE;
+
if (myDisposed) {
return;
}
@@ -1480,8 +1532,8 @@ public class AbstractPopup implements JBPopup {
@Override
public Dimension getSize() {
if (myPopup != null) {
- final Window popupWindow = SwingUtilities.windowForComponent(myContent);
- return popupWindow.getSize();
+ final Window popupWindow = getContentWindow(myContent);
+ return (popupWindow == null) ? myForcedSize : popupWindow.getSize();
} else {
return myForcedSize;
}
@@ -1491,7 +1543,8 @@ public class AbstractPopup implements JBPopup {
public void moveToFitScreen() {
if (myPopup == null) return;
- final Window popupWindow = SwingUtilities.windowForComponent(myContent);
+ final Window popupWindow = getContentWindow(myContent);
+ if (popupWindow == null) return;
Rectangle bounds = popupWindow.getBounds();
ScreenUtil.moveRectangleToFitTheScreen(bounds);
@@ -1501,7 +1554,8 @@ public class AbstractPopup implements JBPopup {
public static Window setSize(JComponent content, final Dimension size) {
- final Window popupWindow = SwingUtilities.windowForComponent(content);
+ final Window popupWindow = getContentWindow(content);
+ if (popupWindow == null) return null;
Insets insets = content.getInsets();
if (insets != null) {
size.width += insets.left + insets.right;
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java
new file mode 100644
index 000000000000..2a79368f65bb
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 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.ui.popup;
+
+import com.intellij.openapi.util.registry.Registry;
+
+import javax.swing.Popup;
+import java.awt.Component;
+import java.awt.GraphicsEnvironment;
+
+/**
+ * @author Sergey Malenkov
+ */
+public final class OurHeavyWeightPopup extends Popup {
+ public OurHeavyWeightPopup(Component owner, Component content, int x, int y) {
+ super(owner, content, x, y);
+ }
+
+ public static boolean isEnabled() {
+ return !GraphicsEnvironment.isHeadless() && Registry.is("our.heavy.weight.popup");
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java
index 301758511612..1670491b91bf 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -58,6 +58,9 @@ public interface PopupComponent {
class AwtHeavyweight implements Factory {
public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) {
+ if (OurHeavyWeightPopup.isEnabled()) {
+ return new AwtPopupWrapper(new OurHeavyWeightPopup(owner, content, x, y), jbPopup);
+ }
final PopupFactory factory = PopupFactory.getSharedInstance();
final int oldType = PopupUtil.getPopupType(factory);
@@ -172,7 +175,7 @@ public interface PopupComponent {
myJBPopup = jbPopup;
if (SystemInfo.isMac && UIUtil.isUnderAquaLookAndFeel()) {
- final Component c = (Component)ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component");
+ final Component c = ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component");
c.setBackground(UIUtil.getPanelBackground());
}
}
@@ -220,7 +223,7 @@ public interface PopupComponent {
}
public Window getWindow() {
- final Component c = (Component)ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component");
+ final Component c = ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component");
return c instanceof JWindow ? (JWindow)c : null;
}