/*
* Copyright 2000-2015 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.util;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.editor.impl.SettingsImpl;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
import com.intellij.openapi.editor.markup.HighlighterLayer;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ScreenUtil;
import com.intellij.ui.UIBundle;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
/**
* @author zajac
* @since 6.05.2012
*/
public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder {
private final Project myProject;
private final UserDataHolderBase myDataHolderBase = new UserDataHolderBase();
private final JLabel myLabel = new JLabel("", SwingConstants.CENTER);
private Editor myEditor;
private ItemWrapper myWrapper;
private JPanel myDetailPanel;
private JPanel myDetailPanelWrapper;
private RangeHighlighter myHighlighter;
private PreviewEditorState myEditorState = PreviewEditorState.EMPTY;
private String myEmptyLabel = UIBundle.message("message.nothingToShow");
public DetailViewImpl(Project project) {
super(new BorderLayout());
myProject = project;
setPreferredSize(JBUI.size(600, 300));
myLabel.setVerticalAlignment(SwingConstants.CENTER);
}
@Override
public void clearEditor() {
if (getEditor() != null) {
clearHighlighting();
remove(getEditor().getComponent());
EditorFactory.getInstance().releaseEditor(getEditor());
myEditorState = PreviewEditorState.EMPTY;
setEditor(null);
repaint();
}
}
@Override
public void setCurrentItem(@Nullable ItemWrapper wrapper) {
myWrapper = wrapper;
}
@Override
public PreviewEditorState getEditorState() {
return myEditorState;
}
@Override
public ItemWrapper getCurrentItem() {
return myWrapper;
}
@Override
public boolean hasEditorOnly() {
return false;
}
@Override
public void removeNotify() {
super.removeNotify();
if (ScreenUtil.isStandardAddRemoveNotify(this))
clearEditor();
}
@Override
public Editor getEditor() {
return myEditor;
}
public void setEditor(Editor editor) {
myEditor = editor;
}
@Override
public void navigateInPreviewEditor(PreviewEditorState editorState) {
final VirtualFile file = editorState.getFile();
final LogicalPosition positionToNavigate = editorState.getNavigate();
final TextAttributes lineAttributes = editorState.getAttributes();
Document document = FileDocumentManager.getInstance().getDocument(file);
clearEditor();
myEditorState = editorState;
remove(myLabel);
if (document != null) {
if (getEditor() == null || getEditor().getDocument() != document) {
setEditor(createEditor(myProject, document, file));
add(getEditor().getComponent(), BorderLayout.CENTER);
}
if (positionToNavigate != null) {
getEditor().getCaretModel().moveToLogicalPosition(positionToNavigate);
validate();
getEditor().getScrollingModel().scrollToCaret(ScrollType.CENTER);
} else {
revalidate();
repaint();
}
clearHighlighting();
if (lineAttributes != null && positionToNavigate != null && positionToNavigate.line < getEditor().getDocument().getLineCount()) {
myHighlighter = getEditor().getMarkupModel().addLineHighlighter(positionToNavigate.line, HighlighterLayer.SELECTION - 1,
lineAttributes);
}
}
else {
myLabel.setText("Navigate to selected " + (file.isDirectory() ? "directory " : "file ") + "in Project View");
add(myLabel, BorderLayout.CENTER);
validate();
}
}
@NotNull
protected Editor createEditor(@Nullable Project project, Document document, VirtualFile file) {
EditorEx editor = (EditorEx)EditorFactory.getInstance().createViewer(document, project);
final EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(file, scheme, project);
editor.setFile(file);
editor.setHighlighter(highlighter);
EditorSettings settings = editor.getSettings();
settings.setAnimatedScrolling(false);
settings.setRefrainFromScrolling(false);
settings.setLineNumbersShown(true);
settings.setFoldingOutlineShown(false);
if (settings instanceof SettingsImpl) {
((SettingsImpl)settings).setSoftWrapAppliancePlace(SoftWrapAppliancePlaces.PREVIEW);
}
editor.getFoldingModel().setFoldingEnabled(false);
return editor;
}
private void clearHighlighting() {
if (myHighlighter != null) {
getEditor().getMarkupModel().removeHighlighter(myHighlighter);
myHighlighter = null;
}
}
@Override
public JPanel getPropertiesPanel() {
return myDetailPanel;
}
@Override
public void setPropertiesPanel(@Nullable final JPanel panel) {
if (panel == null) {
if (myDetailPanelWrapper != null) {
myDetailPanelWrapper.removeAll();
}
myLabel.setText(myEmptyLabel);
add(myLabel, BorderLayout.CENTER);
}
else if (panel != myDetailPanel) {
remove(myLabel);
if (myDetailPanelWrapper == null) {
myDetailPanelWrapper = new JPanel(new GridLayout(1, 1));
myDetailPanelWrapper.setBorder(IdeBorderFactory.createEmptyBorder(5, 5, 5, 5));
myDetailPanelWrapper.add(panel);
add(myDetailPanelWrapper, BorderLayout.NORTH);
} else {
myDetailPanelWrapper.removeAll();
myDetailPanelWrapper.add(panel);
}
}
myDetailPanel = panel;
revalidate();
repaint();
}
public void setEmptyLabel(String text) {
myEmptyLabel = text;
}
@Override
public <T> T getUserData(@NotNull Key<T> key) {
return myDataHolderBase.getUserData(key);
}
@Override
public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
myDataHolderBase.putUserData(key, value);
}
}