|
|
|
@@ -3,18 +3,21 @@ package com.intellij.ide.actions;
|
|
|
|
|
|
|
|
|
|
import com.intellij.featureStatistics.FeatureUsageTracker;
|
|
|
|
|
import com.intellij.ide.DataManager;
|
|
|
|
|
import com.intellij.ide.IdeBundle;
|
|
|
|
|
import com.intellij.ide.IdeEventQueue;
|
|
|
|
|
import com.intellij.ide.ui.UISettings;
|
|
|
|
|
import com.intellij.ide.ui.UISettingsState;
|
|
|
|
|
import com.intellij.openapi.actionSystem.*;
|
|
|
|
|
import com.intellij.openapi.actionSystem.impl.PresentationFactory;
|
|
|
|
|
import com.intellij.openapi.application.ApplicationManager;
|
|
|
|
|
import com.intellij.openapi.application.Experiments;
|
|
|
|
|
import com.intellij.openapi.application.ModalityState;
|
|
|
|
|
import com.intellij.openapi.command.CommandProcessor;
|
|
|
|
|
import com.intellij.openapi.editor.markup.EffectType;
|
|
|
|
|
import com.intellij.openapi.editor.markup.TextAttributes;
|
|
|
|
|
import com.intellij.openapi.fileEditor.FileEditorManager;
|
|
|
|
|
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
|
|
|
|
|
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
|
|
|
|
|
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
|
|
|
|
|
import com.intellij.openapi.fileEditor.impl.EditorTabPresentationUtil;
|
|
|
|
|
import com.intellij.openapi.fileEditor.impl.EditorWindow;
|
|
|
|
@@ -43,6 +46,8 @@ import com.intellij.openapi.wm.impl.ToolWindowManagerImpl;
|
|
|
|
|
import com.intellij.problems.WolfTheProblemSolver;
|
|
|
|
|
import com.intellij.ui.*;
|
|
|
|
|
import com.intellij.ui.border.CustomLineBorder;
|
|
|
|
|
import com.intellij.ui.components.JBCheckBox;
|
|
|
|
|
import com.intellij.ui.components.JBLabel;
|
|
|
|
|
import com.intellij.ui.components.JBList;
|
|
|
|
|
import com.intellij.ui.speedSearch.NameFilteringListModel;
|
|
|
|
|
import com.intellij.ui.speedSearch.SpeedSearchUtil;
|
|
|
|
@@ -66,6 +71,7 @@ import java.io.File;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
import static com.intellij.ide.actions.RecentLocationsAction.SHORTCUT_HEX_COLOR;
|
|
|
|
|
import static com.intellij.openapi.keymap.KeymapUtil.getActiveKeymapShortcuts;
|
|
|
|
|
import static java.awt.event.InputEvent.CTRL_DOWN_MASK;
|
|
|
|
|
import static java.awt.event.KeyEvent.*;
|
|
|
|
@@ -146,7 +152,8 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
}
|
|
|
|
|
if (SWITCHER == null) {
|
|
|
|
|
isNewSwitcher = true;
|
|
|
|
|
SWITCHER = createAndShowSwitcher(e, SWITCHER_TITLE, false, null);
|
|
|
|
|
// Assigns SWITCHER field
|
|
|
|
|
createAndShowSwitcher(project, SWITCHER_TITLE, IdeActions.ACTION_SWITCHER, false, false);
|
|
|
|
|
FeatureUsageTracker.getInstance().triggerFeatureUsed(SWITCHER_FEATURE_ID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -167,32 +174,47 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @deprecated Please use {@link Switcher#createAndShowSwitcher(AnActionEvent, String, boolean, boolean)}
|
|
|
|
|
*/
|
|
|
|
|
@Deprecated
|
|
|
|
|
@Nullable
|
|
|
|
|
public static SwitcherPanel createAndShowSwitcher(@NotNull AnActionEvent e, @NotNull String title, boolean pinned, @Nullable final VirtualFile[] vFiles) {
|
|
|
|
|
Project project = getEventProject(e);
|
|
|
|
|
if (SWITCHER != null && Comparing.equal(SWITCHER.myTitle, title)) {
|
|
|
|
|
SWITCHER.goForward();
|
|
|
|
|
return null;
|
|
|
|
|
return createAndShowSwitcher(e, title, "RecentFiles", pinned, vFiles != null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static SwitcherPanel createAndShowSwitcher(@NotNull AnActionEvent e, @NotNull String title, @NotNull String actionId, boolean onlyEdited, boolean pinned) {
|
|
|
|
|
Project project = e.getProject();
|
|
|
|
|
if (SWITCHER != null) {
|
|
|
|
|
final boolean sameShortcut = Comparing.equal(SWITCHER.myTitle, title);
|
|
|
|
|
if (SWITCHER.isCheckboxMode()) {
|
|
|
|
|
if (sameShortcut) {
|
|
|
|
|
SWITCHER.toggleShowEditedFiles();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
SWITCHER.setShowOnlyEditedFiles(onlyEdited);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else if (sameShortcut) {
|
|
|
|
|
SWITCHER.goForward();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return project == null ? null : createAndShowSwitcher(project, title, pinned, vFiles == null ? null : Arrays.asList(vFiles));
|
|
|
|
|
return project == null ? null : createAndShowSwitcher(project, title, actionId, onlyEdited, pinned);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
|
private static SwitcherPanel createAndShowSwitcher(@NotNull Project project,
|
|
|
|
|
@NotNull String title,
|
|
|
|
|
boolean pinned,
|
|
|
|
|
@Nullable final List<VirtualFile> vFiles) {
|
|
|
|
|
@NotNull String actionId,
|
|
|
|
|
boolean onlyEdited,
|
|
|
|
|
boolean pinned) {
|
|
|
|
|
synchronized (Switcher.class) {
|
|
|
|
|
if (SWITCHER != null) {
|
|
|
|
|
SWITCHER.cancel();
|
|
|
|
|
}
|
|
|
|
|
SWITCHER = new SwitcherPanel(project, title, pinned) {
|
|
|
|
|
@NotNull
|
|
|
|
|
@Override
|
|
|
|
|
protected List<VirtualFile> getFiles(@NotNull Project project) {
|
|
|
|
|
return vFiles != null ? vFiles : super.getFiles(project);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
SWITCHER = new SwitcherPanel(project, title, actionId, onlyEdited, pinned);
|
|
|
|
|
return SWITCHER;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -203,6 +225,7 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
final JBList files;
|
|
|
|
|
final JPanel separator;
|
|
|
|
|
final ToolWindowManager twManager;
|
|
|
|
|
final JBCheckBox myShowOnlyEditedFilesCheckBox;
|
|
|
|
|
final JLabel pathLabel = new JLabel(" ");
|
|
|
|
|
final JPanel descriptions;
|
|
|
|
|
final Project project;
|
|
|
|
@@ -211,6 +234,7 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
final Alarm myAlarm;
|
|
|
|
|
final SwitcherSpeedSearch mySpeedSearch;
|
|
|
|
|
final String myTitle;
|
|
|
|
|
final String myActionId;
|
|
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
|
@Override
|
|
|
|
@@ -301,10 +325,11 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings({"ConstantConditions"})
|
|
|
|
|
SwitcherPanel(@NotNull final Project project, @NotNull String title, boolean pinned) {
|
|
|
|
|
SwitcherPanel(@NotNull final Project project, @NotNull String title, @NotNull String actionId, boolean onlyEdited, boolean pinned) {
|
|
|
|
|
setLayout(new SwitcherLayouter());
|
|
|
|
|
this.project = project;
|
|
|
|
|
myTitle = title;
|
|
|
|
|
myActionId = actionId;
|
|
|
|
|
myPinned = pinned;
|
|
|
|
|
mySpeedSearch = pinned ? new SwitcherSpeedSearch() : null;
|
|
|
|
|
|
|
|
|
@@ -327,7 +352,7 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
descriptions.setBorder(new CustomLineBorder(JBUI.CurrentTheme.Advertiser.borderColor(), JBUI.insetsTop(1)));
|
|
|
|
|
descriptions.add(pathLabel, BorderLayout.CENTER);
|
|
|
|
|
twManager = ToolWindowManager.getInstance(project);
|
|
|
|
|
DefaultListModel twModel = new DefaultListModel();
|
|
|
|
|
CollectionListModel<ToolWindow> twModel = new CollectionListModel<ToolWindow>();
|
|
|
|
|
List<ActivateToolWindowAction> actions = ToolWindowsGroup.getToolWindowActions(project, true);
|
|
|
|
|
List<ToolWindow> windows = ContainerUtil.newArrayList();
|
|
|
|
|
for (ActivateToolWindowAction action : actions) {
|
|
|
|
@@ -340,7 +365,7 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
final Map<ToolWindow, String> map = ContainerUtil.reverseMap(twShortcuts);
|
|
|
|
|
Collections.sort(windows, (o1, o2) -> StringUtil.compare(map.get(o1), map.get(o2), false));
|
|
|
|
|
for (ToolWindow window : windows) {
|
|
|
|
|
twModel.addElement(window);
|
|
|
|
|
twModel.add(window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toolWindows = new JBList(twModel);
|
|
|
|
@@ -390,66 +415,12 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
separator.setPreferredSize(JBUI.size(9, 10));
|
|
|
|
|
separator.setBackground(toolWindows.getBackground());
|
|
|
|
|
|
|
|
|
|
int selectionIndex = -1;
|
|
|
|
|
final FileEditorManagerImpl editorManager = (FileEditorManagerImpl)FileEditorManager.getInstance(project);
|
|
|
|
|
final ArrayList<FileInfo> filesData = new ArrayList<>();
|
|
|
|
|
final ArrayList<FileInfo> editors = new ArrayList<>();
|
|
|
|
|
if (!pinned) {
|
|
|
|
|
if (UISettings.getInstance().getEditorTabPlacement() != UISettings.TABS_NONE) {
|
|
|
|
|
for (Pair<VirtualFile, EditorWindow> pair : editorManager.getSelectionHistory()) {
|
|
|
|
|
editors.add(new FileInfo(pair.first, pair.second, project));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (editors.size() < 2 || isPinnedMode()) {
|
|
|
|
|
if (isPinnedMode() && editors.size() > 1) {
|
|
|
|
|
filesData.addAll(editors);
|
|
|
|
|
}
|
|
|
|
|
final List<VirtualFile> recentFiles = getFiles(project);
|
|
|
|
|
final int maxFiles = Math.max(editors.size(), recentFiles.size());
|
|
|
|
|
final int minIndex = isPinnedMode() ? 0 : (recentFiles.size() - Math.min(toolWindows.getModel().getSize(), maxFiles));
|
|
|
|
|
boolean firstRecentMarked = false;
|
|
|
|
|
final List<VirtualFile> selectedFiles = Arrays.asList(editorManager.getSelectedFiles());
|
|
|
|
|
for (int i = recentFiles.size() - 1; i >= minIndex; i--) {
|
|
|
|
|
if (isPinnedMode()
|
|
|
|
|
&& selectedFiles.contains(recentFiles.get(i))
|
|
|
|
|
&& UISettings.getInstance().getEditorTabPlacement() != UISettings.TABS_NONE) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final FileInfo info = new FileInfo(recentFiles.get(i), null, project);
|
|
|
|
|
boolean add = true;
|
|
|
|
|
if (isPinnedMode()) {
|
|
|
|
|
for (FileInfo fileInfo : filesData) {
|
|
|
|
|
if (fileInfo.first.equals(info.first)) {
|
|
|
|
|
add = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (add) {
|
|
|
|
|
filesData.add(info);
|
|
|
|
|
if (!firstRecentMarked) {
|
|
|
|
|
selectionIndex = filesData.size() - 1;
|
|
|
|
|
if (selectionIndex != 0 || UISettings.getInstance().getEditorTabPlacement() != UISettings.TABS_NONE || !isPinnedMode() || selectedFiles.isEmpty()) {
|
|
|
|
|
firstRecentMarked = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//if (editors.size() == 1) selectionIndex++;
|
|
|
|
|
if (editors.size() == 1 && (filesData.isEmpty() || !editors.get(0).getFirst().equals(filesData.get(0).getFirst()))) {
|
|
|
|
|
filesData.add(0, editors.get(0));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (int i = 0; i < Math.min(30, editors.size()); i++) {
|
|
|
|
|
filesData.add(editors.get(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final DefaultListModel filesModel = new DefaultListModel();
|
|
|
|
|
for (FileInfo editor : filesData) {
|
|
|
|
|
filesModel.addElement(editor);
|
|
|
|
|
final Pair<List<FileInfo>, Integer> filesAndSelection = getFilesToShowAndSelectionIndex(project, collectFiles(project, onlyEdited),
|
|
|
|
|
toolWindows.getModel().getSize(), pinned);
|
|
|
|
|
final int selectionIndex = filesAndSelection.getSecond();
|
|
|
|
|
final CollectionListModel<FileInfo> filesModel = new CollectionListModel<FileInfo>();
|
|
|
|
|
for (FileInfo editor : filesAndSelection.getFirst()) {
|
|
|
|
|
filesModel.add(editor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final VirtualFilesRenderer filesRenderer = new VirtualFilesRenderer(this) {
|
|
|
|
@@ -557,7 +528,7 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
ScrollingUtil.ensureSelectionExists(files);
|
|
|
|
|
|
|
|
|
|
this.add(toolWindows, BorderLayout.WEST);
|
|
|
|
|
if (filesModel.size() > 0) {
|
|
|
|
|
if (filesModel.getSize() > 0) {
|
|
|
|
|
files.setAlignmentY(1f);
|
|
|
|
|
final JScrollPane pane = ScrollPaneFactory.createScrollPane(files, true);
|
|
|
|
|
pane.setPreferredSize(new Dimension(files.getPreferredSize().width, 20 * 20));
|
|
|
|
@@ -580,13 +551,31 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
KeymapUtil.reassignAction(files, getKeyStroke(VK_UP, 0), getKeyStroke(VK_UP, CTRL_DOWN_MASK), WHEN_FOCUSED, false);
|
|
|
|
|
KeymapUtil.reassignAction(files, getKeyStroke(VK_DOWN, 0), getKeyStroke(VK_DOWN, CTRL_DOWN_MASK), WHEN_FOCUSED, false);
|
|
|
|
|
|
|
|
|
|
myShowOnlyEditedFilesCheckBox = new MyCheckBox(actionId, onlyEdited);
|
|
|
|
|
|
|
|
|
|
JPanel topPanel = createTopPanel(myShowOnlyEditedFilesCheckBox, isCheckboxMode() ? IdeBundle.message("title.popup.recent.files") : title);
|
|
|
|
|
this.add(topPanel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
|
|
if (isCheckboxMode()) {
|
|
|
|
|
myShowOnlyEditedFilesCheckBox.addActionListener(new ActionListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
|
setShowOnlyEditedFiles(myShowOnlyEditedFilesCheckBox.isSelected());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
myShowOnlyEditedFilesCheckBox.setEnabled(false);
|
|
|
|
|
myShowOnlyEditedFilesCheckBox.setVisible(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(this, filesModel.getSize() > 0 ? files : toolWindows)
|
|
|
|
|
.setResizable(pinned)
|
|
|
|
|
.setModalContext(false)
|
|
|
|
|
.setFocusable(true)
|
|
|
|
|
.setRequestFocus(true)
|
|
|
|
|
.setTitle(title)
|
|
|
|
|
.setCancelOnWindowDeactivation(true)
|
|
|
|
|
.setCancelOnOtherWindowOpen(true)
|
|
|
|
|
.setMovable(pinned)
|
|
|
|
@@ -637,7 +626,6 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
addFocusTraversalKeys(popupFocusAncestor, KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, "LEFT");
|
|
|
|
|
addFocusTraversalKeys(popupFocusAncestor, KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, "control RIGHT");
|
|
|
|
|
addFocusTraversalKeys(popupFocusAncestor, KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, "control LEFT");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Container getPopupFocusAncestor() {
|
|
|
|
@@ -645,6 +633,92 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
return content == null ? null : content.getFocusCycleRootAncestor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
|
private static List<VirtualFile> collectFiles(@NotNull Project project, boolean onlyEdited) {
|
|
|
|
|
return onlyEdited ? Arrays.asList(IdeDocumentHistory.getInstance(project).getChangedFiles())
|
|
|
|
|
: EditorHistoryManager.getInstance(project).getFileList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
|
private static Pair<List<FileInfo>, Integer> getFilesToShowAndSelectionIndex(@NotNull Project project,
|
|
|
|
|
@NotNull List<VirtualFile> filesForInit,
|
|
|
|
|
int toolWindowsCount,
|
|
|
|
|
boolean pinned) {
|
|
|
|
|
int selectionIndex = -1;
|
|
|
|
|
final FileEditorManagerImpl editorManager = (FileEditorManagerImpl)FileEditorManager.getInstance(project);
|
|
|
|
|
final ArrayList<FileInfo> filesData = new ArrayList<>();
|
|
|
|
|
final ArrayList<FileInfo> editors = new ArrayList<>();
|
|
|
|
|
if (!pinned) {
|
|
|
|
|
if (UISettings.getInstance().getEditorTabPlacement() != UISettings.TABS_NONE) {
|
|
|
|
|
for (Pair<VirtualFile, EditorWindow> pair : editorManager.getSelectionHistory()) {
|
|
|
|
|
editors.add(new FileInfo(pair.first, pair.second, project));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (editors.size() < 2 || pinned) {
|
|
|
|
|
if (pinned && editors.size() > 1) {
|
|
|
|
|
filesData.addAll(editors);
|
|
|
|
|
}
|
|
|
|
|
final List<VirtualFile> recentFiles = filesForInit;
|
|
|
|
|
final int maxFiles = Math.max(editors.size(), recentFiles.size());
|
|
|
|
|
final int minIndex = pinned ? 0 : (recentFiles.size() - Math.min(toolWindowsCount, maxFiles));
|
|
|
|
|
boolean firstRecentMarked = false;
|
|
|
|
|
final List<VirtualFile> selectedFiles = Arrays.asList(editorManager.getSelectedFiles());
|
|
|
|
|
for (int i = recentFiles.size() - 1; i >= minIndex; i--) {
|
|
|
|
|
if (pinned
|
|
|
|
|
&& selectedFiles.contains(recentFiles.get(i))
|
|
|
|
|
&& UISettings.getInstance().getEditorTabPlacement() != UISettings.TABS_NONE) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final FileInfo info = new FileInfo(recentFiles.get(i), null, project);
|
|
|
|
|
boolean add = true;
|
|
|
|
|
if (pinned) {
|
|
|
|
|
for (FileInfo fileInfo : filesData) {
|
|
|
|
|
if (fileInfo.first.equals(info.first)) {
|
|
|
|
|
add = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (add) {
|
|
|
|
|
filesData.add(info);
|
|
|
|
|
if (!firstRecentMarked) {
|
|
|
|
|
selectionIndex = filesData.size() - 1;
|
|
|
|
|
if (selectionIndex != 0 || UISettings.getInstance().getEditorTabPlacement() != UISettings.TABS_NONE || !pinned || selectedFiles.isEmpty()) {
|
|
|
|
|
firstRecentMarked = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//if (editors.size() == 1) selectionIndex++;
|
|
|
|
|
if (editors.size() == 1 && (filesData.isEmpty() || !editors.get(0).getFirst().equals(filesData.get(0).getFirst()))) {
|
|
|
|
|
filesData.add(0, editors.get(0));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (int i = 0; i < Math.min(30, editors.size()); i++) {
|
|
|
|
|
filesData.add(editors.get(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Pair.create(filesData, selectionIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
|
private static JPanel createTopPanel(JBCheckBox showOnlyEditedFilesCheckBox, @NotNull String title) {
|
|
|
|
|
JPanel topPanel = new CaptionPanel();
|
|
|
|
|
JBLabel titleLabel = new JBLabel(title);
|
|
|
|
|
titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD));
|
|
|
|
|
topPanel.add(titleLabel, BorderLayout.WEST);
|
|
|
|
|
topPanel.add(showOnlyEditedFilesCheckBox, BorderLayout.EAST);
|
|
|
|
|
|
|
|
|
|
Dimension size = topPanel.getPreferredSize();
|
|
|
|
|
size.height = JBUI.scale(29);
|
|
|
|
|
topPanel.setPreferredSize(size);
|
|
|
|
|
topPanel.setBorder(JBUI.Borders.empty(5, 8));
|
|
|
|
|
return topPanel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void addFocusTraversalKeys (Container focusCycleRoot, int focusTraversalType, String keyStroke) {
|
|
|
|
|
Set<AWTKeyStroke> focusTraversalKeySet = focusCycleRoot.getFocusTraversalKeys(focusTraversalType);
|
|
|
|
|
|
|
|
|
@@ -653,9 +727,10 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
focusCycleRoot.setFocusTraversalKeys(focusTraversalType, set);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Deprecated
|
|
|
|
|
@NotNull
|
|
|
|
|
protected List<VirtualFile> getFiles(@NotNull Project project) {
|
|
|
|
|
return EditorHistoryManager.getInstance(project).getFileList();
|
|
|
|
|
throw new UnsupportedOperationException("deprecated");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
@@ -817,8 +892,8 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
|
|
|
|
|
private static void removeElementAt(@NotNull JList jList, int index) {
|
|
|
|
|
final ListModel model = jList.getModel();
|
|
|
|
|
if (model instanceof DefaultListModel) {
|
|
|
|
|
((DefaultListModel)model).removeElementAt(index);
|
|
|
|
|
if (model instanceof CollectionListModel) {
|
|
|
|
|
((CollectionListModel)model).remove(index);
|
|
|
|
|
}
|
|
|
|
|
else if (model instanceof NameFilteringListModel) {
|
|
|
|
|
((NameFilteringListModel)model).remove(index);
|
|
|
|
@@ -891,6 +966,40 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
return files.hasFocus() ? files : toolWindows.hasFocus() ? toolWindows : preferable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean isCheckboxMode() {
|
|
|
|
|
return isPinnedMode() && Experiments.isFeatureEnabled("recent.and.edited.files.together");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void toggleShowEditedFiles() {
|
|
|
|
|
myShowOnlyEditedFilesCheckBox.doClick();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setShowOnlyEditedFiles(boolean onlyEdited) {
|
|
|
|
|
if (myShowOnlyEditedFilesCheckBox.isSelected() != onlyEdited) {
|
|
|
|
|
myShowOnlyEditedFilesCheckBox.setSelected(onlyEdited);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final boolean listWasSelected = files.getSelectedIndex() != -1;
|
|
|
|
|
|
|
|
|
|
final Pair<List<FileInfo>, Integer> filesAndSelection = getFilesToShowAndSelectionIndex(
|
|
|
|
|
project, collectFiles(project, onlyEdited), toolWindows.getModel().getSize(), isPinnedMode());
|
|
|
|
|
final int selectionIndex = filesAndSelection.getSecond();
|
|
|
|
|
|
|
|
|
|
final ListModel model = files.getModel();
|
|
|
|
|
if (model instanceof CollectionListModel) {
|
|
|
|
|
((CollectionListModel)model).replaceAll(filesAndSelection.getFirst());
|
|
|
|
|
}
|
|
|
|
|
else if (model instanceof NameFilteringListModel) {
|
|
|
|
|
((NameFilteringListModel)model).replaceAll(filesAndSelection.getFirst());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (selectionIndex > -1 && listWasSelected) {
|
|
|
|
|
files.setSelectedIndex(selectionIndex);
|
|
|
|
|
}
|
|
|
|
|
files.revalidate();
|
|
|
|
|
files.repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void navigate(final InputEvent e) {
|
|
|
|
|
final boolean openInNewWindow = e != null && e.isShiftDown() && e instanceof KeyEvent && ((KeyEvent)e).getKeyCode() == VK_ENTER;
|
|
|
|
|
final Object[] values = getSelectedList().getSelectedValues();
|
|
|
|
@@ -1178,6 +1287,23 @@ public class Switcher extends AnAction implements DumbAware {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static class MyCheckBox extends JBCheckBox {
|
|
|
|
|
private MyCheckBox(@NotNull String actionId, boolean selected) {
|
|
|
|
|
super(layoutText(actionId), selected);
|
|
|
|
|
setOpaque(false);
|
|
|
|
|
setFocusable(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String layoutText(@NotNull String actionId) {
|
|
|
|
|
ShortcutSet shortcuts = KeymapUtil.getActiveKeymapShortcuts(actionId);
|
|
|
|
|
return "<html>"
|
|
|
|
|
+ IdeBundle.message("recent.files.checkbox.label")
|
|
|
|
|
+ " <font color=\"" + SHORTCUT_HEX_COLOR + "\">"
|
|
|
|
|
+ KeymapUtil.getShortcutsText(shortcuts.getShortcuts()) + "</font>"
|
|
|
|
|
+ "</html>";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static class VirtualFilesRenderer extends ColoredListCellRenderer {
|
|
|
|
|
private final SwitcherPanel mySwitcherPanel;
|
|
|
|
|
boolean open;
|
|
|
|
|