mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix SearchTextField investigation
GitOrigin-RevId: 447d74a6c130e732190ad550b73772b0d02d62ec
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9eceb8a740
commit
2f45a7afc9
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -9,8 +8,9 @@ import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.JBPopupListener;
|
||||
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.components.JBList;
|
||||
@@ -29,31 +29,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchTextField extends JPanel {
|
||||
private class SearchHistoryAction extends AnAction{
|
||||
private final @NlsSafe String name;
|
||||
private final boolean enabled;
|
||||
|
||||
SearchHistoryAction(@NlsSafe String name, boolean enabled){
|
||||
this.name = name;
|
||||
this.enabled = enabled;
|
||||
getTemplatePresentation().setText(name);
|
||||
getTemplatePresentation().setEnabled(enabled);
|
||||
setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
e.getPresentation().setText(name);
|
||||
e.getPresentation().setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
myTextField.setText(getTemplatePresentation().getText());
|
||||
addCurrentTextToHistory();
|
||||
historyItemChosen(getTemplatePresentation().getText());
|
||||
}
|
||||
}
|
||||
|
||||
public static final DataKey<SearchTextField> KEY = DataKey.create("search.text.field");
|
||||
public static final KeyStroke SHOW_HISTORY_KEYSTROKE = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK);
|
||||
@@ -66,11 +41,10 @@ public class SearchTextField extends JPanel {
|
||||
private final MyModel myModel;
|
||||
private final TextFieldWithProcessing myTextField;
|
||||
|
||||
@Nullable
|
||||
private JBPopup myPopup;
|
||||
private ActionPopupMenu myNativeSearchPopup;
|
||||
private DefaultActionGroup myHistoryPopupActionGroup = new DefaultActionGroup();
|
||||
private final SearchHistoryAction noItemsSearchHistoryAction = new SearchHistoryAction(IdeBundle.message("no.recent.searches"), false);
|
||||
private String myHistoryPropertyName;
|
||||
private final boolean historyPopupEnabled;
|
||||
|
||||
public SearchTextField() {
|
||||
this(true);
|
||||
@@ -86,9 +60,9 @@ public class SearchTextField extends JPanel {
|
||||
|
||||
public SearchTextField(boolean historyPopupEnabled, @Nullable String historyPropertyName) {
|
||||
super(new BorderLayout());
|
||||
this.historyPopupEnabled = historyPopupEnabled;
|
||||
|
||||
myModel = new MyModel();
|
||||
|
||||
myTextField = new TextFieldWithProcessing() {
|
||||
@Override
|
||||
public void processKeyEvent(final KeyEvent e) {
|
||||
@@ -133,15 +107,7 @@ public class SearchTextField extends JPanel {
|
||||
|
||||
setHistoryPropertyName(historyPropertyName);
|
||||
|
||||
if (historyPopupEnabled) {
|
||||
DumbAwareAction.create(event -> {
|
||||
if (myNativeSearchPopup != null) {
|
||||
myNativeSearchPopup.getComponent().show(myTextField, 5, myTextField.getHeight());
|
||||
} else if (myPopup == null || !myPopup.isVisible()) {
|
||||
showPopup();
|
||||
}
|
||||
}).registerCustomShortcutSet(KeymapUtil.getActiveKeymapShortcuts("ShowSearchHistory"), myTextField);
|
||||
} else if (historyPropertyName != null) {
|
||||
if (historyPropertyName != null) {
|
||||
myTextField.getActionMap().put("showPrevHistoryItem", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -166,20 +132,15 @@ public class SearchTextField extends JPanel {
|
||||
myTextField.getInputMap().put(SHOW_HISTORY_KEYSTROKE, "showNextHistoryItem");
|
||||
}
|
||||
|
||||
myTextField.putClientProperty("JTextField.variant", "search");
|
||||
myTextField.putClientProperty("JTextField.variant", "searchWithJbPopup");
|
||||
myTextField.putClientProperty("JTextField.Search.Gap", JBUIScale.scale(6));
|
||||
myTextField.putClientProperty("JTextField.Search.CancelAction", (ActionListener)e -> {
|
||||
myTextField.setText("");
|
||||
onFieldCleared();
|
||||
});
|
||||
|
||||
if (historyPopupEnabled) {
|
||||
myHistoryPopupActionGroup = new DefaultActionGroup();
|
||||
myNativeSearchPopup = ActionManager.getInstance()
|
||||
.createActionPopupMenu(ActionPlaces.UNKNOWN, myHistoryPopupActionGroup);
|
||||
updateMenu();
|
||||
myTextField.putClientProperty("JTextField.Search.FindPopup", myNativeSearchPopup.getComponent());
|
||||
}
|
||||
DumbAwareAction.create(event -> {
|
||||
showPopup();
|
||||
}).registerCustomShortcutSet(KeymapUtil.getActiveKeymapShortcuts("ShowSearchHistory"), myTextField);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -208,22 +169,6 @@ public class SearchTextField extends JPanel {
|
||||
protected void onFocusGained() {
|
||||
}
|
||||
|
||||
private void updateMenu() {
|
||||
if (myNativeSearchPopup != null) {
|
||||
myHistoryPopupActionGroup.removeAll();
|
||||
final int itemsCount = myModel.getSize();
|
||||
if (itemsCount == 0) {
|
||||
myHistoryPopupActionGroup.add(noItemsSearchHistoryAction);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < itemsCount; i++) {
|
||||
final String item = myModel.getElementAt(i);
|
||||
addMenuItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated unused
|
||||
*/
|
||||
@@ -289,19 +234,13 @@ public class SearchTextField extends JPanel {
|
||||
public void addCurrentTextToHistory() {
|
||||
if (myModel.addElement(getText()) && myHistoryPropertyName != null) {
|
||||
PropertiesComponent.getInstance().setValue(myHistoryPropertyName, StringUtil.join(getHistory(), "\n"));
|
||||
reInitPopup();
|
||||
}
|
||||
}
|
||||
|
||||
protected void historyItemChosen(String item) {
|
||||
}
|
||||
|
||||
private void addMenuItem(@NlsSafe String item) {
|
||||
if (myNativeSearchPopup != null) {
|
||||
myHistoryPopupActionGroup.remove(noItemsSearchHistoryAction);
|
||||
myHistoryPopupActionGroup.add(new SearchHistoryAction(item, true));
|
||||
}
|
||||
}
|
||||
|
||||
public void selectText() {
|
||||
getTextEditor().selectAll();
|
||||
}
|
||||
@@ -318,7 +257,7 @@ public class SearchTextField extends JPanel {
|
||||
@Override
|
||||
public void requestFocus() {
|
||||
IdeFocusManager.getGlobalInstance()
|
||||
.doWhenFocusSettlesDown(() -> IdeFocusManager.getGlobalInstance().requestFocus(getTextEditor(), true));
|
||||
.doWhenFocusSettlesDown(() -> IdeFocusManager.getGlobalInstance().requestFocus(getTextEditor(), true));
|
||||
}
|
||||
|
||||
protected void setHistoryPropertyName(String historyPropertyName) {
|
||||
@@ -410,7 +349,7 @@ public class SearchTextField extends JPanel {
|
||||
|
||||
public void fireContentsChanged() {
|
||||
fireContentsChanged(this, -1, -1);
|
||||
updateMenu();
|
||||
reInitPopup();
|
||||
}
|
||||
|
||||
public void setItems(List<String> aList) {
|
||||
@@ -440,19 +379,32 @@ public class SearchTextField extends JPanel {
|
||||
|
||||
protected void showPopup() {
|
||||
addCurrentTextToHistory();
|
||||
if (myPopup == null || !myPopup.isVisible()) {
|
||||
final JList<String> list = new JBList<>(myModel);
|
||||
final Runnable chooseRunnable = createItemChosenCallback(list);
|
||||
myPopup = JBPopupFactory.getInstance().createListPopupBuilder(list)
|
||||
.setMovable(false)
|
||||
.setRequestFocus(true)
|
||||
.setItemChoosenCallback(chooseRunnable).createPopup();
|
||||
if ((myPopup == null || !myPopup.isVisible()) && historyPopupEnabled) {
|
||||
reInitPopup();
|
||||
if (isShowing()) {
|
||||
myPopup.showUnderneathOf(getPopupLocationComponent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void reInitPopup() {
|
||||
final JList<String> list = new JBList<>(myModel);
|
||||
final Runnable chooseRunnable = createItemChosenCallback(list);
|
||||
myPopup = JBPopupFactory.getInstance().createListPopupBuilder(list)
|
||||
.setMovable(false)
|
||||
.setRequestFocus(true)
|
||||
.addListener(new JBPopupListener() {
|
||||
@Override
|
||||
public void onClosed(@NotNull LightweightWindowEvent event) {
|
||||
//because jbpopup can be shown only once
|
||||
reInitPopup();
|
||||
}
|
||||
})
|
||||
.setItemChoosenCallback(chooseRunnable).createPopup();
|
||||
myTextField.putClientProperty("JTextField.Search.FindPopup", myPopup);
|
||||
myTextField.putClientProperty("JTextField.variant", "searchWithJbPopup");
|
||||
}
|
||||
|
||||
protected Component getPopupLocationComponent() {
|
||||
return this;
|
||||
}
|
||||
@@ -477,7 +429,7 @@ public class SearchTextField extends JPanel {
|
||||
}
|
||||
|
||||
protected boolean preprocessEventForTextField(KeyEvent e) {
|
||||
if (SHOW_HISTORY_KEYSTROKE.equals(KeyStroke.getKeyStrokeForEvent(e)) && getClientProperty("JTextField.Search.FindPopup") instanceof JPopupMenu) {
|
||||
if (SHOW_HISTORY_KEYSTROKE.equals(KeyStroke.getKeyStrokeForEvent(e)) && getClientProperty("JTextField.Search.FindPopup") instanceof JBPopup) {
|
||||
showPopup();
|
||||
return true;
|
||||
}
|
||||
|
||||
+47
-13
@@ -5,6 +5,7 @@ import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.ui.ComponentUtil;
|
||||
@@ -221,7 +222,11 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple
|
||||
}
|
||||
|
||||
public static boolean isSearchField(Component c) {
|
||||
return c instanceof JTextField && "search".equals(((JTextField)c).getClientProperty(VARIANT));
|
||||
if(!(c instanceof JTextField)){
|
||||
return false;
|
||||
}
|
||||
var variant = ((JTextField)c).getClientProperty(VARIANT);
|
||||
return "search".equals(variant) || "searchWithJbPopup".equals(variant);
|
||||
}
|
||||
|
||||
public static boolean isSearchFieldWithHistoryPopup(Component c) {
|
||||
@@ -557,7 +562,15 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple
|
||||
if (extension instanceof Extension) {
|
||||
addExtension((Extension)extension);
|
||||
}
|
||||
addExtension(new SearchExtension());
|
||||
addExtension(new SearchExtension(PopupState.forPopupMenu()));
|
||||
addExtension(new ClearExtension());
|
||||
}
|
||||
else if ("searchWithJbPopup".equals(variant)) {
|
||||
Object extension = getComponent().getClientProperty("search.extension");
|
||||
if (extension instanceof Extension) {
|
||||
addExtension((Extension)extension);
|
||||
}
|
||||
addExtension(new SearchExtension(PopupState.forPopup()));
|
||||
addExtension(new ClearExtension());
|
||||
}
|
||||
}
|
||||
@@ -618,9 +631,13 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple
|
||||
|
||||
|
||||
private final class SearchExtension implements Extension {
|
||||
private final PopupState<JPopupMenu> myPopupState = PopupState.forPopupMenu();
|
||||
private final PopupState myPopupState;
|
||||
private Rectangle bounds; // should be bound to IconHandler#bounds
|
||||
|
||||
public SearchExtension(PopupState popupState){
|
||||
this.myPopupState = popupState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon(boolean hovered) {
|
||||
return getSearchIcon(hovered, null != getActionOnClick());
|
||||
@@ -645,16 +662,33 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple
|
||||
@Override
|
||||
public Runnable getActionOnClick() {
|
||||
JTextComponent component = getComponent();
|
||||
Object property = component == null ? null : component.getClientProperty(POPUP);
|
||||
JPopupMenu popup = property instanceof JPopupMenu ? (JPopupMenu)property : null;
|
||||
return popup == null ? null : () -> {
|
||||
if (myPopupState.isRecentlyHidden()) return; // do not show new popup
|
||||
Rectangle editor = getVisibleEditorRect();
|
||||
if (editor != null) {
|
||||
myPopupState.prepareToShow(popup);
|
||||
popup.show(component, bounds.x, editor.y + editor.height);
|
||||
}
|
||||
};
|
||||
if(component == null){
|
||||
return null;
|
||||
}
|
||||
Object property = component.getClientProperty(POPUP);
|
||||
if(property instanceof JPopupMenu){
|
||||
JPopupMenu popup = (JPopupMenu) property;
|
||||
return () -> {
|
||||
if (myPopupState.isRecentlyHidden()) return; // do not show new popup
|
||||
Rectangle editor = getVisibleEditorRect();
|
||||
if (editor != null) {
|
||||
myPopupState.prepareToShow(popup);
|
||||
popup.show(component, bounds.x, editor.y + editor.height);
|
||||
}
|
||||
};
|
||||
}
|
||||
if(property instanceof JBPopup){
|
||||
JBPopup popup = (JBPopup) property;
|
||||
return () -> {
|
||||
if (myPopupState.isRecentlyHidden()) return; // do not show new popup
|
||||
Rectangle editor = getVisibleEditorRect();
|
||||
if (editor != null) {
|
||||
myPopupState.prepareToShow(popup);
|
||||
popup.showUnderneathOf(component);
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user