+++ /dev/null
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * Jalview is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.gui;
-
-import org.jmol.api.*;
-
-import jalview.jbgui.GStructureViewer;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-import javax.swing.text.*;
-
-import java.util.Vector;
-
-import org.jmol.i18n.GT;
-import org.jmol.util.Logger;
-import org.jmol.util.CommandHistory;
-
-// TODO: this class is copied in from jmol 11.0.2 - upgrade to 12.0.2 ?
-public final class ScriptWindow extends JPanel implements ActionListener,
- EnterListener
-{
-
- private ConsoleTextPane console;
-
- private JButton closeButton;
-
- private JButton runButton;
-
- private JButton haltButton;
-
- private JButton clearButton;
-
- private JButton historyButton;
-
- private JButton stateButton;
-
- JmolViewer viewer;
-
- GStructureViewer appJmol;
-
- public ScriptWindow(AppJmol appJmol)
- {
- this.viewer = appJmol.jmb.viewer;
- this.appJmol = appJmol;
-
- setLayout(new BorderLayout());
-
- console = new ConsoleTextPane(this);
-
- console.setPrompt();
- add(new JScrollPane(console), BorderLayout.CENTER);
-
- JPanel buttonPanel = new JPanel();
- add(buttonPanel, BorderLayout.SOUTH);
-
- runButton = new JButton(GT._("Run"));
- haltButton = new JButton(GT._("Halt"));
- runButton.addActionListener(this);
- // buttonPanel.add(runButton);
- haltButton.addActionListener(this);
- // buttonPanel.add(haltButton);
- haltButton.setEnabled(false);
-
- clearButton = new JButton(GT._("Clear"));
- clearButton.addActionListener(this);
- buttonPanel.add(clearButton);
-
- historyButton = new JButton(GT._("History"));
- historyButton.addActionListener(this);
- buttonPanel.add(historyButton);
-
- stateButton = new JButton(GT._("State"));
- stateButton.addActionListener(this);
- buttonPanel.add(stateButton);
-
- closeButton = new JButton(GT._("Close"));
- closeButton.addActionListener(this);
- buttonPanel.add(closeButton);
-
- for (int i = 0; i < buttonPanel.getComponentCount(); i++)
- {
- // ((JButton)buttonPanel.getComponent(i))
- // .setMargin(new Insets(0, 0, 0, 0));
- }
-
- }
-
- public void sendConsoleEcho(String strEcho)
- {
- if (strEcho != null && !isError)
- {
-
- console.outputEcho(strEcho);
-
- }
- setError(false);
- }
-
- boolean isError = false;
-
- void setError(boolean TF)
- {
- isError = TF;
- // if (isError)
- // console.recallCommand(true);
- }
-
- public void sendConsoleMessage(String strStatus)
- {
- if (strStatus == null)
- {
- console.clearContent();
- console.outputStatus("");
- }
- else if (strStatus.indexOf("ERROR:") >= 0)
- {
- console.outputError(strStatus);
- isError = true;
- }
- else if (!isError)
- {
- console.outputStatus(strStatus);
- }
- }
-
- public void notifyScriptTermination(String strMsg, int msWalltime)
- {
- if (strMsg != null && strMsg.indexOf("ERROR") >= 0)
- {
- console.outputError(strMsg);
- }
- runButton.setEnabled(true);
- haltButton.setEnabled(false);
- }
-
- public void enterPressed()
- {
- runButton.doClick(100);
- // executeCommand();
- }
-
- class ExecuteCommandThread extends Thread
- {
-
- String strCommand;
-
- ExecuteCommandThread(String command)
- {
- strCommand = command;
- }
-
- public void run()
- {
- try
- {
- executeCommand(strCommand);
- } catch (Exception ie)
- {
- Logger.debug("execution command interrupted!" + ie);
- }
- }
- }
-
- ExecuteCommandThread execThread;
-
- void executeCommandAsThread()
- {
- String strCommand = console.getCommandString().trim();
- if (strCommand.length() > 0)
- {
- execThread = new ExecuteCommandThread(strCommand);
- execThread.start();
- }
- }
-
- void executeCommand(String strCommand)
- {
- boolean doWait;
- setError(false);
- console.appendNewline();
- console.setPrompt();
- if (strCommand.length() > 0)
- {
- String strErrorMessage = null;
- doWait = (strCommand.indexOf("WAIT ") == 0);
- if (doWait)
- { // for testing, mainly
- // demonstrates using the statusManager system.
- runButton.setEnabled(false);
- haltButton.setEnabled(true);
-
- Vector info = (Vector) viewer
- .scriptWaitStatus(strCommand.substring(5),
- "+fileLoaded,+scriptStarted,+scriptStatus,+scriptEcho,+scriptTerminated");
- runButton.setEnabled(true);
- haltButton.setEnabled(false);
- /*
- * info = [ statusRecortSet0, statusRecortSet1, statusRecortSet2, ...]
- * statusRecordSet = [ statusRecord0, statusRecord1, statusRecord2, ...]
- * statusRecord = [int msgPtr, String statusName, int intInfo, String
- * msg]
- */
- for (int i = 0; i < info.size(); i++)
- {
- Vector statusRecordSet = (Vector) info.get(i);
- for (int j = 0; j < statusRecordSet.size(); j++)
- {
- Vector statusRecord = (Vector) statusRecordSet.get(j);
- Logger.info("msg#=" + statusRecord.get(0) + " "
- + statusRecord.get(1) + " intInfo="
- + statusRecord.get(2) + " stringInfo="
- + statusRecord.get(3));
- }
- }
- console.appendNewline();
- }
- else
- {
- boolean isScriptExecuting = viewer.isScriptExecuting();
- if (viewer.checkHalt(strCommand, true))
- strErrorMessage = (isScriptExecuting ? "string execution halted with "
- + strCommand
- : "no script was executing");
- else
- strErrorMessage = "";// viewer.scriptCheck(strCommand);
- // the problem is that scriptCheck is synchronized, so these might get
- // backed up.
- if (strErrorMessage != null && strErrorMessage.length() > 0)
- {
- console.outputError(strErrorMessage);
- }
- else
- {
- // runButton.setEnabled(false);
- haltButton.setEnabled(true);
- viewer.script(strCommand);
- }
- }
- }
- console.grabFocus();
- }
-
- public void actionPerformed(ActionEvent e)
- {
- Object source = e.getSource();
- if (source == closeButton)
- {
- // appJmol.showConsole(false);
- }
- else if (source == runButton)
- {
- executeCommandAsThread();
- }
- else if (source == clearButton)
- {
- console.clearContent();
- }
- else if (source == historyButton)
- {
- console.clearContent(viewer.getSetHistory(Integer.MAX_VALUE));
- }
- else if (source == stateButton)
- {
- console.clearContent(viewer.getStateInfo());
- }
- else if (source == haltButton)
- {
- viewer.haltScriptExecution();
- }
- console.grabFocus(); // always grab the focus (e.g., after clear)
- }
-}
-
-class ConsoleTextPane extends JTextPane
-{
-
- ConsoleDocument consoleDoc;
-
- EnterListener enterListener;
-
- JmolViewer viewer;
-
- ConsoleTextPane(ScriptWindow scriptWindow)
- {
- super(new ConsoleDocument());
- consoleDoc = (ConsoleDocument) getDocument();
- consoleDoc.setConsoleTextPane(this);
- this.enterListener = (EnterListener) scriptWindow;
- this.viewer = scriptWindow.viewer;
- }
-
- public String getCommandString()
- {
- String cmd = consoleDoc.getCommandString();
- return cmd;
- }
-
- public void setPrompt()
- {
- consoleDoc.setPrompt();
- }
-
- public void appendNewline()
- {
- consoleDoc.appendNewline();
- }
-
- public void outputError(String strError)
- {
- consoleDoc.outputError(strError);
- }
-
- public void outputErrorForeground(String strError)
- {
- consoleDoc.outputErrorForeground(strError);
- }
-
- public void outputEcho(String strEcho)
- {
- consoleDoc.outputEcho(strEcho);
- }
-
- public void outputStatus(String strStatus)
- {
- consoleDoc.outputStatus(strStatus);
- }
-
- public void enterPressed()
- {
- if (enterListener != null)
- enterListener.enterPressed();
- }
-
- public void clearContent()
- {
- clearContent(null);
- }
-
- public void clearContent(String text)
- {
- consoleDoc.clearContent();
- if (text != null)
- consoleDoc.outputEcho(text);
- setPrompt();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.awt.Component#processKeyEvent(java.awt.event.KeyEvent)
- */
-
- /**
- * Custom key event processing for command 0 implementation.
- *
- * Captures key up and key down strokes to call command history and redefines
- * the same events with control down to allow caret vertical shift.
- *
- * @see java.awt.Component#processKeyEvent(java.awt.event.KeyEvent)
- */
- protected void processKeyEvent(KeyEvent ke)
- {
- // Id Control key is down, captures events does command
- // history recall and inhibits caret vertical shift.
- if (ke.getKeyCode() == KeyEvent.VK_UP
- && ke.getID() == KeyEvent.KEY_PRESSED && !ke.isControlDown())
- {
- recallCommand(true);
- }
- else if (ke.getKeyCode() == KeyEvent.VK_DOWN
- && ke.getID() == KeyEvent.KEY_PRESSED && !ke.isControlDown())
- {
- recallCommand(false);
- }
- // If Control key is down, redefines the event as if it
- // where a key up or key down stroke without modifiers.
- // This allows to move the caret up and down
- // with no command history recall.
- else if ((ke.getKeyCode() == KeyEvent.VK_DOWN || ke.getKeyCode() == KeyEvent.VK_UP)
- && ke.getID() == KeyEvent.KEY_PRESSED && ke.isControlDown())
- {
- super.processKeyEvent(new KeyEvent((Component) ke.getSource(), ke
- .getID(), ke.getWhen(), 0, // No modifiers
- ke.getKeyCode(), ke.getKeyChar(), ke.getKeyLocation()));
- }
- // Standard processing for other events.
- else
- {
- super.processKeyEvent(ke);
- // check command for compiler-identifyable syntax issues
- // this may have to be taken out if people start complaining
- // that only some of the commands are being checked
- // that is -- that the script itself is not being fully checked
-
- // not perfect -- help here?
- if (ke.getID() == KeyEvent.KEY_RELEASED
- && (ke.getKeyCode() > KeyEvent.VK_DOWN)
- || ke.getKeyCode() == KeyEvent.VK_BACK_SPACE)
- checkCommand();
- }
- }
-
- /**
- * Recall command history.
- *
- * @param up
- * - history up or down
- */
- void recallCommand(boolean up)
- {
- String cmd = viewer.getSetHistory(up ? -1 : 1);
- if (cmd == null)
- {
- return;
- }
- try
- {
- if (cmd.endsWith(CommandHistory.ERROR_FLAG))
- {
- cmd = cmd.substring(0, cmd.indexOf(CommandHistory.ERROR_FLAG));
- consoleDoc.replaceCommand(cmd, true);
- }
- else
- {
- consoleDoc.replaceCommand(cmd, false);
- }
- } catch (BadLocationException e)
- {
- e.printStackTrace();
- }
- }
-
- void checkCommand()
- {
- String strCommand = consoleDoc.getCommandString();
- if (strCommand.length() == 0)
- return;
- consoleDoc
- .colorCommand(viewer.scriptCheck(strCommand) == null ? consoleDoc.attUserInput
- : consoleDoc.attError);
- }
-
-}
-
-class ConsoleDocument extends DefaultStyledDocument
-{
-
- ConsoleTextPane consoleTextPane;
-
- SimpleAttributeSet attError;
-
- SimpleAttributeSet attEcho;
-
- SimpleAttributeSet attPrompt;
-
- SimpleAttributeSet attUserInput;
-
- SimpleAttributeSet attStatus;
-
- ConsoleDocument()
- {
- super();
-
- attError = new SimpleAttributeSet();
- StyleConstants.setForeground(attError, Color.red);
-
- attPrompt = new SimpleAttributeSet();
- StyleConstants.setForeground(attPrompt, Color.magenta);
-
- attUserInput = new SimpleAttributeSet();
- StyleConstants.setForeground(attUserInput, Color.black);
-
- attEcho = new SimpleAttributeSet();
- StyleConstants.setForeground(attEcho, Color.blue);
- StyleConstants.setBold(attEcho, true);
-
- attStatus = new SimpleAttributeSet();
- StyleConstants.setForeground(attStatus, Color.black);
- StyleConstants.setItalic(attStatus, true);
- }
-
- void setConsoleTextPane(ConsoleTextPane consoleTextPane)
- {
- this.consoleTextPane = consoleTextPane;
- }
-
- Position positionBeforePrompt; // starts at 0, so first time isn't tracked
-
- // (at least on Mac OS X)
-
- Position positionAfterPrompt; // immediately after $, so this will track
-
- int offsetAfterPrompt; // only still needed for the insertString override and
-
- // replaceCommand
-
- /**
- * Removes all content of the script window, and add a new prompt.
- */
- void clearContent()
- {
- try
- {
- super.remove(0, getLength());
- } catch (BadLocationException exception)
- {
- System.out.println("Could not clear script window content: "
- + exception.getMessage());
- }
- }
-
- void setPrompt()
- {
- try
- {
- super.insertString(getLength(), "$ ", attPrompt);
- setOffsetPositions();
- consoleTextPane.setCaretPosition(offsetAfterPrompt);
- } catch (BadLocationException e)
- {
- e.printStackTrace();
- }
- }
-
- void setOffsetPositions()
- {
- try
- {
- offsetAfterPrompt = getLength();
- positionBeforePrompt = createPosition(offsetAfterPrompt - 2);
- // after prompt should be immediately after $ otherwise tracks the end
- // of the line (and no command will be found) at least on Mac OS X it did.
- positionAfterPrompt = createPosition(offsetAfterPrompt - 1);
- } catch (BadLocationException e)
- {
- e.printStackTrace();
- }
- }
-
- void setNoPrompt()
- {
- try
- {
- offsetAfterPrompt = getLength();
- positionAfterPrompt = positionBeforePrompt = createPosition(offsetAfterPrompt);
- consoleTextPane.setCaretPosition(offsetAfterPrompt);
- } catch (BadLocationException e)
- {
- e.printStackTrace();
- }
- }
-
- // it looks like the positionBeforePrompt does not track when it started out
- // as 0
- // and a insertString at location 0 occurs. It may be better to track the
- // position after the prompt in stead
- void outputBeforePrompt(String str, SimpleAttributeSet attribute)
- {
- try
- {
- int pt = consoleTextPane.getCaretPosition();
- Position caretPosition = createPosition(pt);
- pt = positionBeforePrompt.getOffset();
- super.insertString(pt, str + "\n", attribute);
- setOffsetPositions();
- pt = caretPosition.getOffset();
- consoleTextPane.setCaretPosition(pt);
- } catch (BadLocationException e)
- {
- e.printStackTrace();
- }
- }
-
- void outputError(String strError)
- {
- outputBeforePrompt(strError, attError);
- }
-
- void outputErrorForeground(String strError)
- {
- try
- {
- super.insertString(getLength(), strError + "\n", attError);
- consoleTextPane.setCaretPosition(getLength());
- } catch (BadLocationException e)
- {
- e.printStackTrace();
-
- }
- }
-
- void outputEcho(String strEcho)
- {
- outputBeforePrompt(strEcho, attEcho);
- }
-
- void outputStatus(String strStatus)
- {
- outputBeforePrompt(strStatus, attStatus);
- }
-
- void appendNewline()
- {
- try
- {
- super.insertString(getLength(), "\n", attUserInput);
- consoleTextPane.setCaretPosition(getLength());
- } catch (BadLocationException e)
- {
- e.printStackTrace();
- }
- }
-
- // override the insertString to make sure everything typed ends up at the end
- // or in the 'command line' using the proper font, and the newline is
- // processed.
- public void insertString(int offs, String str, AttributeSet a)
- throws BadLocationException
- {
- int ichNewline = str.indexOf('\n');
- if (ichNewline > 0)
- str = str.substring(0, ichNewline);
- if (ichNewline != 0)
- {
- if (offs < offsetAfterPrompt)
- {
- offs = getLength();
- }
- super.insertString(offs, str, a == attError ? a : attUserInput);
- consoleTextPane.setCaretPosition(offs + str.length());
- }
- if (ichNewline >= 0)
- {
- consoleTextPane.enterPressed();
- }
- }
-
- String getCommandString()
- {
- String strCommand = "";
- try
- {
- int cmdStart = positionAfterPrompt.getOffset();
- strCommand = getText(cmdStart, getLength() - cmdStart);
- while (strCommand.length() > 0 && strCommand.charAt(0) == ' ')
- strCommand = strCommand.substring(1);
- } catch (BadLocationException e)
- {
- e.printStackTrace();
- }
- return strCommand;
- }
-
- public void remove(int offs, int len) throws BadLocationException
- {
- if (offs < offsetAfterPrompt)
- {
- len -= offsetAfterPrompt - offs;
- if (len <= 0)
- return;
- offs = offsetAfterPrompt;
- }
- super.remove(offs, len);
- // consoleTextPane.setCaretPosition(offs);
- }
-
- public void replace(int offs, int length, String str, AttributeSet attrs)
- throws BadLocationException
- {
- if (offs < offsetAfterPrompt)
- {
- if (offs + length < offsetAfterPrompt)
- {
- offs = getLength();
- length = 0;
- }
- else
- {
- length -= offsetAfterPrompt - offs;
- offs = offsetAfterPrompt;
- }
- }
- super.replace(offs, length, str, attrs);
- // consoleTextPane.setCaretPosition(offs + str.length());
- }
-
- /**
- * Replaces current command on script.
- *
- * @param newCommand
- * new command value
- * @param isError
- * true to set error color ends with #??
- *
- * @throws BadLocationException
- */
- void replaceCommand(String newCommand, boolean isError)
- throws BadLocationException
- {
- if (positionAfterPrompt == positionBeforePrompt)
- return;
- replace(offsetAfterPrompt, getLength() - offsetAfterPrompt, newCommand,
- isError ? attError : attUserInput);
- }
-
- void colorCommand(SimpleAttributeSet att)
- {
- if (positionAfterPrompt == positionBeforePrompt)
- return;
- setCharacterAttributes(offsetAfterPrompt, getLength()
- - offsetAfterPrompt, att, true);
- }
-}
-
-interface EnterListener
-{
- public void enterPressed();
-}