Bug 11841 fixed: There was no way to search a word in the console. It is now possible... 43/8943/7
Calixte DENIZET [Wed, 5 Sep 2012 13:04:34 +0000 (15:04 +0200)]
Change-Id: I934a3451f6c22ace789c4ba2fc6a0faf4c86fc09

scilab/CHANGES_5.4.X
scilab/modules/console/etc/XConfiguration-general.xml
scilab/modules/console/src/java/org/scilab/modules/console/SciConsole.java
scilab/modules/gui/src/java/org/scilab/modules/gui/utils/HelpSearchField.java
scilab/modules/preferences/etc/XConfiguration.xml

index 7d536ab..b4e9d69 100644 (file)
@@ -29,6 +29,9 @@ Improvements
    schema
    If the file does not exist, propose to create it.
 
+* Search is now possible in the console. Shortcut F3 or CTRL+F enables it.
+  See Bug #11841.
+
 
 Removed functions
 ==================
index feae938..254300f 100644 (file)
@@ -53,7 +53,6 @@
                     <action key="OSSCKEY A" description="_(Line beginning)" name="console-line-begin"/>
                     <action key="OSSCKEY E" description="_(Line end)" name="console-line-end"/>
                     <action key="OSSCKEY B" description="_(Previous char)" name="console-prev-char"/>
-                    <action key="OSSCKEY F" description="_(Next char)" name="console-next-char"/>
                     <action key="OSSCKEY D" description="_(Delete next char)" name="console-del-next-char"/>
                     <action key="OSSCKEY H" description="_(Delete previous char)" name="console-del-prev-char"/>
                     <action key="OSSCKEY K" description="_(Delete end of line)" name="console-del-end-line"/>
@@ -72,6 +71,8 @@
                     <action key="OSSCKEY N" description="_(Previous history line)" name="console-prev-history"/>
                     <action key="OSSCKEY P" description="_(Next history line)" name="console-next-history"/>
                     <action key="F1" description="_(Help Browser)" name="console-help-browser"/>
+                    <action key="F3" description="_(Console Search Field)" name="console-search-field"/>
+                   <action key="OSSCKEY F" description="_(Console Search Field)" name="console-search-field"/>
                     <!--action key="OSSCKEY V" description="_(Paste)" name="console-paste"/>
           <action key="OSSCKEY O" description="_(Open a file)" name="console-open"/>
           <action key="OSSCKEY L" description="_(Load environment)" name="console-load"/>
index ba115f0..81fe3f7 100644 (file)
@@ -23,6 +23,7 @@ import java.awt.event.ComponentEvent;
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.Semaphore;
@@ -38,6 +39,7 @@ import javax.swing.JViewport;
 import javax.swing.SwingUtilities;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
 import javax.swing.KeyStroke;
 import javax.xml.parsers.ParserConfigurationException;
 import org.scilab.modules.localization.Messages;
