From e7f03be37039dcd3be0e245834f05331df373c2d Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Thu, 25 Jun 2015 23:53:26 +0300 Subject: [PATCH] IDEA-69435 Search for Multi-line fragment Step 1: new UI for existing behavior & models --- .../src/com/intellij/util/IconUtil.java | 32 ++- .../src/com/intellij/find/FindModel.java | 17 ++ .../intellij/find/EditorSearchComponent.java | 231 +++++++++++------- .../editorHeaderActions/FindAllAction.java | 12 +- .../ShowHistoryAction.java | 10 +- .../VariantsCompletionAction.java | 2 +- .../ide/ui/laf/darcula/DarculaUIUtil.java | 17 +- .../src/messages/ApplicationBundle.properties | 3 + .../util/src/com/intellij/util/ui/UIUtil.java | 16 +- 9 files changed, 233 insertions(+), 107 deletions(-) diff --git a/platform/core-api/src/com/intellij/util/IconUtil.java b/platform/core-api/src/com/intellij/util/IconUtil.java index 88a964c3e3f9..91f290593808 100644 --- a/platform/core-api/src/com/intellij/util/IconUtil.java +++ b/platform/core-api/src/com/intellij/util/IconUtil.java @@ -29,11 +29,10 @@ import com.intellij.openapi.vfs.VFileProperty; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.WritingAccessProvider; import com.intellij.ui.IconDeferrer; +import com.intellij.ui.JBColor; import com.intellij.ui.LayeredIcon; import com.intellij.ui.RowIcon; -import com.intellij.util.ui.EmptyIcon; -import com.intellij.util.ui.JBImageIcon; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.ui.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -464,4 +463,31 @@ public class IconUtil { } }; } + + @NotNull + public static Icon textToIcon(final String text, final Component component, final float fontSize) { + final Font font = JBFont.create(JBUI.Fonts.label().deriveFont(fontSize)); + FontMetrics metrics = component.getFontMetrics(font); + final int width = metrics.stringWidth(text) + JBUI.scale(4); + final int height = metrics.getHeight(); + + return new Icon() { + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + GraphicsUtil.setupAntialiasing(g); + g.setFont(font); + UIUtil.drawStringWithHighlighting(g, text, x + JBUI.scale(2), y + height - JBUI.scale(1), JBColor.foreground(), JBColor.background()); + } + + @Override + public int getIconWidth() { + return width; + } + + @Override + public int getIconHeight() { + return height; + } + }; + } } diff --git a/platform/indexing-api/src/com/intellij/find/FindModel.java b/platform/indexing-api/src/com/intellij/find/FindModel.java index 3467ebb060e1..dd9310feb3b8 100644 --- a/platform/indexing-api/src/com/intellij/find/FindModel.java +++ b/platform/indexing-api/src/com/intellij/find/FindModel.java @@ -24,6 +24,7 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -945,4 +946,20 @@ public class FindModel extends UserDataHolderBase implements Cloneable { return pattern; } + + public String getStateDescription() { + ArrayList state = new ArrayList(); + if (isCaseSensitive()) state.add("Match Case"); + if (isRegularExpressions()) state.add("Regex"); + if (isWholeWordsOnly()) state.add("Words"); + if (isInCommentsOnly()) state.add("In Comments Only"); + if (isInStringLiteralsOnly()) state.add("In Literals Only"); + if (isExceptComments()) state.add("Except Comments"); + if (isExceptStringLiterals()) state.add("Except Literals"); + if (isExceptCommentsAndStringLiterals()) state.add("Except Comments and Literals"); + if (isPreserveCase()) state.add("Preserve Case"); + if (!isGlobal()) state.add("In Selection"); + String join = StringUtil.join(state, ", "); + return join.isEmpty()? "" : "(" + join+")"; + } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index 88b6124165f2..3f0feb1801c5 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -22,9 +22,13 @@ import com.intellij.find.impl.livePreview.LivePreviewController; import com.intellij.find.impl.livePreview.SearchResults; import com.intellij.icons.AllIcons; import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.laf.darcula.DarculaUIUtil; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.CustomComponentAction; +import com.intellij.openapi.actionSystem.impl.ActionButton; import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl; +import com.intellij.openapi.actionSystem.impl.InplaceActionButtonLook; +import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.event.SelectionEvent; @@ -36,10 +40,7 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.JBSplitter; -import com.intellij.ui.LightColors; -import com.intellij.ui.SearchTextField; +import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.components.labels.LinkLabel; @@ -48,6 +49,7 @@ import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.speedSearch.SpeedSearchSupply; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -58,6 +60,8 @@ import javax.swing.event.DocumentListener; import javax.swing.text.JTextComponent; import java.awt.*; import java.awt.event.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.Arrays; import java.util.regex.Pattern; @@ -70,6 +74,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data private LinkLabel myClickToHighlightLabel; private final Project myProject; private ActionToolbar myActionsToolbar; + private JLabel myStateLabel; @NotNull public Editor getEditor() { @@ -132,7 +137,6 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data private JButton myReplaceAllButton; private JButton myExcludeButton; - public static final Color COMPLETION_BACKGROUND_COLOR = new Color(235, 244, 254); private static final Color FOCUS_CATCHER_COLOR = new Color(0x9999ff); private JComponent myToolbarComponent; @@ -196,29 +200,21 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data updateUIWithEmptyResults(); } else { int count = sr.getMatchesCount(); - if (count <= mySearchResults.getMatchesLimit()) { - myClickToHighlightLabel.setVisible(false); - + boolean notTooMuch = count <= mySearchResults.getMatchesLimit(); + myMatchInfoLabel.setText(notTooMuch + ? ApplicationBundle.message("editorsearch.matches", count) + : ApplicationBundle.message("editorsearch.toomuch", mySearchResults.getMatchesLimit())); + myClickToHighlightLabel.setVisible(!notTooMuch); + if (notTooMuch) { if (count > 0) { setRegularBackground(); - if (count > 1) { - myMatchInfoLabel.setText(count + " matches"); - } - else { - myMatchInfoLabel.setText("1 match"); - } } else { setNotFoundBackground(); - myMatchInfoLabel.setText("No matches "); - boldMatchInfo(); } } else { setRegularBackground(); - myMatchInfoLabel.setText("More than " + mySearchResults.getMatchesLimit() + " matches"); - myClickToHighlightLabel.setVisible(true); - boldMatchInfo(); } } @@ -271,11 +267,12 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data } private void configureLeadPanel() { - JPanel myLeadPanel = createLeadPane(); + final int oldCaretPosition = mySearchField != null ? mySearchField.getCaretPosition() : 0; + JPanel myLeadPanel = new NonOpaquePanel(new BorderLayout()); myRightComponent.add(myLeadPanel, BorderLayout.WEST); Ref ref = Ref.create(); - mySearchField = createTextField(BorderLayout.NORTH, ref); + mySearchField = createTextField(BorderLayout.NORTH, ref, true); mySearchRootComponent = ref.get(); SearchTextField searchTextField = (ref.get() instanceof SearchTextField) ? (SearchTextField)ref.get() : null; @@ -332,6 +329,15 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data } }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, SystemInfo.isMac ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK), JComponent.WHEN_FOCUSED); + if (mySearchField instanceof JTextField) { + mySearchField.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent e) { + myFindModel.setMultiline(true); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.ALT_DOWN_MASK), JComponent.WHEN_FOCUSED); + + } final String initialText = myFindModel.getStringToFind(); @@ -339,6 +345,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data @Override public void run() { setInitialText(initialText); + mySearchField.setCaretPosition(oldCaretPosition); } }); @@ -355,7 +362,6 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data private void initToolbar() { DefaultActionGroup actionGroup = new DefaultActionGroup("search bar", false); - actionGroup.add(new ShowHistoryAction(mySearchFieldGetter, this)); actionGroup.add(new PrevOccurrenceAction(this, mySearchFieldGetter)); actionGroup.add(new NextOccurrenceAction(this, mySearchFieldGetter)); actionGroup.add(new AddOccurrenceAction(this)); @@ -363,10 +369,17 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data actionGroup.add(new SelectAllAction(this)); actionGroup.add(new FindAllAction(this)); actionGroup.add(new ToggleMultiline(this)); - actionGroup.add(new ToggleMatchCase(this)); - actionGroup.add(new ToggleRegex(this)); - myMatchInfoLabel = new JLabel(); + myMatchInfoLabel = new JLabel() { + @Override + public Font getFont() { + Font font = super.getFont(); + return font != null ? font.deriveFont(Font.BOLD) : null; + } + + }; + myStateLabel = new JLabel("", SwingConstants.RIGHT); + myClickToHighlightLabel = new LinkLabel("Click to highlight", null, new LinkListener() { @Override @@ -380,7 +393,11 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data myActionsToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, actionGroup, true); myActionsToolbar.setSecondaryActionsTooltip("More Options(" + ShowMoreOptions.SHORT_CUT + ")"); - actionGroup.addAction(new ToggleWholeWordsOnlyAction(this)); + actionGroup.addAction(new ToggleMatchCase(this)).setAsSecondary(true); + actionGroup.addAction(new ToggleRegex(this)).setAsSecondary(true); + actionGroup.addAction(new ToggleWholeWordsOnlyAction(this)).setAsSecondary(true); + + actionGroup.addAction(new Separator()).setAsSecondary(true); actionGroup.addAction(new ToggleInCommentsAction(this)).setAsSecondary(true); actionGroup.addAction(new ToggleInLiteralsOnlyAction(this)).setAsSecondary(true); @@ -388,8 +405,10 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data actionGroup.addAction(new ToggleExceptLiteralsAction(this)).setAsSecondary(true); actionGroup.addAction(new ToggleExceptCommentsAndLiteralsAction(this)).setAsSecondary(true); - actionGroup.addAction(new TogglePreserveCaseAction(this)); - actionGroup.addAction(new ToggleSelectionOnlyAction(this)); + actionGroup.addAction(new Separator()).setAsSecondary(true); + + actionGroup.addAction(new TogglePreserveCaseAction(this)).setAsSecondary(true); + actionGroup.addAction(new ToggleSelectionOnlyAction(this)).setAsSecondary(true); class MyCustomComponentDoNothingAction extends AnAction implements CustomComponentAction { private final JComponent c; @@ -408,8 +427,10 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data return c; } } + actionGroup.add(new MyCustomComponentDoNothingAction(myMatchInfoLabel)); actionGroup.add(new MyCustomComponentDoNothingAction(myClickToHighlightLabel)); + actionGroup.add(new MyCustomComponentDoNothingAction(myStateLabel)); myActionsToolbar.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY); myToolbarComponent = myActionsToolbar.getComponent(); @@ -451,12 +472,12 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data nothingToSearchFor(); } if (mySearchField instanceof JTextArea) { - adjustRows((JTextArea)mySearchField, 2, 6); + adjustRows((JTextArea)mySearchField); } } - private static void adjustRows(JTextArea area, int minRows, int maxRows) { - area.setRows(Math.max(minRows, Math.min(maxRows, area.getText().split("\n").length))); + private static void adjustRows(JTextArea area) { + area.setRows(Math.max(2, Math.min(3, StringUtil.countChars(area.getText(),'\n')+1))); } @@ -505,6 +526,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data } myLivePreviewController.setTrackingSelection(!myFindModel.isGlobal()); + myStateLabel.setText(myFindModel.getStateDescription()); if (myFindModel.isReplaceState() && myReplacementPane == null) { configureReplacementPane(); @@ -548,7 +570,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data myReplacementPane = new NonOpaquePanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); Ref ref = Ref.create(); - myReplaceField = createTextField(BorderLayout.SOUTH, ref); + myReplaceField = createTextField(BorderLayout.SOUTH, ref, false); myReplaceRootComponent = ref.get(); SearchTextField searchTextField = ref.get() instanceof SearchTextField ? (SearchTextField)ref.get() : null; @@ -618,17 +640,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data myExcludeButton.setMnemonic('l'); } - - ActionGroup actionsGroup = new DefaultActionGroup(new ShowHistoryAction(myReplaceFieldGetter, this)); - final ActionToolbar tb = ActionManager.getInstance().createActionToolbar("ReplaceBar", actionsGroup, true); - tb.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY); - final JComponent tbComponent = tb.getComponent(); - tbComponent.setOpaque(false); - tbComponent.setBorder(null); - myReplacementPane.add(tbComponent); - myReplacementPane.add(myReplaceButton); - myReplacementPane.add(myReplaceAllButton); myReplacementPane.add(myExcludeButton); @@ -646,7 +658,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data setMatchesLimit(LivePreviewController.MATCHES_LIMIT); myFindModel.setStringToReplace(myReplaceField.getText()); if (myReplaceField instanceof JTextArea) { - adjustRows((JTextArea)myReplaceField, 2, 6); + adjustRows((JTextArea)myReplaceField); } } @@ -670,9 +682,6 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data } } - private static JPanel createLeadPane() { - return new NonOpaquePanel(new BorderLayout()); - } public void showHistory(final boolean byClickingToolbarButton, JTextComponent textField) { FeatureUsageTracker.getInstance().triggerFeatureUsed("find.recent.search"); @@ -686,51 +695,25 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data toShowAd ? RestorePreviousSettingsAction.getAd() : null); } - private String gerRestoreFindModelAd() { - return "Use " + KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0) + " to restore your last search/replace settings"; - } - - private void paintBorderOfTextField(Graphics g) { - if (!(UIUtil.isUnderAquaLookAndFeel() || UIUtil.isUnderGTKLookAndFeel() || UIUtil.isUnderNimbusLookAndFeel()) && - isFocusOwner()) { - final Rectangle bounds = getBounds(); - g.setColor(FOCUS_CATCHER_COLOR); - g.drawRect(0, 0, bounds.width - 1, bounds.height - 1); - } - } - - private JTextComponent createTextField(Object constraint, Ref componentRef) { + private JTextComponent createTextField(Object constraint, Ref componentRef, boolean search) { final JTextComponent editorTextField; if (myFindModel.isMultiline()) { - editorTextField = new JTextArea("") { - @Override - protected void paintBorder(final Graphics g) { - super.paintBorder(g); - paintBorderOfTextField(g); - } - - @Override - public Dimension getPreferredSize() { - return super.getPreferredSize(); - } - }; + editorTextField = new JTextArea(); + componentRef.set(editorTextField); ((JTextArea)editorTextField).setColumns(25); - ((JTextArea)editorTextField).setRows(2); - final JScrollPane scrollPane = new JBScrollPane(editorTextField, - ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); - myLeftComponent.add(scrollPane, constraint); - componentRef.set(scrollPane); + ((JTextArea)editorTextField).setRows(3); + final SearchWrapper wrapper = new SearchWrapper(editorTextField, new ShowHistoryAction(search? mySearchFieldGetter : myReplaceFieldGetter, this)); + myLeftComponent.add(wrapper, constraint); } else { SearchTextField stf = new SearchTextField(true); + componentRef.set(stf); stf.setOpaque(false); editorTextField = stf.getTextEditor(); if (UIUtil.isUnderGTKLookAndFeel()) { editorTextField.setOpaque(false); } myLeftComponent.add(stf, constraint); - componentRef.set(stf); } editorTextField.setMinimumSize(new Dimension(200, -1)); editorTextField.putClientProperty("AuxEditorComponent", Boolean.TRUE); @@ -752,12 +735,15 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data public void setInitialText(final String initialText) { + boolean wasEmpty = getTextInField().isEmpty(); final String text = initialText != null ? initialText : ""; if (text.contains("\n")) { myFindModel.setMultiline(true); } setTextInField(text); - mySearchField.selectAll(); + if (wasEmpty) { + mySearchField.selectAll(); + } } private void requestFocus(Component c) { @@ -849,7 +835,6 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data } private void updateResults(final boolean allowedToChangedEditorSelection) { - myMatchInfoLabel.setFont(myMatchInfoLabel.getFont().deriveFont(Font.PLAIN)); final String text = myFindModel.getStringToFind(); if (text.length() == 0) { nothingToSearchFor(); @@ -862,10 +847,9 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data } catch (Exception e) { setNotFoundBackground(); - myMatchInfoLabel.setText("Incorrect regular expression"); - boldMatchInfo(); myClickToHighlightLabel.setVisible(false); mySearchResults.clear(); + myMatchInfoLabel.setText("Incorrect regular expression"); return; } } @@ -898,13 +882,6 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data myClickToHighlightLabel.setVisible(false); } - private void boldMatchInfo() { - Font font = myMatchInfoLabel.getFont(); - if (!font.isBold()) { - myMatchInfoLabel.setFont(font.deriveFont(Font.BOLD)); - } - } - private void setRegularBackground() { mySearchField.setBackground(myDefaultBackground); } @@ -952,4 +929,78 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data UIUtil.resetUndoRedoActions(mySearchField); UIUtil.resetUndoRedoActions(myReplaceField); } + + private static class SearchWrapper extends NonOpaquePanel implements PropertyChangeListener, FocusListener{ + private final JComponent myToWrap; + + public SearchWrapper(JComponent toWrap, AnAction showHistoryAction) { + myToWrap = toWrap; + setBorder(JBUI.Borders.empty(6, 6, 6, 8)); + setLayout(new BorderLayout(JBUI.scale(4), 0)); + myToWrap.addPropertyChangeListener("background", this); + myToWrap.addFocusListener(this); + myToWrap.setBorder(null); + myToWrap.setOpaque(false); + JBScrollPane scrollPane = new JBScrollPane(myToWrap, + ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane.getVerticalScrollBar().setBackground(UIUtil.TRANSPARENT_COLOR); + scrollPane.getViewport().setBorder(null); + scrollPane.getViewport().setOpaque(false); + scrollPane.setBorder(JBUI.Borders.empty(0, 0, 0, 2)); + scrollPane.setOpaque(false); + ActionButton button = + new ActionButton(showHistoryAction, showHistoryAction.getTemplatePresentation(), ActionPlaces.UNKNOWN, new Dimension(JBUI.scale(16), JBUI.scale(16))); + button.setLook(new InplaceActionButtonLook()); + JPanel p = new NonOpaquePanel(new BorderLayout()); + p.add(button, BorderLayout.NORTH); + add(p, BorderLayout.WEST); + add(scrollPane, BorderLayout.CENTER); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + repaint(); + } + + @Override + public void focusGained(FocusEvent e) { + repaint(); + } + + @Override + public void focusLost(FocusEvent e) { + repaint(); + } + + @Override + public void paint(Graphics graphics) { + Graphics2D g = (Graphics2D)graphics.create(); + try { + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); + Rectangle r = new Rectangle(getSize()); + r.x += JBUI.scale(4); + r.y += JBUI.scale(3); + r.width -= JBUI.scale(9); + r.height -= JBUI.scale(6); + int arcSize = Math.min(25, r.height - 1) - 6; + g.setColor(myToWrap.getBackground()); + boolean hasFocus = myToWrap.hasFocus(); + g.fillRoundRect(r.x, r.y + 1, r.width, r.height - 2, arcSize, arcSize); + g.setColor(myToWrap.isEnabled() ? Gray._100 : Gray._83); + + if (hasFocus) { + DarculaUIUtil.paintSearchFocusRing(g, r, arcSize + 6); + } + else { + g.drawRoundRect(r.x, r.y, r.width, r.height - 1, arcSize, arcSize); + } + } + finally { + g.dispose(); + } + super.paint(graphics); + } + } } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/FindAllAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/FindAllAction.java index f3412f079423..0e1a591f6637 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/FindAllAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/FindAllAction.java @@ -29,6 +29,11 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; +import com.intellij.ui.LayeredIcon; +import com.intellij.util.IconUtil; +import com.intellij.util.ui.JBUI; + +import javax.swing.*; /** * Created by IntelliJ IDEA. @@ -40,7 +45,12 @@ import com.intellij.psi.PsiDocumentManager; public class FindAllAction extends EditorHeaderAction implements DumbAware { public FindAllAction(EditorSearchComponent editorSearchComponent) { super(editorSearchComponent); - getTemplatePresentation().setIcon(AllIcons.Actions.Export); + Icon base = AllIcons.Actions.Find; + Icon text = IconUtil.textToIcon("ALL", editorSearchComponent, JBUI.scale(6F)); + LayeredIcon icon = new LayeredIcon(2); + icon.setIcon(base, 0); + icon.setIcon(text, 1, 0, base.getIconHeight() - text.getIconHeight()); + getTemplatePresentation().setIcon(icon); getTemplatePresentation().setDescription("Export matches to Find tool window"); getTemplatePresentation().setText("Find All"); final AnAction findUsages = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES); diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ShowHistoryAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ShowHistoryAction.java index b8b240d3d4e2..362fa5ebd859 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ShowHistoryAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ShowHistoryAction.java @@ -1,15 +1,17 @@ package com.intellij.find.editorHeaderActions; import com.intellij.find.EditorSearchComponent; -import com.intellij.icons.AllIcons; +import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.util.Getter; +import com.intellij.openapi.util.IconLoader; import com.intellij.util.containers.ContainerUtil; import javax.swing.*; import javax.swing.text.JTextComponent; -import java.awt.event.*; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.util.ArrayList; /** @@ -29,7 +31,7 @@ public class ShowHistoryAction extends EditorHeaderAction implements DumbAware { public ShowHistoryAction(final Getter textField, EditorSearchComponent editorSearchComponent) { super(editorSearchComponent); myTextField = textField; - getTemplatePresentation().setIcon(AllIcons.Actions.Search); + getTemplatePresentation().setIcon(IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/search.png", DarculaTextFieldUI.class, true)); final String s = getTextField() == getEditorSearchComponent().getSearchField() ? "Search" : "Replace"; getTemplatePresentation().setDescription(s + " history"); getTemplatePresentation().setText(s + " History"); @@ -51,7 +53,7 @@ public class ShowHistoryAction extends EditorHeaderAction implements DumbAware { @Override public void actionPerformed(final AnActionEvent e) { - getEditorSearchComponent().showHistory(e.getInputEvent() instanceof MouseEvent, getTextField()); + getEditorSearchComponent().showHistory(false, getTextField()); } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/VariantsCompletionAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/VariantsCompletionAction.java index c29720b6ca58..56ef585040e9 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/VariantsCompletionAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/VariantsCompletionAction.java @@ -80,7 +80,7 @@ public class VariantsCompletionAction extends AnAction { super.paintComponent(g); } }; - list.setBackground(new JBColor(EditorSearchComponent.COMPLETION_BACKGROUND_COLOR, new Color(0x4C4F51))); + list.setBackground(new JBColor(new Color(235, 244, 254), new Color(0x4C4F51))); list.setFont(editor.getColorsScheme().getFont(EditorFontType.PLAIN)); Utils.showCompletionPopup( diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaUIUtil.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaUIUtil.java index 86575cc438a0..19db0f8d1dd7 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaUIUtil.java @@ -41,6 +41,9 @@ public class DarculaUIUtil { } public static void paintSearchFocusRing(Graphics2D g, Rectangle bounds) { + paintSearchFocusRing(g, bounds, -1); + } + public static void paintSearchFocusRing(Graphics2D g, Rectangle bounds, int maxArcSize) { int correction = UIUtil.isUnderAquaLookAndFeel() ? 30 : UIUtil.isUnderDarcula() ? 50 : 0; final Color[] colors = new Color[]{ ColorUtil.toAlpha(getGlow(), 180 - correction), @@ -58,22 +61,26 @@ public class DarculaUIUtil { final Rectangle r = new Rectangle(bounds.x - 3, bounds.y - 3, bounds.width + 6, bounds.height + 6); + int arcSize = r.height - 1; + if (maxArcSize>0) arcSize = Math.min(maxArcSize, arcSize); + if (arcSize %2 == 1) arcSize--; + g.setColor(colors[0]); - g.drawRoundRect(r.x + 2, r.y + 2, r.width - 5, r.height - 5, r.height - 5, r.height - 5); + g.drawRoundRect(r.x + 2, r.y + 2, r.width - 5, r.height - 5, arcSize-4, arcSize-4); g.setColor(colors[1]); - g.drawRoundRect(r.x + 1, r.y + 1, r.width - 3, r.height - 3, r.height - 3, r.height - 3); + g.drawRoundRect(r.x + 1, r.y + 1, r.width - 3, r.height - 3, arcSize-2, arcSize-2); g.setColor(colors[2]); - g.drawRoundRect(r.x, r.y, r.width - 1, r.height - 1, r.height - 1, r.height - 1); + g.drawRoundRect(r.x, r.y, r.width - 1, r.height - 1, arcSize, arcSize); g.setColor(colors[3]); - g.drawRoundRect(r.x+3, r.y+3, r.width - 7, r.height - 7, r.height - 7, r.height - 7); + g.drawRoundRect(r.x+3, r.y+3, r.width - 7, r.height - 7, arcSize-6, arcSize-6); g.setColor(colors[4]); - g.drawRoundRect(r.x+4, r.y+4, r.width - 9, r.height - 9, r.height - 9, r.height - 9); + g.drawRoundRect(r.x+4, r.y+4, r.width - 9, r.height - 9, arcSize-8, arcSize-8); // restore rendering hints g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAntialiasingValue); diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 7ee78bcc5737..bd6fdca56f44 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -700,3 +700,6 @@ code.style.detector.use.tabs=Indent with tab code.style.indents.detector.show.settings=Show Settings code.style.indents.detector.accept=OK + +editorsearch.matches={0, choice, 0#No matches|1#One match|2#{0} matches} +editorsearch.toomuch=More than {0} matches diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 4ff75567cc20..839870366758 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -1982,9 +1982,10 @@ public class UIUtil { public static void drawStringWithHighlighting(Graphics g, String s, int x, int y, Color foreground, Color highlighting) { g.setColor(highlighting); - for (int i = x - 1; i <= x + 1; i++) { - for (int j = y - 1; j <= y + 1; j++) { - g.drawString(s, i, j); + boolean isRetina = isRetina(); + for (float i = x - 1; i <= x + 1; i += isRetina ? .5 : 1) { + for (float j = y - 1; j <= y + 1; j += isRetina ? .5 : 1) { + ((Graphics2D)g).drawString(s, i, j); } } g.setColor(foreground); @@ -3393,4 +3394,13 @@ public class UIUtil { } return false; } + + public static void setColumns(JTextComponent textComponent, int columns) { + if (textComponent instanceof JTextField) { + ((JTextField)textComponent).setColumns(columns); + } + if (textComponent instanceof JTextArea) { + ((JTextArea)textComponent).setColumns(columns); + } + } }