diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java index 3ffc227167e2..c94274204e17 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.externalSystem.util; import com.intellij.build.*; @@ -86,7 +86,6 @@ import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; -import com.intellij.openapi.wm.impl.ToolWindowImpl; import com.intellij.pom.Navigatable; import com.intellij.pom.NonNavigatable; import com.intellij.util.ArrayUtil; @@ -107,10 +106,7 @@ import java.util.function.Supplier; import static com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings.SyncType.*; import static com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.doWriteAction; -/** - * @author Denis Zhdanov - */ -public class ExternalSystemUtil { +public final class ExternalSystemUtil { private static final Logger LOG = Logger.getInstance(ExternalSystemUtil.class); @NotNull private static final Map RUNNER_IDS = new HashMap<>(); @@ -185,16 +181,7 @@ public class ExternalSystemUtil { @Nullable public static ToolWindow ensureToolWindowContentInitialized(@NotNull Project project, @NotNull ProjectSystemId externalSystemId) { - final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); - if (toolWindowManager == null) return null; - - final ToolWindow toolWindow = toolWindowManager.getToolWindow(externalSystemId.getReadableName()); - if (toolWindow == null) return null; - - if (toolWindow instanceof ToolWindowImpl) { - ((ToolWindowImpl)toolWindow).ensureContentInitialized(); - } - return toolWindow; + return ToolWindowManager.getInstance(project).getToolWindow(externalSystemId.getReadableName()); } /** @@ -282,9 +269,9 @@ public class ExternalSystemUtil { } } - @Nullable + @NotNull private static String extractDetails(@NotNull Throwable e) { - final Throwable unwrapped = RemoteUtil.unwrap(e); + Throwable unwrapped = RemoteUtil.unwrap(e); if (unwrapped instanceof ExternalSystemException) { return ((ExternalSystemException)unwrapped).getOriginalReason(); } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java index 6006899df54e..4392891d3d9d 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.ui; import com.intellij.icons.AllIcons; @@ -474,18 +474,15 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { * */ public void setFirstComponent(@Nullable JComponent component) { - if (myFirstComponent != component) { - if (myFirstComponent != null) { - remove(myFirstComponent); - } - myFirstComponent = component; - updateComponentTreeUI(myFirstComponent); - - if (myFirstComponent != null) { - add(myFirstComponent); - myFirstComponent.invalidate(); - } + if (myFirstComponent == component) { + return; } + + if (myFirstComponent != null) { + remove(myFirstComponent); + } + myFirstComponent = component; + doAddComponent(component); } @Nullable @@ -493,25 +490,20 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { return myLastComponent; } - /** * Sets component which is located as the "second" split area. The method doesn't validate and * repaint the splitter. - * */ public void setLastComponent(@Nullable JComponent component) { - if (myLastComponent != component) { - if (myLastComponent != null) { - remove(myLastComponent); - } - myLastComponent = component; - updateComponentTreeUI(myLastComponent); - - if (myLastComponent != null) { - add(myLastComponent); - myLastComponent.invalidate(); - } + if (myLastComponent == component) { + return; } + + if (myLastComponent != null) { + remove(myLastComponent); + } + myLastComponent = component; + doAddComponent(component); } @Nullable @@ -519,10 +511,12 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { return myInnerComponent; } - private static void updateComponentTreeUI(@Nullable JComponent component) { - UIUtil.uiTraverser(component).postOrderDfsTraversal(). - filter(c -> c instanceof JComponent). - forEach(c -> ((JComponent)c).updateUI()); + private static void updateComponentTreeUI(@Nullable JComponent rootComponent) { + for (Component component : UIUtil.uiTraverser(rootComponent).postOrderDfsTraversal()) { + if (component instanceof JComponent) { + ((JComponent)component).updateUI(); + } + } } /** @@ -537,13 +531,15 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { if (myInnerComponent != null) { remove(myInnerComponent); } - myInnerComponent = component; - updateComponentTreeUI(myInnerComponent); + doAddComponent(component); + } - if (myInnerComponent != null) { - add(myInnerComponent); - myInnerComponent.invalidate(); + private void doAddComponent(@Nullable JComponent component) { + if (component != null) { + updateComponentTreeUI(component); + add(component); + component.invalidate(); } } @@ -637,11 +633,6 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { } private void _processMouseMotionEvent(MouseEvent e) { MouseEvent event = getTargetEvent(e); - if (event == null) { - myGlassPane.setCursor(null, myListener); - return; - } - processMouseMotionEvent(event); if (event.isConsumed()) { e.consume(); @@ -650,11 +641,6 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { private void _processMouseEvent(MouseEvent e) { MouseEvent event = getTargetEvent(e); - if (event == null) { - myGlassPane.setCursor(null, myListener); - return; - } - processMouseEvent(event); if (event.isConsumed()) { e.consume(); @@ -664,7 +650,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { private final MouseAdapter myListener = new MyMouseAdapter(); - private MouseEvent getTargetEvent(MouseEvent e) { + private MouseEvent getTargetEvent(@NotNull MouseEvent e) { return SwingUtilities.convertMouseEvent(e.getComponent(), e, this); } diff --git a/platform/platform-api/src/com/intellij/ui/content/Content.java b/platform/platform-api/src/com/intellij/ui/content/Content.java index 58d08f513f6b..d3b1004fb883 100644 --- a/platform/platform-api/src/com/intellij/ui/content/Content.java +++ b/platform/platform-api/src/com/intellij/ui/content/Content.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ui.content; import com.intellij.ide.dnd.DnDTarget; @@ -50,17 +50,16 @@ public interface Content extends UserDataHolder, ComponentContainer { void setTabName(String tabName); String getTabName(); - void setToolwindowTitle(String toolwindowTitle); String getToolwindowTitle(); + void setToolwindowTitle(String toolwindowTitle); + Disposable getDisposer(); void setDisposer(@NotNull Disposable disposer); void setShouldDisposeContent(boolean value); - boolean shouldDisposeContent(); - String getDescription(); void setDescription(String description); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java index c4d0ecdaf8da..81346a426f3a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java @@ -7,18 +7,17 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.keymap.KeymapUtil; -import com.intellij.openapi.project.DumbService; import com.intellij.openapi.ui.Queryable; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.*; +import com.intellij.openapi.wm.impl.content.ToolWindowContentUi; import com.intellij.ui.ComponentWithMnemonics; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.ui.content.Content; -import com.intellij.ui.content.ContentManager; import com.intellij.ui.paint.LinePainter2D; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NonNls; @@ -41,30 +40,43 @@ import java.util.Map; */ public final class InternalDecorator extends JPanel implements Queryable, DataProvider, ComponentWithMnemonics { private final ToolWindowImpl toolWindow; - private final MyDivider myDivider; + private final JPanel divider; + private IdeGlassPane glassPane; + + private Disposable disposable; + private final MouseAdapter myListener = new MyMouseListener(); + private boolean isDragging; /** * Catches all event from tool window and modifies decorator's appearance. */ static final String HIDE_ACTIVE_WINDOW_ACTION_ID = "HideActiveWindow"; - //See ToolWindowViewModeAction and ToolWindowMoveAction + // see ToolWindowViewModeAction and ToolWindowMoveAction public static final String TOGGLE_DOCK_MODE_ACTION_ID = "ToggleDockMode"; public static final String TOGGLE_FLOATING_MODE_ACTION_ID = "ToggleFloatingMode"; public static final String TOGGLE_SIDE_MODE_ACTION_ID = "ToggleSideMode"; private final ToolWindowHeader header; - InternalDecorator(@NotNull ToolWindowImpl toolWindow) { + InternalDecorator(@NotNull ToolWindowImpl toolWindow, @NotNull ToolWindowContentUi contentUi) { super(new BorderLayout()); this.toolWindow = toolWindow; - myDivider = new MyDivider(); + divider = new JPanel() { + @NotNull + @Override + public Cursor getCursor() { + WindowInfo info = InternalDecorator.this.toolWindow.getWindowInfo(); + boolean isVerticalCursor = info.getType() == ToolWindowType.DOCKED ? info.getAnchor().isSplitVertically() : info.getAnchor().isHorizontal(); + return isVerticalCursor ? Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); + } + }; setFocusable(false); setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); - header = new ToolWindowHeader(toolWindow, () -> toolWindow.createPopupGroup(true)) { + header = new ToolWindowHeader(toolWindow, contentUi, () -> toolWindow.createPopupGroup(true)) { @Override protected boolean isActive() { return toolWindow.isActive(); @@ -83,6 +95,8 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr if (SystemInfo.isMac) { setBackground(new JBColor(Gray._200, Gray._90)); } + + setBorder(new InnerPanelBorder(toolWindow)); } @Override @@ -90,38 +104,22 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr return toolWindow.getId(); } - public boolean isFocused(@NotNull JFrame frame) { - IdeFocusManager focusManager = toolWindow.getToolWindowManager().getFocusManager(); - JComponent toolWindowComponent = toolWindow.getComponentIfInitialized(); - if (toolWindowComponent == null) { - return false; - } - - Component component = focusManager.getFocusedDescendantFor(toolWindowComponent); - if (component != null) { - return true; - } - - Component owner = focusManager.getLastFocusedFor(frame); - return owner != null && SwingUtilities.isDescendingFrom(owner, toolWindowComponent); - } - void applyWindowInfo(@NotNull WindowInfo info) { // Anchor ToolWindowAnchor anchor = info.getAnchor(); if (info.isSliding()) { - myDivider.invalidate(); - if (ToolWindowAnchor.TOP == anchor) { - add(myDivider, BorderLayout.SOUTH); + divider.invalidate(); + if (anchor == ToolWindowAnchor.TOP) { + add(divider, BorderLayout.SOUTH); } - else if (ToolWindowAnchor.LEFT == anchor) { - add(myDivider, BorderLayout.EAST); + else if (anchor == ToolWindowAnchor.LEFT) { + add(divider, BorderLayout.EAST); } - else if (ToolWindowAnchor.BOTTOM == anchor) { - add(myDivider, BorderLayout.NORTH); + else if (anchor == ToolWindowAnchor.BOTTOM) { + add(divider, BorderLayout.NORTH); } - else if (ToolWindowAnchor.RIGHT == anchor) { - add(myDivider, BorderLayout.WEST); + else if (anchor == ToolWindowAnchor.RIGHT) { + add(divider, BorderLayout.WEST); } divider.setPreferredSize(new Dimension(0, 0)); } @@ -130,9 +128,6 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr remove(divider); } - validate(); - repaint(); - // push "apply" request forward if (info.isFloating()) { FloatingDecorator floatingDecorator = (FloatingDecorator)SwingUtilities.getAncestorOfClass(FloatingDecorator.class, this); @@ -140,9 +135,6 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr floatingDecorator.apply(info); } } - - toolWindow.getContentUI().setType(info.getContentUiType()); - setBorder(new InnerPanelBorder(toolWindow, info)); } @Nullable @@ -154,14 +146,6 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr return null; } - void addContentComponent(boolean dumbAware, @NotNull ContentManager contentManager) { - JComponent toolWindowComponent = contentManager.getComponent(); - if (!dumbAware) { - toolWindowComponent = DumbService.getInstance(toolWindow.getToolWindowManager().getProject()).wrapGently(toolWindowComponent, toolWindow.getDisposable()); - } - add(toolWindowComponent, BorderLayout.CENTER); - } - @Override protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { if (condition == WHEN_ANCESTOR_OF_FOCUSED_COMPONENT && pressed) { @@ -185,16 +169,13 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr private static final class InnerPanelBorder implements Border { @NotNull private final ToolWindowImpl window; - @NotNull - private final WindowInfo windowInfo; - private InnerPanelBorder(@NotNull ToolWindowImpl window, @NotNull WindowInfo windowInfo) { + private InnerPanelBorder(@NotNull ToolWindowImpl window) { this.window = window; - this.windowInfo = windowInfo; } @Override - public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) { + public void paintBorder(@NotNull Component c, @NotNull Graphics g, int x, int y, int width, int height) { g.setColor(JBColor.border()); doPaintBorder(c, g, x, y, width, height); } @@ -227,6 +208,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr @Override public Insets getBorderInsets(@NotNull Component c) { ToolWindowManagerImpl toolWindowManager = window.getToolWindowManager(); + WindowInfo windowInfo = window.getWindowInfo(); if (toolWindowManager.getProject().isDisposed() || !toolWindowManager.isToolWindowRegistered(window.getId()) || windowInfo.getType() == ToolWindowType.FLOATING || windowInfo.getType() == ToolWindowType.WINDOWED) { return JBUI.emptyInsets(); @@ -280,103 +262,95 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr header.setVisible(value); } - private final class MyDivider extends JPanel { - private boolean myDragging; - private Disposable myDisposable; - private IdeGlassPane myGlassPane; + @Override + public void addNotify() { + super.addNotify(); - private final MouseAdapter myListener = new MyMouseAdapter(); + glassPane = IdeGlassPaneUtil.find(this); + disposable = Disposer.newDisposable(); + glassPane.addMouseMotionPreprocessor(myListener, disposable); + glassPane.addMousePreprocessor(myListener, disposable); + } - @Override - public void addNotify() { - super.addNotify(); - myGlassPane = IdeGlassPaneUtil.find(this); - myDisposable = Disposer.newDisposable(); - myGlassPane.addMouseMotionPreprocessor(myListener, myDisposable); - myGlassPane.addMousePreprocessor(myListener, myDisposable); + @Override + public void removeNotify() { + super.removeNotify(); + + Disposable disposable = this.disposable; + if (disposable != null && !Disposer.isDisposed(disposable)) { + this.disposable = null; + Disposer.dispose(disposable); + } + } + + private final class MyMouseListener extends MouseAdapter { + private boolean isInDragZone(@NotNull MouseEvent e) { + Point point = new Point(e.getPoint()); + SwingUtilities.convertPointToScreen(point, e.getComponent()); + if ((toolWindow.getWindowInfo().getAnchor().isHorizontal() ? point.y : point.x) == 0) { + return false; + } + + SwingUtilities.convertPointFromScreen(point, divider); + return Math.abs(toolWindow.getWindowInfo().getAnchor().isHorizontal() ? point.y : point.x) < 6; + } + + private void updateCursor(@NotNull MouseEvent event, boolean isInDragZone) { + if (isInDragZone) { + glassPane.setCursor(divider.getCursor(), divider); + event.consume(); + } } @Override - public void removeNotify() { - super.removeNotify(); - if (myDisposable != null && !Disposer.isDisposed(myDisposable)) { - Disposer.dispose(myDisposable); - } + public void mousePressed(@NotNull MouseEvent e) { + isDragging = isInDragZone(e); + updateCursor(e, isDragging); } - boolean isInDragZone(MouseEvent e) { - Point p = SwingUtilities.convertMouseEvent(e.getComponent(), e, this).getPoint(); - return Math.abs(toolWindow.getWindowInfo().getAnchor().isHorizontal() ? p.y : p.x) < 6; - } - - private final class MyMouseAdapter extends MouseAdapter { - private void updateCursor(MouseEvent e) { - if (isInDragZone(e)) { - myGlassPane.setCursor(MyDivider.this.getCursor(), MyDivider.this); - e.consume(); - } - } - - @Override - public void mousePressed(MouseEvent e) { - myDragging = isInDragZone(e); - updateCursor(e); - } - - @Override - public void mouseClicked(MouseEvent e) { - updateCursor(e); - } - - @Override - public void mouseReleased(MouseEvent e) { - updateCursor(e); - myDragging = false; - } - - @Override - public void mouseMoved(MouseEvent e) { - updateCursor(e); - } - - @Override - public void mouseDragged(MouseEvent e) { - if (!myDragging) { - return; - } - - MouseEvent event = SwingUtilities.convertMouseEvent(e.getComponent(), e, MyDivider.this); - final ToolWindowAnchor anchor = toolWindow.getAnchor(); - final Point point = event.getPoint(); - final Container windowPane = InternalDecorator.this.getParent(); - Point lastPoint = SwingUtilities.convertPoint(MyDivider.this, point, windowPane); - lastPoint.x = Math.min(Math.max(lastPoint.x, 0), windowPane.getWidth()); - lastPoint.y = Math.min(Math.max(lastPoint.y, 0), windowPane.getHeight()); - - final Rectangle bounds = InternalDecorator.this.getBounds(); - if (anchor == ToolWindowAnchor.TOP) { - InternalDecorator.this.setBounds(0, 0, bounds.width, lastPoint.y); - } - else if (anchor == ToolWindowAnchor.LEFT) { - InternalDecorator.this.setBounds(0, 0, lastPoint.x, bounds.height); - } - else if (anchor == ToolWindowAnchor.BOTTOM) { - InternalDecorator.this.setBounds(0, lastPoint.y, bounds.width, windowPane.getHeight() - lastPoint.y); - } - else if (anchor == ToolWindowAnchor.RIGHT) { - InternalDecorator.this.setBounds(lastPoint.x, 0, windowPane.getWidth() - lastPoint.x, bounds.height); - } - InternalDecorator.this.validate(); - e.consume(); - } - } - - @NotNull @Override - public Cursor getCursor() { - WindowInfo info = toolWindow.getWindowInfo(); - boolean isVerticalCursor = info.getType() == ToolWindowType.DOCKED ? info.getAnchor().isSplitVertically() : info.getAnchor().isHorizontal(); - return isVerticalCursor ? Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); + public void mouseClicked(@NotNull MouseEvent e) { + updateCursor(e, isInDragZone(e)); + } + + @Override + public void mouseReleased(@NotNull MouseEvent e) { + updateCursor(e, isInDragZone(e)); + isDragging = false; + } + + @Override + public void mouseMoved(@NotNull MouseEvent e) { + updateCursor(e, isDragging || isInDragZone(e)); + } + + @Override + public void mouseDragged(@NotNull MouseEvent e) { + if (!isDragging) { + return; + } + + ToolWindowAnchor anchor = toolWindow.getAnchor(); + Container windowPane = InternalDecorator.this.getParent(); + Point lastPoint = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), windowPane); + lastPoint.x = Math.min(Math.max(lastPoint.x, 0), windowPane.getWidth()); + lastPoint.y = Math.min(Math.max(lastPoint.y, 0), windowPane.getHeight()); + + Rectangle bounds = InternalDecorator.this.getBounds(); + if (anchor == ToolWindowAnchor.TOP) { + InternalDecorator.this.setBounds(0, 0, bounds.width, lastPoint.y); + } + else if (anchor == ToolWindowAnchor.LEFT) { + InternalDecorator.this.setBounds(0, 0, lastPoint.x, bounds.height); + } + else if (anchor == ToolWindowAnchor.BOTTOM) { + InternalDecorator.this.setBounds(0, lastPoint.y, bounds.width, windowPane.getHeight() - lastPoint.y); + } + else if (anchor == ToolWindowAnchor.RIGHT) { + InternalDecorator.this.setBounds(lastPoint.x, 0, windowPane.getWidth() - lastPoint.x, bounds.height); + } + InternalDecorator.this.validate(); + e.consume(); } } @@ -384,7 +358,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr public void putInfo(@NotNull Map info) { info.put("toolWindowTitle", toolWindow.getTitle()); - final Content selection = toolWindow.getContentManager().getSelectedContent(); + Content selection = toolWindow.getContentManager().getSelectedContent(); if (selection != null) { info.put("toolWindowTab", selection.getTabName()); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java index b61cbffddbbd..39b0ba1b1be0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl; import com.intellij.featureStatistics.FeatureUsageTracker; @@ -313,7 +313,7 @@ public final class StripeButton extends AnchoredButton implements DataProvider { } void apply(@NotNull WindowInfo info) { - setSelected(info.isVisible() || info.isActive()); + setSelected(info.isVisible()); updateState(toolWindow); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java index 4174b6e8f4de..e9d075eabf2e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl; import com.intellij.icons.AllIcons; @@ -13,12 +13,14 @@ import com.intellij.openapi.wm.impl.content.ToolWindowContentUi; import com.intellij.ui.DoubleClickListener; import com.intellij.ui.PopupHandler; import com.intellij.ui.UIBundle; -import com.intellij.ui.components.panels.NonOpaquePanel; +import com.intellij.ui.layout.migLayout.MigLayoutBuilderKt; +import com.intellij.ui.layout.migLayout.patched.MigLayout; import com.intellij.ui.tabs.impl.MorePopupAware; import com.intellij.ui.tabs.impl.SingleHeightTabs; import com.intellij.util.ui.*; import com.intellij.util.ui.accessibility.AccessibleContextUtil; -import net.miginfocom.swing.MigLayout; +import net.miginfocom.layout.CC; +import net.miginfocom.layout.ConstraintParser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,6 +37,7 @@ import java.util.function.Supplier; * @author pegov */ public abstract class ToolWindowHeader extends JPanel implements UISettingsListener, DataProvider { + @NotNull private final ToolWindowContentUi contentUi; @NotNull private final Supplier myGearProducer; @NotNull @@ -50,20 +53,19 @@ public abstract class ToolWindowHeader extends JPanel implements UISettingsListe private ActionToolbar myToolbarWest; private final JPanel myWestPanel; - ToolWindowHeader(@NotNull ToolWindowImpl toolWindow, @NotNull Supplier gearProducer) { + ToolWindowHeader(@NotNull ToolWindowImpl toolWindow, @NotNull ToolWindowContentUi contentUi, @NotNull Supplier gearProducer) { + super(new MigLayout(MigLayoutBuilderKt.createLayoutConstraints(0, 0).noVisualPadding().fill(), ConstraintParser.parseColumnConstraints("[grow][pref!]"))); + + this.contentUi = contentUi; myGearProducer = gearProducer; AccessibleContextUtil.setName(this, "Tool Window Header"); myToolWindow = toolWindow; - setLayout(new MigLayout("novisualpadding, ins 0, gap 0, fill", "[grow][pref!]")); - myWestPanel = new NonOpaquePanel(new MigLayout("filly, novisualpadding, ins 0, gap 0")); - - add(myWestPanel, "grow"); - myWestPanel.add(toolWindow.getContentUI().getTabComponent(), "growy"); - - ToolWindowContentUi.initMouseListeners(myWestPanel, toolWindow.getContentUI(), true); + myWestPanel = contentUi.getTabComponent(); + add(myWestPanel, new CC().grow()); + ToolWindowContentUi.initMouseListeners(myWestPanel, contentUi, true); ActionManager actionManager = ActionManager.getInstance(); AnAction tabListAction = actionManager.getAction("TabList"); @@ -83,8 +85,7 @@ public abstract class ToolWindowHeader extends JPanel implements UISettingsListe myWestPanel.addMouseListener(new PopupHandler() { @Override public void invokePopup(final Component comp, final int x, final int y) { - toolWindow.getContentUI() - .showContextMenu(comp, x, y, toolWindow.getPopupGroup(), toolWindow.getContentManager().getSelectedContent()); + contentUi.showContextMenu(comp, x, y, toolWindow.getPopupGroup(), contentUi.getContentManager().getSelectedContent()); } }); myWestPanel.addMouseListener(new MouseAdapter() { @@ -139,7 +140,7 @@ public abstract class ToolWindowHeader extends JPanel implements UISettingsListe @Override public Object getData(@NotNull String dataId) { if (MorePopupAware.KEY.is(dataId) && myToolWindow instanceof ToolWindowImpl) { - return ((ToolWindowImpl)myToolWindow).getContentUI().getData(dataId); + return contentUi.getData(dataId); } return null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.kt b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.kt index d7b719c1f6d5..d069e20792dd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.kt +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl import com.intellij.icons.AllIcons @@ -10,10 +10,10 @@ import com.intellij.notification.EventLog import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.* import com.intellij.openapi.actionSystem.ex.ActionUtil -import com.intellij.openapi.actionSystem.impl.ActionManagerImpl import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.project.DumbAware +import com.intellij.openapi.project.DumbService import com.intellij.openapi.util.ActionCallback import com.intellij.openapi.util.BusyObject import com.intellij.openapi.util.Disposer @@ -22,18 +22,22 @@ import com.intellij.openapi.wm.ex.ToolWindowEx import com.intellij.openapi.wm.impl.content.ToolWindowContentUi import com.intellij.ui.LayeredIcon import com.intellij.ui.UIBundle +import com.intellij.ui.content.Content import com.intellij.ui.content.ContentManager import com.intellij.ui.content.ContentManagerListener import com.intellij.ui.content.impl.ContentImpl import com.intellij.ui.content.impl.ContentManagerImpl import com.intellij.ui.scale.JBUIScale +import com.intellij.util.ui.UIUtil import com.intellij.util.ui.update.Activatable import com.intellij.util.ui.update.UiNotifyConnector +import java.awt.BorderLayout import java.awt.Component import java.awt.Rectangle import java.awt.event.ComponentAdapter import java.awt.event.ComponentEvent import java.awt.event.InputEvent +import java.util.* import javax.swing.Icon import javax.swing.JComponent import javax.swing.JLabel @@ -45,7 +49,7 @@ private val LOG = logger() class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManagerImpl, val id: String, private val canCloseContent: Boolean, - private val canWorkInDumbMode: Boolean, + private val dumbAware: Boolean, component: JComponent?, private val parentDisposable: Disposable, windowInfo: WindowInfo, @@ -56,16 +60,14 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag var windowInfo: WindowInfo = windowInfo private set - private val contentUi by lazy { - ToolWindowContentUi(this) - } + private var contentUi: ToolWindowContentUi? = null private var decorator: InternalDecorator? = null private var hideOnEmptyContent = false var isPlaceholderMode = false - private val pendingContentManagerListeners: List? = null + private var pendingContentManagerListeners: MutableList? = null private val showing = object : BusyObject.Impl() { override fun isReady(): Boolean { @@ -82,36 +84,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag internal var icon: ToolWindowIcon? = null private val contentManager = lazy { - val contentManager = ContentManagerImpl(contentUi, canCloseContent, toolWindowManager.project, parentDisposable) - - val contentComponent = contentManager.component - InternalDecorator.installFocusTraversalPolicy(contentComponent, LayoutFocusTraversalPolicy()) - Disposer.register(parentDisposable, UiNotifyConnector(contentComponent, object : Activatable { - override fun showNotify() { - showing.onReady() - } - })) - - val decorator = InternalDecorator(this) - this.decorator = decorator - decorator.applyWindowInfo(windowInfo) - decorator.addComponentListener(object : ComponentAdapter() { - override fun componentResized(e: ComponentEvent) { - toolWindowManager.resized(e.component as InternalDecorator) - } - }) - decorator.addContentComponent(canWorkInDumbMode, contentManager) - - toolWindowFocusWatcher = ToolWindowManagerImpl.ToolWindowFocusWatcher(this, contentManager.component) - - // after init, as it was before contentManager creation was changed to be lazy - pendingContentManagerListeners?.let { list -> - for (listener in list) { - contentManager.addContentManagerListener(listener) - } - } - - contentManager + createContentManager() } init { @@ -123,13 +96,67 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag } } + internal fun getOrCreateDecoratorComponent(): JComponent { + ensureContentManagerInitialized() + return decorator!! + } + + private fun createContentManager(): ContentManagerImpl { + val contentUi = ToolWindowContentUi(this, windowInfo.contentUiType) + this.contentUi = contentUi + val contentManager = ContentManagerImpl(contentUi, canCloseContent, toolWindowManager.project, parentDisposable) + + addContentNotInHierarchyComponents(contentUi) + + val contentComponent = contentManager.component + InternalDecorator.installFocusTraversalPolicy(contentComponent, LayoutFocusTraversalPolicy()) + Disposer.register(parentDisposable, UiNotifyConnector(contentComponent, object : Activatable { + override fun showNotify() { + showing.onReady() + } + })) + + val decorator = InternalDecorator(this, contentUi) + this.decorator = decorator + + var decoratorChild = contentManager.component + if (!dumbAware) { + decoratorChild = DumbService.getInstance(toolWindowManager.project).wrapGently(decoratorChild, parentDisposable) + } + decorator.add(decoratorChild, BorderLayout.CENTER) + decorator.applyWindowInfo(windowInfo) + decorator.addComponentListener(object : ComponentAdapter() { + override fun componentResized(e: ComponentEvent) { + toolWindowManager.resized(e.component as InternalDecorator) + } + }) + + toolWindowFocusWatcher = ToolWindowManagerImpl.ToolWindowFocusWatcher(this, contentComponent) + + // after init, as it was before contentManager creation was changed to be lazy + pendingContentManagerListeners?.let { list -> + pendingContentManagerListeners = null + for (listener in list) { + contentManager.addContentManagerListener(listener) + } + } + + return contentManager + } + internal fun applyWindowInfo(info: WindowInfo) { if (windowInfo == info) { return } windowInfo = info - decorator?.applyWindowInfo(info) + val decorator = decorator + contentUi?.setType(info.contentUiType) + if (decorator != null) { + decorator.applyWindowInfo(info) + decorator.validate() + decorator.repaint() + } } val decoratorComponent: JComponent? @@ -142,6 +169,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag toolWindowFocusWatcher?.setFocusedComponentImpl(component) } + @Deprecated(message = "Do not use.", level = DeprecationLevel.ERROR) fun getContentUI() = contentUi override fun getDisposable() = parentDisposable @@ -164,19 +192,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag override fun isActive(): Boolean { ApplicationManager.getApplication().assertIsDispatchThread() - val frameHelper = toolWindowManager.getFrame() ?: return false - val frame = frameHelper.frame - if (!frame.isActive || toolWindowManager.isEditorComponentActive) { - return false - } - - val actionManager = ActionManager.getInstance() - if (actionManager is ActionManagerImpl && !actionManager.isActionPopupStackEmpty && !actionManager.isToolWindowContextMenuVisible) { - return false - } - else { - return windowInfo.isActive || (windowInfo.isVisible && (decorator?.isFocused(frameHelper.frame) ?: false)) - } + return windowInfo.isVisible && decorator != null && toolWindowManager.activeToolWindowId == id } override fun getReady(requestor: Any): ActionCallback { @@ -262,27 +278,22 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag override fun getDecorator() = decorator!! - val isFocused: Boolean - get() { - return decorator?.isFocused(toolWindowManager.getFrame()?.frame ?: return false) ?: false - } - override fun setAdditionalGearActions(value: ActionGroup?) { additionalGearActions = value } override fun setTitleActions(vararg actions: AnAction) { - contentManager.value + createContentIfNeeded() decorator!!.setTitleActions(actions) } override fun setTabActions(vararg actions: AnAction) { - contentManager.value + createContentIfNeeded() decorator!!.setTabActions(actions) } fun setTabDoubleClickActions(vararg actions: AnAction) { - contentUi.setTabDoubleClickActions(*actions) + contentUi?.setTabDoubleClickActions(*actions) } override fun setAvailable(available: Boolean, runnable: Runnable?) { @@ -321,7 +332,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag } override fun getContentManager(): ContentManager { - ensureContentInitialized() + createContentIfNeeded() return contentManager.value } @@ -329,6 +340,12 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag if (contentManager.isInitialized()) { contentManager.value.addContentManagerListener(listener) } + else { + if (pendingContentManagerListeners == null) { + pendingContentManagerListeners = arrayListOf() + } + pendingContentManagerListeners!!.add(listener) + } } fun canCloseContents() = canCloseContent @@ -414,19 +431,36 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag override fun isDisposed() = contentManager.isInitialized() && contentManager.value.isDisposed - fun ensureContentInitialized() { - val currentContentFactory = contentFactory - if (currentContentFactory != null) { - // clear it first to avoid SOE - this.contentFactory = null - if (contentManager.isInitialized()) { - contentManager.value.removeAllContents(false) - } - contentManager.value - currentContentFactory.createToolWindowContent(toolWindowManager.project, this) + private fun ensureContentManagerInitialized() { + contentManager.value + } + + internal fun scheduleContentInitializationIfNeeded() { + if (contentFactory != null) { + // todo use lazy loading (e.g. JBLoadingPanel) + createContentIfNeeded() } } + @Suppress("DeprecatedCallableAddReplaceWith") + @Deprecated("Do not use. Tool window content will be initialized automatically.", level = DeprecationLevel.ERROR) + fun ensureContentInitialized() { + createContentIfNeeded() + } + + internal fun createContentIfNeeded() { + val currentContentFactory = contentFactory ?: return + // clear it first to avoid SOE + this.contentFactory = null + if (contentManager.isInitialized()) { + contentManager.value.removeAllContents(false) + } + else { + ensureContentManagerInitialized() + } + currentContentFactory.createToolWindowContent(toolWindowManager.project, this) + } + override fun getHelpId() = helpId override fun setHelpId(value: String) { @@ -434,9 +468,8 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag } override fun showContentPopup(inputEvent: InputEvent) { - // create before access contentUi - val contentManager = contentManager.value - ToolWindowContentUi.toggleContentPopup(contentUi, contentManager) + // called only when tool window is already opened, so, content should be already created + ToolWindowContentUi.toggleContentPopup(contentUi!!, contentManager.value) } @JvmOverloads @@ -524,7 +557,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag private inner class ResizeActionGroup : ActionGroup(ActionsBundle.groupText("ResizeToolWindowGroup"), true), DumbAware { private val children by lazy> { // force creation - contentManager.value + createContentIfNeeded() val component = decorator val toolWindow = this@ToolWindowImpl arrayOf( @@ -558,7 +591,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag } override fun update(e: AnActionEvent) { - hadSeveralContents = hadSeveralContents || getContentManager().contentCount > 1 + hadSeveralContents = hadSeveralContents || (contentManager.isInitialized() && contentManager.value.contentCount > 1) super.update(e) e.presentation.isVisible = hadSeveralContents } @@ -596,4 +629,31 @@ private fun addSorted(main: DefaultActionGroup, group: ActionGroup) { if (children.isNotEmpty() && !separatorText.isNullOrEmpty()) { main.addAction(Separator(separatorText), Constraints.FIRST) } +} + +private fun addContentNotInHierarchyComponents(contentUi: ToolWindowContentUi) { + UIUtil.putClientProperty(contentUi.component, UIUtil.NOT_IN_HIERARCHY_COMPONENTS, object : Iterable { + override fun iterator(): Iterator { + val contentManager = contentUi.contentManager ?: return Collections.emptyIterator() + if (contentManager.contentCount == 0) { + return Collections.emptyIterator() + } + + return contentManager.contents + .asSequence() + .mapNotNull { content: Content -> + var last: JComponent? = null + var parent: Component? = content.component + while (parent != null) { + if (parent === contentUi.component || parent !is JComponent) { + return@mapNotNull null + } + last = parent + parent = parent.getParent() + } + last + } + .iterator() + } + }) } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.kt b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.kt index 1159033a7b25..da4bf7d9576d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.kt +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.kt @@ -50,7 +50,6 @@ import com.intellij.openapi.wm.ex.ToolWindowManagerEx import com.intellij.openapi.wm.ex.ToolWindowManagerListener import com.intellij.openapi.wm.ex.WindowManagerEx import com.intellij.openapi.wm.impl.commands.RequestFocusInToolWindowCommand -import com.intellij.openapi.wm.impl.content.ToolWindowContentUi import com.intellij.ui.BalloonImpl import com.intellij.ui.ComponentUtil import com.intellij.ui.GuiUtils @@ -628,9 +627,6 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), if (parent is InternalDecorator) { return parent.toolWindow.id } - else if (parent is ToolWindowContentUi) { - return parent.toolWindowId - } parent = parent.parent } @@ -781,7 +777,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), private fun doHide(entry: ToolWindowEntry, info: WindowInfoImpl, dirtyMode: Boolean, hideSide: Boolean = false, moveFocus: Boolean = true): Boolean { // info.isActive is not reliable (not set to false on focus lost) - val wasActive = entry.toolWindow.isFocused + val wasActive = entry.toolWindow.isActive if (!wasActive && !info.isVisible) { return false @@ -862,8 +858,6 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), } private fun doShowWindow(entry: ToolWindowEntry, info: WindowInfo, dirtyMode: Boolean) { - entry.toolWindow.ensureContentInitialized() - if (entry.readOnlyWindowInfo.type == ToolWindowType.FLOATING) { addFloatingDecorator(entry, info) } @@ -906,12 +900,14 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), } } - toolWindowPane!!.addDecorator(entry.toolWindow.decoratorComponent!!, info, dirtyMode, this) + toolWindowPane!!.addDecorator(entry.toolWindow.getOrCreateDecoratorComponent(), info, dirtyMode, this) // remove tool window from the SideStack if (isStackEnabled) { sideStack.remove(entry.id) } } + + entry.toolWindow.scheduleContentInitializationIfNeeded() } override fun registerToolWindow(task: RegisterToolWindowTask): ToolWindowImpl { @@ -1388,7 +1384,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), private fun hideIfNeededAndShowAfterTask(entry: ToolWindowEntry, info: WindowInfoImpl, task: () -> Unit) { val wasVisible = entry.readOnlyWindowInfo.isVisible - val wasFocused = entry.toolWindow.isFocused + val wasFocused = entry.toolWindow.isActive if (wasVisible) { doHide(entry, info, dirtyMode = true, moveFocus = false) } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ComboContentLayout.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ComboContentLayout.java index 47de0081741e..0db0f3882e44 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ComboContentLayout.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ComboContentLayout.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl.content; import com.intellij.openapi.ui.popup.ListPopup; @@ -34,7 +34,7 @@ final class ComboContentLayout extends ContentLayout { @Override public void layout() { - Rectangle bounds = myUi.getBounds(); + Rectangle bounds = myUi.getTabComponent().getBounds(); Dimension idSize = isIdVisible() ? myIdLabel.getPreferredSize() : JBUI.emptySize(); int eachX = 0; @@ -70,9 +70,6 @@ final class ComboContentLayout extends ContentLayout { g.drawLine(r.width - 1, 0, r.width - 1, r.height); } - @Override - public void paintChildren(Graphics g) { } - @Override public void update() { updateIdLabel(myIdLabel); @@ -81,17 +78,17 @@ final class ComboContentLayout extends ContentLayout { @Override public void rebuild() { - myUi.removeAll(); + myUi.getTabComponent().removeAll(); - myUi.add(myIdLabel); + myUi.getTabComponent().add(myIdLabel); ToolWindowContentUi.initMouseListeners(myIdLabel, myUi, true); - myUi.add(myComboLabel); + myUi.getTabComponent().add(myComboLabel); ToolWindowContentUi.initMouseListeners(myComboLabel, myUi, false); } boolean isToDrawCombo() { - ContentManager manager = myUi.contentManager; + ContentManager manager = myUi.getContentManager(); return manager != null && manager.getContentCount() > 1; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentComboLabel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentComboLabel.java index 00eb3e575bc6..c0dee53b0bab 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentComboLabel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentComboLabel.java @@ -1,8 +1,9 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl.content; import com.intellij.ui.Gray; import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.accessibility.ScreenReader; @@ -44,7 +45,7 @@ final class ContentComboLabel extends BaseLabel { @Override public void keyPressed(KeyEvent e) { if (e.getModifiers() == 0 && e.getKeyCode() == KeyEvent.VK_SPACE) { - ToolWindowContentUi.toggleContentPopup(myUi, myUi.contentManager); + ToolWindowContentUi.toggleContentPopup(myUi, myUi.getContentManager()); } super.keyPressed(e); } @@ -57,7 +58,7 @@ final class ContentComboLabel extends BaseLabel { super.processMouseEvent(e); if (UIUtil.isActionClick(e)) { - ToolWindowContentUi.toggleContentPopup(myUi, myUi.contentManager); + ToolWindowContentUi.toggleContentPopup(myUi, myUi.getContentManager()); } } @@ -109,7 +110,8 @@ final class ContentComboLabel extends BaseLabel { @Nullable @Override public Content getContent() { - return myUi.contentManager == null ? null : myUi.contentManager.getSelectedContent(); + ContentManager contentManager = myUi.getContentManager(); + return contentManager == null ? null : contentManager.getSelectedContent(); } @Override @@ -145,7 +147,7 @@ final class ContentComboLabel extends BaseLabel { @Override public boolean doAccessibleAction(int index) { if (index == 0) { - ToolWindowContentUi.toggleContentPopup(myUi, myUi.contentManager); + ToolWindowContentUi.toggleContentPopup(myUi, myUi.getContentManager()); return true; } else { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java index be37d6a6011f..d1faa5638fa7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl.content; import com.intellij.openapi.ui.popup.ListPopup; @@ -13,8 +13,6 @@ import javax.swing.*; import java.awt.*; abstract class ContentLayout { - static final int TAB_ARC = 2; - ToolWindowContentUi myUi; BaseLabel myIdLabel; @@ -30,8 +28,6 @@ abstract class ContentLayout { public abstract void paintComponent(Graphics g); - public abstract void paintChildren(Graphics g); - public abstract void update(); public abstract void rebuild(); @@ -54,7 +50,7 @@ abstract class ContentLayout { } private String getTitleSuffix() { - ContentManager manager = myUi.contentManager; + ContentManager manager = myUi.getContentManager(); switch (manager == null ? 0 : manager.getContentCount()) { case 0: return null; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentTabLabel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentTabLabel.java index 16d46d626c5e..81df3f11f6d9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentTabLabel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentTabLabel.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl.content; import com.intellij.ide.DataManager; @@ -23,7 +23,6 @@ import com.intellij.util.ui.TimedDeadzone; import com.intellij.util.ui.UIUtilities; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -105,7 +104,6 @@ class ContentTabLabel extends BaseLabel { } String toolText = icon.getTooltip(); - if (toolText != null && !toolText.isEmpty()) { IdeTooltip tooltip = new IdeTooltip(this, icon.getCenterPoint(), new JLabel(toolText)); currentIconTooltip = new CurrentTooltip(IdeTooltipManager.getInstance().show(tooltip, false, false), icon); @@ -118,7 +116,6 @@ class ContentTabLabel extends BaseLabel { IdeTooltip tooltip = new IdeTooltip(this, getMousePosition(), new JLabel(myText)); currentIconTooltip = new CurrentTooltip(IdeTooltipManager.getInstance().show(tooltip, false, false), null); } - } private void hideCurrentTooltip() { @@ -130,15 +127,12 @@ class ContentTabLabel extends BaseLabel { private final BaseButtonBehavior behavior = new BaseButtonBehavior(this) { @Override - protected void execute(final MouseEvent e) { - - Optional first = myAdditionalIcons.stream() - .filter(icon -> mouseOverIcon(icon)) - .map(icon -> icon.getAction()).findFirst(); - - if (first.isPresent()) { - first.get().run(); - return; + protected void execute(@NotNull MouseEvent e) { + for (AdditionalIcon icon : myAdditionalIcons) { + if (mouseOverIcon(icon)) { + icon.getAction().run(); + return; + } } selectContent(); @@ -358,10 +352,10 @@ class ContentTabLabel extends BaseLabel { @NotNull private ContentManager getContentManager() { - return myUi.myWindow.getContentManager(); + return myUi.getContentManager(); } - @Nullable + @NotNull @Override public Content getContent() { return myContent; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java index 781a91dc0aa1..9f952e930776 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl.content; import com.intellij.ide.dnd.DnDSupport; @@ -39,10 +39,10 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { List myDoubleClickActions = new ArrayList<>(); - TabContentLayout(ToolWindowContentUi ui) { + TabContentLayout(@NotNull ToolWindowContentUi ui) { super(ui); - new BaseButtonBehavior(myUi) { + new BaseButtonBehavior(myUi.getTabComponent()) { @Override protected void execute(final MouseEvent e) { if (!myUi.isCurrent(TabContentLayout.this)) return; @@ -65,7 +65,7 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { } }; - ContentManager contentManager = myUi.contentManager; + ContentManager contentManager = myUi.getContentManager(); for (int i = 0; i < contentManager.getContentCount(); i++) { contentAdded(new ContentManagerEvent(this, contentManager.getContent(i), i)); } @@ -99,14 +99,14 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { List tabs = ContainerUtil.filter(myTabs, myLastLayout.toDrop::contains); final List contentsToShow = ContainerUtil.map(tabs, ContentTabLabel::getContent); final SelectContentStep step = new SelectContentStep(contentsToShow); - RelativePoint point = new RelativePoint(myUi, new Point(rect.x, rect.y + rect.height)); + RelativePoint point = new RelativePoint(myUi.getTabComponent(), new Point(rect.x, rect.y + rect.height)); JBPopupFactory.getInstance().createListPopup(step).show(point); } @Override public void layout() { - Rectangle bounds = myUi.getBounds(); - ContentManager manager = myUi.contentManager; + Rectangle bounds = myUi.getTabComponent().getBounds(); + ContentManager manager = myUi.getContentManager(); LayoutData data = new LayoutData(myUi); data.eachX = TAB_LAYOUT_START; @@ -137,7 +137,6 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { } } - if (data.fullLayout) { for (ContentTabLabel eachTab : myTabs) { final Dimension eachSize = eachTab.getPreferredSize(); @@ -200,8 +199,7 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { data.moreRect = null; } - final Rectangle moreRect = data.moreRect == null ? null : new Rectangle(data.eachX, 0, /*getMoreToolbarWidth()*/16+MORE_ICON_BORDER, bounds.height); - + Rectangle moreRect = data.moreRect == null ? null : new Rectangle(data.eachX, 0, /*getMoreToolbarWidth()*/16+MORE_ICON_BORDER, bounds.height); myUi.isResizableArea = p -> moreRect == null || !moreRect.contains(p); myLastLayout = data; if (toolbarUpdateNeeded) { @@ -220,7 +218,7 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { } } - ContentManager contentManager = myUi.contentManager; + ContentManager contentManager = myUi.getContentManager(); Content selected = contentManager.getSelectedContent(); if (selected == null && contentManager.getContents().length > 0) { selected = contentManager.getContents()[0]; @@ -237,14 +235,16 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { } boolean isToDrawTabs() { - if(myTabs.size() > 1) return true; - - if(myTabs.size() == 1) { - String title = myTabs.get(0).getContent().getToolwindowTitle(); - return !StringUtil.isEmpty(title); - } - + int size = myTabs.size(); + if (size > 1) { + return true; + } + else if (size == 1) { + return !StringUtil.isEmpty(myTabs.get(0).getContent().getToolwindowTitle()); + } + else { return false; + } } static class LayoutData { @@ -263,12 +263,12 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { public int contentCount; LayoutData(ToolWindowContentUi ui) { - layoutSize = ui.getSize(); - contentCount = ui.contentManager.getContentCount(); + layoutSize = ui.getTabComponent().getSize(); + contentCount = ui.getContentManager().getContentCount(); } } - private JBTabPainter tabPainter = JBTabPainter.getTOOL_WINDOW(); + private final JBTabPainter tabPainter = JBTabPainter.getTOOL_WINDOW(); @Override public void paintComponent(Graphics g) { @@ -292,11 +292,6 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { g2d.dispose(); } - @Override - public void paintChildren(Graphics g) { - if (!isToDrawTabs()) return; - } - @Override public void update() { for (ContentTabLabel each : myTabs) { @@ -308,13 +303,13 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { @Override public void rebuild() { - myUi.removeAll(); + myUi.getTabComponent().removeAll(); - myUi.add(myIdLabel); + myUi.getTabComponent().add(myIdLabel); ToolWindowContentUi.initMouseListeners(myIdLabel, myUi, true); for (ContentTabLabel each : myTabs) { - myUi.add(each); + myUi.getTabComponent().add(each); ToolWindowContentUi.initMouseListeners(each, myUi, false); } } @@ -359,7 +354,7 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware { @Override public void showContentPopup(ListPopup listPopup) { - Content selected = myUi.contentManager.getSelectedContent(); + Content selected = myUi.getContentManager().getSelectedContent(); if (selected != null) { ContentTabLabel tab = myContent2Tabs.get(selected); listPopup.showUnderneathOf(tab); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabbedContentTabLabel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabbedContentTabLabel.java index 8405f0a0fb9b..1b267d911fb6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabbedContentTabLabel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabbedContentTabLabel.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl.content; import com.intellij.ide.IdeEventQueue; @@ -8,7 +8,6 @@ import com.intellij.reference.SoftReference; import com.intellij.ui.content.TabbedContent; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.awt.*; import java.lang.ref.Reference; @@ -18,8 +17,7 @@ import java.util.List; /** * @author Konstantin Bulenkov */ -public class TabbedContentTabLabel extends ContentTabLabel { - +public final class TabbedContentTabLabel extends ContentTabLabel { private final TabbedContent myContent; private Reference myPopupReference = null; @@ -80,7 +78,7 @@ public class TabbedContentTabLabel extends ContentTabLabel { return hasMultipleTabs(); } - @Nullable + @NotNull @Override public Runnable getAction() { return () -> selectContent(); @@ -99,7 +97,7 @@ public class TabbedContentTabLabel extends ContentTabLabel { } } - @Nullable + @NotNull @Override public TabbedContent getContent() { return myContent; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ToolWindowContentUi.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ToolWindowContentUi.java index c96e7f0ac9b3..e34c763fd3fd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ToolWindowContentUi.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ToolWindowContentUi.java @@ -13,22 +13,21 @@ import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.ThreeComponentsSplitter; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; -import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.wm.*; import com.intellij.openapi.wm.impl.ToolWindowImpl; import com.intellij.openapi.wm.impl.ToolWindowManagerImpl; -import com.intellij.ui.ComponentUtil; import com.intellij.ui.PopupHandler; import com.intellij.ui.content.*; import com.intellij.ui.content.tabs.PinToolwindowTabAction; import com.intellij.ui.content.tabs.TabbedContentAction; +import com.intellij.ui.layout.migLayout.MigLayoutBuilderKt; +import com.intellij.ui.layout.migLayout.patched.MigLayout; import com.intellij.ui.tabs.impl.MorePopupAware; import com.intellij.util.Alarm; import com.intellij.util.ContentUtilEx; -import com.intellij.util.containers.JBIterable; import com.intellij.util.containers.Predicate; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.LocationOnDragTracker; @@ -44,62 +43,48 @@ import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; import java.util.List; -public final class ToolWindowContentUi extends JPanel implements ContentUI, DataProvider, UISettingsListener { +public final class ToolWindowContentUi implements ContentUI, DataProvider { // when client property is put in toolwindow component, hides toolwindow label public static final String HIDE_ID_LABEL = "HideIdLabel"; private static final String TOOLWINDOW_UI_INSTALLED = "ToolWindowUiInstalled"; - ContentManager contentManager; + private ContentManager contentManager; - final JPanel myContent = new JPanel(new BorderLayout()); - ToolWindowImpl myWindow; + public ContentManager getContentManager() { + return contentManager; + } - TabbedContentAction.CloseAllAction myCloseAllAction; - TabbedContentAction.MyNextTabAction myNextTabAction; - TabbedContentAction.MyPreviousTabAction myPreviousTabAction; + private final JPanel myContent = new JPanel(new BorderLayout()); + final ToolWindowImpl myWindow; - ShowContentAction myShowContent; + private TabbedContentAction.CloseAllAction myCloseAllAction; + private TabbedContentAction.MyNextTabAction myNextTabAction; + private TabbedContentAction.MyPreviousTabAction myPreviousTabAction; - TabContentLayout myTabsLayout = new TabContentLayout(this); - ContentLayout myComboLayout = new ComboContentLayout(this); + private ShowContentAction myShowContent; - private ToolWindowContentUiType myType = ToolWindowContentUiType.TABBED; + private final TabContentLayout myTabsLayout; + private ContentLayout myComboLayout; + + private ToolWindowContentUiType myType; public Predicate isResizableArea = p -> true; - public ToolWindowContentUi(@NotNull ToolWindowImpl window) { + private final JPanel tabComponent = new TabPanel(); + + @NotNull + public JPanel getTabComponent() { + return tabComponent; + } + + public ToolWindowContentUi(@NotNull ToolWindowImpl window, @NotNull ToolWindowContentUiType contentUiType) { + myType = contentUiType; + myTabsLayout = new TabContentLayout(this); myWindow = window; myContent.setOpaque(false); myContent.setFocusable(false); - setOpaque(false); - - setBorder(JBUI.Borders.emptyRight(2)); - - // InternalDecorator adds myContent right after "this" (via ToolWindowHeader) - // also myContent is never removed (can be invisible due to DumbAwareHider) - ComponentUtil.putClientProperty(myContent, UIUtil.NOT_IN_HIERARCHY_COMPONENTS, new Iterable() { - @Override - public Iterator iterator() { - if (contentManager == null || contentManager.getContentCount() == 0) { - return Collections.emptyIterator(); - } - return JBIterable.of(contentManager.getContents()) - .map(content -> { - JComponent last = null; - for (Component c : UIUtil.uiParents(content.getComponent(), false)) { - if (c == contentManager.getComponent() || !(c instanceof JComponent)) return null; - last = (JComponent)c; - } - return last; - }) - .filter(Conditions.notNull()) - .iterator(); - } - }); } @NotNull @@ -107,12 +92,6 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data return myWindow.getId(); } - @Override - public void uiSettingsChanged(@NotNull UISettings uiSettings) { - revalidate(); - repaint(); - } - private boolean isResizeable() { if (myWindow.getType() == ToolWindowType.FLOATING || myWindow.getType() == ToolWindowType.WINDOWED) { return false; @@ -158,7 +137,15 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data @NotNull private ContentLayout getCurrentLayout() { - return myType == ToolWindowContentUiType.TABBED ? myTabsLayout : myComboLayout; + if (myType == ToolWindowContentUiType.TABBED) { + return myTabsLayout; + } + else { + if (myComboLayout == null) { + myComboLayout = new ComboContentLayout(this); + } + return myComboLayout; + } } @Override @@ -166,10 +153,6 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data return myContent; } - public JComponent getTabComponent() { - return this; - } - @Override public void setManager(@NotNull ContentManager manager) { if (contentManager != null) { @@ -214,7 +197,7 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data } }); - initMouseListeners(this, this, true); + initMouseListeners(tabComponent, this, true); rebuild(); @@ -249,57 +232,19 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data getCurrentLayout().rebuild(); getCurrentLayout().update(); - revalidate(); - repaint(); + tabComponent.revalidate(); + tabComponent.repaint(); if (contentManager != null && contentManager.getContentCount() == 0 && myWindow.isToHideOnEmptyContent()) { myWindow.hide(null); } } - @Override - public void doLayout() { - getCurrentLayout().layout(); - } - - @Override - protected void paintComponent(final Graphics g) { - super.paintComponent(g); - getCurrentLayout().paintComponent(g); - } - - @Override - protected void paintChildren(final Graphics g) { - super.paintChildren(g); - getCurrentLayout().paintChildren(g); - } - - @Override - public Dimension getMinimumSize() { - Insets insets = getInsets(); - return new Dimension(insets.left + insets.right + getCurrentLayout().getMinimumWidth(), super.getMinimumSize().height); - } - - @Override - public Dimension getPreferredSize() { - Dimension size = new Dimension(); - size.height = 0; - size.width = TabContentLayout.TAB_LAYOUT_START + getInsets().left + getInsets().right; - for (int i = 0; i < getComponentCount(); i++) { - final Component each = getComponent(i); - size.height = Math.max(each.getPreferredSize().height, size.height); - size.width += each.getPreferredSize().width; - } - - size.width = Math.max(size.width, getMinimumSize().width); - return size; - } - private void update() { getCurrentLayout().update(); - revalidate(); - repaint(); + tabComponent.revalidate(); + tabComponent.repaint(); } @Override @@ -363,7 +308,9 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data final Ref myDragTracker = Ref.create(); private Component getActualSplitter() { - if (!allowResize || !ui.isResizeable()) return null; + if (!allowResize || !ui.isResizeable()) { + return null; + } Component component = c; Component parent = component.getParent(); @@ -628,7 +575,8 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data } else if (CloseAction.CloseTarget.KEY.is(dataId)) { return computeCloseTarget(); - } else if (MorePopupAware.KEY.is(dataId)) { + } + else if (MorePopupAware.KEY.is(dataId)) { ContentLayout layout = getCurrentLayout(); return (layout instanceof TabContentLayout) ? layout : null; } @@ -685,4 +633,51 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data new Alarm(Alarm.ThreadToUse.SWING_THREAD, popup).addRequest(() -> popup.handleSelect(false), 50); } } + + private final class TabPanel extends JPanel implements UISettingsListener { + private TabPanel() { + super(new MigLayout(MigLayoutBuilderKt.createLayoutConstraints(0, 0).noVisualPadding().fillY())); + + setOpaque(false); + setBorder(JBUI.Borders.emptyRight(2)); + } + + @Override + public void uiSettingsChanged(@NotNull UISettings uiSettings) { + revalidate(); + repaint(); + } + + @Override + public void doLayout() { + getCurrentLayout().layout(); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + getCurrentLayout().paintComponent(g); + } + + @Override + public Dimension getMinimumSize() { + Insets insets = getInsets(); + return new Dimension(insets.left + insets.right + getCurrentLayout().getMinimumWidth(), super.getMinimumSize().height); + } + + @Override + public Dimension getPreferredSize() { + Dimension size = new Dimension(); + size.height = 0; + size.width = TabContentLayout.TAB_LAYOUT_START + getInsets().left + getInsets().right; + for (int i = 0; i < getComponentCount(); i++) { + final Component each = getComponent(i); + size.height = Math.max(each.getPreferredSize().height, size.height); + size.width += each.getPreferredSize().width; + } + + size.width = Math.max(size.width, getMinimumSize().width); + return size; + } + } } diff --git a/platform/platform-impl/src/com/intellij/ui/content/impl/ContentImpl.java b/platform/platform-impl/src/com/intellij/ui/content/impl/ContentImpl.java index 789820e6a5ce..a98ab23fbd38 100644 --- a/platform/platform-impl/src/com/intellij/ui/content/impl/ContentImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/content/impl/ContentImpl.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ui.content.impl; import com.intellij.icons.AllIcons; @@ -153,8 +153,7 @@ public class ContentImpl extends UserDataHolderBase implements Content { @Override public String getToolwindowTitle() { - if (myToolwindowTitle != null) return myToolwindowTitle; - return myDisplayName; + return myToolwindowTitle == null ? myDisplayName : myToolwindowTitle; } @Override @@ -172,11 +171,6 @@ public class ContentImpl extends UserDataHolderBase implements Content { myShouldDisposeContent = value; } - @Override - public boolean shouldDisposeContent() { - return myShouldDisposeContent; - } - @Override public String getDescription() { return myDescription; diff --git a/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java b/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java index b06a8ae12e2d..078d9a92ea68 100644 --- a/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ui.content.impl; import com.intellij.ide.DataManager; @@ -169,7 +169,7 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene @Override public boolean removeContent(@NotNull Content content, boolean dispose) { - boolean wasFocused = content.getComponent() != null && UIUtil.isFocusAncestor(content.getComponent()); + boolean wasFocused = UIUtil.isFocusAncestor(content.getComponent()); return removeContent(content, dispose, wasFocused, false).isDone(); } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java index 526d79774aa2..31daaf92618d 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.plugins.terminal; import com.google.common.collect.Sets; @@ -161,11 +161,9 @@ public class TerminalView { } @Nullable - private JBTerminalWidget createNewSession(@NotNull AbstractTerminalRunner terminalRunner, @Nullable TerminalTabState tabState, boolean requestFocus) { + private JBTerminalWidget createNewSession(@NotNull AbstractTerminalRunner terminalRunner, @Nullable TerminalTabState tabState, boolean requestFocus) { ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(TerminalToolWindowFactory.TOOL_WINDOW_ID); if (window != null && window.isAvailable()) { - // ensure TerminalToolWindowFactory.createToolWindowContent gets called - ((ToolWindowImpl)window).ensureContentInitialized(); Content content = createNewTab(null, terminalRunner, myToolWindow, tabState, requestFocus); window.activate(null); return Objects.requireNonNull(getWidgetByContent(content)); @@ -350,16 +348,16 @@ public class TerminalView { public void openTerminalIn(@Nullable VirtualFile fileToOpen) { ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(TerminalToolWindowFactory.TOOL_WINDOW_ID); - if (window != null && window.isAvailable()) { - // ensure TerminalToolWindowFactory.createToolWindowContent gets called - ((ToolWindowImpl)window).ensureContentInitialized(); - TerminalTabState state = new TerminalTabState(); - if (fileToOpen != null) { - state.myWorkingDirectory = fileToOpen.getPath(); - } - createNewSession(myTerminalRunner, state); - window.activate(null); + if (window == null || !window.isAvailable()) { + return; } + + TerminalTabState state = new TerminalTabState(); + if (fileToOpen != null) { + state.myWorkingDirectory = fileToOpen.getPath(); + } + createNewSession(myTerminalRunner, state); + window.activate(null); } @Nullable