@@ -120,6 +122,8 @@ public abstract class SciConsole extends JPanel {
 
     private boolean isToHome;
 
+    private Object searchField;
+
     /**
      * Constructor
      * @param configFilePath the configuration file to use
@@ -141,6 +145,13 @@ public abstract class SciConsole extends JPanel {
         }
 
         sciConsole = ConsoleBuilder.buildConsole(config, this);
+
+        try {
+            Class hsf = Class.forName("org.scilab.modules.gui.utils.HelpSearchField");
+            Constructor constructor = hsf.getConstructor(JPanel.class, JTextComponent.class);
+            searchField = constructor.newInstance(this, (SciOutputView) config.getOutputView());
+        } catch (Exception e) { }
+
         XConfiguration.addXConfigurationListener(new org.scilab.modules.console.ConsoleConfiguration(this));
         sciConsole.setForeground(ConsoleOptions.getConsoleColor().foreground);
         sciConsole.setBackground(ConsoleOptions.getConsoleColor().background);
@@ -152,30 +163,30 @@ public abstract class SciConsole extends JPanel {
 
         BoundedRangeModel model = jSP.getVerticalScrollBar().getModel();
         jSP.getVerticalScrollBar().setModel(new DefaultBoundedRangeModel(model.getValue(), model.getExtent(), model.getMinimum(), model.getMaximum()) {
-            public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting) {
-                // This method is overriden to keep the knob at the bottom during viewport resize
-                // and to keep the knob at an other place if the user decided it.
-                if (newMax != getMaximum()) {
-                    if (!adjusting) {
-                        if (atBottom) {
-                            super.setRangeProperties(newMax - newExtent, newExtent, newMin, newMax, false);
+                public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting) {
+                    // This method is overriden to keep the knob at the bottom during viewport resize
+                    // and to keep the knob at an other place if the user decided it.
+                    if (newMax != getMaximum()) {
+                        if (!adjusting) {
+                            if (atBottom) {
+                                super.setRangeProperties(newMax - newExtent, newExtent, newMin, newMax, false);
+                            } else {
+                                super.setRangeProperties(newValue, newExtent, newMin, newMax, false);
+                            }
                         } else {
-                            super.setRangeProperties(newValue, newExtent, newMin, newMax, false);
+                            double percent = (double) Math.abs(newMax - newValue - newExtent) / (double) newMax;
+                            if (atBottom && percent <= 0.03) {
+                                super.setRangeProperties(newMax - newExtent, newExtent, newMin, newMax, true);
+                            } else {
+                                super.setRangeProperties(newValue, newExtent, newMin, newMax, true);
+                                atBottom = percent <= 0.01;
+                            }
                         }
                     } else {
-                        double percent = (double) Math.abs(newMax - newValue - newExtent) / (double) newMax;
-                        if (atBottom && percent <= 0.03) {
-                            super.setRangeProperties(newMax - newExtent, newExtent, newMin, newMax, true);
-                        } else {
-                            super.setRangeProperties(newValue, newExtent, newMin, newMax, true);
-                            atBottom = percent <= 0.01;
-                        }
+                        super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
                     }
-                } else {
-                    super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
                 }
-            }
-        });
+            });
 
         this.add(jSP, BorderLayout.CENTER);
 
@@ -198,16 +209,16 @@ public abstract class SciConsole extends JPanel {
 
         // Bug 8055 : update the lines/columns only when the console is resized
         addComponentListener(new ComponentAdapter() {
-            public void componentResized(ComponentEvent evt) {
-                SwingUtilities.invokeLater(new Runnable() {
-                    public void run() {
-                        scilabLinesUpdate();
-                        jSP.getVerticalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().height);
-                        jSP.getHorizontalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().width);
-                    }
-                });
-            }
-        });
+                public void componentResized(ComponentEvent evt) {
+                    SwingUtilities.invokeLater(new Runnable() {
+                            public void run() {
+                                scilabLinesUpdate();
+                                jSP.getVerticalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().height);
+                                jSP.getHorizontalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().width);
+                            }
+                        });
+                }
+            });
 
         sciConsole.invalidate();
         sciConsole.doLayout();
@@ -262,6 +273,12 @@ public abstract class SciConsole extends JPanel {
         while (iter.hasNext()) {
             KeyStroke key = iter.next();
             String actionName = map.get(key);
+            if (actionName.equals("console-search-field") && searchField != null) {
+                try {
+                    Method sks = searchField.getClass().getMethod("setKeyStroke", KeyStroke.class);
+                    sks.invoke(searchField, key);
+                } catch (Exception e) { }
+            }
             String action = actionToName.get(actionName);
             if (action != null) {
                 try {
@@ -368,10 +385,10 @@ public abstract class SciConsole extends JPanel {
         jSP.getVerticalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().height);
         jSP.getHorizontalScrollBar().setBlockIncrement(jSP.getViewport().getExtentSize().width);
         SwingUtilities.invokeLater(new Runnable() {
-            public void run() {
-                jSP.getVerticalScrollBar().getModel().setValue(jSP.getVerticalScrollBar().getModel().getMaximum() - jSP.getVerticalScrollBar().getModel().getExtent());
-            }
-        });
+                public void run() {
+                    jSP.getVerticalScrollBar().getModel().setValue(jSP.getVerticalScrollBar().getModel().getMaximum() - jSP.getVerticalScrollBar().getModel().getExtent());
+                }
+            });
     }
 
     /**
@@ -459,15 +476,15 @@ public abstract class SciConsole extends JPanel {
             sciConsole.invalidate();
             sciConsole.doLayout();
             ((SciOutputView) config.getOutputView()).addComponentListener(new ComponentAdapter() {
-                public void componentResized(ComponentEvent evt) {
-                    if (evt.getComponent().getSize().height >= sciConsole.getSize().height) {
-                        evt.getComponent().removeComponentListener(this);
-                        sciConsole.setPreferredSize(null);
-                        sciConsole.invalidate();
-                        sciConsole.doLayout();
+                    public void componentResized(ComponentEvent evt) {
+                        if (evt.getComponent().getSize().height >= sciConsole.getSize().height) {
+                            evt.getComponent().removeComponentListener(this);
+                            sciConsole.setPreferredSize(null);
+                            sciConsole.invalidate();
+                            sciConsole.doLayout();
+                        }
                     }
-                }
-            });
+                });
 
             isToHome = false;
             jSP.getVerticalScrollBar().getModel().setValue(jSP.getVerticalScrollBar().getModel().getMaximum() - jSP.getVerticalScrollBar().getModel().getExtent());
@@ -547,7 +564,7 @@ public abstract class SciConsole extends JPanel {
             }
 
             ((SciInputCommandView) config.getInputCommandView())
-            .setCmdBuffer(linesToExec[nbStatements].replace(BACKSLASH_R, ""), displayCmdInOutput);
+                .setCmdBuffer(linesToExec[nbStatements].replace(BACKSLASH_R, ""), displayCmdInOutput);
             if (storeInHistory) {
                 ((SciHistoryManager) config.getHistoryManager()).addEntry(linesToExec[nbStatements].replace(BACKSLASH_R, ""));
             }
index b2d7e98..cda072e 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2011 - Calixte DENIZET
+ * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
  *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
@@ -41,6 +42,7 @@ import javax.swing.text.Document;
 import javax.swing.text.JTextComponent;
 
 import org.scilab.modules.commons.ScilabConstants;
+import org.scilab.modules.commons.gui.ScilabKeyStroke;
 
 /**
  * Class to have an incremental search field.
@@ -51,7 +53,8 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
 
     private static final String SCI = ScilabConstants.SCI.getPath();
     private static final String TAB = "tab";
-    private static final String F3 = "f3";
+    private static final String F3 = "F3";
+    private static final String KEY = "help-search-field";
     private static final ImageIcon CLOSEICON = new ImageIcon(SCI + "/modules/gui/images/icons/close-tab.png");
     private static final ImageIcon TOPICON = new ImageIcon(ScilabSwingUtilities.findIcon("go-top"));
     private static final ImageIcon BOTICON = new ImageIcon(ScilabSwingUtilities.findIcon("go-bottom"));
@@ -65,23 +68,31 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
 
     private final DefaultHighlighter.DefaultHighlightPainter highlighter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
     private int currentPos;
+    private String currentWord;
 
     /**
      * Default Constructor
      */
     public HelpSearchField(JPanel parent, JTextComponent textcomp) {
+        this(parent, textcomp, F3);
+    }
+
+    /**
+     * Default Constructor
+     */
+    public HelpSearchField(JPanel parent, JTextComponent textcomp, String key) {
         super(new BorderLayout());
         this.parent = parent;
-        this.textcomp = textcomp;
+        setTextComponent(textcomp, key);
         field = new JTextField();
         field.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET);
         field.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), TAB);
         field.getActionMap().put(TAB, new AbstractAction() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                HelpSearchField.this.textcomp.requestFocus();
-            }
-        });
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    HelpSearchField.this.textcomp.requestFocus();
+                }
+            });
         JPanel panelButtons = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
         panelButtons.add(new CloseButton());
         panelButtons.add(new TopBotButtons(true));
