Bug 4840 fixed: The more there was text in the console, the slower was the display 35/2935/2
Calixte DENIZET [Mon, 17 Jan 2011 14:43:10 +0000 (15:43 +0100)]
Change-Id: I367631f01a702ccd3276e3c568d10a9601a51924

scilab/CHANGES_5.3.X
scilab/modules/console/src/java/org/scilab/modules/console/InterruptScilabWorkOrCopy.java
scilab/modules/console/src/java/org/scilab/modules/console/SciConsole.java
scilab/modules/console/src/java/org/scilab/modules/console/SciInputCommandView.java
scilab/modules/console/src/java/org/scilab/modules/console/SciOutputView.java
scilab/modules/console/src/java/org/scilab/modules/console/SelectAllAction.java
scilab/modules/console/tests/nonreg_tests/bug_4840.tst [new file with mode: 0644]
scilab/modules/gui/src/java/org/scilab/modules/gui/bridge/console/SwingScilabConsole.java

index f33df06..37c053e 100644 (file)
@@ -1,6 +1,14 @@
             Changes between version 5.3.0 and 5.3.1 of Scilab
             =================================================
 
+
+Console:
+========
+
+* Performance improvements on the display of long computation with a lot of
+  output (the more text in the console, the slower was the display). 
+  See bug #4840. 
+
 Removed functions (previously declared as obsolete):
 ====================================================
 
@@ -85,6 +93,7 @@ Localization:
 
 * bug 8096 fixed - With Russian localization, the banner was not centered.
 
+
 Graphics:
 =========
 
index db3a7af..73210c5 100644 (file)
@@ -16,6 +16,7 @@ import java.awt.datatransfer.StringSelection;
 import java.awt.event.ActionEvent;
 import java.awt.Toolkit;
 import javax.swing.JPanel;
+import javax.swing.JEditorPane;
 import javax.swing.JTextPane;
 
 import org.scilab.modules.action_binding.InterpreterManagement;
@@ -31,45 +32,45 @@ import com.artenum.rosetta.util.StringConstants;
  */
 public class InterruptScilabWorkOrCopy extends AbstractConsoleAction {
 
-       private static final long serialVersionUID = 1L;
+        private static final long serialVersionUID = 1L;
 
-       /**
-        * Constructor
-        */
-       public InterruptScilabWorkOrCopy() {
-               super();
+        /**
+         * Constructor
+         */
+        public InterruptScilabWorkOrCopy() {
+                super();
 
-       }
+        }
 
-       /**
-        * Threats the event
-        * @param e the action event that occured
-        * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
-        */
-       public void actionPerformed(ActionEvent e) {
+        /**
+         * Threats the event
+         * @param e the action event that occured
+         * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+         */
+        public void actionPerformed(ActionEvent e) {
 
-               if (((JTextPane) configuration.getInputCommandView()).getSelectedText() != null) {
-                       /* Text selected in the input --> Copy */
-                       StringSelection strSelected = new StringSelection(((JTextPane) configuration.getInputCommandView()).getSelectedText());
-                       Toolkit.getDefaultToolkit().getSystemClipboard().setContents(strSelected, null);
-               } else if (((JTextPane) configuration.getOutputView()).getSelectedText() != null) {
-                       /* Text selected in the output --> Copy */
-                       StringSelection strSelected = new StringSelection(((JTextPane) configuration.getOutputView()).getSelectedText());
-                       Toolkit.getDefaultToolkit().getSystemClipboard().setContents(strSelected, null);
-               } else {
-                       /* Interrupt Scilab */
-                       InterpreterManagement.interruptScilab();
+                if (((JTextPane) configuration.getInputCommandView()).getSelectedText() != null) {
+                        /* Text selected in the input --> Copy */
+                        StringSelection strSelected = new StringSelection(((JTextPane) configuration.getInputCommandView()).getSelectedText());
+                        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(strSelected, null);
+                } else if (((JEditorPane) configuration.getOutputView()).getSelectedText() != null) {
+                        /* Text selected in the output --> Copy */
+                        StringSelection strSelected = new StringSelection(((JEditorPane) configuration.getOutputView()).getSelectedText());
+                        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(strSelected, null);
+                } else {
+                        /* Interrupt Scilab */
+                        InterpreterManagement.interruptScilab();
 
-                       // If Scilab is on prompt, then emulate a user entry
-                       if (((JPanel) configuration.getPromptView()).isVisible()) {
-                               configuration.getOutputView().append(StringConstants.NEW_LINE);
-                               configuration.getOutputView().append(configuration.getPromptView().getDefaultPrompt());
-                               configuration.getOutputView().append(configuration.getInputParsingManager().getCommandLine());
-                               configuration.getOutputView().append(StringConstants.NEW_LINE);
-                               ((SciOutputView) configuration.getOutputView()).getConsole().sendCommandsToScilab("", false, false);
-                               configuration.getInputParsingManager().reset();
-                       }
-               }
-       }
+                        // If Scilab is on prompt, then emulate a user entry
+                        if (((JPanel) configuration.getPromptView()).isVisible()) {
+                                configuration.getOutputView().append(StringConstants.NEW_LINE);
+                                configuration.getOutputView().append(configuration.getPromptView().getDefaultPrompt());
+                                configuration.getOutputView().append(configuration.getInputParsingManager().getCommandLine());
+                                configuration.getOutputView().append(StringConstants.NEW_LINE);
+                                ((SciOutputView) configuration.getOutputView()).getConsole().sendCommandsToScilab("", false, false);
+                                configuration.getInputParsingManager().reset();
+                        }
+                }
+        }
 
 }
index 0255e81..3395bff 100644 (file)
@@ -26,10 +26,12 @@ import java.util.concurrent.Semaphore;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
+import javax.swing.JEditorPane;
 import javax.swing.JTextPane;
+import javax.swing.JViewport;
 import javax.swing.SwingUtilities;
 import javax.swing.text.BadLocationException;
-import javax.swing.text.StyledDocument;
+import javax.swing.text.Document;
 import javax.swing.KeyStroke;
 import javax.xml.parsers.ParserConfigurationException;
 import org.scilab.modules.localization.Messages;
