Stage 7: "Usages" provider, fix for 'tabless' editor requestFocus(), persistance for PreviewManager
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) {
+ if (PreviewManager.SERVICE.preview(myProject, DocumentationPreviewPanelProvider.ID, Couple.of(element, originalElement), requestFocus) != null) {
return;
}
import com.intellij.openapi.preview.PreviewPanelProvider;
import com.intellij.openapi.preview.PreviewProviderId;
import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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);
}
@Override
- public boolean shouldBeEnabledByDefault() {
- return true;
+ public void dispose() {
+ Disposer.dispose(myDocumentationComponent);
}
@NotNull
}
@Override
- public boolean moveContentToStandardView(@NotNull Couple<PsiElement> content) {
- myBlocked = true;
- try {
- myDocumentationManager.showJavaDocInfo(content.getFirst(), content.getSecond());
- }
- finally {
- myBlocked = false;
- }
- return true;
+ public void showInStandardPlace(@NotNull Couple<PsiElement> content) {
+ myDocumentationManager.showJavaDocInfo(content.getFirst(), content.getSecond());
+ }
+
+ @Override
+ public void release(@NotNull Couple<PsiElement> content) {
+ }
+
+ @Override
+ public boolean contentsAreEqual(@NotNull Couple<PsiElement> content1, @NotNull Couple<PsiElement> content2) {
+ return content1.getFirst().getManager().areElementsEquivalent(content1.getFirst(), content2.getFirst());
+ }
+
+ @Override
+ public boolean isModified(Couple<PsiElement> content, boolean beforeReuse) {
+ return beforeReuse;
}
@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);
}
--- /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.find;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.preview.PreviewPanelProvider;
+import com.intellij.openapi.preview.PreviewProviderId;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Pair;
+import com.intellij.usages.impl.UsageViewImpl;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class UsagesPreviewPanelProvider extends PreviewPanelProvider<Pair<UsageViewImpl, ? extends JTable>, Boolean> {
+ public static final PreviewProviderId<Pair<UsageViewImpl, ? extends JTable>, Boolean> ID = PreviewProviderId.create("Usages");
+
+ private JComponent myComponent;
+ private Collection<UsageViewImpl> myViews = new ArrayList<UsageViewImpl>();
+
+ public UsagesPreviewPanelProvider(Project project) {
+ super(ID);
+ myComponent = new JPanel(new BorderLayout()) {
+ @Override
+ public String toString() {
+ return "UsagesPreviewPanel";
+ }
+ };
+ }
+
+ @Override
+ public void dispose() {
+ //myPresentation = null;
+ myComponent.removeAll();
+ for (UsageViewImpl view : myViews) {
+ Disposer.dispose(view);
+ }
+ }
+
+ @NotNull
+ @Override
+ protected JComponent getComponent() {
+ return myComponent;
+ }
+
+ @NotNull
+ @Override
+ protected String getTitle(@NotNull Pair<UsageViewImpl, ? extends JTable> content) {
+ return content.first.getPresentation().getTabText();
+ }
+
+ @Nullable
+ @Override
+ protected Icon getIcon(@NotNull Pair<UsageViewImpl, ? extends JTable> content) {
+ return AllIcons.Actions.Find;
+ }
+
+ @Override
+ public float getMenuOrder() {
+ return 2;
+ }
+
+ @Override
+ public void showInStandardPlace(@NotNull Pair<UsageViewImpl, ? extends JTable> content) {
+ }
+
+ @Override
+ public boolean supportsStandardPlace() {
+ return false;
+ }
+
+ @Override
+ public boolean isModified(Pair<UsageViewImpl, ? extends JTable> content, boolean beforeReuse) {
+ return beforeReuse;
+ }
+
+ @Override
+ public void release(@NotNull Pair<UsageViewImpl, ? extends JTable> content) {
+ myViews.remove(content.first);
+ Disposer.dispose(content.first);
+ myComponent.remove(content.second);
+ }
+
+ @Override
+ public boolean contentsAreEqual(@NotNull Pair<UsageViewImpl, ? extends JTable> content1, @NotNull Pair<UsageViewImpl, ? extends JTable> content2) {
+ return content1.getFirst().getPresentation().equals(content2.getFirst().getPresentation());
+ }
+
+ @Override
+ protected Boolean initComponent(final Pair<UsageViewImpl, ? extends JTable> content, boolean requestFocus) {
+ myComponent.removeAll();
+ myComponent.add(content.second);
+ myViews.add(content.first);
+ return Boolean.TRUE;
+ }
+}
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.find.FindManager;
import com.intellij.find.FindSettings;
+import com.intellij.find.UsagesPreviewPanelProvider;
import com.intellij.find.findUsages.*;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.fileEditor.FileEditorLocation;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.keymap.KeymapUtil;
+import com.intellij.openapi.preview.PreviewManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.util.ui.AsyncProcessIcon;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
+import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumn;
import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.event.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
final List<UsageNode> data = collectData(usages, visibleNodes, usageView, presentation);
setTableModel(table, usageView, data, outOfScopeUsages, options.searchScope);
- SpeedSearchBase<JTable> speedSearch = new MySpeedSearch(table);
- speedSearch.setComparator(new SpeedSearchComparator(false));
- final JBPopup popup = createUsagePopup(usages, visibleNodes, handler, editor, popupPosition,
- maxUsages, usageView, options, table, presentation, processIcon);
+ boolean isPreviewMode = (Boolean.TRUE == PreviewManager.SERVICE.preview(handler.getProject(), UsagesPreviewPanelProvider.ID, Pair.create(usageView, table), false) );
+ Runnable itemChosenCallback = prepareTable(table, editor, popupPosition, handler, maxUsages, options, isPreviewMode);
- Disposer.register(popup, usageView);
+ @Nullable final JBPopup popup = isPreviewMode ? null : createUsagePopup(usages, visibleNodes, handler, editor, popupPosition,
+ maxUsages, usageView, options, table, itemChosenCallback, presentation, processIcon);
+ if (popup != null) {
+ Disposer.register(popup, usageView);
- // show popup only if find usages takes more than 300ms, otherwise it would flicker needlessly
- Alarm alarm = new Alarm(usageView);
- alarm.addRequest(new Runnable() {
- @Override
- public void run() {
- showPopupIfNeedTo(popup, popupPosition);
- }
- }, 300);
+ // show popup only if find usages takes more than 300ms, otherwise it would flicker needlessly
+ Alarm alarm = new Alarm(usageView);
+ alarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ showPopupIfNeedTo(popup, popupPosition);
+ }
+ }, 300);
+ }
final PingEDT pingEDT = new PingEDT("Rebuild popup in EDT", new Condition<Object>() {
@Override
public boolean value(Object o) {
- return popup.isDisposed();
+ return popup != null && popup.isDisposed();
}
}, 100, new Runnable() {
@Override
public void run() {
- if (popup.isDisposed()) return;
+ if (popup != null && popup.isDisposed()) return;
final List<UsageNode> nodes = new ArrayList<UsageNode>();
List<Usage> copy;
synchronized (usages) {
// open up popup as soon as several usages 've been found
- if (!popup.isVisible() && (usages.size() <= 1 || !showPopupIfNeedTo(popup, popupPosition))) {
+ if (popup != null && (!popup.isVisible() && (usages.size() <= 1 || !showPopupIfNeedTo(popup, popupPosition)))) {
return;
}
addUsageNodes(usageView.getRoot(), usageView, nodes);
copy = new ArrayList<Usage>(usages);
}
- rebuildPopup(usageView, copy, nodes, table, popup, presentation, popupPosition, !processIcon.isDisposed(), outOfScopeUsages,
+ rebuildTable(usageView, copy, nodes, table, popup, presentation, popupPosition, !processIcon.isDisposed(), outOfScopeUsages,
options.searchScope);
}
});
public void run() {
Disposer.dispose(processIcon);
Container parent = processIcon.getParent();
- parent.remove(processIcon);
- parent.repaint();
+ if (parent != null) {
+ parent.remove(processIcon);
+ parent.repaint();
+ }
pingEDT.ping(); // repaint title
synchronized (usages) {
if (visibleNodes.isEmpty()) {
if (usages.isEmpty()) {
String text = UsageViewBundle.message("no.usages.found.in", searchScopePresentableName(options));
hint(editor, text, handler, popupPosition, maxUsages, options, false);
- popup.cancel();
+ cancel(popup);
}
else {
// all usages filtered out
String message = UsageViewBundle.message("show.usages.only.usage", searchScopePresentableName(options));
navigateAndHint(usage, message, handler, popupPosition, maxUsages, options);
}
- popup.cancel();
+ cancel(popup);
}
else {
assert usages.size() > 1 : usages;
if (areAllUsagesInOneLine(visibleUsage, usages)) {
String hint = UsageViewBundle.message("all.usages.are.in.this.line", usages.size(), searchScopePresentableName(options));
navigateAndHint(visibleUsage, hint, handler, popupPosition, maxUsages, options);
- popup.cancel();
+ cancel(popup);
}
}
}
else {
- String title = presentation.getTabText();
- boolean shouldShowMoreSeparator = visibleNodes.contains(MORE_USAGES_SEPARATOR_NODE);
- String fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator, visibleNodes.size() - (shouldShowMoreSeparator ? 1 : 0), false);
- ((AbstractPopup)popup).setCaption(fullTitle);
+ if (popup != null) {
+ String title = presentation.getTabText();
+ boolean shouldShowMoreSeparator = visibleNodes.contains(MORE_USAGES_SEPARATOR_NODE);
+ String fullTitle =
+ getFullTitle(usages, title, shouldShowMoreSeparator, visibleNodes.size() - (shouldShowMoreSeparator ? 1 : 0), false);
+ ((AbstractPopup)popup).setCaption(fullTitle);
+ }
}
}
}
}, project.getDisposed());
}
});
- Disposer.register(popup, new Disposable() {
- @Override
- public void dispose() {
- indicator.cancel();
- }
- });
+ if (popup != null) {
+ Disposer.register(popup, new Disposable() {
+ @Override
+ public void dispose() {
+ indicator.cancel();
+ }
+ });
+ }
}
@NotNull
return options.searchScope.getDisplayName();
}
- @NotNull
- private JBPopup createUsagePopup(@NotNull final List<Usage> usages,
- @NotNull Set<UsageNode> visibleNodes,
- @NotNull final FindUsagesHandler handler,
- final Editor editor,
- @NotNull final RelativePoint popupPosition,
- final int maxUsages,
- @NotNull final UsageViewImpl usageView,
- @NotNull final FindUsagesOptions options,
- @NotNull final JTable table,
- @NotNull final UsageViewPresentation presentation,
- @NotNull final AsyncProcessIcon processIcon) {
+ private Runnable prepareTable(final MyTable table,
+ final Editor editor,
+ final RelativePoint popupPosition,
+ final FindUsagesHandler handler,
+ final int maxUsages,
+ final @NotNull FindUsagesOptions options,
+ final boolean previewMode) {
+
+ SpeedSearchBase<JTable> speedSearch = new MySpeedSearch(table);
+ speedSearch.setComparator(new SpeedSearchComparator(false));
+
table.setRowHeight(PlatformIcons.CLASS_ICON.getIconHeight()+2);
table.setShowGrid(false);
table.setShowVerticalLines(false);
table.setTableHeader(null);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
table.setIntercellSpacing(new Dimension(0, 0));
-
- PopupChooserBuilder builder = new PopupChooserBuilder(table);
- final String title = presentation.getTabText();
- if (title != null) {
- String result = getFullTitle(usages, title, false, visibleNodes.size() - 1, true);
- builder.setTitle(result);
- builder.setAdText(getSecondInvocationTitle(options, handler));
- }
-
- builder.setMovable(true).setResizable(true);
final AtomicReference<Object> selectedUsage = new AtomicReference<Object>();
final AtomicBoolean moreUsagesSelected = new AtomicBoolean();
final AtomicBoolean outsideScopeUsagesSelected = new AtomicBoolean();
+ final Runnable itemChosenCallback = new Runnable() {
+ @Override
+ public void run() {
+ if (moreUsagesSelected.get()) {
+ appendMoreUsages(editor, popupPosition, handler, maxUsages, options);
+ return;
+ }
+ if (outsideScopeUsagesSelected.get()) {
+ options.searchScope = GlobalSearchScope.projectScope(handler.getProject());
+ showElementUsages(editor, popupPosition, handler, maxUsages, options);
+ return;
+ }
+ Object usage = selectedUsage.get();
+ if (usage instanceof UsageInfo) {
+ UsageViewUtil.navigateTo((UsageInfo)usage, true);
+ }
+ else if (usage instanceof Navigatable) {
+ ((Navigatable)usage).navigate(true);
+ }
+ }
+ };
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
}
}
});
- builder.setMovable(true).setResizable(true);
- builder.setItemChoosenCallback(new Runnable() {
- @Override
- public void run() {
- if (moreUsagesSelected.get()) {
- appendMoreUsages(editor, popupPosition, handler, maxUsages, options);
- return;
- }
- if (outsideScopeUsagesSelected.get()) {
- options.searchScope = GlobalSearchScope.projectScope(handler.getProject());
- showElementUsages(editor, popupPosition, handler, maxUsages, options);
- return;
- }
- Object usage = selectedUsage.get();
- if (usage instanceof UsageInfo) {
- UsageViewUtil.navigateTo((UsageInfo)usage, true);
+ if (previewMode) {
+ table.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ if (UIUtil.isActionClick(e, MouseEvent.MOUSE_RELEASED) && !UIUtil.isSelectionButtonDown(e) && !e.isConsumed()) {
+ itemChosenCallback.run();
+ }
}
- else if (usage instanceof Navigatable) {
- ((Navigatable)usage).navigate(true);
+ });
+ table.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_ENTER) {
+ itemChosenCallback.run();
+ }
}
- }
- });
+ });
+ }
+ return itemChosenCallback;
+ }
+
+ @NotNull
+ private JBPopup createUsagePopup(@NotNull final List<Usage> usages,
+ @NotNull Set<UsageNode> visibleNodes,
+ @NotNull final FindUsagesHandler handler,
+ final Editor editor,
+ @NotNull final RelativePoint popupPosition,
+ final int maxUsages,
+ @NotNull final UsageViewImpl usageView,
+ @NotNull final FindUsagesOptions options,
+ @NotNull final JTable table,
+ @NotNull final Runnable itemChoseCallback,
+ @NotNull final UsageViewPresentation presentation,
+ @NotNull final AsyncProcessIcon processIcon) {
+
+ PopupChooserBuilder builder = new PopupChooserBuilder(table);
+ final String title = presentation.getTabText();
+ if (title != null) {
+ String result = getFullTitle(usages, title, false, visibleNodes.size() - 1, true);
+ builder.setTitle(result);
+ builder.setAdText(getSecondInvocationTitle(options, handler));
+ }
+
+ builder.setMovable(true).setResizable(true);
+ builder.setMovable(true).setResizable(true);
+ builder.setItemChoosenCallback(itemChoseCallback);
final JBPopup[] popup = new JBPopup[1];
KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut();
new DumbAwareAction() {
@Override
public void actionPerformed(AnActionEvent e) {
- popup[0].cancel();
+ cancel(popup);
showDialogAndFindUsages(handler, popupPosition, editor, maxUsages);
}
}.registerCustomShortcutSet(new CustomShortcutSet(shortcut.getFirstKeyStroke()), table);
new DumbAwareAction() {
@Override
public void actionPerformed(AnActionEvent e) {
- popup[0].cancel();
+ cancel(popup);
searchEverywhere(options, handler, editor, popupPosition, maxUsages);
}
}.registerCustomShortcutSet(new CustomShortcutSet(shortcut.getFirstKeyStroke()), table);
InplaceButton settingsButton = createSettingsButton(handler, popupPosition, editor, maxUsages, new Runnable() {
@Override
public void run() {
- popup[0].cancel();
+ cancel(popup);
}
});
@Override
public void actionPerformed(AnActionEvent e) {
hideHints();
- popup[0].cancel();
+ cancel(popup);
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(usageView.getProject())).getFindUsagesManager();
findUsagesManager.findUsages(handler.getPrimaryElements(), handler.getSecondaryElements(), handler, options,
FindSettings.getInstance().isSkipResultsWithOneUsage());
};
}
+ private static void cancel(@Nullable JBPopup... popup) {
+ if (popup != null && popup.length>0 && popup[0] != null) {
+ popup[0].cancel();
+ }
+ }
+
@NotNull
private static String getFullTitle(@NotNull List<Usage> usages,
@NotNull String title,
private int myWidth;
- private void rebuildPopup(@NotNull final UsageViewImpl usageView,
+ private void rebuildTable(@NotNull final UsageViewImpl usageView,
@NotNull final List<Usage> usages,
@NotNull List<UsageNode> nodes,
@NotNull final JTable table,
- @NotNull final JBPopup popup,
+ @Nullable final JBPopup popup,
@NotNull final UsageViewPresentation presentation,
@NotNull final RelativePoint popupPosition,
boolean findUsagesInProgress,
String title = presentation.getTabText();
String fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator || hasOutsideScopeUsages, nodes.size() - (shouldShowMoreSeparator || hasOutsideScopeUsages ? 1 : 0), findUsagesInProgress);
-
- ((AbstractPopup)popup).setCaption(fullTitle);
+ if (popup != null) {
+ ((AbstractPopup)popup).setCaption(fullTitle);
+ }
List<UsageNode> data = collectData(usages, nodes, usageView, presentation);
MyModel tableModel = setTableModel(table, usageView, data, outOfScopeUsages, searchScope);
}
TableScrollingUtil.ensureIndexIsVisible(table, newSelection, 0);
- setSizeAndDimensions(table, popup, popupPosition, data);
+ if (popup != null) {
+ setSizeAndDimensions(table, popup, popupPosition, data);
+ }
}
// returns new selection
});
}
};
- if (editor == null) runnable.run(); else editor.getScrollingModel().runActionOnScrollingFinished(runnable);
+ if (editor == null) runnable.run();
+ else editor.getScrollingModel().runActionOnScrollingFinished(runnable);
}
});
}
if (myTabbedPane != null) {
myTabbedPane.requestFocus(forced);
} else {
- IdeFocusManager.findInstanceByComponent(myPanel).requestFocus(myPanel, forced);
+ EditorWithProviderComposite editor = getSelectedEditor();
+ if (editor != null) {
+ JComponent toFocus = editor.getPreferredFocusedComponent();
+ IdeFocusManager.findInstanceByComponent(toFocus).requestFocus(toFocus, forced);
+ } else {
+ IdeFocusManager.findInstanceByComponent(myPanel).requestFocus(myPanel, forced);
+ }
}
}
}
if (wndToOpenIn == null || !wndToOpenIn.isFileOpen(file)) {
- PreviewManager previewManager = PreviewManager.SERVICE.getInstance(myProject);
- if (previewManager != null) {
- Pair<FileEditor[], FileEditorProvider[]> previewResult = previewManager.preview(FilePreviewPanelProvider.ID, file, focusEditor);
+ Pair<FileEditor[], FileEditorProvider[]> previewResult =
+ PreviewManager.SERVICE.preview(myProject, FilePreviewPanelProvider.ID, file, focusEditor);
if (previewResult != null) {
return previewResult;
}
}
- }
EditorsSplitters splitters = getSplitters();
import com.intellij.openapi.preview.PreviewPanelProvider;
import com.intellij.openapi.preview.PreviewProviderId;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.IdeFocusManager;
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");
myWindow.setTabsPlacement(UISettings.TABS_NONE);
}
- @NotNull
@Override
- protected JComponent getComponent() {
- return myEditorsSplitters;
+ public void dispose() {
+ myEditorsSplitters.dispose();
}
+ @NotNull
@Override
- public boolean shouldBeEnabledByDefault() {
- return true;
+ protected JComponent getComponent() {
+ return myEditorsSplitters;
}
@Override
protected Pair<FileEditor[], FileEditorProvider[]> initComponent(VirtualFile file, boolean requestFocus) {
- return myManager.openFileWithProviders(file, requestFocus, myWindow);
+ Pair<FileEditor[], FileEditorProvider[]> result = myManager.openFileWithProviders(file, requestFocus, myWindow);
+ IdeFocusManager.findInstance().doWhenFocusSettlesDown(new Runnable() {
+ @Override
+ public void run() {
+ myWindow.requestFocus(true);
+ }
+ });
+ return result;
}
@NotNull
}
@Override
- public boolean moveContentToStandardView(@NotNull VirtualFile file) {
+ public void showInStandardPlace(@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;
+ }
+
+ @Override
+ public boolean isModified(VirtualFile content, boolean beforeReuse) {
+ for (EditorWithProviderComposite composite : myEditorsSplitters.getEditorsComposites()) {
+ if (composite.isModified() && Comparing.equal(composite.getFile(), content)) return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void release(@NotNull VirtualFile content) {
+ myEditorsSplitters.closeFile(content, false);
+ }
+
+ @Override
+ public boolean contentsAreEqual(@NotNull VirtualFile content1, @NotNull VirtualFile content2) {
+ return Comparing.equal(content1, content2);
}
private class MyEditorsSplitters extends EditorsSplitters {
@Override
protected void afterFileClosed(VirtualFile file) {
- PreviewManager previewManager = PreviewManager.SERVICE.getInstance(myProject);
- if (previewManager != null) {
- previewManager.close(getId(), file);
- }
+ PreviewManager.SERVICE.close(myProject, getId(), file);
}
@Override
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);
+ //Estimation: no more than one file is modified at the same time
+ PreviewManager.SERVICE.moveToStandardPlaceImpl(myProject, getId(), composite.getFile());
+ return;
}
}
}
import com.intellij.util.ui.EmptyIcon;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
return myData;
}
+ @Nullable
public C initComponent(boolean requestFocus) {
return myProvider.initComponent(myData, requestFocus);
}
+ public boolean isModified(boolean beforeReuse) {
+ return myProvider.isModified(myData, beforeReuse);
+ }
+
@Override
public int hashCode() {
- return myProvider.hashCode() * 31 + myData.hashCode();
+ return myProvider.hashCode();
}
@Override
public boolean equals(Object obj) {
- return obj == this ||
- (obj instanceof PreviewInfo && ((PreviewInfo)obj).myProvider.equals(myProvider) && ((PreviewInfo)obj).myData.equals(myData));
+ if (obj == this) return true;
+ if (!(obj instanceof PreviewInfo)) return false;
+ //noinspection unchecked
+ return ((PreviewInfo)obj).getId() == getId() && myProvider.contentsAreEqual( (V)((PreviewInfo)obj).myData, myData);
+ }
+
+ public void release() {
+ myProvider.release(myData);
+ }
+
+ public boolean supportsStandardPlace() {
+ return myProvider.supportsStandardPlace();
}
}
}
@Nullable
- public static PreviewManager getInstance(@NotNull Project project) {
+ private static PreviewManager getInstance(@NotNull Project project) {
if (!UISettings.getInstance().NAVIGATE_TO_PREVIEW) return null;
return ServiceManager.getService(project, PreviewManager.class);
}
+
+ /**
+ * @return null if preview cannot be performed
+ */
+ @Nullable
+ public static <V, C> C preview(@NotNull Project project, @NotNull PreviewProviderId<V, C> id, V data, boolean requestFocus) {
+ PreviewManager instance = getInstance(project);
+ if (instance == null) return null;
+ return instance.preview(id, data, requestFocus);
+ }
+
+ public static <V, C> void close(@NotNull Project project, @NotNull PreviewProviderId<V, C> id, V data) {
+ PreviewManager instance = getInstance(project);
+ if (instance != null) {
+ instance.close(id, data);
+ }
+ }
+
+ public static <V, C> void moveToStandardPlaceImpl(@NotNull Project project, @NotNull PreviewProviderId<V, C> id, V data) {
+ PreviewManager instance = getInstance(project);
+ if (instance != null) {
+ instance.moveToStandardPlaceImpl(id, data);
+ }
+ }
}
/**
@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 moveToStandardPlaceImpl(@NotNull PreviewProviderId<V, C> id, V data);
<V, C> void close(@NotNull PreviewProviderId<V, C> id, V data);
}
*/
package com.intellij.openapi.preview;
+import com.intellij.openapi.Disposable;
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");
+public abstract class PreviewPanelProvider<V, C> implements Disposable {
+ 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) {
return myId;
}
- public abstract boolean shouldBeEnabledByDefault();
-
//Let's share single specific component for all provided previews (if possible)
@NotNull
protected abstract JComponent getComponent();
public abstract float getMenuOrder();
- public abstract boolean moveContentToStandardView(@NotNull V content);
+ public abstract void showInStandardPlace(@NotNull V content);
+
+ @Nullable protected abstract C initComponent(V content, boolean requestFocus);
+
+ public abstract boolean isModified(V content, boolean beforeReuse);
+
+ public abstract void release(@NotNull V content);
- protected abstract C initComponent(V content, boolean requestFocus);
+ public abstract boolean contentsAreEqual(@NotNull V content1, @NotNull V content2);
+
+ @Override
+ public final String toString() {
+ return myId.getVisualName();
+ }
+
+ public boolean supportsStandardPlace() {
+ return true;
+ }
}
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.components.PersistentStateComponent;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.preview.PreviewInfo;
import com.intellij.openapi.preview.PreviewProviderId;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.impl.ToolWindowImpl;
import javax.swing.*;
import java.awt.*;
import java.util.*;
-
-public class PreviewManagerImpl implements PreviewManager {
+@State(
+ name = "PreviewManager",
+ storages = {
+ @Storage(
+ file = StoragePathMacros.WORKSPACE_FILE
+ )}
+)
+public class PreviewManagerImpl implements PreviewManager, PersistentStateComponent<PreviewManagerState> {
private static final Key<PreviewInfo> INFO_KEY = Key.create("preview_info");
private static final int HISTORY_LIMIT = 10;
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());
+ int result = Float.compare(o1.getMenuOrder(), o2.getMenuOrder());
+ return result != 0 ? result : o1.toString().compareTo(o2.toString());
}
});
private Set<PreviewProviderId> myActiveProviderIds = new HashSet<PreviewProviderId>();
+ private Set<PreviewProviderId> myLockedProviderIds = new HashSet<PreviewProviderId>();
private boolean myInnerSelectionChange;
private static boolean isAvailable() {
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
+ myActiveProviderIds.add(provider.getId());
+ Disposer.register(project, provider);
}
UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
}
@Nullable
- public <V, C> PreviewPanelProvider<V, C> findProvider(@NotNull PreviewProviderId<V, C> id) {
+ @Override
+ public PreviewManagerState getState() {
+ PreviewManagerState state = new PreviewManagerState();
+ state.myArtifactFilesMap = new HashMap<String, Boolean>();
+ for (PreviewPanelProvider provider : myProviders) {
+ state.myArtifactFilesMap.put(provider.toString(), myActiveProviderIds.contains(provider.getId()));
+ }
+ return state;
+ }
+
+ @Override
+ public void loadState(PreviewManagerState state) {
+ if (state == null) return;
+ for (Map.Entry<String, Boolean> entry : state.myArtifactFilesMap.entrySet()) {
+ if (!entry.getValue()) {
+ for (Iterator<PreviewProviderId> iterator = myActiveProviderIds.iterator(); iterator.hasNext(); ) {
+ PreviewProviderId id = iterator.next();
+ if (id.getVisualName().equals(entry.getKey())) {
+ iterator.remove();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private <V, C> PreviewPanelProvider<V, C> findProvider(@NotNull PreviewProviderId<V, C> id) {
for (PreviewPanelProvider provider : myProviders) {
if (id == provider.getId()) return provider;
}
myToolWindow = (ToolWindowImpl)toolWindowManager
.registerToolWindow(ToolWindowId.PREVIEW, myEmptyStatePanel, ToolWindowAnchor.RIGHT, myProject, false);
myContentManager = myToolWindow.getContentManager();
- myToolWindow.setIcon(AllIcons.Actions.PreviewDetails);
+ myToolWindow.setIcon(AllIcons.Toolwindows.ToolWindowPreview);
myToolWindow.setContentUiType(ToolWindowContentUiType.COMBO, null);
myToolWindow.setAutoHide(true);
myEmptyStateContent = myContentManager.getContent(0);
+ final MoveToStandardViewAction moveToStandardViewAction = new MoveToStandardViewAction();
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);
+ preview(previewInfo, false);
+ myToolWindow.setTitleActions(previewInfo.supportsStandardPlace() ? moveToStandardViewAction : null);
}
}
});
- MoveToStandardViewAction moveToStandardViewAction = new MoveToStandardViewAction();
moveToStandardViewAction.registerCustomShortcutSet(new ShortcutSet() {
@NotNull
myGearActions.add(new ContentTypeToggleAction(provider));
}
myToolWindow.setAdditionalGearActions(new DefaultActionGroup("Preview", myGearActions));
- //myToolWindow.hide(null);
+ myToolWindow.activate(new Runnable() {
+ @Override
+ public void run() {
+ myToolWindow.activate(null);
+ }
+ });
}
}
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");
@Nullable
private Content getContent(@NotNull PreviewInfo info) {
for (Content content : myContentManager.getContents()) {
- if (info.equals(content.getUserData(INFO_KEY))) {
- return content;
- }
+ PreviewInfo eachInfo = content.getUserData(INFO_KEY);
+ if (info.equals(eachInfo)) return content;
}
return null;
}
private Content addContent(PreviewInfo info) {
myHistory.add(info);
while (myHistory.size() > HISTORY_LIMIT) {
- PreviewInfo previewInfo = myHistory.remove(0);
- close(previewInfo);
+ close(myHistory.remove(0));
}
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 static void updateContentWithInfo(Content content, PreviewInfo info) {
+ content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
+ content.putUserData(INFO_KEY, info);
+ content.setIcon(info.getIcon());
+ content.setPopupIcon(info.getIcon());
+ }
+
private void close(@NotNull PreviewInfo info) {
Content content = getContent(info);
if (content != null) {
myContentManager.removeContent(content, false);
+ info.release();
if (myContentManager.getContents().length == 0) {
- toggleToolWindow(false);
+ toggleToolWindow(false, null);
}
checkEmptyState();
}
@Override
public <V, C> C preview(@NotNull PreviewProviderId<V, C> id, V data, boolean requestFocus) {
+ if (!myActiveProviderIds.contains(id) || myLockedProviderIds.contains(id)) {
+ return null;
+ }
PreviewPanelProvider<V, C> provider = findProvider(id);
- if (provider == null || !myActiveProviderIds.contains(id)) return null;
+ if (provider == null) {
+ return null;
+ }
return preview(PreviewInfo.create(provider, data), requestFocus);
}
- public <V, C> C preview(@NotNull PreviewInfo<V, C> info, boolean requestFocus) {
- toggleToolWindow(true);
+ private <V, C> C preview(@NotNull final PreviewInfo<V, C> info, boolean requestFocus) {
+ toggleToolWindow(true, null);
Content content = getContent(info);
- if (myContentManager.getSelectedContent() != content) {
+ Content selectedContent = myContentManager.getSelectedContent();
+ if (selectedContent != content) {
myInnerSelectionChange = true;
try {
+ PreviewInfo selectedInfo = selectedContent != null ? selectedContent.getUserData(INFO_KEY) : null;
+ if (selectedInfo != null && selectedInfo.isModified(selectedInfo.getId() == info.getId())) {
+ moveToStandardPlaceImpl(selectedInfo.getId(), selectedInfo.getData());
+ }
if (content == null) {
content = addContent(info);
}
- myContentManager.setSelectedContent(content);
}
finally {
myInnerSelectionChange = false;
}
}
if (content != null) {
- myContentManager.addContent(content, 0);
+ myContentManager.addContent(content, 0);//Adjust usage order
+ }
+ myInnerSelectionChange = true;
+ try {
+ if (content != null) {
+ updateContentWithInfo(content, info);
+ myContentManager.setSelectedContent(content, requestFocus);
+ }
+ return info.initComponent(requestFocus);
+ }
+ finally {
+ myInnerSelectionChange = false;
}
- 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) {
+ if (info != null && info.getId() == id && info.getProvider().contentsAreEqual(info.getData(),data)) {
close(info);
break;
}
}
@Override
- public <V, C> boolean moveToStandardPlace(@NotNull PreviewProviderId<V, C> id, V data) {
+ public <V, C> void moveToStandardPlaceImpl(@NotNull PreviewProviderId<V, C> id, V data) {
PreviewPanelProvider<V, C> provider = findProvider(id);
- if (provider != null && provider.moveContentToStandardView(data)) {
- close(id, data);
- return true;
+ if (provider == null) return;
+ myLockedProviderIds.add(id);
+ try {
+ provider.showInStandardPlace(data);
+ } finally {
+ myLockedProviderIds.remove(id);
}
- return false;
+ close(id, data);
}
- private void toggleToolWindow(boolean activate) {
+ private void toggleToolWindow(boolean activate, Runnable runnable) {
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));
+ toolWindow.activate(runnable, true);
}
else {
if (!myAlarm.isEmpty()) {
private class MoveToStandardViewAction extends AnAction {
public MoveToStandardViewAction() {
- super("Move to standard view", "Move to standard view", AllIcons.Duplicates.SendToTheLeftGrayed);
+ super("Move to standard view", "Move to standard view", AllIcons.Actions.MoveToStandardPlace);
}
@Override
if (selectedContent == null) return;
PreviewInfo previewInfo = selectedContent.getUserData(INFO_KEY);
if (previewInfo != null) {
- moveToStandardPlace(previewInfo.getId(), previewInfo.getData());
- toggleToolWindow(false);
+ moveToStandardPlaceImpl(previewInfo.getId(), previewInfo.getData());
+ toggleToolWindow(false, null);
}
}
}
--- /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.util.containers.hash.LinkedHashMap;
+import com.intellij.util.xmlb.annotations.MapAnnotation;
+import com.intellij.util.xmlb.annotations.Property;
+
+import java.util.Map;
+
+public class PreviewManagerState {
+ //@Tag("providers")
+ @Property(surroundWithTag = false)
+ @MapAnnotation(surroundWithTag = false)
+ public Map<String, Boolean> myArtifactFilesMap = new LinkedHashMap<String, Boolean>();
+}
<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"/>
+ <previewPanelProvider implementation="com.intellij.find.UsagesPreviewPanelProvider"/>
<projectService serviceInterface="com.intellij.openapi.preview.PreviewManager"
serviceImplementation="com.intellij.openapi.preview.impl.PreviewManagerImpl"/>
public void setUsageTypeFilteringAvailable(boolean usageTypeFilteringAvailable) {
myUsageTypeFilteringAvailable = usageTypeFilteringAvailable;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof UsageViewPresentation)) return false;
+
+ UsageViewPresentation that = (UsageViewPresentation)o;
+
+ if (myCodeUsages != that.myCodeUsages) return false;
+ if (myDetachedMode != that.myDetachedMode) return false;
+ if (myMergeDupLinesAvailable != that.myMergeDupLinesAvailable) return false;
+ if (myOpenInNewTab != that.myOpenInNewTab) return false;
+ if (myShowCancelButton != that.myShowCancelButton) return false;
+ if (myShowReadOnlyStatusAsRed != that.myShowReadOnlyStatusAsRed) return false;
+ if (myUsageTypeFilteringAvailable != that.myUsageTypeFilteringAvailable) return false;
+ if (myCodeUsagesString != null ? !myCodeUsagesString.equals(that.myCodeUsagesString) : that.myCodeUsagesString != null) return false;
+ if (myDynamicCodeUsagesString != null
+ ? !myDynamicCodeUsagesString.equals(that.myDynamicCodeUsagesString)
+ : that.myDynamicCodeUsagesString != null) {
+ return false;
+ }
+ if (myNonCodeUsagesString != null ? !myNonCodeUsagesString.equals(that.myNonCodeUsagesString) : that.myNonCodeUsagesString != null) {
+ return false;
+ }
+ if (myNotFoundActions != null ? !myNotFoundActions.equals(that.myNotFoundActions) : that.myNotFoundActions != null) return false;
+ if (myScopeText != null ? !myScopeText.equals(that.myScopeText) : that.myScopeText != null) return false;
+ if (myTabName != null ? !myTabName.equals(that.myTabName) : that.myTabName != null) return false;
+ if (myTabText != null ? !myTabText.equals(that.myTabText) : that.myTabText != null) return false;
+ if (myTargetsNodeText != null ? !myTargetsNodeText.equals(that.myTargetsNodeText) : that.myTargetsNodeText != null) return false;
+ if (myToolwindowTitle != null ? !myToolwindowTitle.equals(that.myToolwindowTitle) : that.myToolwindowTitle != null) return false;
+ if (myUsagesInGeneratedCodeString != null
+ ? !myUsagesInGeneratedCodeString.equals(that.myUsagesInGeneratedCodeString)
+ : that.myUsagesInGeneratedCodeString != null) {
+ return false;
+ }
+ if (myUsagesString != null ? !myUsagesString.equals(that.myUsagesString) : that.myUsagesString != null) return false;
+ if (myUsagesWord != null ? !myUsagesWord.equals(that.myUsagesWord) : that.myUsagesWord != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myTabText != null ? myTabText.hashCode() : 0;
+ result = 31 * result + (myScopeText != null ? myScopeText.hashCode() : 0);
+ result = 31 * result + (myUsagesString != null ? myUsagesString.hashCode() : 0);
+ result = 31 * result + (myTargetsNodeText != null ? myTargetsNodeText.hashCode() : 0);
+ result = 31 * result + (myNonCodeUsagesString != null ? myNonCodeUsagesString.hashCode() : 0);
+ result = 31 * result + (myCodeUsagesString != null ? myCodeUsagesString.hashCode() : 0);
+ result = 31 * result + (myUsagesInGeneratedCodeString != null ? myUsagesInGeneratedCodeString.hashCode() : 0);
+ result = 31 * result + (myShowReadOnlyStatusAsRed ? 1 : 0);
+ result = 31 * result + (myShowCancelButton ? 1 : 0);
+ result = 31 * result + (myOpenInNewTab ? 1 : 0);
+ result = 31 * result + (myCodeUsages ? 1 : 0);
+ result = 31 * result + (myUsageTypeFilteringAvailable ? 1 : 0);
+ result = 31 * result + (myUsagesWord != null ? myUsagesWord.hashCode() : 0);
+ result = 31 * result + (myTabName != null ? myTabName.hashCode() : 0);
+ result = 31 * result + (myToolwindowTitle != null ? myToolwindowTitle.hashCode() : 0);
+ result = 31 * result + (myNotFoundActions != null ? myNotFoundActions.hashCode() : 0);
+ result = 31 * result + (myDetachedMode ? 1 : 0);
+ result = 31 * result + (myDynamicCodeUsagesString != null ? myDynamicCodeUsagesString.hashCode() : 0);
+ result = 31 * result + (myMergeDupLinesAvailable ? 1 : 0);
+ return result;
+ }
}