import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.preview.PreviewManager;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderEntry;
myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project);
JBPopup _oldHint = getDocInfoHint();
+ PreviewManager previewManager = PreviewManager.SERVICE.getInstance(myProject);
+ if (previewManager != null &&
+ previewManager.preview(DocumentationPreviewPanelProvider.ID, Couple.of(element, originalElement), requestFocus) != null) {
+ return;
+ }
+
if (myToolWindow == null && PropertiesComponent.getInstance().isTrueValue(SHOW_DOCUMENTATION_IN_TOOL_WINDOW)) {
createToolWindow(element, originalElement);
}
}
}
- private static String getTitle(@NotNull final PsiElement element, final boolean _short) {
+ static String getTitle(@NotNull final PsiElement element, final boolean _short) {
final String title = SymbolPresentationUtil.getSymbolPresentableText(element);
return _short ? title != null ? title : element.getText() : CodeInsightBundle.message("javadoc.info.title", title != null ? title : element.getText());
}
--- /dev/null
+/*
+ * 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.codeInsight.documentation;
+
+import com.intellij.openapi.preview.PreviewPanelProvider;
+import com.intellij.openapi.preview.PreviewProviderId;
+import com.intellij.openapi.util.Couple;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class DocumentationPreviewPanelProvider extends PreviewPanelProvider<Couple<PsiElement>, DocumentationComponent> {
+ public static final PreviewProviderId<Couple<PsiElement>, DocumentationComponent> ID = PreviewProviderId.create("Documentation");
+ private final DocumentationComponent myDocumentationComponent;
+ private final DocumentationManager myDocumentationManager;
+ private boolean myBlocked = false;
+
+ public DocumentationPreviewPanelProvider(DocumentationManager documentationManager) {
+ super(ID);
+ myDocumentationManager = documentationManager;
+ myDocumentationComponent = new DocumentationComponent(documentationManager) {
+ @Override
+ public String toString() {
+ return "Preview DocumentationComponent (" + (isEmpty() ? "empty" : "not empty") + ")";
+ }
+ };
+ }
+
+ @Override
+ public boolean shouldBeEnabledByDefault() {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ protected JComponent getComponent() {
+ return myDocumentationComponent;
+ }
+
+ @NotNull
+ @Override
+ protected String getTitle(@NotNull Couple<PsiElement> content) {
+ return DocumentationManager.getTitle(content.getFirst(), false);
+ }
+
+ @Nullable
+ @Override
+ protected Icon getIcon(@NotNull Couple<PsiElement> content) {
+ return content.getFirst().getIcon(0);
+ }
+
+ @Override
+ public float getMenuOrder() {
+ return 1;
+ }
+
+ @Override
+ public boolean moveContentToStandardView(@NotNull Couple<PsiElement> content) {
+ myBlocked = true;
+ try {
+ myDocumentationManager.showJavaDocInfo(content.getFirst(), content.getSecond());
+ }
+ finally {
+ myBlocked = false;
+ }
+ return true;
+ }
+
+ @Override
+ protected DocumentationComponent initComponent(Couple<PsiElement> content, boolean requestFocus) {
+ if (myBlocked) return null;
+ if (!content.getFirst().getManager().areElementsEquivalent(myDocumentationComponent.getElement(), content.getFirst())) {
+ myDocumentationManager.fetchDocInfo(content.getFirst(), myDocumentationComponent);
+ }
+ return myDocumentationComponent;
+ }
+}
UIUtil.TextPainter painter = new UIUtil.TextPainter().withLineSpacing(1.5f);
painter.withShadow(true, new JBColor(Gray._200.withAlpha(100), Gray._0.withAlpha(255)));
- painter.appendLine("No files are open");
+ painter.appendLine("No files are open").underlined(new JBColor(Gray._150, Gray._180));
- if (!splitters.isPreview()) {
- painter.underlined(new JBColor(Gray._150, Gray._180));
- advertiseActions(splitters, painter);
- }
+ advertiseActions(splitters, painter);
painter.draw(g, new PairFunction<Integer, Integer, Couple<Integer>>() {
@Override
import com.intellij.openapi.fileTypes.FileTypeEvent;
import com.intellij.openapi.fileTypes.FileTypeListener;
import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.preview.PreviewManager;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.PossiblyDumbAware;
public static final String FILE_EDITOR_MANAGER = "FileEditorManager";
private volatile JPanel myPanels;
- private PreviewPanel myPreviewPanel;
private EditorsSplitters mySplitters;
private final Project myProject;
private final List<Pair<VirtualFile, EditorWindow>> mySelectionHistory = new ArrayList<Pair<VirtualFile, EditorWindow>>();
@NotNull
public Set<EditorsSplitters> getAllSplitters() {
Set<EditorsSplitters> all = new LinkedHashSet<EditorsSplitters>();
- EditorWindow previewWindow = getPreviewWindow();
- if (previewWindow != null) {
- all.add(previewWindow.getOwner());
- }
all.add(getMainSplitters());
Set<DockContainer> dockContainers = myDockManager.getContainers();
for (DockContainer each : dockContainers) {
}
}
}
- if (myPreviewPanel == null && PreviewPanel.isAvailable()) {
- synchronized (myInitLock) {
- myPreviewPanel = new PreviewPanel(myProject, this, myDockManager);
- }
- }
- }
-
- @Nullable
- private EditorWindow getPreviewWindow() {
- if (!PreviewPanel.isAvailable()) return null;
- initUI();
- return myPreviewPanel.getWindow();
}
private static class MyBorder implements Border {
}
if (wndToOpenIn == null || !wndToOpenIn.isFileOpen(file)) {
- EditorWindow previewWindow = getPreviewWindow();
- if (previewWindow != null) {
- wndToOpenIn = previewWindow;
- focusEditor = true;
+ PreviewManager previewManager = PreviewManager.SERVICE.getInstance(myProject);
+ if (previewManager != null) {
+ Pair<FileEditor[], FileEditorProvider[]> previewResult = previewManager.preview(FilePreviewPanelProvider.ID, file, focusEditor);
+ if (previewResult != null) {
+ return previewResult;
+ }
}
}
--- /dev/null
+/*
+ * 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.openapi.fileEditor.impl;
+
+import com.intellij.ide.ui.UISettings;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorProvider;
+import com.intellij.openapi.preview.PreviewManager;
+import com.intellij.openapi.preview.PreviewPanelProvider;
+import com.intellij.openapi.preview.PreviewProviderId;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.docking.DockManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FilePreviewPanelProvider extends PreviewPanelProvider<VirtualFile, Pair<FileEditor[], FileEditorProvider[]>> {
+ public static final PreviewProviderId<VirtualFile, Pair<FileEditor[], FileEditorProvider[]>> ID = PreviewProviderId.create("Files");
+
+ private final FileEditorManagerImpl myManager;
+ private final Project myProject;
+
+ private EditorWindow myWindow;
+ private EditorsSplitters myEditorsSplitters;
+
+ public FilePreviewPanelProvider(@NotNull Project project, @NotNull FileEditorManagerImpl manager, @NotNull DockManager dockManager) {
+ super(ID);
+ myProject = project;
+ myManager = manager;
+ myEditorsSplitters = new MyEditorsSplitters(manager, dockManager, false);
+ myEditorsSplitters.createCurrentWindow();
+ myWindow = myEditorsSplitters.getCurrentWindow();
+ myWindow.setTabsPlacement(UISettings.TABS_NONE);
+ }
+
+ @NotNull
+ @Override
+ protected JComponent getComponent() {
+ return myEditorsSplitters;
+ }
+
+ @Override
+ public boolean shouldBeEnabledByDefault() {
+ return true;
+ }
+
+ @Override
+ protected Pair<FileEditor[], FileEditorProvider[]> initComponent(VirtualFile file, boolean requestFocus) {
+ return myManager.openFileWithProviders(file, requestFocus, myWindow);
+ }
+
+ @NotNull
+ @Override
+ protected String getTitle(@NotNull VirtualFile file) {
+ return StringUtil.getShortened(EditorTabbedContainer.calcTabTitle(myProject, file), UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT);
+ }
+
+ @Nullable
+ @Override
+ protected Icon getIcon(@NotNull VirtualFile file) {
+ return file.getFileType().getIcon();
+ }
+
+ @Override
+ public float getMenuOrder() {
+ return 0;
+ }
+
+ @Override
+ public boolean moveContentToStandardView(@NotNull VirtualFile file) {
+ EditorWindow window = myManager.getCurrentWindow();
+ if (window == null) { //main tab set is still not created, rare situation
+ myManager.getMainSplitters().createCurrentWindow();
+ window = myManager.getCurrentWindow();
+ }
+ myManager.openFileWithProviders(file, true, window);
+ return true;
+ }
+
+ private class MyEditorsSplitters extends EditorsSplitters {
+ public MyEditorsSplitters(final FileEditorManagerImpl manager, DockManager dockManager, boolean createOwnDockableContainer) {
+ super(manager, dockManager, createOwnDockableContainer);
+ }
+
+ @Override
+ protected void afterFileClosed(VirtualFile file) {
+ PreviewManager previewManager = PreviewManager.SERVICE.getInstance(myProject);
+ if (previewManager != null) {
+ previewManager.close(getId(), file);
+ }
+ }
+
+ @Override
+ protected EditorWindow createEditorWindow() {
+ return new EditorWindow(this) {
+ @Override
+ protected void onBeforeSetEditor(VirtualFile file) {
+ List<VirtualFile> toMove = new ArrayList<VirtualFile>();
+ for (EditorWithProviderComposite composite : getEditorsComposites()) {
+ if (composite.isModified()) {
+ toMove.add(composite.getFile());
+ }
+ }
+ PreviewManager previewManager = PreviewManager.SERVICE.getInstance(myProject);
+ if (previewManager != null) {
+ for (VirtualFile virtualFile : toMove) {
+ previewManager.moveToStandardPlace(getId(), virtualFile);
+ }
+ }
+ }
+ };
+ }
+
+
+ @Override
+ public void setTabsPlacement(int tabPlacement) {
+ super.setTabsPlacement(UISettings.TABS_NONE);
+ }
+
+ @Override
+ public boolean isPreview() {
+ return true;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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.openapi.preview;
+
+import com.intellij.util.ui.EmptyIcon;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @param <V> is value type for data we show
+ * @param <C> is "container" type that would be used/reused for displaying data
+ */
+public class PreviewInfo<V, C> {
+ @NotNull private final PreviewPanelProvider<V, C> myProvider;
+ @NotNull private final V myData;
+
+ public static <V, C> PreviewInfo<V, C> create(@NotNull PreviewPanelProvider<V, C> provider, @NotNull V data) {
+ return new PreviewInfo<V, C>(provider, data);
+ }
+
+ public PreviewInfo(@NotNull PreviewPanelProvider<V, C> provider, @NotNull V data) {
+ myProvider = provider;
+ myData = data;
+ }
+
+ public PreviewProviderId<V, C> getId() {
+ return myProvider.getId();
+ }
+
+ @NotNull
+ public JComponent getComponent() {
+ return myProvider.getComponent();
+ }
+
+ @NotNull
+ public String getTitle() {
+ return myProvider.getTitle(myData);
+ }
+
+ @NotNull
+ public Icon getIcon() {
+ Icon icon = myProvider.getIcon(myData);
+ return icon != null ? icon : EmptyIcon.ICON_16;
+ }
+
+ @NotNull
+ public PreviewPanelProvider<V, C> getProvider() {
+ return myProvider;
+ }
+
+ @NotNull
+ public V getData() {
+ return myData;
+ }
+
+ public C initComponent(boolean requestFocus) {
+ return myProvider.initComponent(myData, requestFocus);
+ }
+
+ @Override
+ public int hashCode() {
+ return myProvider.hashCode() * 31 + myData.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this ||
+ (obj instanceof PreviewInfo && ((PreviewInfo)obj).myProvider.equals(myProvider) && ((PreviewInfo)obj).myData.equals(myData));
+ }
+}
--- /dev/null
+/*
+ * 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.openapi.preview;
+
+import com.intellij.ide.ui.UISettings;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface PreviewManager {
+ class SERVICE {
+
+ private SERVICE() {
+ }
+
+ @Nullable
+ public static PreviewManager getInstance(@NotNull Project project) {
+ if (!UISettings.getInstance().NAVIGATE_TO_PREVIEW) return null;
+ return ServiceManager.getService(project, PreviewManager.class);
+ }
+ }
+
+ /**
+ * @return <code>null</code> if provider is not available / not active or if it forces to use standard view instead of preview at the moment
+ */
+ @Nullable
+ <V, C> C preview(@NotNull PreviewProviderId<V, C> id, V data, boolean requestFocus);
+
+ <V, C> boolean moveToStandardPlace(@NotNull PreviewProviderId<V, C> id, V data);
+
+ <V, C> void close(@NotNull PreviewProviderId<V, C> id, V data);
+}
--- /dev/null
+/*
+ * 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.openapi.preview;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public abstract class PreviewPanelProvider<V, C> {
+ public static final ExtensionPointName<PreviewPanelProvider> EP_NAME =
+ new ExtensionPointName<PreviewPanelProvider>("com.intellij.previewPanelProvider");
+ private final PreviewProviderId<V, C> myId;
+
+ public PreviewPanelProvider(PreviewProviderId<V, C> id) {
+ myId = id;
+ }
+
+ @NotNull
+ public final PreviewProviderId<V, C> getId() {
+ return myId;
+ }
+
+ public abstract boolean shouldBeEnabledByDefault();
+
+ //Let's share single specific component for all provided previews (if possible)
+ @NotNull
+ protected abstract JComponent getComponent();
+
+ @NotNull
+ protected abstract String getTitle(@NotNull V content);
+
+ @Nullable
+ protected abstract Icon getIcon(@NotNull V content);
+
+ public abstract float getMenuOrder();
+
+ public abstract boolean moveContentToStandardView(@NotNull V content);
+
+ protected abstract C initComponent(V content, boolean requestFocus);
+}
--- /dev/null
+/*
+ * 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.openapi.preview;
+
+public class PreviewProviderId<V, C> {
+ private final String myVisualName;
+
+ public static <V, C> PreviewProviderId<V, C> create(String visualName) {
+ return new PreviewProviderId<V, C>(visualName);
+ }
+
+ private PreviewProviderId(String visualName) {
+ myVisualName = visualName;
+ }
+
+ public final String getVisualName() {
+ return myVisualName;
+ }
+
+ @Override
+ public final String toString() {
+ return getVisualName();
+ }
+}
--- /dev/null
+/*
+ * 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.openapi.preview.impl;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.ui.UISettings;
+import com.intellij.ide.ui.UISettingsListener;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.keymap.Keymap;
+import com.intellij.openapi.keymap.KeymapManager;
+import com.intellij.openapi.preview.PreviewInfo;
+import com.intellij.openapi.preview.PreviewManager;
+import com.intellij.openapi.preview.PreviewPanelProvider;
+import com.intellij.openapi.preview.PreviewProviderId;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.wm.*;
+import com.intellij.openapi.wm.impl.ToolWindowImpl;
+import com.intellij.openapi.wm.impl.ToolWindowManagerImpl;
+import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
+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.content.ContentManagerAdapter;
+import com.intellij.ui.content.ContentManagerEvent;
+import com.intellij.util.Alarm;
+import com.intellij.util.PairFunction;
+import com.intellij.util.ui.GraphicsUtil;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+
+public class PreviewManagerImpl implements PreviewManager {
+ private static final Key<PreviewInfo> INFO_KEY = Key.create("preview_info");
+ private static final int HISTORY_LIMIT = 10;
+
+ private final Project myProject;
+ private final Alarm myAlarm = new Alarm();
+
+ private ToolWindowImpl myToolWindow;
+
+ private ContentManager myContentManager;
+ private Content myEmptyStateContent;
+ private final JPanel myEmptyStatePanel;
+
+ private ArrayList<PreviewInfo> myHistory = new ArrayList<PreviewInfo>();
+
+
+ private TreeSet<PreviewPanelProvider> myProviders = new TreeSet<PreviewPanelProvider>(new Comparator<PreviewPanelProvider>() {
+ @Override
+ public int compare(PreviewPanelProvider o1, PreviewPanelProvider o2) {
+ return Float.compare(o1.getMenuOrder(), o2.getMenuOrder());
+ }
+ });
+ private Set<PreviewProviderId> myActiveProviderIds = new HashSet<PreviewProviderId>();
+ private boolean myInnerSelectionChange;
+
+ private static boolean isAvailable() {
+ return UISettings.getInstance().NAVIGATE_TO_PREVIEW;
+ }
+
+
+ public PreviewManagerImpl(Project project) {
+ myProject = project;
+ myEmptyStatePanel = new EmptyStatePanel();
+ PreviewPanelProvider[] providers = PreviewPanelProvider.EP_NAME.getExtensions(project);
+ for (PreviewPanelProvider provider : providers) {
+ myProviders.add(provider);
+ if (provider.shouldBeEnabledByDefault()) {
+ myActiveProviderIds.add(provider.getId());
+ }
+ //todo make it all externalizable to store/restore enabled/disabled state
+ }
+
+ UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
+ @Override
+ public void uiSettingsChanged(UISettings source) {
+ checkGlobalState();
+ }
+ }, myProject);
+ checkGlobalState();
+ checkEmptyState();
+ }
+
+ @Nullable
+ public <V, C> PreviewPanelProvider<V, C> findProvider(@NotNull PreviewProviderId<V, C> id) {
+ for (PreviewPanelProvider provider : myProviders) {
+ if (id == provider.getId()) return provider;
+ }
+ return null;
+ }
+
+
+ protected void checkGlobalState() {
+ ToolWindowManagerImpl toolWindowManager = (ToolWindowManagerImpl)ToolWindowManager.getInstance(myProject);
+ if (!isAvailable() && toolWindowManager.getToolWindow(ToolWindowId.PREVIEW) != null) {
+ myHistory.clear();
+ myContentManager.removeAllContents(true);
+ toolWindowManager.unregisterToolWindow(ToolWindowId.PREVIEW);
+ return;
+ }
+ if (isAvailable() && toolWindowManager.getToolWindow(ToolWindowId.PREVIEW) == null) {
+ myToolWindow = (ToolWindowImpl)toolWindowManager
+ .registerToolWindow(ToolWindowId.PREVIEW, myEmptyStatePanel, ToolWindowAnchor.RIGHT, myProject, false);
+ myContentManager = myToolWindow.getContentManager();
+ myToolWindow.setIcon(AllIcons.Actions.PreviewDetails);
+ myToolWindow.setContentUiType(ToolWindowContentUiType.COMBO, null);
+ myToolWindow.setAutoHide(true);
+ myEmptyStateContent = myContentManager.getContent(0);
+ myContentManager.addContentManagerListener(new ContentManagerAdapter() {
+ @Override
+ public void selectionChanged(ContentManagerEvent event) {
+ if (myInnerSelectionChange || event.getOperation() != ContentManagerEvent.ContentOperation.add) return;
+ PreviewInfo previewInfo = event.getContent().getUserData(INFO_KEY);
+ if (previewInfo != null) {
+ preview(previewInfo, true);
+ }
+ }
+ });
+ MoveToStandardViewAction moveToStandardViewAction = new MoveToStandardViewAction();
+
+ moveToStandardViewAction.registerCustomShortcutSet(new ShortcutSet() {
+ @NotNull
+ @Override
+ public Shortcut[] getShortcuts() {
+ Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
+ return keymap.getShortcuts("ShowContent");
+ }
+ }, myToolWindow.getComponent());
+
+ myToolWindow.setTitleActions(moveToStandardViewAction);
+ ArrayList<AnAction> myGearActions = new ArrayList<AnAction>();
+ for (PreviewPanelProvider provider : myProviders) {
+ myGearActions.add(new ContentTypeToggleAction(provider));
+ }
+ myToolWindow.setAdditionalGearActions(new DefaultActionGroup("Preview", myGearActions));
+ //myToolWindow.hide(null);
+ }
+ }
+
+ private void checkEmptyState() {
+ if (myContentManager.getContents().length == 0) {
+ myToolWindow.getComponent().putClientProperty(ToolWindowContentUi.HIDE_ID_LABEL, "false");
+ myContentManager.addContent(myEmptyStateContent);
+ //ApplicationManager.getApplication().invokeLater(new Runnable() {
+ // @Override
+ // public void run() {
+ // if (myContentManager.getIndexOfContent(myEmptyStateContent) != -1) {
+ // toggleToolWindow(false);
+ // }
+ // }
+ //});
+ }
+ else if (myContentManager.getContents().length > 1) {
+ myToolWindow.getComponent().putClientProperty(ToolWindowContentUi.HIDE_ID_LABEL, "true");
+ myContentManager.removeContent(myEmptyStateContent, false);
+ }
+ }
+
+ @Nullable
+ private Content getContent(@NotNull PreviewInfo info) {
+ for (Content content : myContentManager.getContents()) {
+ if (info.equals(content.getUserData(INFO_KEY))) {
+ return content;
+ }
+ }
+ return null;
+ }
+
+ @NotNull
+ private Content addContent(PreviewInfo info) {
+ myHistory.add(info);
+ while (myHistory.size() > HISTORY_LIMIT) {
+ PreviewInfo previewInfo = myHistory.remove(0);
+ close(previewInfo);
+ }
+
+ Content content = myContentManager.getFactory().createContent(info.getComponent(), info.getTitle(), false);
+ content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
+ content.putUserData(INFO_KEY, info);
+ content.setIcon(info.getIcon());
+ content.setPopupIcon(info.getIcon());
+
+ myContentManager.addContent(content, 0);
+ checkEmptyState();
+ return content;
+ }
+
+ private void close(@NotNull PreviewInfo info) {
+ Content content = getContent(info);
+ if (content != null) {
+ myContentManager.removeContent(content, false);
+ if (myContentManager.getContents().length == 0) {
+ toggleToolWindow(false);
+ }
+ checkEmptyState();
+ }
+ }
+
+ @Override
+ public <V, C> C preview(@NotNull PreviewProviderId<V, C> id, V data, boolean requestFocus) {
+ PreviewPanelProvider<V, C> provider = findProvider(id);
+ if (provider == null || !myActiveProviderIds.contains(id)) return null;
+ return preview(PreviewInfo.create(provider, data), requestFocus);
+ }
+
+ public <V, C> C preview(@NotNull PreviewInfo<V, C> info, boolean requestFocus) {
+ toggleToolWindow(true);
+ Content content = getContent(info);
+ if (myContentManager.getSelectedContent() != content) {
+ myInnerSelectionChange = true;
+ try {
+ if (content == null) {
+ content = addContent(info);
+ }
+ myContentManager.setSelectedContent(content);
+ }
+ finally {
+ myInnerSelectionChange = false;
+ }
+ }
+ if (content != null) {
+ myContentManager.addContent(content, 0);
+ }
+ return info.initComponent(requestFocus);
+ }
+
+ @Override
+ public <V, C> void close(@NotNull PreviewProviderId<V, C> id, V data) {
+ for (Content content : myContentManager.getContents()) {
+ PreviewInfo info = content.getUserData(INFO_KEY);
+ if (info != null && info.getId() == id && info.getData() == data) {
+ close(info);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public <V, C> boolean moveToStandardPlace(@NotNull PreviewProviderId<V, C> id, V data) {
+ PreviewPanelProvider<V, C> provider = findProvider(id);
+ if (provider != null && provider.moveContentToStandardView(data)) {
+ close(id, data);
+ return true;
+ }
+ return false;
+ }
+
+ private void toggleToolWindow(boolean activate) {
+ final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW);
+ if (toolWindow != null && activate != toolWindow.isActive()) {
+ if (activate) {
+ myAlarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ toolWindow.activate(null, false);
+ }
+ }, 75, ModalityState.stateForComponent(myEmptyStatePanel));
+ }
+ else {
+ if (!myAlarm.isEmpty()) {
+ toolWindow.hide(null);
+ }
+ }
+ }
+ }
+
+ private class MoveToStandardViewAction extends AnAction {
+
+ public MoveToStandardViewAction() {
+ super("Move to standard view", "Move to standard view", AllIcons.Duplicates.SendToTheLeftGrayed);
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ Content selectedContent = myContentManager.getSelectedContent();
+ if (selectedContent == null) return;
+ PreviewInfo previewInfo = selectedContent.getUserData(INFO_KEY);
+ if (previewInfo != null) {
+ moveToStandardPlace(previewInfo.getId(), previewInfo.getData());
+ toggleToolWindow(false);
+ }
+ }
+ }
+
+ private class ContentTypeToggleAction extends ToggleAction {
+ private final PreviewPanelProvider myProvider;
+
+ ContentTypeToggleAction(PreviewPanelProvider provider) {
+ super(provider.getId().getVisualName());
+ myProvider = provider;
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return myActiveProviderIds.contains(myProvider.getId());
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ if (state) {
+ myActiveProviderIds.add(myProvider.getId());
+ }
+ else {
+ myActiveProviderIds.remove(myProvider.getId());
+ for (Iterator<PreviewInfo> iterator = myHistory.iterator(); iterator.hasNext(); ) {
+ PreviewInfo info = iterator.next();
+ if (info.getId().equals(myProvider.getId())) {
+ Content content = getContent(info);
+ if (content != null) {
+ myContentManager.removeContent(content, true);
+ }
+ iterator.remove();
+ }
+ }
+ checkEmptyState();
+ }
+ }
+ }
+
+ private static class EmptyStatePanel extends JPanel {
+ public EmptyStatePanel() {
+ setOpaque(true);
+ }
+
+ @Override
+ public void paint(Graphics g) {
+ boolean isDarkBackground = UIUtil.isUnderDarcula();
+ UIUtil.applyRenderingHints(g);
+ GraphicsUtil.setupAntialiasing(g, true, false);
+ g.setColor(new JBColor(isDarkBackground ? Gray._230 : Gray._80, Gray._160));
+ g.setFont(UIUtil.getLabelFont().deriveFont(isDarkBackground ? 24f : 20f));
+
+ UIUtil.TextPainter painter = new UIUtil.TextPainter().withLineSpacing(1.5f);
+ painter.withShadow(true, new JBColor(Gray._200.withAlpha(100), Gray._0.withAlpha(255)));
+
+ painter.appendLine("No files are open");//.underlined(new JBColor(Gray._150, Gray._180));
+ painter.draw(g, new PairFunction<Integer, Integer, Couple<Integer>>() {
+ @Override
+ public Couple<Integer> fun(Integer width, Integer height) {
+ Dimension s = EmptyStatePanel.this.getSize();
+ return Couple.of((s.width - width) / 2, (s.height - height) / 2);
+ }
+ });
+ }
+ }
+}
public final ActionGroup createPopupGroup() {
final DefaultActionGroup group = createGearPopupGroup();
-
- group.add(myToggleContentUiTypeAction);
+ if (!ToolWindowId.PREVIEW.equals(myInfo.getId())) {
+ group.add(myToggleContentUiTypeAction);
+ }
final DefaultActionGroup moveGroup = new DefaultActionGroup(UIBundle.message("tool.window.move.to.action.group.name"), true);
final ToolWindowAnchor anchor = myInfo.getAnchor();
group.add(myToggleFloatingModeAction);
}
else if (myInfo.isSliding()) {
- group.add(myToggleDockModeAction);
+ if (!ToolWindowId.PREVIEW.equals(myInfo.getId())) {
+ group.add(myToggleDockModeAction);
+ }
group.add(myToggleFloatingModeAction);
group.add(myToggleSideModeAction);
}
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.JDOMExternalizable;
-import com.intellij.openapi.wm.ToolWindowAnchor;
-import com.intellij.openapi.wm.ToolWindowContentUiType;
-import com.intellij.openapi.wm.ToolWindowType;
-import com.intellij.openapi.wm.WindowInfo;
+import com.intellij.openapi.wm.*;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
myAutoHide = info.myAutoHide;
myFloatingBounds = info.myFloatingBounds == null ? null : (Rectangle)info.myFloatingBounds.clone();
myId = info.myId;
- myType = info.myType;
+ setTypeAndCheck(info.myType);
myInternalType = info.myInternalType;
myVisible = info.myVisible;
myWeight = info.myWeight;
catch (IllegalArgumentException ignored) {
}
try {
- myType = parseToolWindowType(element.getAttributeValue(TYPE_ATTR));
+ setTypeAndCheck(parseToolWindowType(element.getAttributeValue(TYPE_ATTR)));
}
catch (IllegalArgumentException ignored) {
}
if(ToolWindowType.DOCKED==type||ToolWindowType.SLIDING==type){
myInternalType=type;
}
- myType=type;
+ setTypeAndCheck(type);
+ }
+ //Hardcoded to avoid single-usage-API
+ private void setTypeAndCheck(ToolWindowType type) {
+ myType = ToolWindowId.PREVIEW == myId && type == ToolWindowType.DOCKED ? ToolWindowType.SLIDING : type;
}
void setVisible(final boolean visible){
<extensionPoint name="goto.nonProjectScopeDisabler" beanClass="com.intellij.ide.actions.NonProjectScopeDisablerEP"/>
<extensionPoint qualifiedName="com.intellij.equivalenceDescriptorProvider" interface="com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider"/>
+
+ <extensionPoint name="previewPanelProvider" interface="com.intellij.openapi.preview.PreviewPanelProvider" area="IDEA_PROJECT"/>
</extensionPoints>
</idea-plugin>
<projectService serviceInterface="com.intellij.execution.ExecutionManager" serviceImplementation="com.intellij.execution.impl.ExecutionManagerImpl"/>
<projectService serviceInterface="com.intellij.execution.ExecutionTargetManager" serviceImplementation="com.intellij.execution.ExecutionTargetManagerImpl"/>
+ <previewPanelProvider implementation="com.intellij.openapi.fileEditor.impl.FilePreviewPanelProvider"/>
+ <previewPanelProvider implementation="com.intellij.codeInsight.documentation.DocumentationPreviewPanelProvider"/>
+ <projectService serviceInterface="com.intellij.openapi.preview.PreviewManager"
+ serviceImplementation="com.intellij.openapi.preview.impl.PreviewManagerImpl"/>
</extensions>
</idea-plugin>