@@ -52,530 +54,530 @@ import com.artenum.rosetta.util.StringConstants;
  */
 public abstract class SciConsole extends JPanel {
 
-       private static final long serialVersionUID = 1L;
-
-       private static final int LINE_NUMBER_IN_PROMPT = 2;
-
-       private static final String BACKSLASH_R = "\r";
-
-       /**
-        * Maximum length of a command send to Scilab
-        */
-       private static final int MAX_CMD_LENGTH = 512;
-
-       /**
-        * Configuration associated to the console oject
-        */
-       private ConsoleConfiguration config;
-
-       /**
-        * Scroll Pane used in Scilab Console
-        */
-       private JScrollPane jSP;
-
-       /**
-        * Generic console object
-        */
-       private Console sciConsole;
-
-       /**
-        * Flag indicating if the input command vieaw size has been forced to a value by a call to toHome
-        */
-       private boolean inputCommandViewSizeForced;
-
-       /**
-        * Value used to get one char from user input (when using [more y or n ?])
-        */
-       private int userInputValue;
-
-       /**
-        * Protection for userInputValue variable R/W
-        */
-       private Semaphore canReadUserInputValue = new Semaphore(1);
-
-       /**
-        * Boolean flag used to store the state of Scilab (true is all works done)
-        */
-       private boolean workDone;
-
-       /**
-        * Constructor
-        * @param configFilePath the configuration file to use
-        */
-       public SciConsole(String configFilePath) {
-               super(new BorderLayout());
-
-               try {
-                       config = ConfigurationBuilder.buildConfiguration(configFilePath);
-                       config.setActiveProfile("scilab");
-                       if (System.getProperty("os.name").toLowerCase().indexOf("mac") != -1)
-                               {
-                                       ConsoleConfiguration configMac = ConfigurationBuilder.buildConfiguration(configFilePath);;
-                                       configMac.setActiveProfile("macosx");
-                                       for (KeyStroke key : config.getKeyMapping().keys()){
-                                               config.getKeyMapping().put(key,"");
-                                       }
-                                       for (KeyStroke key : configMac.getKeyMapping().keys()){
-                                               config.getKeyMapping().put(key, configMac.getKeyMapping().get(key));
-                                       }
-                               }
-               } catch (IllegalArgumentException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
-               } catch (SAXException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
-               } catch (IOException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
-               } catch (ParserConfigurationException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
-               }
-
-               sciConsole = ConsoleBuilder.buildConsole(config, this);
-               jSP = new JScrollPane(sciConsole);
-
-               this.add(jSP, BorderLayout.CENTER);
-
-               // The console is given to the outputView so that updateScrollPosition is is accessible
-               ((SciOutputView) config.getOutputView()).setConsole(this);
-
-               // The console is given to the outputView so that Drag&Drop can work
-               ((SciInputCommandView) config.getInputCommandView()).setConsole(this);
-
-               // The console is given to the CompletionWindow
-               ((SciCompletionWindow) config.getCompletionWindow()).setConsole(this);
-               ((SciCompletionWindow) config.getCompletionWindow()).setGraphicalContext(this);
-
-               // The promptview is given to the Parsing Manager
-               // Used to get the position of the CompletionWindow
-               ((SciInputParsingManager) config.getInputParsingManager()).setPromptView(this.getConfiguration().getPromptView());
-
-               // Reset history settings - bug 3612
-               ((SciHistoryManager)config.getHistoryManager()).setInHistory(false);
-
-               // Bug 8055 : update the lines/columns only when the console is resized
-               addComponentListener(new ComponentAdapter() {
-                               public void componentResized(ComponentEvent evt) {
-                                       scilabLinesUpdate();
-                                       jSP.getVerticalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().height);
-                                       jSP.getHorizontalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().width);
-                               }
-                       });
-       }
-
-       /**
-        * Gets the configuration associated to the console
-        * @return the configuration
-        */
-       public ConsoleConfiguration getConfiguration() {
-               return config;
-       }
-
-       /**
-        * Sets the configuration associated to the console
-        * @param newConfig the new config to set
-        */
-       public void setConfiguration(ConsoleConfiguration newConfig) {
-               config = newConfig;
-       }
-
-       /**
-        * Updates Scilab internal variables containing the size of the console
-        * These variables are used to format data before displaying it
-        */
-       public void scilabLinesUpdate() {
-               // Size of the console
-               int outputViewWidth = jSP.getWidth();
-
-               // Size of a char
-               OutputView outputView = this.getConfiguration().getOutputView();
-               int[] charsWidth = ((JTextPane) outputView).getFontMetrics(((JTextPane) outputView).getFont()).getWidths();
-
-               // This loop is not needed for monospaced fonts !
-               int maxCharWidth = charsWidth[33];
-                // The range 33--126 corresponds to the usual characters in ASCII
-               for (int i = 34; i < 126; i++) {
-                       if (charsWidth[i] > maxCharWidth) {
-                               maxCharWidth = charsWidth[i];
-                       }
-               }
-
-               int numberOfLines = getNumberOfLines();
-               int promptWidth = ((JPanel) this.getConfiguration().getPromptView()).getPreferredSize().width;
-
-               int numberOfColumns = (outputViewWidth - promptWidth) / maxCharWidth - 1;
-               /* -1 because of the margin between text prompt and command line text */
-
-               GuiManagement.setScilabLines(numberOfLines, numberOfColumns);
-       }
-
-       /**
-        * Get the number of lines that can be displayed in the visible part of the console
-        * @return the number of lines
-        */
-       public int getNumberOfLines() {
-               // Size of the console
-               int outputViewHeight = jSP.getHeight();
-
-               // Size of a char
-               OutputView outputView = this.getConfiguration().getOutputView();
-               int charHeight = ((JTextPane) outputView).getFontMetrics(((JTextPane) outputView).getFont()).getHeight();
-               int[] charsWidth = ((JTextPane) outputView).getFontMetrics(((JTextPane) outputView).getFont()).getWidths();
-
-               // This loop is not needed for monospaced fonts !
-               int maxCharWidth = charsWidth[0];
-               for (int i = 1; i < charsWidth.length; i++) {
-                       if (charsWidth[i] > maxCharWidth) {
-                               maxCharWidth = charsWidth[i];
-                       }
-               }
-
-               return outputViewHeight / charHeight - 1; /* -1 because of the size of the InputCommandLine */
-       }
-
-       /**
-        * Updates the scroll bars according to the contents
-        */
-       public void updateScrollPosition() {
-               SwingUtilities.invokeLater(new Runnable() {
-                               public void run() {
-                                       jSP.getViewport().setViewPosition(new Point(0,
-                                                                                                                               sciConsole.getPreferredSize().height - jSP.getViewport().getExtentSize().height));
-                                       //jSP.revalidate();
-                               }
-                       });
-               //jSP.getVerticalScrollBar().setValue(jSP.getVerticalScrollBar().getMaximum());
-               //jSP.invalidate();
-               //jSP.getViewport().setViewPosition(new Point(0, sciConsole.getPreferredSize().height - jSP.getViewport().getExtentSize().height));
-               //jSP.revalidate();
-
-               // Update the scrollbar properties
-               jSP.getVerticalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().height);
-               jSP.getHorizontalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().width);
-       }
-
-       /**
-        * Clears the console and the output view
-        */
-       public void clear() {
-               try {
-                       config.getInputCommandViewStyledDocument().remove(0, config.getInputCommandViewStyledDocument().getLength());
-               } catch (BadLocationException e) {
-                       e.printStackTrace();
-               }
-               config.getOutputView().reset();
-               /* Bug 4014 */
-               /* We add a space to add a line */
-               /* clc , F2 and menus have same position */
-               config.getOutputView().append(" ");
-       }
-
-       /**
-        * Clears lines from the end of the output view
-        * If nbLines == -1 ==> Called from SwingScilabConsole.getCharWithoutOutput() ([more y or n ?])
-        * If nbLines == 0 ==> Clear the InputCommandLine
-        * @param nbLines the number of lines to be deleted
-        */
-       public void clear(int nbLines) {
-
-               if (nbLines == 0) {
-                       // Clear the prompt
-                       config.getInputCommandView().reset();
-               } else {
-                       // Clear lines in output command view
-                       try {
-                               // We have to remove the command entered by the user
-                               int totalNumberOfLines = nbLines + LINE_NUMBER_IN_PROMPT;
-
-                               StyledDocument outputStyle = config.getOutputViewStyledDocument();
-                               String outputTxt =  outputStyle.getText(0, outputStyle.getLength());
-
-                               // Are there enough lines in the output view ?
-                               String[] allLines = outputTxt.split(StringConstants.NEW_LINE);
-                               if (allLines.length < totalNumberOfLines) {
-                                       // Delete lines
-                                       config.getOutputView().reset();
-                                       config.getOutputView().append(Messages.gettext("Out of Screen"));
-                               } else {
-                                       // Delete lines
-                                       int lastEOL;
-                                       for (int i = 0; i < totalNumberOfLines; i++) {
-                                               outputTxt = outputStyle.getText(0, outputStyle.getLength());
-                                               lastEOL = outputTxt.lastIndexOf(StringConstants.NEW_LINE);
-                                               outputStyle.remove(lastEOL, outputStyle.getLength() - lastEOL);
-                                       }
-                               }
-                       } catch (BadLocationException e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
-                       }
-               }
-       }
-
-       /**
-        * Puts the prompt in the top left corner of the console
-        */
-       public void toHome() {
-               Dimension jSPExtSize = jSP.getViewport().getExtentSize();
-               Dimension newDim = new Dimension(jSPExtSize.width - jSP.getVerticalScrollBar().getPreferredSize().width, jSPExtSize.height);
-               ((JTextPane) config.getInputCommandView()).setPreferredSize(newDim);
-               ((JTextPane) config.getInputCommandView()).invalidate();
-               ((JTextPane) config.getInputCommandView()).doLayout();
-               inputCommandViewSizeForced = true;
-       }
-
-       /**
-        * Sets the flags indicating if the input command view has been resize by calling toHome()
-        * @param status the new status
-        */
-       public void setInputCommandViewSizeForced(boolean status) {
-               inputCommandViewSizeForced = status;
-       }
-
-       /**
-        * Gets the flags indicating if the input command view has been resize by calling toHome()
-        * @return true if a toHome() call is still affecting the size of the input command view
-        */
-       public boolean getInputCommandViewSizeForced() {
-               return inputCommandViewSizeForced;
-       }
-
-       /**
-        * Gets the user input value
-        * @return the value entered by the used
-        */
-       public int getUserInputValue() {
-               try {
-                       canReadUserInputValue.acquire();
-               } catch (InterruptedException e) {
-                       e.printStackTrace();
-               }
-               return userInputValue;
-       }
-
-       /**
-        * Sets the value entered by the user
-        * @param userInputValue new value
-        */
-       public void setUserInputValue(int userInputValue) {
-               this.userInputValue = userInputValue;
-               canReadUserInputValue.release();
-       }
-
-       /**
-        * Gets the semaphore protection so that it can be acquired
-        * @return the semaphore
-        */
-       public Semaphore getCanReadUserInputValue() {
-               return canReadUserInputValue;
-       }
-
-       /**
-        * Send commands to be executed by Scilab (after a copy/paste or drag&drop...)
-        * @param textToExec all text lines to executed
-        * @param displayCmdInOutput flag indicating if the input command has to be displayed in the output view
-        * @param storeInHistory flag indicating if the input command has to be stored in the history
-        */
-       public void sendCommandsToScilab(String textToExec, boolean displayCmdInOutput, boolean storeInHistory) {
-               String[] linesToExec = textToExec.split(StringConstants.NEW_LINE);
-               int nbStatements = 0;
-
-               // Display Cursor to show Scilab is busy
-               this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-
-               while (nbStatements < linesToExec.length) {
-                       // This loop contains code very similar to the code of ValidationAction.java
-                       InputParsingManager inputParsingManager = config.getInputParsingManager();
-                       PromptView promptView = config.getPromptView();
-
-                       // Reset command line
-                       inputParsingManager.reset();
-                       promptView.updatePrompt();
-
-                       // Reset history settings
-                       config.getHistoryManager().setInHistory(false);
-
-                       // Hide the prompt and command line
-                       config.getInputCommandView().setEditable(false);
-                       config.getPromptView().setVisible(false);
-
-                       // Remove the prompt if present at the beginning of the text to execute
-                       // Bug 3002 fix: this "functionality" has been removed because:
-                       // - Remove the --> even if not from paste action
-                       // - Does not remove pause prompts
-
-                       // Store the command in the buffer so that Scilab can read it
-                       if (linesToExec[nbStatements].length() > MAX_CMD_LENGTH) {
-                               config.getOutputView().append("Command is too long (more than " + MAX_CMD_LENGTH
-                                                                                         + " characters long): could not send it to Scilab\n");
-                               ((SciInputCommandView) config.getInputCommandView()).setCmdBuffer("", false);
-                               return;
-                       }
-
-                       ((SciInputCommandView) config.getInputCommandView())
-                               .setCmdBuffer(linesToExec[nbStatements].replace(BACKSLASH_R, ""), displayCmdInOutput);
-                       if (storeInHistory) {
-                               ((SciHistoryManager) config.getHistoryManager()).addEntry(linesToExec[nbStatements].replace(BACKSLASH_R, ""));
-                       }
-                       nbStatements++;
-               }
-
-       }
-
-       /**
-        * Get the JScrollPane associated to the console
-        * @return the JScrollPane associated to the console
-        */
-       public JScrollPane getJScrollPane() {
-               return jSP;
-       }
-
-       /**
-        * Get the Console object associated to the console
-        * @return the Console object associated to the console
-        */
-       public Console getSciConsole() {
-               return sciConsole;
-       }
-
-       /**
-        * Get the current status of the console
-        * If the prompt view is visible, Scilab is waiting for commands
-        * @return true is Scilab is waiting for commands
-        */
-       public boolean isWaitingForInput() {
-               return ((JTextPane) config.getInputCommandView()).isEditable();
-       }
-
-       /**
-        * This methods is used by Scilab to get a new command to execute
-        * @return the command to execute
-        */
-       public String readLine() {
-
-               InputCommandView inputCmdView = this.getConfiguration().getInputCommandView();
-
-               getConfiguration().getOutputView().setCaretPositionToEnd();
-
-               displayPrompt();
-
-               // Display Cursor to show Scilab is available.
-               this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-
-               // Reads the buffer
-               return ((SciInputCommandView) inputCmdView).getCmdBuffer();
-       }
-
-       /**
-        * This method is used to display the prompt
-        */
-       public abstract void displayPrompt();
-
-       /**
-        * Does Scilab have finished its work ?
-        * @return true if Scilab is waiting for new commands
-        */
-       public boolean isWorkDone() {
-               return workDone;
-       }
-
-       /**
-        * Set the font of the Console
-        * @param font the font to set
-        */
-       public void setFont(Font font) {
-               if (sciConsole != null) {
-                       sciConsole.setFont(font);
-
-                       /* Have to update the output view contents with new font */
-                       String txt;
-                       try {
-                               txt = config.getOutputViewStyledDocument().getText(0, config.getOutputViewStyledDocument().getLength());
-                               config.getOutputViewStyledDocument().remove(0, config.getOutputViewStyledDocument().getLength());
-                               config.getOutputView().append(txt);
-                       } catch (BadLocationException e) {
-                               System.out.println(Messages.gettext("Could not change the Console Font."));
-                               return;
-                       }
-
-                       /* Update the prompt */
-                       ((JLabel) ((SciPromptView) config.getPromptView()).getPromptUI()).setFont(font);
-                       config.getPromptView().updatePrompt();
-                       scilabLinesUpdate();
-               }
-       }
-
-       /**
-        * Get the font of the Console
-        * @return the font
-        */
-       public Font getFont() {
-               if (sciConsole != null) {
-                       return ((JLabel) ((SciPromptView) config.getPromptView()).getPromptUI()).getFont();
-               } else {
-                       return null;
-               }
-       }
-
-       /**
-        * Get the Foreground Color of the Console
-        * @return the Foreground Color
-        */
-       public Color getForeground() {
-               if (sciConsole != null) {
-                       return sciConsole.getForeground();
-               } else {
-                       return null;
-               }
-       }
-
-       /**
-        * Get the Background Color of the Console
-        * @return the Background Color
-        */
-       public Color getBackground() {
-               if (sciConsole != null) {
-                       return sciConsole.getBackground();
-               } else {
-                       return null;
-               }
-       }
-
-       /**
-        * Set the Foreground Color of the Console
-        * @param color the Foreground Color
-        */
-       public void setForeground(Color color) {
-               if (sciConsole != null) {
-                       sciConsole.setForeground(color);
-
-                       /* Have to update the output view contents with new Foreground */
-                       String txt;
-                       try {
-                               txt = config.getOutputViewStyledDocument().getText(0, config.getOutputViewStyledDocument().getLength());
-                               config.getOutputViewStyledDocument().remove(0, config.getOutputViewStyledDocument().getLength());
-                               config.getOutputView().append(txt);
-                       } catch (BadLocationException e) {
-                               System.out.println(Messages.gettext("Could not change the Console Foreground."));
-                               return;
-                       }
-
-                       /* Update the prompt */
-                       ((JLabel) ((SciPromptView) config.getPromptView()).getPromptUI()).setForeground(color);
-                       config.getPromptView().updatePrompt();
-               }
-       }
-
-       /**
-        * Set the Background Color of the Console
-        * @param color the Background Color
-        */
-       public void setBackground(Color color) {
-               if (sciConsole != null) {
-                       sciConsole.setBackground(color);
-               }
-       }
-
+    private static final long serialVersionUID = 1L;
+
+    private static final int LINE_NUMBER_IN_PROMPT = 2;
+
+    private static final String BACKSLASH_R = "\r";
+
+    /**
+     * Maximum length of a command send to Scilab
+     */
+    private static final int MAX_CMD_LENGTH = 512;
+
+    /**
+     * Configuration associated to the console oject
+     */
+    private ConsoleConfiguration config;
+
+    /**
+     * Scroll Pane used in Scilab Console
+     */
+    private JScrollPane jSP;
+
+    /**
+     * Generic console object
+     */
+    private Console sciConsole;
+
+    /**
+     * Flag indicating if the input command vieaw size has been forced to a value by a call to toHome
+     */
+    private boolean inputCommandViewSizeForced;
+
+    /**
+     * Value used to get one char from user input (when using [more y or n ?])
+     */
+    private int userInputValue;
+
+    /**
+     * Protection for userInputValue variable R/W
+     */
+    private Semaphore canReadUserInputValue = new Semaphore(1);
+
+    /**
+     * Boolean flag used to store the state of Scilab (true is all works done)
+     */
+    private boolean workDone;
+
+    /**
+     * Constructor
+     * @param configFilePath the configuration file to use
+     */
+    public SciConsole(String configFilePath) {
+        super(new BorderLayout());
+
+        try {
+            config = ConfigurationBuilder.buildConfiguration(configFilePath);
+            config.setActiveProfile("scilab");
+            if (System.getProperty("os.name").toLowerCase().indexOf("mac") != -1)
+                {
+                    ConsoleConfiguration configMac = ConfigurationBuilder.buildConfiguration(configFilePath);;
+                    configMac.setActiveProfile("macosx");
+                    for (KeyStroke key : config.getKeyMapping().keys()){
+                        config.getKeyMapping().put(key,"");
+                    }
+                    for (KeyStroke key : configMac.getKeyMapping().keys()){
+                        config.getKeyMapping().put(key, configMac.getKeyMapping().get(key));
+                    }
+                }
+        } catch (IllegalArgumentException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (SAXException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ParserConfigurationException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        sciConsole = ConsoleBuilder.buildConsole(config, this);
+        jSP = new JScrollPane(sciConsole);
+        /* This option is a good compromise for speed and rendering (bad display when several lines with default SIMPLE_SCROLL_MODE) */
+        jSP.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
+
+        this.add(jSP, BorderLayout.CENTER);
+
+        // The console is given to the outputView so that updateScrollPosition is is accessible
+        ((SciOutputView) config.getOutputView()).setConsole(this);
+
+        // The console is given to the outputView so that Drag&Drop can work
+        ((SciInputCommandView) config.getInputCommandView()).setConsole(this);
+
+        // The console is given to the CompletionWindow
+        ((SciCompletionWindow) config.getCompletionWindow()).setConsole(this);
+        ((SciCompletionWindow) config.getCompletionWindow()).setGraphicalContext(this);
+
+        // The promptview is given to the Parsing Manager
+        // Used to get the position of the CompletionWindow
+        ((SciInputParsingManager) config.getInputParsingManager()).setPromptView(this.getConfiguration().getPromptView());
+
+        // Reset history settings - bug 3612
+        ((SciHistoryManager)config.getHistoryManager()).setInHistory(false);
+
+        // Bug 8055 : update the lines/columns only when the console is resized
+        addComponentListener(new ComponentAdapter() {
+                public void componentResized(ComponentEvent evt) {
+                    scilabLinesUpdate();
+                    jSP.getVerticalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().height);
+                    jSP.getHorizontalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().width);
+                }
+            });
+    }
+
+    /**
+     * Gets the configuration associated to the console
+     * @return the configuration
+     */
+    public ConsoleConfiguration getConfiguration() {
+        return config;
+    }
+
+    /**
+     * Sets the configuration associated to the console
+     * @param newConfig the new config to set
+     */
+    public void setConfiguration(ConsoleConfiguration newConfig) {
+        config = newConfig;
+    }
+
+    /**
+     * Updates Scilab internal variables containing the size of the console
+     * These variables are used to format data before displaying it
+     */
+    public void scilabLinesUpdate() {
+        // Size of the console
+        int outputViewWidth = jSP.getWidth();
+
+        // Size of a char
+        OutputView outputView = this.getConfiguration().getOutputView();
+        int[] charsWidth = ((JEditorPane) outputView).getFontMetrics(((JEditorPane) outputView).getFont()).getWidths();
+
+        // This loop is not needed for monospaced fonts !
+        int maxCharWidth = charsWidth[33];
+        // The range 33--126 corresponds to the usual characters in ASCII
+        for (int i = 34; i < 126; i++) {
+            if (charsWidth[i] > maxCharWidth) {
+                maxCharWidth = charsWidth[i];
+            }
+        }
+
+        int numberOfLines = getNumberOfLines();
+        int promptWidth = ((JPanel) this.getConfiguration().getPromptView()).getPreferredSize().width;
+
+        int numberOfColumns = (outputViewWidth - promptWidth) / maxCharWidth - 1;
+        /* -1 because of the margin between text prompt and command line text */
+
+        GuiManagement.setScilabLines(numberOfLines, numberOfColumns);
+    }
+
+    /**
+     * Get the number of lines that can be displayed in the visible part of the console
+     * @return the number of lines
+     */
+    public int getNumberOfLines() {
+        // Size of the console
+        int outputViewHeight = jSP.getHeight();
+
+        // Size of a char
+        OutputView outputView = this.getConfiguration().getOutputView();
+        int charHeight = ((JEditorPane) outputView).getFontMetrics(((JEditorPane) outputView).getFont()).getHeight();
+        int[] charsWidth = ((JEditorPane) outputView).getFontMetrics(((JEditorPane) outputView).getFont()).getWidths();
+
+        // This loop is not needed for monospaced fonts !
+        int maxCharWidth = charsWidth[0];
+        for (int i = 1; i < charsWidth.length; i++) {
+            if (charsWidth[i] > maxCharWidth) {
+                maxCharWidth = charsWidth[i];
+            }
+        }
+
+        return outputViewHeight / charHeight - 1; /* -1 because of the size of the InputCommandLine */
+    }
+
+    /**
+     * Updates the scroll bars according to the contents
+     */
+    public void updateScrollPosition() {
+        SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
+                    jSP.getViewport().setViewPosition(new Point(0, sciConsole.getPreferredSize().height - jSP.getViewport().getExtentSize().height));
+                }
+            });
+        //jSP.getVerticalScrollBar().setValue(jSP.getVerticalScrollBar().getMaximum());
+        //jSP.invalidate();
+        //jSP.getViewport().setViewPosition(new Point(0, sciConsole.getPreferredSize().height - jSP.getViewport().getExtentSize().height));
+        //jSP.revalidate();
+
+        // Update the scrollbar properties
+        jSP.getVerticalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().height);
+        jSP.getHorizontalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().width);
+    }
+
+    /**
+     * Clears the console and the output view
+     */
+    public void clear() {
+        try {
+            config.getInputCommandViewStyledDocument().remove(0, config.getInputCommandViewStyledDocument().getLength());
+        } catch (BadLocationException e) {
+            e.printStackTrace();
+        }
+        config.getOutputView().reset();
+        /* Bug 4014 */
+        /* We add a space to add a line */
+        /* clc , F2 and menus have same position */
+        config.getOutputView().append(" ");
+    }
+
+    /**
+     * Clears lines from the end of the output view
+     * If nbLines == -1 ==> Called from SwingScilabConsole.getCharWithoutOutput() ([more y or n ?])
+     * If nbLines == 0 ==> Clear the InputCommandLine
+     * @param nbLines the number of lines to be deleted
+     */
+    public void clear(int nbLines) {
+        if (nbLines == 0) {
+            // Clear the prompt
+            config.getInputCommandView().reset();
+        } else {
+            // Clear lines in output command view
+            try {
+                // We have to remove the command entered by the user
+                int totalNumberOfLines = nbLines + LINE_NUMBER_IN_PROMPT;
+
+                Document outputDoc = ((JEditorPane) config.getOutputView()).getDocument();
+                String outputTxt =  outputDoc.getText(0, outputDoc.getLength());
+
+                // Are there enough lines in the output view ?
+                String[] allLines = outputTxt.split(StringConstants.NEW_LINE);
+                if (allLines.length < totalNumberOfLines) {
+                    // Delete lines
+                    config.getOutputView().reset();
+                    config.getOutputView().append(Messages.gettext("Out of Screen"));
+                } else {
+                    // Delete lines
+                    int lastEOL;
+                    for (int i = 0; i < totalNumberOfLines; i++) {
+                        outputTxt = outputDoc.getText(0, outputDoc.getLength());
+                        lastEOL = outputTxt.lastIndexOf(StringConstants.NEW_LINE);
+                        outputDoc.remove(lastEOL, outputDoc.getLength() - lastEOL);
+                    }
+                }
+            } catch (BadLocationException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Puts the prompt in the top left corner of the console
+     */
+    public void toHome() {
+        Dimension jSPExtSize = jSP.getViewport().getExtentSize();
+        Dimension newDim = new Dimension(jSPExtSize.width - jSP.getVerticalScrollBar().getPreferredSize().width, jSPExtSize.height);
+        ((JTextPane) config.getInputCommandView()).setPreferredSize(newDim);
+        ((JTextPane) config.getInputCommandView()).invalidate();
+        ((JTextPane) config.getInputCommandView()).doLayout();
+        inputCommandViewSizeForced = true;
+    }
+
+    /**
+     * Sets the flags indicating if the input command view has been resize by calling toHome()
+     * @param status the new status
+     */
+    public void setInputCommandViewSizeForced(boolean status) {
+        inputCommandViewSizeForced = status;
+    }
+
+    /**
+     * Gets the flags indicating if the input command view has been resize by calling toHome()
+     * @return true if a toHome() call is still affecting the size of the input command view
+     */
+    public boolean getInputCommandViewSizeForced() {
+        return inputCommandViewSizeForced;
+    }
+
+    /**
+     * Gets the user input value
+     * @return the value entered by the used
+     */
+    public int getUserInputValue() {
+        try {
+            canReadUserInputValue.acquire();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        return userInputValue;
+    }
+
+    /**
+     * Sets the value entered by the user
+     * @param userInputValue new value
+     */
+    public void setUserInputValue(int userInputValue) {
+        this.userInputValue = userInputValue;
+        canReadUserInputValue.release();
+    }
+
+    /**
+     * Gets the semaphore protection so that it can be acquired
+     * @return the semaphore
+     */
+    public Semaphore getCanReadUserInputValue() {
+        return canReadUserInputValue;
+    }
+
+    /**
+     * Send commands to be executed by Scilab (after a copy/paste or drag&drop...)
+     * @param textToExec all text lines to executed
+     * @param displayCmdInOutput flag indicating if the input command has to be displayed in the output view
+     * @param storeInHistory flag indicating if the input command has to be stored in the history
+     */
+    public void sendCommandsToScilab(String textToExec, boolean displayCmdInOutput, boolean storeInHistory) {
+        String[] linesToExec = textToExec.split(StringConstants.NEW_LINE);
+        int nbStatements = 0;
+
+        // Display Cursor to show Scilab is busy
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+        while (nbStatements < linesToExec.length) {
+            // This loop contains code very similar to the code of ValidationAction.java
+            InputParsingManager inputParsingManager = config.getInputParsingManager();
+            PromptView promptView = config.getPromptView();
+
+            // Reset command line
+            inputParsingManager.reset();
+            promptView.updatePrompt();
+
+            // Reset history settings
+            config.getHistoryManager().setInHistory(false);
+
+            // Hide the prompt and command line
+            config.getInputCommandView().setEditable(false);
+            config.getPromptView().setVisible(false);
+
+            // Remove the prompt if present at the beginning of the text to execute
+            // Bug 3002 fix: this "functionality" has been removed because:
+            // - Remove the --> even if not from paste action
+            // - Does not remove pause prompts
+
+            // Store the command in the buffer so that Scilab can read it
+            if (linesToExec[nbStatements].length() > MAX_CMD_LENGTH) {
+                config.getOutputView().append("Command is too long (more than " + MAX_CMD_LENGTH
+                                              + " characters long): could not send it to Scilab\n");
+                ((SciInputCommandView) config.getInputCommandView()).setCmdBuffer("", false);
+                return;
+            }
+
+            ((SciInputCommandView) config.getInputCommandView())
+                .setCmdBuffer(linesToExec[nbStatements].replace(BACKSLASH_R, ""), displayCmdInOutput);
+            if (storeInHistory) {
+                ((SciHistoryManager) config.getHistoryManager()).addEntry(linesToExec[nbStatements].replace(BACKSLASH_R, ""));
+            }
+            nbStatements++;
+        }
+
+    }
+
+    /**
+     * Get the JScrollPane associated to the console
+     * @return the JScrollPane associated to the console
+     */
+    public JScrollPane getJScrollPane() {
+        return jSP;
+    }
+
+    /**
+     * Get the Console object associated to the console
+     * @return the Console object associated to the console
+     */
+    public Console getSciConsole() {
+        return sciConsole;
+    }
+
+    /**
+     * Get the current status of the console
+     * If the prompt view is visible, Scilab is waiting for commands
+     * @return true is Scilab is waiting for commands
+     */
+    public boolean isWaitingForInput() {
+        return ((JTextPane) config.getInputCommandView()).isEditable();
+    }
+
+    /**
+     * This methods is used by Scilab to get a new command to execute
+     * @return the command to execute
+     */
+    public String readLine() {
+
+        InputCommandView inputCmdView = this.getConfiguration().getInputCommandView();
+
+        getConfiguration().getOutputView().setCaretPositionToEnd();
+
+        displayPrompt();
+
+        // Display Cursor to show Scilab is available.
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+
+        // Reads the buffer
+        return ((SciInputCommandView) inputCmdView).getCmdBuffer();
+    }
+
+    /**
+     * This method is used to display the prompt
+     */
+    public abstract void displayPrompt();
+
+    /**
+     * Does Scilab have finished its work ?
+     * @return true if Scilab is waiting for new commands
+     */
+    public boolean isWorkDone() {
+        return workDone;
+    }
+
+    /**
+     * Set the font of the Console
+     * @param font the font to set
+     */
+    public void setFont(Font font) {
+        if (sciConsole != null) {
+            sciConsole.setFont(font);
+
+            /* Have to update the output view contents with new font */
+            String txt;
+            try {
+                Document outputDoc = ((JEditorPane) config.getOutputView()).getDocument();
+                txt = outputDoc.getText(0, outputDoc.getLength());
+                outputDoc.remove(0, outputDoc.getLength());
+                config.getOutputView().append(txt);
+            } catch (BadLocationException e) {
+                System.out.println(Messages.gettext("Could not change the Console Font."));
+                return;
+            }
+
+            /* Update the prompt */
+            ((JLabel) ((SciPromptView) config.getPromptView()).getPromptUI()).setFont(font);
+            config.getPromptView().updatePrompt();
+            scilabLinesUpdate();
+        }
+    }
+
+    /**
+     * Get the font of the Console
+     * @return the font
+     */
+    public Font getFont() {
+        if (sciConsole != null) {
+            return ((JLabel) ((SciPromptView) config.getPromptView()).getPromptUI()).getFont();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Get the Foreground Color of the Console
+     * @return the Foreground Color
+     */
+    public Color getForeground() {
+        if (sciConsole != null) {
+            return sciConsole.getForeground();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Get the Background Color of the Console
+     * @return the Background Color
+     */
+    public Color getBackground() {
+        if (sciConsole != null) {
+            return sciConsole.getBackground();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Set the Foreground Color of the Console
+     * @param color the Foreground Color
+     */
+    public void setForeground(Color color) {
+        if (sciConsole != null) {
+            sciConsole.setForeground(color);
+
+            /* Have to update the output view contents with new Foreground */
+            String txt;
+            try {
+                Document outputDoc = ((JEditorPane) config.getOutputView()).getDocument();
+                txt = outputDoc.getText(0, outputDoc.getLength());
+                outputDoc.remove(0, outputDoc.getLength());
+                config.getOutputView().append(txt);
+            } catch (BadLocationException e) {
+                System.out.println(Messages.gettext("Could not change the Console Foreground."));
+                return;
+            }
+
+            /* Update the prompt */
+            ((JLabel) ((SciPromptView) config.getPromptView()).getPromptUI()).setForeground(color);
+            config.getPromptView().updatePrompt();
+        }
+    }
+
+    /**
+     * Set the Background Color of the Console
+     * @param color the Background Color
+     */
+    public void setBackground(Color color) {
+        if (sciConsole != null) {
+            sciConsole.setBackground(color);
+        }
+    }
 }
index 1cac64d..bb88388 100644 (file)
@@ -155,46 +155,46 @@ public class SciInputCommandView extends ConsoleTextPane implements InputCommand
 
         // BUG 2510 fix: automatic validation of pasted lines
         this.getDocument().addDocumentListener(new DocumentListener() {
-            public void changedUpdate(DocumentEvent e) {
-                // Nothing to do in Scilab
-            }
+                public void changedUpdate(DocumentEvent e) {
+                    // Nothing to do in Scilab
+                }
 
-            public void insertUpdate(DocumentEvent e) {
-                // Validates commands if followed by a carriage return
-                String wholeTxt = console.getConfiguration().getInputParsingManager().getCommandLine();
-                if ((e.getLength()) > 1 && (wholeTxt.lastIndexOf(StringConstants.NEW_LINE) == (wholeTxt.length() - 1))) {
+                public void insertUpdate(DocumentEvent e) {
+                    // Validates commands if followed by a carriage return
+                    String wholeTxt = console.getConfiguration().getInputParsingManager().getCommandLine();
+                    if ((e.getLength()) > 1 && (wholeTxt.lastIndexOf(StringConstants.NEW_LINE) == (wholeTxt.length() - 1))) {
                         EventQueue.invokeLater(new Runnable() {
                                 public void run() {
-                                        String wholeTxt = console.getConfiguration().getInputParsingManager().getCommandLine();
-                                        console.sendCommandsToScilab(wholeTxt, true, true);
+                                    String wholeTxt = console.getConfiguration().getInputParsingManager().getCommandLine();
+                                    console.sendCommandsToScilab(wholeTxt, true, true);
                                 };
-                        });
+                            });
+                    }
                 }
-            }
 
-            public void removeUpdate(DocumentEvent e) {
-                // Nothing to do in Scilab
-            }
-        });
+                public void removeUpdate(DocumentEvent e) {
+                    // Nothing to do in Scilab
+                }
+            });
 
         this.addKeyListener(new KeyListener() {
-            public void keyPressed (KeyEvent e) {
-                if (e.getKeyCode()==KeyEvent.VK_BACK_SPACE) {
+                public void keyPressed (KeyEvent e) {
+                    if (e.getKeyCode()==KeyEvent.VK_BACK_SPACE) {
                         if (console.getConfiguration().getHistoryManager().isInHistory()) {
-                                //console.getConfiguration().getInputParsingManager().reset();
-                                //console.getConfiguration().getInputParsingManager().append(console.getConfiguration().getHistoryManager().getTmpEntry());
-                                console.getConfiguration().getHistoryManager().setInHistory(false);
+                            //console.getConfiguration().getInputParsingManager().reset();
+                            //console.getConfiguration().getInputParsingManager().append(console.getConfiguration().getHistoryManager().getTmpEntry());
+                            console.getConfiguration().getHistoryManager().setInHistory(false);
                         }
+                    }
                 }
-            }
 
-            public void keyReleased (KeyEvent e) {
-                // Nothing to do in Scilab
-            }
+                public void keyReleased (KeyEvent e) {
+                    // Nothing to do in Scilab
+                }
 
-            public void keyTyped (KeyEvent e) {
-                // Nothing to do in Scilab
-            }
-});
+                public void keyTyped (KeyEvent e) {
+                    // Nothing to do in Scilab
+                }
+            });
     }
 }
index 8fa053b..fc4017e 100644 (file)
@@ -33,13 +33,17 @@ import java.util.concurrent.BlockingQueue;
 import javax.swing.BorderFactory;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
+import javax.swing.JEditorPane;
 import javax.swing.JTextPane;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.DefaultCaret;
+import javax.swing.text.DefaultStyledDocument;
 import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
 import javax.swing.text.StyleContext;
+import javax.swing.text.StyledDocument;
 
 import org.scilab.modules.commons.gui.ScilabCaret;
 
@@ -52,400 +56,387 @@ import com.artenum.rosetta.util.StringConstants;
  *
  * @author Vincent COUVERT
  */
-public class SciOutputView extends JTextPane implements OutputView {
-       private static final long serialVersionUID = 1L;
-
-       private static final int TOP_BORDER = 0;
-
-       private static final int BOTTOM_BORDER = 0;
-
-       private static final int LEFT_BORDER = 0;
-
-       private static final int RIGHT_BORDER = 0;
-
-       private static final int BUFFER_SIZE = 10;
-
-       private String activeStyle;
-
-       private String lastAppendedStyle;
-
-       private BlockingQueue<StringBuffer> bufferQueue;
-
-       private LinkedList<String> styleQueue;
-
-       private StringBuffer currentWorkingBuffer;
-
-       private SciConsole console;
-
-       private Thread thread;
-       
-       private int insertPosition;
-       
-       private int maxNumberOfLines;
-       private int numberOfLines;
-       
-       /**
-        * Constructor
-        */
-       public SciOutputView() {
-               setBorder(BorderFactory.createEmptyBorder(TOP_BORDER, LEFT_BORDER,
-                               BOTTOM_BORDER, RIGHT_BORDER));
-
-               // Enabled Drag&Drop with this component
-               this.setDragEnabled(true);
-               this.setDoubleBuffered(true);
-
-               activeStyle = StyleContext.DEFAULT_STYLE;
-               bufferQueue = new ArrayBlockingQueue<StringBuffer>(BUFFER_SIZE);
-               styleQueue = new LinkedList<String>();
-               setFocusable(false);
-
-               /**
-                * Default caret for output view (to handle paste actions using middle button)
-                * @author Vincent COUVERT
-                */
-               final class FixedCaret extends ScilabCaret {
-
-                       /**
-                        * Constructor
-                        */
-                       private FixedCaret() {
-                               super(SciOutputView.this);
-                       }
-
-                       /**
-                        * Manages mouse clicks
-                        * @param e the event
-                        * @see javax.swing.text.DefaultCaret#mouseClicked(java.awt.event.MouseEvent)
-                        */
-                       public void mouseClicked(MouseEvent e) {
-                               if (SwingUtilities.isMiddleMouseButton(e) && e.getClickCount() == 1) {
-                                       /*** PASTE USING MIDDLE BUTTON ***/
-                                       JTextComponent c = (JTextComponent) e.getSource();
-                                       if (c != null) {
-                                               Toolkit tk = c.getToolkit();
-                                               Clipboard buffer = tk.getSystemSelection();
-                                               if (buffer != null) {
-                                                       Transferable trans = buffer.getContents(null);
-                                                       if (trans.isDataFlavorSupported(DataFlavor.stringFlavor)) {
-                                                               try {
-                                                                       String pastedText = (String) trans.getTransferData(DataFlavor.stringFlavor);
-                                                                       ((JTextPane) getConsole()
-                                                                                       .getConfiguration()
-                                                                                       .getInputCommandView())
-                                                                                       .replaceSelection(pastedText);
-                                                               } catch (UnsupportedFlavorException e1) {
-                                                                       e1.printStackTrace();
-                                                               } catch (IOException e1) {
-                                                                       e1.printStackTrace();
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               } else if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 1) {
-                                       /*** SEND THE FOCUS TO THE INPUT COMMAND VIEW ***/
-                                       ((JTextPane) getConsole().getConfiguration().getInputCommandView()).requestFocus();
-                                       ((JTextPane) getConsole().getConfiguration().getInputCommandView()).getCaret().setVisible(true);
-                               } else {
-                                       /*** DELEGATE TO THE SYSTEM ***/
-                                       super.mouseClicked(e);
-                               }
-                       }
-               }
-
-               // Set the caret
-               setCaret(new FixedCaret());
-               // Selection is forced to be visible because the component is not editable
-               getCaret().setSelectionVisible(true);
-       }
-
-       /**
-        * Display a buffer entry in the console
-        * @param buff the string  to write
-        * @param style the style to use to format the string
-        */
-       private void displayLineBuffer(String buff, String style) {
-
-               int sDocLength = getStyledDocument().getLength();
-               
-               if (buff.equals("\r")) {
-                       /* If \r sent by mprintf then display nothing but prepare next display */
-                       /* Insertion will be done just after last NEW_LINE */
-                       try {
-                               sDocLength = getStyledDocument().getLength();
-                               String outputTxt = getStyledDocument().getText(0, sDocLength);
-                               insertPosition = outputTxt.lastIndexOf(StringConstants.NEW_LINE) + 1;
-                       } catch (BadLocationException e) {
-                               e.printStackTrace();
-                       }
-                       return;
-               } else {
-                       /* Change position for insertion if a previous \r still influence display */
-                       if ((insertPosition != 0) && (insertPosition < sDocLength)) {
-                               sDocLength = insertPosition;
-                               try {
-                                       /* Remove chars to be replaced */
-                                       if (insertPosition + buff.length() <= getStyledDocument().getLength()) {
-                                               getStyledDocument().remove(insertPosition, buff.length());
-                                       } else {
-                                               /* Remove end of line */
-                                               getStyledDocument().remove(insertPosition, getStyledDocument().getLength() - insertPosition);
-                                       }
-                               } catch (BadLocationException e) {
-                                       e.printStackTrace();
-                               }
-                       } else {
-                               /* Reinit insertPosition: 0 is equivalent to insertPosition value ignored */
-                               insertPosition = 0;
-                       }
-               }
-               
-               try {
-                       getStyledDocument().insertString(sDocLength, buff, getStyledDocument().getStyle(style));
-                       /* Move insertPosition to the end of last inserted data */
-                       if (insertPosition != 0) {
-                               insertPosition += buff.length();
-                       }
-               } catch (BadLocationException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
-               }
-               
-               /* Special case for Scilab when clc or tohome have been used */
-               String[] lines = buff.split(StringConstants.NEW_LINE);
-
-               numberOfLines += lines.length;
-
-               while (numberOfLines > maxNumberOfLines) {
-                       try {
-                               getStyledDocument().remove(0, 
-                                               getStyledDocument().getText(0, getStyledDocument().getLength()).indexOf(StringConstants.NEW_LINE, 0));
-                               numberOfLines--;
-                       } catch (BadLocationException e) {
-                               e.printStackTrace();
-                       }
-               }
-               
-               /* Change the size of the input command view if necessary */
-               /* - if the console size has been forced to a value */
-               /* - if a carriage return has been appended */
-               if (console != null
-                               && console.getInputCommandViewSizeForced()
-                               && lines.length > 0) {
-
-                       JTextPane outputView = ((JTextPane) console
-                                       .getConfiguration().getOutputView());
-
-                       // Get JScrollPane viewport size to adapt input command
-                       // view size
-                       JScrollPane jSP = console.getJScrollPane();
-                       Dimension jSPExtSize = jSP.getViewport()
-                       .getExtentSize();
-
-                       /* Height of a text line in the ouput view */
-                       int charHeight = outputView.getFontMetrics(
-                                       outputView.getFont()).getHeight();
-
-                       JPanel promptView = ((JPanel) console
-                                       .getConfiguration().getPromptView());
-
-                       /* Input command view dimensions */
-                       JTextPane inputCmdView = ((JTextPane) console
-                                       .getConfiguration().getInputCommandView());
-                       int height = inputCmdView.getPreferredSize().height;
-                       int width = inputCmdView.getPreferredSize().width
-                       - jSPExtSize.width;
-
-                       int promptViewHeight = promptView.getPreferredSize().height;
-
-                       /* New dimension for the input command view */
-                       /*
-                        * -1 because last EOL removed in
-                        * SwingScilabConsole.readline
-                        */
-                       int newHeight = height - (lines.length - 1)
-                       * charHeight;
-                       Dimension newDim = null;
-
-                       if (newHeight > promptViewHeight) {
-                               /*
-                                * If the input command view is bigger than the
-                                * promptUI
-                                */
-                               /*
-                                * It's height is descreased according to line
-                                * number of lines added to output view
-                                */
-                               newDim = new Dimension(width, newHeight);
-                       } else {
-                               /*
-                                * If the input command view is smaller than the
-                                * promptUI
-                                */
-                               /* It's height adapted to the promptUI height */
-                               newDim = new Dimension(width, promptViewHeight);
-                               console.setInputCommandViewSizeForced(false);
-                       }
-                       /* Change the input command view size */
-                       ((JTextPane) console.getConfiguration()
-                                       .getInputCommandView())
-                                       .setPreferredSize(newDim);
-                       ((JTextPane) console.getConfiguration()
-                                       .getInputCommandView()).invalidate();
-                       ((JTextPane) console.getConfiguration()
-                                       .getInputCommandView()).doLayout();
-               }
-               /* Update scroll only if console has been set */
-               /* TODO : Must not do this each time... consume pretty much computing resources */
-               if (console != null) {
-                       console.updateScrollPosition();
-               }
-       }
-
-       /**
-        * Adds text to the output view and change the size of others components if
-        * necessary
-        *
-        * @param content
-        *            text to add
-        */
-       public void append(String content) {
-               //append(content, activeStyle);
-               displayLineBuffer(content, activeStyle);
-       }
-
-       /**
-        * Adds text to the output view and change the size of others components if
-        * necessary
-        *
-        * @param content
-        *            text to add
-        * @param styleName
-        *            style to set for content
-        */
-       public void append(String content, String styleName) {
-               if (styleName.equals(lastAppendedStyle) && bufferQueue.size() > 1) {
-                       currentWorkingBuffer.append(content);
-               } else {
-                       lastAppendedStyle = styleName;
-                       styleQueue.add(lastAppendedStyle);
-                       try {
-                               currentWorkingBuffer = new StringBuffer(content);
-                               bufferQueue.put(currentWorkingBuffer);
-                       } catch (InterruptedException e) {
-                               e.printStackTrace();
-                       }
-               }
-               if (!thread.isAlive()) {
-                       thread.run();
-               }
-       }
-
-       /**
-        * Gets the error writer
-        *
-        * @return the error writer
-        * @see com.artenum.rosetta.interfaces.ui.OutputView#getErrorWriter()
-        */
-       public Writer getErrorWriter() {
-               return new BufferedWriter(StyleContext.DEFAULT_STYLE, bufferQueue,
-                               styleQueue);
-       }
-
-       /**
-        * Gets the writer
-        *
-        * @return the writer
-        * @see com.artenum.rosetta.interfaces.ui.OutputView#getWriter()
-        */
-       public Writer getWriter() {
-               return new BufferedWriter(StyleContext.DEFAULT_STYLE, bufferQueue,
-                               styleQueue);
-       }
-
-       /**
-        * Resets the output view (remove text)
-        *
-        * @see com.artenum.rosetta.interfaces.ui.OutputView#reset()
-        */
-       public void reset() {
-               setText("");
-               setCaretPosition(0);
-       }
-
-       /**
-        * Move the caret to the beginning of the styled document
-        *
-        * @see com.artenum.rosetta.interfaces.ui.OutputView#setCaretPositionToBeginning()
-        */
-       public void setCaretPositionToBeginning() {
-               insertPosition = 0;
-               setCaretPosition(0);
-       }
-
-       /**
-        * Move the caret to the end of the styled document
-        *
-        * @see com.artenum.rosetta.interfaces.ui.OutputView#setCaretPositionToEnd()
-        */
-       public void setCaretPositionToEnd() {
-               insertPosition = 0;
-               setCaretPosition(getStyledDocument().getLength());
-       }
-
-       /**
-        * Set the style for current text
-        *
-        * @param styleName
-        *            the style to set
-        * @see com.artenum.rosetta.interfaces.ui.OutputView#setStyleName(java.lang.String)
-        */
-       public void setStyleName(String styleName) {
-               activeStyle = styleName;
-       }
-
-       /**
-        * Sets the console object containing this output view
-        *
-        * @param c
-        *            the console associated
-        */
-       public void setConsole(SciConsole c) {
-               console = c;
-
-               // Drag n' Drop handling
-               this.setDropTarget(new DropTarget(this,
-                               DnDConstants.ACTION_COPY_OR_MOVE, new SciDropTargetListener(
-                                               console)));
-
-               // Commented because now done by the caret class
-               //FocusMouseListener focusGrabber = new FocusMouseListener(console);
-               //this.addMouseListener(focusGrabber);
-       }
-
-       /**
-        * Gets the console object containing this output view
-        *
-        * @return the console associated
-        */
-       public SciConsole getConsole() {
-               return console;
-       }
-
-       /**
-        * Get the current thread used to display
-        * @return the thread
-        */
-       public Thread getThread() {
-               return thread;
-       }
-       
-       /**
-        * Set the maximum number of lines to keep before deleting the older one
-        * @param number the maximum
-        */
-       public void setMaxSize(int number) {
-               maxNumberOfLines = number;
-       }
+public class SciOutputView extends JEditorPane implements OutputView {
+    private static final long serialVersionUID = 1L;
+
+    private static final int TOP_BORDER = 0;
+
+    private static final int BOTTOM_BORDER = 0;
+
+    private static final int LEFT_BORDER = 0;
+
+    private static final int RIGHT_BORDER = 0;
+
+    private static final int BUFFER_SIZE = 10;
+
+    private String activeStyle;
+
+    private String lastAppendedStyle;
+
+    private BlockingQueue<StringBuffer> bufferQueue;
+
+    private LinkedList<String> styleQueue;
+
+    private StringBuffer currentWorkingBuffer;
+
+    private SciConsole console;
+
+    private Thread thread;
+
+    private int insertPosition;
+
+    private int maxNumberOfLines;
+    private int numberOfLines;
+
+    /**
+     * Constructor
+     */
+    public SciOutputView() {
+        super();
+
+        /* A PlainDocument contains only "box" for lines not for all characters (as in a StyledDocument)
+           so there are less boxes to explore in a PlainDocument... */
+        setDocument(new PlainDocument());
+        setMaxSize(10000);
+        setBorder(BorderFactory.createEmptyBorder(TOP_BORDER, LEFT_BORDER, BOTTOM_BORDER, RIGHT_BORDER));
+
+        // Enabled Drag&Drop with this component
+        this.setDragEnabled(true);
+        this.setDoubleBuffered(true);
+
+        activeStyle = StyleContext.DEFAULT_STYLE;
+        bufferQueue = new ArrayBlockingQueue<StringBuffer>(BUFFER_SIZE);
+        styleQueue = new LinkedList<String>();
+        setFocusable(false);
+
+        /**
+         * Default caret for output view (to handle paste actions using middle button)
+         * @author Vincent COUVERT
+         */
+        final class FixedCaret extends ScilabCaret {
+
+            /**
+             * Constructor
+             */
+            private FixedCaret() {
+                super(SciOutputView.this);
+            }
+
+            /**
+             * Manages mouse clicks
+             * @param e the event
+             * @see javax.swing.text.DefaultCaret#mouseClicked(java.awt.event.MouseEvent)
+             */
+            public void mouseClicked(MouseEvent e) {
+                if (SwingUtilities.isMiddleMouseButton(e) && e.getClickCount() == 1) {
+                    /*** PASTE USING MIDDLE BUTTON ***/
+                    JTextComponent c = (JTextComponent) e.getSource();
+                    if (c != null) {
+                        Toolkit tk = c.getToolkit();
+                        Clipboard buffer = tk.getSystemSelection();
+                        if (buffer != null) {
+                            Transferable trans = buffer.getContents(null);
+                            if (trans.isDataFlavorSupported(DataFlavor.stringFlavor)) {
+                                try {
+                                    String pastedText = (String) trans.getTransferData(DataFlavor.stringFlavor);
+                                    ((JTextPane) getConsole().getConfiguration().getInputCommandView()).replaceSelection(pastedText);
+                                } catch (UnsupportedFlavorException e1) {
+                                    e1.printStackTrace();
+                                } catch (IOException e1) {
+                                    e1.printStackTrace();
+                                }
+                            }
+                        }
+                    }
+                } else if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 1) {
+                    /*** SEND THE FOCUS TO THE INPUT COMMAND VIEW ***/
+                    ((JTextPane) getConsole().getConfiguration().getInputCommandView()).requestFocus();
+                    ((JTextPane) getConsole().getConfiguration().getInputCommandView()).getCaret().setVisible(true);
+                } else {
+                    /*** DELEGATE TO THE SYSTEM ***/
+                    super.mouseClicked(e);
+                }
+            }
+        }
+
+        // Set the caret
+        setCaret(new FixedCaret());
+        // Selection is forced to be visible because the component is not editable
+        getCaret().setSelectionVisible(true);
+    }
+
+    /**
+     * @param styledDocument
+     */
+    public void setStyledDocument(StyledDocument styledDocument) { }
+
+    /**
+     * Display a buffer entry in the console
+     * @param buff the string  to write
+     * @param style the style to use to format the string
+     */
+    private void displayLineBuffer(String buff, String style) {
+        int sDocLength = getDocument().getLength();
+
+        if (buff.equals("\r")) {
+            /* If \r sent by mprintf then display nothing but prepare next display */
+            /* Insertion will be done just after last NEW_LINE */
+            try {
+                String outputTxt = getDocument().getText(0, sDocLength);
+                insertPosition = outputTxt.lastIndexOf(StringConstants.NEW_LINE) + 1;
+            } catch (BadLocationException e) {
+                e.printStackTrace();
+            }
+            return;
+        } else {
+            /* Change position for insertion if a previous \r still influence display */
+            if ((insertPosition != 0) && (insertPosition < sDocLength)) {
+                sDocLength = insertPosition;
+                try {
+                    /* Remove chars to be replaced */
+                    if (insertPosition + buff.length() <= getDocument().getLength()) {
+                        getDocument().remove(insertPosition, buff.length());
+                    } else {
+                        /* Remove end of line */
+                        getDocument().remove(insertPosition, getDocument().getLength() - insertPosition);
+                    }
+                } catch (BadLocationException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                /* Reinit insertPosition: 0 is equivalent to insertPosition value ignored */
+                insertPosition = 0;
+            }
+        }
+
+        try {
+            getDocument().insertString(sDocLength, buff, null);
+            /* Move insertPosition to the end of last inserted data */
+            if (insertPosition != 0) {
+                insertPosition += buff.length();
+            }
+        } catch (BadLocationException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        int count = getDocument().getDefaultRootElement().getElementCount();
+        if (count > 1.5 * maxNumberOfLines) {
+            /* A removal is costly: array copy and with a gap buffer that leads to two array copies (when remove is followed by an insert).
+               So the idea is to minimize the number of removal: a removal only when 0.5*maxNumberOfLines useless lines are entered.
+            */
+            try {
+                getDocument().remove(0, getDocument().getDefaultRootElement().getElement(count - maxNumberOfLines - 1).getEndOffset());
+            } catch (BadLocationException e) {
+                e.printStackTrace();
+            }
+        }
+
+        /* Special case for Scilab when clc or tohome have been used */
+        String[] lines = buff.split(StringConstants.NEW_LINE);
+
+        /* Change the size of the input command view if necessary */
+        /* - if the console size has been forced to a value */
+        /* - if a carriage return has been appended */
+        if (console != null && console.getInputCommandViewSizeForced() && lines.length > 0) {
+            JEditorPane outputView = ((JEditorPane) console.getConfiguration().getOutputView());
+
+            // Get JScrollPane viewport size to adapt input command
+            // view size
+            JScrollPane jSP = console.getJScrollPane();
+            Dimension jSPExtSize = jSP.getViewport().getExtentSize();
+
+            /* Height of a text line in the ouput view */
+            int charHeight = outputView.getFontMetrics(outputView.getFont()).getHeight();
+            JPanel promptView = ((JPanel) console.getConfiguration().getPromptView());
+
+            /* Input command view dimensions */
+            JTextPane inputCmdView = ((JTextPane) console.getConfiguration().getInputCommandView());
+            int height = inputCmdView.getPreferredSize().height;
+            int width = inputCmdView.getPreferredSize().width - jSPExtSize.width;
+
+            int promptViewHeight = promptView.getPreferredSize().height;
+
+            /* New dimension for the input command view */
+            /*
+             * -1 because last EOL removed in
+             * SwingScilabConsole.readline
+             */
+            int newHeight = height - (lines.length - 1) * charHeight;
+            Dimension newDim = null;
+
+            if (newHeight > promptViewHeight) {
+                /*
+                 * If the input command view is bigger than the
+                 * promptUI
+                 */
+                /*
+                 * It's height is descreased according to line
+                 * number of lines added to output view
+                 */
+                newDim = new Dimension(width, newHeight);
+            } else {
+                /*
+                 * If the input command view is smaller than the
+                 * promptUI
+                 */
+                /* It's height adapted to the promptUI height */
+                newDim = new Dimension(width, promptViewHeight);
+                console.setInputCommandViewSizeForced(false);
+            }
+            /* Change the input command view size */
+            ((JTextPane) console.getConfiguration().getInputCommandView()).setPreferredSize(newDim);
+            ((JTextPane) console.getConfiguration().getInputCommandView()).invalidate();
+            ((JTextPane) console.getConfiguration().getInputCommandView()).doLayout();
+        }
+        /* Update scroll only if console has been set */
+        /* TODO : Must not do this each time... consume pretty much computing resources */
+        if (console != null) {
+            console.updateScrollPosition();
+        }
+    }
+
+    /**
+     * Adds text to the output view and change the size of others components if
+     * necessary
+     *
+     * @param content
+     *            text to add
+     */
+    public void append(String content) {
+        //append(content, activeStyle);
+        displayLineBuffer(content, activeStyle);
+    }
+
+    /**
+     * Adds text to the output view and change the size of others components if
+     * necessary
+     *
+     * @param content
+     *            text to add
+     * @param styleName
+     *            style to set for content
+     */
+    public void append(String content, String styleName) {
+        if (styleName.equals(lastAppendedStyle) && bufferQueue.size() > 1) {
+            currentWorkingBuffer.append(content);
+        } else {
+            lastAppendedStyle = styleName;
+            styleQueue.add(lastAppendedStyle);
+            try {
+                currentWorkingBuffer = new StringBuffer(content);
+                bufferQueue.put(currentWorkingBuffer);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        if (!thread.isAlive()) {
+            thread.run();
+        }
+    }
+
+    /**
+     * Gets the error writer
+     *
+     * @return the error writer
+     * @see com.artenum.rosetta.interfaces.ui.OutputView#getErrorWriter()
+     */
+    public Writer getErrorWriter() {
+        return new BufferedWriter(StyleContext.DEFAULT_STYLE, bufferQueue, styleQueue);
+    }
+
+    /**
+     * Gets the writer
+     *
+     * @return the writer
+     * @see com.artenum.rosetta.interfaces.ui.OutputView#getWriter()
+     */
+    public Writer getWriter() {
+        return new BufferedWriter(StyleContext.DEFAULT_STYLE, bufferQueue, styleQueue);
+    }
+
+    /**
+     * Resets the output view (remove text)
+     *
+     * @see com.artenum.rosetta.interfaces.ui.OutputView#reset()
+     */
+    public void reset() {
+        setText("");
+        setCaretPosition(0);
+    }
+
+    /**
+     * Move the caret to the beginning of the styled document
+     *
+     * @see com.artenum.rosetta.interfaces.ui.OutputView#setCaretPositionToBeginning()
+     */
+    public void setCaretPositionToBeginning() {
+        insertPosition = 0;
+        setCaretPosition(0);
+    }
+
+    /**
+     * Move the caret to the end of the styled document
+     *
+     * @see com.artenum.rosetta.interfaces.ui.OutputView#setCaretPositionToEnd()
+     */
+    public void setCaretPositionToEnd() {
+        insertPosition = 0;
+        setCaretPosition(getDocument().getLength());
+    }
+
+    /**
+     * Set the style for current text
+     *
+     * @param styleName
+     *            the style to set
+     * @see com.artenum.rosetta.interfaces.ui.OutputView#setStyleName(java.lang.String)
+     */
+    public void setStyleName(String styleName) {
+        activeStyle = styleName;
+    }
+
+    /**
+     * Sets the console object containing this output view
+     *
+     * @param c
+     *            the console associated
+     */
+    public void setConsole(SciConsole c) {
+        console = c;
+
+        // Drag n' Drop handling
+        this.setDropTarget(new DropTarget(this,
+                                          DnDConstants.ACTION_COPY_OR_MOVE, new SciDropTargetListener(console)));
+
+        // Commented because now done by the caret class
+        //FocusMouseListener focusGrabber = new FocusMouseListener(console);
+        //this.addMouseListener(focusGrabber);
+    }
+
+    /**
+     * Gets the console object containing this output view
+     *
+     * @return the console associated
+     */
+    public SciConsole getConsole() {
+        return console;
+    }
+
+    /**
+     * Get the current thread used to display
+     * @return the thread
+     */
+    public Thread getThread() {
+        return thread;
+    }
+
+    /**
+     * Set the maximum number of lines to keep before deleting the older one
+     * @param number the maximum
+     */
+    public void setMaxSize(int number) {
+        maxNumberOfLines = Math.max(1, number);
+    }
 
 }
index faf13c6..8fff5a2 100644 (file)
@@ -13,6 +13,7 @@
 package org.scilab.modules.console;
 
 import java.awt.event.ActionEvent;
+import javax.swing.JEditorPane;
 import javax.swing.JTextPane;
 import com.artenum.rosetta.core.action.AbstractConsoleAction;
 
@@ -21,29 +22,29 @@ import com.artenum.rosetta.core.action.AbstractConsoleAction;
  * @author Allan CORNET
  */
 public class SelectAllAction extends AbstractConsoleAction {
-       private static final long serialVersionUID = 1L;
-
-       /**
-        * Constructor
-        */
-       public SelectAllAction() {
-               super();
-       }
-
-       /**
-        * Threats the event
-        * @param e the action event that occured
-        * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
-        */
-       public void actionPerformed(ActionEvent e) {
-               JTextPane outputPane = (JTextPane) configuration.getOutputView();
-               JTextPane inputPane = (JTextPane) configuration.getInputCommandView();
-               
-               outputPane.setSelectionStart(0);
-               outputPane.setSelectionEnd(outputPane.getText().length());
-               
-               inputPane.setSelectionStart(0);
-               inputPane.setSelectionEnd(inputPane.getText().length());
-               
-       }
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * Constructor
+         */
+        public SelectAllAction() {
+                super();
+        }
+
+        /**
+         * Threats the event
+         * @param e the action event that occured
+         * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+         */
+        public void actionPerformed(ActionEvent e) {
+                JEditorPane outputPane = (JEditorPane) configuration.getOutputView();
+                JTextPane inputPane = (JTextPane) configuration.getInputCommandView();
+
+                outputPane.setSelectionStart(0);
+                outputPane.setSelectionEnd(outputPane.getText().length());
+
+                inputPane.setSelectionStart(0);
+                inputPane.setSelectionEnd(inputPane.getText().length());
+
+        }
 }
diff --git a/scilab/modules/console/tests/nonreg_tests/bug_4840.tst b/scilab/modules/console/tests/nonreg_tests/bug_4840.tst
new file mode 100644 (file)
index 0000000..f1d8c49
--- /dev/null
@@ -0,0 +1,39 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2011 - Calixte DENIZET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- INTERACTIVE TEST -->
+// <-- TEST WITH CONSOLE -->
+//
+// <-- Non-regression test for bug 4840 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/4840
+//
+// <-- Short Description -->
+// There is a performance problem with the console.
+// The more there is text in the console, the slower is the 
+// display, with exponential times.
+
+times = []
+rmax = 12
+IMAX = 50;
+JMAX = IMAX;
+for run = 1:rmax
+  tic;
+  for i = 1:IMAX
+    for j = 1:JMAX
+      mprintf("I=%d, J=%d\n",i,j);
+    end
+  end
+  t = toc();
+  times = [times t];
+end
+times
+
+// The times should be approximatively constant
+
+
index e98f071..f0cef7f 100644 (file)
@@ -31,6 +31,7 @@ import java.beans.PropertyChangeListener;
 import java.io.IOException;
 
 import javax.swing.JPanel;
+import javax.swing.JEditorPane;
 import javax.swing.JTextPane;
 import javax.swing.SwingUtilities;
 import javax.swing.event.ChangeEvent;
@@ -154,7 +155,7 @@ public class SwingScilabConsole extends SciConsole implements SimpleConsole {
 
                 menu.add(helpMenu);
 
-                ((JTextPane) getConfiguration().getOutputView()).setComponentPopupMenu(menu);
+                ((JEditorPane) getConfiguration().getOutputView()).setComponentPopupMenu(menu);
                 ((JTextPane) getConfiguration().getInputCommandView()).setComponentPopupMenu(menu);
                 ((JPanel) getConfiguration().getPromptView()).setComponentPopupMenu(menu);
 
@@ -238,7 +239,7 @@ public class SwingScilabConsole extends SciConsole implements SimpleConsole {
                 // Add a keylistener which will set the returned char
                 OneCharKeyEventListener keyListener = new OneCharKeyEventListener(this);
                 ((JTextPane) this.getConfiguration().getInputCommandView()).addKeyListener(keyListener);
-                ((JTextPane) this.getConfiguration().getOutputView()).addKeyListener(keyListener);
+                ((JEditorPane) this.getConfiguration().getOutputView()).addKeyListener(keyListener);
 
                 // Reads the buffer
                 retChar = this.getUserInputValue();
@@ -250,7 +251,7 @@ public class SwingScilabConsole extends SciConsole implements SimpleConsole {
 
                 // Remove the key listener
                 ((JTextPane) this.getConfiguration().getInputCommandView()).removeKeyListener(keyListener);
-                ((JTextPane) this.getConfiguration().getOutputView()).removeKeyListener(keyListener);
+                ((JEditorPane) this.getConfiguration().getOutputView()).removeKeyListener(keyListener);
 
                 this.getConfiguration().getPromptView().setVisible(true);
                 this.getConfiguration().getInputCommandView().setEditable(true);
@@ -406,7 +407,7 @@ public class SwingScilabConsole extends SciConsole implements SimpleConsole {
          * Select all the console contents
          */
         public void selectAll() {
-                JTextPane output = (JTextPane) this.getConfiguration().getOutputView();
+                JEditorPane output = (JEditorPane) this.getConfiguration().getOutputView();
                 output.setSelectionStart(0);
                 output.setSelectionEnd(output.getText().length());
                 // TODO should also select the prompt and the input
@@ -417,7 +418,7 @@ public class SwingScilabConsole extends SciConsole implements SimpleConsole {
          * @return The selected text in the console
          */
         private String getSelectedText() {
-                JTextPane output = (JTextPane) this.getConfiguration().getOutputView();
+                JEditorPane output = (JEditorPane) this.getConfiguration().getOutputView();
                 JTextPane input = (JTextPane) this.getConfiguration().getInputCommandView();
 
                 String selection = "";