All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.openapi.diff.impl.util.DiffPanelOuterComponent Maven / Gradle / Ivy

/*
 * 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.openapi.diff.impl.util;

import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.diff.DiffToolbar;
import com.intellij.openapi.diff.ex.DiffStatusBar;
import com.intellij.openapi.diff.impl.DiffToolbarComponent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.util.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.util.List;

public class DiffPanelOuterComponent extends JPanel implements DataProvider {
  private final DiffStatusBar myStatusBar;
  private final DiffToolbarComponent myToolbar;
  @Nullable private DiffRequest.ToolbarAddons myDefaultActions;
  private DataProvider myDataProvider = null;
  private DeferScrollToFirstDiff myScrollState = NO_SCROLL_NEEDED;
  private ScrollingPanel myScrollingPanel = null;
  private final JPanel myBottomContainer;
  private JComponent myBottomComponent;
  private JPanel myWrapper;
  private Getter myPreferredHeightGetter;
  private int myPrefferedWidth;
  private Getter myDefaultHeight;

  public DiffPanelOuterComponent(List diffTypes, @Nullable DiffRequest.ToolbarAddons toolbarAddons) {
    super(new BorderLayout());
    myStatusBar = new DiffStatusBar(diffTypes);
    myBottomContainer = new JPanel(new BorderLayout());
    myBottomContainer.add(myStatusBar, BorderLayout.SOUTH);
    add(myBottomContainer, BorderLayout.SOUTH);
    myDefaultActions = toolbarAddons;
    myToolbar = new DiffToolbarComponent(this);
    disableToolbar(false);
    myWrapper = new JPanel(new BorderLayout());
    add(myWrapper, BorderLayout.CENTER);
    myDefaultHeight = new Getter() {
      @Override
      public Integer get() {
        return 400;
      }
    };
    myPreferredHeightGetter = myDefaultHeight;
    myPrefferedWidth = 600;
  }

  public void setToolbarActions(@NotNull DiffRequest.ToolbarAddons toolbarAddons) {
    myDefaultActions = toolbarAddons;
  }

  public DiffToolbar resetToolbar() {
    if (myDefaultActions != null) {
      myToolbar.resetToolbar(myDefaultActions);
    }
    return myToolbar.getToolbar();
  }

  public void resetDiffComponent(JComponent component, ScrollingPanel scrollingPanel) {
    myWrapper.removeAll();
    insertDiffComponent(component, scrollingPanel);
  }

  public void insertDiffComponent(JComponent component, ScrollingPanel scrollingPanel) {
    myWrapper.add(component, BorderLayout.CENTER);
    setScrollingPanel(scrollingPanel);
  }

  public void insertTopComponent(JComponent component) {
    myWrapper.add(component, BorderLayout.NORTH);
  }

  public JComponent getBottomComponent() {
    return myBottomComponent;
  }

  public void setBottomComponent(JComponent component) {
    if (myBottomComponent != null) {
      myBottomContainer.remove(myBottomComponent);
    }
    myBottomComponent = component;
    if (myBottomComponent != null) {
      myBottomContainer.add(BorderLayout.CENTER, component);
    }
  }

  public void setDataProvider(DataProvider dataProvider) {
    myDataProvider = dataProvider;
  }

  public void setStatusBarText(String text) {
    myStatusBar.setText(text);
  }

  @Override
  public Dimension getPreferredSize() {
    return new Dimension(myPrefferedWidth, myPreferredHeightGetter.get());
  }

  public void setPrefferedWidth(int prefferedWidth) {
    myPrefferedWidth = prefferedWidth;
  }

  public void setPreferredHeightGetter(final Getter getter) {
    if (getter == null) {
      myPreferredHeightGetter = myDefaultHeight;
    } else {
      myPreferredHeightGetter = getter;
    }
  }

  public void removeStatusBar() {
    if (myStatusBar != null) {
      myStatusBar.setVisible(false);
    }
  }

  public Object getData(String dataId) {
    if (PlatformDataKeys.SOURCE_NAVIGATION_LOCKED.is(dataId)) {
      return Boolean.TRUE;
    }
    if (myDataProvider == null) {
      return null;
    }
    if (CommonDataKeys.EDITOR.is(dataId)) {
      if (myBottomComponent != null) {
        // we don't want editor actions to be executed when the bottom component has focus
        final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
        if (myBottomComponent.isAncestorOf(focusOwner)) {
          return null;
        }
      }
      final FocusDiffSide side = (FocusDiffSide)myDataProvider.getData(FocusDiffSide.DATA_KEY.getName());
      if (side != null) {
        final Editor editor = side.getEditor();
        return editor != null && editor.getComponent().hasFocus() ? editor : null;
      }
    }
    return myDataProvider.getData(dataId);
  }

  public void setScrollingPanel(ScrollingPanel scrollingPanel) {
    myScrollingPanel = scrollingPanel;
  }

  public void requestScrollEditors() {
    myScrollState = SCROLL_WHEN_POSSIBLE;
    tryScrollNow();
  }

  private void tryScrollNow() {
    if (myScrollingPanel == null) return;
    myScrollState.deferScroll(this);
  }

  private void performScroll() {
    DeferScrollToFirstDiff newState = myScrollState.scrollNow(myScrollingPanel, this);
    if (newState != null) myScrollState = newState;
  }

  public void addNotify() {
    super.addNotify();
    tryScrollNow();
  }

  public void setBounds(int x, int y, int width, int height) {
    super.setBounds(x, y, width, height);
    tryScrollNow();
  }

  protected void validateTree() {
    super.validateTree();
    tryScrollNow();
  }

  public void cancelScrollEditors() {
    myScrollState = NO_SCROLL_NEEDED;
  }

  public void removeTopComponent(final JComponent jComponent) {
    myWrapper.remove(jComponent);
  }

  public void addStatusBar() {
    if (myStatusBar != null) {
      myStatusBar.setVisible(true);
    }
  }

  private interface DeferScrollToFirstDiff {
    DeferScrollToFirstDiff scrollNow(ScrollingPanel panel, JComponent component);

    void deferScroll(DiffPanelOuterComponent outer);
  }

  public interface ScrollingPanel {
    void scrollEditors();
  }

  private static final DeferScrollToFirstDiff NO_SCROLL_NEEDED = new DeferScrollToFirstDiff() {
    public DeferScrollToFirstDiff scrollNow(ScrollingPanel panel, JComponent component) {
      return NO_SCROLL_NEEDED;
    }

    public void deferScroll(DiffPanelOuterComponent outer) {
    }
  };

  private static final DeferScrollToFirstDiff SCROLL_WHEN_POSSIBLE = new DeferScrollToFirstDiff() {
    public DeferScrollToFirstDiff scrollNow(ScrollingPanel panel, JComponent component) {
      if (!component.isDisplayable()) return null;
      panel.scrollEditors();
      return NO_SCROLL_NEEDED;
    }

    public void deferScroll(final DiffPanelOuterComponent outer) {
      if (!outer.isDisplayable()) return;
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          outer.performScroll();
        }
      });
    }
  };

  public void disableToolbar(boolean disable) {
    if (disable && isToolbarEnabled()) remove(myToolbar);
    else if (myToolbar.getParent() == null) add(myToolbar, BorderLayout.NORTH);
  }

  public boolean isToolbarEnabled() {
    return myToolbar.getParent() != null;
  }

  public void registerToolbarActions() {
    myToolbar.getToolbar().registerKeyboardActions(this);
  }

  public void setColorScheme(EditorColorsScheme scheme) {
    myStatusBar.setColorScheme(scheme);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy