// Copyright (c) 2006 - 2008, Markus Strauch. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF // THE POSSIBILITY OF SUCH DAMAGE. package net.sf.sdedit.ui.impl; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import javax.swing.JTextField; import javax.swing.SwingUtilities; import net.sf.sdedit.ui.components.TextArea; public class FilterCommandField extends JTextField implements ActionListener, KeyListener, Runnable { private UserInterfaceImpl ui; private ArrayList<String> history; private int historyPointer; private String currentText; private String homeDir; private boolean first; private Process process; private String text; private boolean selection; private TextArea textArea; private Tab tab; public FilterCommandField(UserInterfaceImpl ui) { this.ui = ui; addActionListener(this); addKeyListener(this); history = new ArrayList<String>(); historyPointer = 0; currentText = null; homeDir = System.getProperty("user.home"); first = true; } public void reset() { currentText = null; if (first) { setText("<enter filter command>"); selectAll(); first = false; } else { setText(""); } historyPointer = history.size(); } private void execute(String command) throws IOException { history.add(command); if (homeDir != null && !homeDir.equals("")) { command = command.replaceAll("~", homeDir); } selection = true; tab = ui.currentTab(); if (tab == null) { return; } textArea = tab.getTextArea(); text = tab.getTextArea().getSelectedText(); if (text == null) { selection = false; text = tab.getTextArea().getText(); } synchronized (this) { process = Runtime.getRuntime().exec(command); changeBackground(Color.RED); } new Thread(this).start(); } public void run() { try { BufferedReader reader = new BufferedReader(new InputStreamReader( process.getInputStream())); BufferedReader errorReader = new BufferedReader( new InputStreamReader(process.getErrorStream())); OutputStreamWriter osw = new OutputStreamWriter( new BufferedOutputStream(process.getOutputStream())); PrintWriter writer = new PrintWriter(osw); writer.print(text); writer.flush(); writer.close(); StringBuffer output = new StringBuffer(); String line = reader.readLine(); while (line != null) { output.append(line + "\n"); line = reader.readLine(); } StringBuffer errors = new StringBuffer(); line = errorReader.readLine(); while (line != null) { errors.append(line + "\n"); line = errorReader.readLine(); } reader.close(); errorReader.close(); final String result = output.toString().trim(); String error = errors.toString().trim(); if (!error.equals("")) { ui.errorMessage("The filter command returned an error:\n" + error); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { if (selection) { textArea.replaceSelection(result); } else { textArea.setText(result); } } }); } } catch (IOException e) { synchronized (this) { if (process != null) { ui.errorMessage("An exception of type " + e.getClass().getSimpleName() + "has occured with the message:\n" + e.getMessage()); } // Ignore the exception that is thrown when the process is // destroyed and set to null. } } finally { synchronized (this) { process = null; changeBackground (Color.WHITE); } ui.leaveFilterMode(); } } private void changeBackground (final Color color) { SwingUtilities.invokeLater(new Runnable() { public void run () { setBackground(color); } }); } public void actionPerformed(ActionEvent e) { if (process != null) { return; } String command = getText().trim(); if (command.equals("")) { return; } try { execute(command); } catch (IOException ex) { ui.errorMessage("An exception of type " + ex.getClass().getSimpleName() + " has occured with the message:\n" + ex.getMessage()); } } private void useHistory(int direction) { if (historyPointer == history.size() && direction > 0) { return; } if (historyPointer == 0 && direction < 0) { return; } historyPointer += direction; if (historyPointer == history.size()) { setText(currentText); currentText = null; } else { if (currentText == null) { currentText = getText(); } setText(history.get(historyPointer)); } } public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { useHistory(-1); } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { useHistory(1); } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { synchronized (this) { if (process != null) { process.destroy(); process = null; } else { ui.leaveFilterMode(); } } } } public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) {} }