diff options
Diffstat (limited to 'platform/platform-impl/src/com/intellij/ui')
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; } |