@@ -96,19 +107,35 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
      * @param textcomp the new textcomponent
      */
     public void setTextComponent(JTextComponent textcomp) {
+        setTextComponent(textcomp, F3);
+    }
+
+    /**
+     * Change the textcomponent
+     * @param textcomp the new textcomponent
+     */
+    public void setTextComponent(JTextComponent textcomp, String key) {
         this.textcomp = textcomp;
-        textcomp.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0), F3);
-        textcomp.getActionMap().put(F3, new AbstractAction() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                HelpSearchField.this.showField();
-            }
-        });
+        if (textcomp != null) {
+            textcomp.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(ScilabKeyStroke.getKeyStroke(key), KEY);
+            textcomp.getActionMap().put(KEY, new AbstractAction() {
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        HelpSearchField.this.showField();
+                    }
+                });
+        }
 
         text = null;
         currentPos = 0;
     }
 
+    public void setKeyStroke(KeyStroke key) {
+        if (textcomp != null) {
+            textcomp.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(key, KEY);
+        }
+    }
+
     /**
      * Get the text in the text component to search in
      */
@@ -161,11 +188,11 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
      * Hide the search field
      */
     public void hideField() {
+        parent.requestFocus();
         removeListeners();
         textcomp.getHighlighter().removeAllHighlights();
         setVisible(false);
         parent.remove(this);
-        parent.revalidate();
     }
 
     /**
@@ -178,7 +205,6 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
             field.addFocusListener(this);
             parent.add(this, BorderLayout.PAGE_END);
             setVisible(true);
-            parent.revalidate();
         }
         requestFocus();
     }
@@ -189,7 +215,6 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
      * @param end the end position
      */
     public void highlightText(int start, int end) {
-        textcomp.getHighlighter().removeAllHighlights();
         if (start != -1) {
             try {
                 JScrollPane scrollPane = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, textcomp);
@@ -199,14 +224,15 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
                     final int value = sb.getValue();
                     final int h = sb.getHeight();
                     SwingUtilities.invokeLater(new Runnable() {
-                        @Override
-                        public void run() {
-                            if (rect.y < value || rect.y > value + h) {
-                                sb.setValue(Math.max(0, rect.y - h / 2));
+                            @Override
+                            public void run() {
+                                if (rect.y < value || rect.y > value + h) {
+                                    sb.setValue(Math.max(0, rect.y - h / 2));
+                                }
                             }
-                        }
-                    });
+                        });
                 }
