package krasa.grepconsole.grep.gui; import java.awt.*; import java.awt.event.*; import java.util.regex.PatternSyntaxException; import javax.swing.*; import krasa.grepconsole.grep.CopyListenerModel; import krasa.grepconsole.grep.OpenGrepConsoleAction; import krasa.grepconsole.grep.listener.GrepCopyingFilterListener; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.Nullable; import com.intellij.execution.impl.ConsoleViewImpl; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.ide.util.PropertiesComponent; import com.intellij.notification.*; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.ui.TextFieldWithStoredHistory; import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.content.Content; import com.intellij.util.ui.JBDimension; public class GrepPanel extends JPanel implements Disposable { public static final NotificationGroup GROUP_DISPLAY_ID_ERROR = new NotificationGroup("Grep Console error", NotificationDisplayType.BALLOON, false); @Nullable private ConsoleViewImpl originalConsole; private final ConsoleViewImpl newConsole; private final GrepCopyingFilterListener copyingListener; private final RunnerLayoutUi runnerLayoutUi; private MyTextFieldWithStoredHistory expressionTextField; private TextFieldWithStoredHistory unlessExpressionTextField; private JBCheckBox matchCase; private JButton applyButton; private JButton reloadButton; private JButton sourceButton; private JPanel rootComponent; private JBCheckBox wholeLine; private JBCheckBox regex; private JLabel expLabel; private JLabel unlessLabel; private JButton clearHistory; private OpenGrepConsoleAction.Callback applyCallback; public JPanel getRootComponent() { return rootComponent; } private void createUIComponents() { expressionTextField = new MyTextFieldWithStoredHistory("ConsoleQuickFilterPanel-expression"); expressionTextField.setHistorySize(50); // expression.setBorder(JBUI.Borders.empty()); expressionTextField.setMinimumAndPreferredWidth(300); unlessExpressionTextField = new TextFieldWithStoredHistory("ConsoleQuickFilterPanel-unlessExpression"); unlessExpressionTextField.setMinimumAndPreferredWidth(150); unlessExpressionTextField.setHistorySize(50); // this.unlessExpression.setBorder(JBUI.Borders.empty()); } public GrepPanel(final ConsoleViewImpl originalConsole, final ConsoleViewImpl newConsole, GrepCopyingFilterListener copyingListener, final String pattern, final RunnerLayoutUi runnerLayoutUi) { this.originalConsole = originalConsole; this.newConsole = newConsole; this.copyingListener = copyingListener; this.runnerLayoutUi = runnerLayoutUi; java.util.List<GrepOptionsItem> history = expressionTextField.reset(); if (!StringUtils.isEmpty(pattern)) { GrepOptionsItem selectedItem = null; for (GrepOptionsItem grepOptionsItem : history) { if (grepOptionsItem.getExpression().equals(pattern)) { selectedItem = grepOptionsItem; break; } } if (selectedItem == null) { selectedItem = new GrepOptionsItem().setExpression(pattern); } this.expressionTextField.setSelectedItem(selectedItem); } updateGrepOptions((GrepOptionsItem) expressionTextField.getSelectedItem()); expLabel.setLabelFor(expressionTextField); unlessLabel.setLabelFor(unlessExpressionTextField); actions(); buttons(); expressionTextField.addItemListener(new ItemChangeListener()); CopyListenerModel copyListenerModel = new CopyListenerModel(matchCase.isSelected(), wholeLine.isSelected(), regex.isSelected(), expressionTextField.getText(), unlessExpressionTextField.getText()); this.expressionTextField.addCurrentTextToHistory(copyListenerModel); } class ItemChangeListener implements ItemListener { @Override public void itemStateChanged(ItemEvent event) { if (event.getStateChange() == ItemEvent.SELECTED) { GrepOptionsItem item = (GrepOptionsItem) event.getItem(); updateGrepOptions(item); } } } protected void updateGrepOptions(GrepOptionsItem selectedItem) { if (selectedItem != null) { wholeLine.setSelected(selectedItem.isWholeLine()); regex.setSelected(selectedItem.isRegex()); matchCase.setSelected(selectedItem.isCaseSensitive()); } } protected void actions() { KeyAdapter reload = new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { final int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_ENTER && e.isAltDown()) { reloadButton.doClick(); } else if (keyCode == KeyEvent.VK_ENTER) { applyButton.doClick(); } } }; expressionTextField.addKeyboardListener(reload); unlessExpressionTextField.addKeyboardListener(reload); } protected void buttons() { applyButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { apply(); } }); reloadButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { reload(); } }); clearHistory.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { expressionTextField.clearHistory(); PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(); propertiesComponent.unsetValue("ConsoleQuickFilterPanel-unlessExpression"); unlessExpressionTextField.reset(); } }); sourceButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Content[] contents = runnerLayoutUi.getContents(); for (Content content : contents) { JComponent component = content.getComponent(); if (component == originalConsole) { runnerLayoutUi.selectAndFocus(content, true, true); } else if (isChild(component, originalConsole)) { runnerLayoutUi.selectAndFocus(content, true, true); } } } private boolean isChild(JComponent component, ConsoleViewImpl originalConsole) { return component.getComponentZOrder(originalConsole) != -1; } }); buttonSize(sourceButton); buttonSize(reloadButton); buttonSize(applyButton); buttonSize(clearHistory); } protected void reload() { apply(); newConsole.clear(); if (originalConsole != null) { Editor editor = originalConsole.getEditor(); Document document = editor.getDocument(); String text = document.getText(); for (String s : text.split("\n")) { copyingListener.process(s + "\n", ConsoleViewContentType.NORMAL_OUTPUT); } } } public void apply() { if (applyCallback != null) { CopyListenerModel copyListenerModel = new CopyListenerModel(matchCase.isSelected(), wholeLine.isSelected(), regex.isSelected(), expressionTextField.getText(), unlessExpressionTextField.getText()); try { applyCallback.apply(copyListenerModel); expressionTextField.addCurrentTextToHistory(copyListenerModel); unlessExpressionTextField.addCurrentTextToHistory(); } catch (PatternSyntaxException e) { final Notification notification = GROUP_DISPLAY_ID_ERROR.createNotification( "Grep: invalid regexp", NotificationType.WARNING); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { Notifications.Bus.notify(notification, newConsole.getProject()); } }); } } } private void buttonSize(JButton sourceButton) { Dimension oldSize = sourceButton.getPreferredSize(); JBDimension newSize = new JBDimension(oldSize.width, oldSize.height - 5); sourceButton.setPreferredSize(newSize); } @Override public void dispose() { originalConsole = null; applyButton.setEnabled(false); reloadButton.setEnabled(false); sourceButton.setEnabled(false); } public void setApplyCallback(OpenGrepConsoleAction.Callback applyCallback) { this.applyCallback = applyCallback; apply(); } }