+                textcomp.getHighlighter().removeAllHighlights();
                 textcomp.getHighlighter().addHighlight(start, end, highlighter);
                 currentPos = start;
             } catch (BadLocationException ex) {
@@ -234,19 +260,33 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
             if (str != null) {
                 int start;
                 str = str.toLowerCase();
+                if (!str.equals(currentWord)) {
+                    currentWord = str;
+                    currentPos = 0;
+                    textcomp.getHighlighter().removeAllHighlights();
+                }
                 getText();
                 if ((key == KeyEvent.VK_ENTER || key == KeyEvent.VK_F3) && ((e.getModifiers() & KeyEvent.SHIFT_MASK) != 0)) {
                     currentPos = Math.max(0, currentPos - 1);
                     start = text.lastIndexOf(str, currentPos);
+                    if (start == -1) {
+                        currentPos = text.length() - 1;
+                    }
                     e.consume();
                 } else {
                     if (key == KeyEvent.VK_ENTER || key == KeyEvent.VK_F3) {
                         currentPos++;
                     }
                     start = text.indexOf(str, currentPos);
+                    if (start == -1) {
+                        currentPos = 0;
+                    }
                 }
 
-                highlightText(start, start + str.length());
+                int end = start + str.length();
+                if (start != end) {
+                    highlightText(start, end);
+                }
             }
         }
     }
@@ -280,11 +320,11 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
             setBorderPainted(false);
             setPreferredSize(new Dimension(BUTTONSIZE, BUTTONSIZE));
             addActionListener(new ActionListener() {
-                @Override
-                public void actionPerformed(ActionEvent e) {
-                    hideField();
-                }
-            });
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        hideField();
+                    }
+                });
         }
     }
 
@@ -306,32 +346,38 @@ public class HelpSearchField extends JPanel implements FocusListener, KeyListene
             setBorderPainted(false);
             setPreferredSize(new Dimension(BUTTONSIZE, BUTTONSIZE));
             addActionListener(new ActionListener() {
-                @Override
-                public void actionPerformed(ActionEvent e) {
-                    String str = field.getText();
-                    String txt = "";
-                    Document doc = textcomp.getDocument();
-                    try {
-                        txt = doc.getText(0, doc.getLength()).toLowerCase();
-                    } catch (BadLocationException ex) {
-                        System.err.println(ex);
-                    }
-
-                    if (str != null) {
-                        int start;
-                        str = str.toLowerCase();
-                        if (top) {
-                            currentPos = Math.max(0, currentPos - 1);;
-                            start = txt.lastIndexOf(str, currentPos);
-                        } else {
-                            currentPos++;
-                            start = txt.indexOf(str, currentPos);
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        String str = field.getText();
+                        String txt = "";
+                        Document doc = textcomp.getDocument();
+                        try {
+                            txt = doc.getText(0, doc.getLength()).toLowerCase();
+                        } catch (BadLocationException ex) {
+                            System.err.println(ex);
                         }
 
-                        highlightText(start, start + str.length());
+                        if (str != null && !str.isEmpty()) {
+                            int start;
+                            str = str.toLowerCase();
+                            if (top) {
+                                currentPos = Math.max(0, currentPos - 1);;
+                                start = txt.lastIndexOf(str, currentPos);
+                                if (start == -1) {
+                                    currentPos = text.length() - 1;
+                                }
+                            } else {
+                                currentPos++;
+                                start = txt.indexOf(str, currentPos);
+                                if (start == -1) {
+                                    currentPos = 0;
+                                }
+                            }
+
+                            highlightText(start, start + str.length());
+                        }
                     }
-                }
-            });
+                });
         }
     }
 }
index e9c99cb..7710e03 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<interface version="0.10" path="1/" width="800" height="550">
+<interface version="0.11" path="1/" width="800" height="550">
     <general/>
     <web/>
     <preference/>