Revision: 6330
          http://sourceforge.net/p/jump-pilot/code/6330
Author:   michaudm
Date:     2020-06-12 20:15:39 +0000 (Fri, 12 Jun 2020)
Log Message:
-----------
Upload BeanshellEditor PlugIn

Added Paths:
-----------
    plug-ins/BshEditor4Jump/
    plug-ins/BshEditor4Jump/trunk/
    plug-ins/BshEditor4Jump/trunk/build.xml
    plug-ins/BshEditor4Jump/trunk/dist/
    plug-ins/BshEditor4Jump/trunk/doc/
    plug-ins/BshEditor4Jump/trunk/lib/
    plug-ins/BshEditor4Jump/trunk/lib/bsh-2.0b6.jar
    plug-ins/BshEditor4Jump/trunk/lib/buoy-1.9.jar
    plug-ins/BshEditor4Jump/trunk/resources/
    plug-ins/BshEditor4Jump/trunk/resources/bsheditor/
    plug-ins/BshEditor4Jump/trunk/resources/bsheditor/BeanShellEditor.properties
    plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/
    
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n.properties
    
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_en_GB.properties
    
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_en_US.properties
    
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_es.properties
    
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_fr_FR.properties
    
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_it.properties
    plug-ins/BshEditor4Jump/trunk/resources/bsheditor/start-jump.bsh
    plug-ins/BshEditor4Jump/trunk/src/
    plug-ins/BshEditor4Jump/trunk/src/fr/
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/BeanShellEditor.java
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/New24.gif
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Open24.gif
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Run24.gif
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Save24.gif
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/SaveAs24.gif
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Script16.gif
    
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreeMinus16.gif
    
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreePlus16.gif
    
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/edit_clear.png
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/
    plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/
    
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/BeanShellEditorPlugIn.java
    
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/BshEditorPlugInExtension.java
    plug-ins/BshEditor4Jump/trunk/src/org/
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/DefaultInputHandler.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/InputHandler.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/JEditTextArea.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/KeywordMap.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/SyntaxDocument.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/SyntaxStyle.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/SyntaxUtilities.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/TextAreaDefaults.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/TextAreaPainter.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/TextUtilities.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/tokenmarker/
    
plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/tokenmarker/CTokenMarker.java
    
plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/tokenmarker/JavaTokenMarker.java
    plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/tokenmarker/Token.java
    
plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/tokenmarker/TokenMarker.java

Added: plug-ins/BshEditor4Jump/trunk/build.xml
===================================================================
--- plug-ins/BshEditor4Jump/trunk/build.xml                             (rev 0)
+++ plug-ins/BshEditor4Jump/trunk/build.xml     2020-06-12 20:15:39 UTC (rev 
6330)
@@ -0,0 +1,92 @@
+<project name="jump-plugins" default="compile" basedir=".">
+
+    
<!--*************************************************************************
+    
*****************************************************************************
+    **                                  PROPERTIES                             
**
+    
*****************************************************************************
+    
**************************************************************************-->
+
+    <!-- PROPERTIES : MAIN ARCHITECTURE -->
+    <property name="src"        value="src" />
+    <property name="bin"        value="bin" />
+    <property name="lib"        value="lib" />
+    <property name="build"      value="build" />
+    <property name="dist"       value="dist" />
+    <property name="javadoc"    value="javadoc" />
+    <property name="resources"  value="resources" />
+    <property name="openjump"   value="../../openjump_lib" />
+    
+    <!-- plugins -->
+    <property name="version"    value="0.3.0" />
+    
+
+    <!-- =================================================================== 
-->
+    <!-- Defines the classpath used for compilation and test.                
-->
+    <!-- =================================================================== 
-->
+    <path id="classpath">
+        <fileset dir="${lib}">
+            <include name="**/*.jar"/>
+        </fileset>
+        <fileset dir="${openjump}">
+            <include name="**/*.jar"/>
+        </fileset>
+    </path>
+    
+    <target name="clean" id="clean">
+        <delete dir="${build}"/>
+    </target>
+   
+    <target name="compile" id="compile" depends="clean">
+        <tstamp/>
+        <mkdir dir="${build}"/>
+        <javac srcdir="${src}" destdir="${build}" 
+               debug="on"      deprecation="false" verbose="no"
+               includeantruntime="false"
+               source="1.8"
+               target="1.8"
+               encoding="UTF-8">
+             <classpath refid="classpath"/>
+        </javac>
+        <copy todir="${build}" >
+            <fileset dir="${src}" casesensitive="false" includes="**/*.gif, 
**/*.jpg, **/*.png" />
+            <fileset dir="${src}" casesensitive="false" 
includes="**/*.properties" />
+            <fileset dir="${src}" casesensitive="false" includes="**/*.html" />
+            <fileset dir="${src}" casesensitive="false" includes="**/*.txt" />
+            <fileset dir="${src}" casesensitive="false" 
includes="**/*.java2xml" />
+        </copy>
+    </target>
+
+    
+    <!-- =================================================================== 
-->
+    <!-- bsheditor4jump                                                        
    -->
+    <!-- =================================================================== 
-->
+    <target name="jar-bsheditor4jump" id="jar-bsheditor4jump" 
depends="compile">
+        <jar basedir="${build}" 
jarfile="${dist}/bsheditor4jump-${version}.jar">
+            <include name="org/syntax/jedit/**/*"/>
+            <include name="fr/michaelm/bsheditor/**/*"/>
+            <include name="fr/michaelm/jump/bsheditor/**/*"/>
+            <fileset dir="${resources}/bsheditor/I18N" />
+            <manifest>
+              <!-- Who is building this jar? -->
+              <attribute name="Built-By" value="${user.name}"/>
+              <!-- Information about the program itself -->
+              <attribute name="Implementation-Version" value="${version}"/>
+              <attribute name="Class-Path" value="../buoy.jar 
../bsh-2.0b4.jar"/>
+              <attribute name="Main-Class" 
value="fr.michaelm.bsheditor.BeanShellEditor"/>
+            </manifest>
+        </jar>
+               <!--copy file="${dist}/bsheditor4jump-${version}.jar" 
todir="${openjump-ext}"/-->
+    </target>
+    
+    <target name="zip-bsheditor4jump-src" id="zip-bsheditor4jump-src" 
depends="compile">
+        <zip basedir="." zipfile="${dist}/bsheditor4jump-src-${version}.zip">
+            <include name="src/org/syntax/jedit/**/*"/>
+            <include name="src/fr/michaelm/bsheditor/**/*"/>
+            <include name="src/fr/michaelm/jump/bsheditor/**/*"/>
+            <include name="dist/bsheditor4jump-0.2.jar"/>
+            <fileset dir="${resources}/jump/bsheditor4jump"/>
+            <include name="build.xml"/>
+        </zip>
+    </target>
+    
+</project>
\ No newline at end of file

Added: plug-ins/BshEditor4Jump/trunk/lib/bsh-2.0b6.jar
===================================================================
(Binary files differ)

Index: plug-ins/BshEditor4Jump/trunk/lib/bsh-2.0b6.jar
===================================================================
--- plug-ins/BshEditor4Jump/trunk/lib/bsh-2.0b6.jar     2020-06-12 15:44:40 UTC 
(rev 6329)
+++ plug-ins/BshEditor4Jump/trunk/lib/bsh-2.0b6.jar     2020-06-12 20:15:39 UTC 
(rev 6330)

Property changes on: plug-ins/BshEditor4Jump/trunk/lib/bsh-2.0b6.jar
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: plug-ins/BshEditor4Jump/trunk/lib/buoy-1.9.jar
===================================================================
(Binary files differ)

Index: plug-ins/BshEditor4Jump/trunk/lib/buoy-1.9.jar
===================================================================
--- plug-ins/BshEditor4Jump/trunk/lib/buoy-1.9.jar      2020-06-12 15:44:40 UTC 
(rev 6329)
+++ plug-ins/BshEditor4Jump/trunk/lib/buoy-1.9.jar      2020-06-12 20:15:39 UTC 
(rev 6330)

Property changes on: plug-ins/BshEditor4Jump/trunk/lib/buoy-1.9.jar
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/BeanShellEditor.properties
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/BeanShellEditor.properties    
                            (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/BeanShellEditor.properties    
    2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,4 @@
+#Sun Jul 25 20:55:09 CEST 2004
+scriptsFolder=
+jarsFolder=
+start=start-jump.bsh
\ No newline at end of file

Added: 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n.properties
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n.properties
                              (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n.properties
      2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,41 @@
+# BeanShellEditor in english en_US
+
+# MENU
+name=BeanShell Editor
+
+menu.file=File
+menu.file.new=New
+menu.file.open=Open
+menu.file.save=Save
+menu.file.saveas=Save as...
+
+menu.options=Options
+menu.options.scriptfolder=Script Folder
+menu.options.extlib=Other Libraries
+menu.options.startingscript=Starting Script
+menu.options.startingscriptalways=Always Use Starting Script
+menu.options.verboseoutput=Verbose Output
+
+menu.help=Help
+menu.help.help=Help
+menu.help.info=Info
+
+# TOOLBAR
+toolbar.button.run=Go!
+toolbar.fontSize=Font Size
+
+# EDITOR
+editor.title.new=New Script
+editor.writehere=//Start writing your script here\n
+editor.status.numbering=Cursor is on line : 
+
+# COMMAND LINE
+commandline.title=Command line
+commandline.button.run=Run
+commandline.button.clearoutput=Clear Output
+
+# SCRIPT MANAGER
+manager.scriptfolder=Scripts Folder
+manager.libraries=External libraries
+manager.variables=Variables and methods
+

Added: 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_en_GB.properties
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_en_GB.properties
                                (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_en_GB.properties
        2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,42 @@
+# BeanShellEditor in english en_EN
+
+# MENU
+
+name=BeanShell Editor
+
+menu.file=File
+menu.file.new=New
+menu.file.open=Open
+menu.file.save=Save
+menu.file.saveas=Save as...
+
+menu.options=Options
+menu.options.scriptfolder=Script Folder
+menu.options.extlib=Other Libraries
+menu.options.startingscript=Starting Script
+menu.options.startingscriptalways=Always Use Starting Script
+menu.options.verboseoutput=Verbose Output
+
+menu.help=Help
+menu.help.help=Help
+menu.help.info=Info
+
+# TOOLBAR
+toolbar.button.run=Go!
+toolbar.fontSize=Font Size
+
+# EDITOR
+editor.title.new=New Script
+editor.writehere=//Start writing your script here\n
+editor.status.numbering=Cursor is on line : 
+
+# COMMAND LINE
+commandline.title=Command line
+commandline.button.run=Run
+commandline.button.clearoutput=Clear Output
+
+# SCRIPT MANAGER
+manager.scriptfolder=Scripts Folder
+manager.libraries=External libraries
+manager.variables=Variables and methods
+

Added: 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_en_US.properties
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_en_US.properties
                                (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_en_US.properties
        2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,42 @@
+# BeanShellEditor in english en_US
+
+# MENU
+
+name=BeanShell Editor
+
+menu.file=File
+menu.file.new=New
+menu.file.open=Open
+menu.file.save=Save
+menu.file.saveas=Save as...
+
+menu.options=Options
+menu.options.scriptfolder=Script Folder
+menu.options.extlib=Other Libraries
+menu.options.startingscript=Starting Script
+menu.options.startingscriptalways=Always Use Starting Script
+menu.options.verboseoutput=Verbose Output
+
+menu.help=Help
+menu.help.help=Help
+menu.help.info=Info
+
+# TOOLBAR
+toolbar.button.run=Go!
+toolbar.fontSize=Font Size
+
+# EDITOR
+editor.title.new=New Script
+editor.writehere=//Start writing your script here\n
+editor.status.numbering=Cursor is on line : 
+
+# COMMAND LINE
+commandline.title=Command line
+commandline.button.run=Run
+commandline.button.clearoutput=Clear Output
+
+# SCRIPT MANAGER
+manager.scriptfolder=Scripts Folder
+manager.libraries=External libraries
+manager.variables=Variables and methods
+

Added: 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_es.properties
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_es.properties
                           (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_es.properties
   2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,30 @@
+#BeanShellEditor_es.properties
+
+name=BeanShell Editor
+
+commandline.button.clearoutput=Borrar salida
+commandline.button.run=Ejecutar
+commandline.title=Riga de comando
+editor.status.numbering=El cursor esta sobre la riga
+editor.title.new=Nuevo script
+editor.writehere=//Empleza a scibir tu script aqu\u00EC
+manager.libraries=Librerias externas
+manager.scriptfolder=Carpeta script
+manager.variables=Variables y metodos
+menu.file=Fichero
+menu.file.new=Nuevo
+menu.file.open=Abrir
+menu.file.save=Guardar
+menu.file.saveas=Guardar como...
+menu.help=Ayuda
+menu.help.help=Ayuda
+menu.help.info=Info
+menu.options=Opciones
+menu.options.extlib=Otras librerias
+menu.options.scriptfolder=Carpeta script
+menu.options.startingscript=Script de inicio
+menu.options.startingscriptalways=Ejecutar siempre el scrip de inicio
+menu.options.verboseoutput=Muchos messajes
+toolbar.button.run=Go!
+toolbar.fontSize=Font Size
+

Added: 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_fr_FR.properties
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_fr_FR.properties
                                (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_fr_FR.properties
        2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,42 @@
+# BeanShellEditor en fran\xE7ais fr_FR
+
+# MENU
+
+name=Editeur BeanShell
+
+menu.file=Fichier
+menu.file.new=Nouveau
+menu.file.open=Ouvrir
+menu.file.save=Enregistrer
+menu.file.saveas=Enregistrer sous...
+
+menu.options=Options
+menu.options.scriptfolder=R\xE9pertoire de scripts
+menu.options.extlib=Biblioth\xE8ques externes
+menu.options.startingscript=Script de d\xE9marrage
+menu.options.startingscriptalways=Toujours ex\xE9cuter le script de 
d\xE9marrage
+menu.options.verboseoutput=Plus de messages
+
+menu.help=Aide
+menu.help.help=Aide
+menu.help.info=Info
+
+# TOOLBAR
+toolbar.button.run=Go!
+toolbar.fontSize=Taille de la police
+
+# EDITOR
+editor.title.new=Nouveau script
+editor.writehere=//Commencez votre script BeanShell ici\n
+editor.status.numbering=Le curseur est sur la ligne : 
+
+# COMMAND LINE
+commandline.title=Ligne de commandes
+commandline.button.run=Ex\xE9cuter
+commandline.button.clearoutput=Effacer sortie
+
+# SCRIPT MANAGER
+manager.scriptfolder=Scripts
+manager.libraries=Biblioth\xE8ques
+manager.variables=Variables et m\xE9thodes
+

Added: 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_it.properties
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_it.properties
                           (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/resources/bsheditor/I18N/BeanShellEditor_i18n_it.properties
   2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,30 @@
+#BeanShellEditor_i18n_it.properties
+
+name=BeanShell Editor
+
+commandline.button.clearoutput=Elimina risultato
+commandline.button.run=Esegui
+commandline.title=Linea di comando
+editor.status.numbering=Il cursore \u00E8 sulla riga
+editor.title.new=Nuovo script
+editor.writehere=//Inizia a scrivere il tuo script qu\u00EC
+manager.libraries=Librerie esterne
+manager.scriptfolder=Cartella script
+manager.variables=Variabili e metodo
+menu.file=File
+menu.file.new=Nuovo
+menu.file.open=Apri
+menu.file.save=Salva
+menu.file.saveas=Salva come...
+menu.help=?
+menu.help.help=Aiuto
+menu.help.info=Info
+menu.options=Opzioni
+menu.options.extlib=Altre librerie
+menu.options.scriptfolder=Cartella script
+menu.options.startingscript=Script di avvio
+menu.options.startingscriptalways=Eseguire sempre lo script di avvio
+menu.options.verboseoutput=Molti messaggi
+toolbar.button.run=Go\!
+toolbar.fontSize=Font Size
+

Added: plug-ins/BshEditor4Jump/trunk/resources/bsheditor/start-jump.bsh
===================================================================
--- plug-ins/BshEditor4Jump/trunk/resources/bsheditor/start-jump.bsh            
                (rev 0)
+++ plug-ins/BshEditor4Jump/trunk/resources/bsheditor/start-jump.bsh    
2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,31 @@
+// Starting script for jump application
+
+// wc is a variable name for workbench context
+// it gives access to the whole OpenJUMP software
+
+import com.vividsolutions.jump.feature.*;
+import com.vividsolutions.jump.workbench.model.*;
+import com.vividsolutions.jump.io.*;
+import com.vividsolutions.jump.io.datasource.*;
+import com.vividsolutions.jump.datastore.*;
+import com.vividsolutions.jump.datastore.postgis.*;
+import com.vividsolutions.jump.io.*;
+import com.vividsolutions.jump.workbench.ui.*;
+import com.vividsolutions.jump.workbench.ui.renderer.style.*;
+
+
+
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.io.*;
+import com.vividsolutions.jts.index.strtree.*;
+import com.vividsolutions.jts.linearref.*;
+import com.vividsolutions.jts.noding.*;
+import com.vividsolutions.jts.planargraph.*;
+import com.vividsolutions.jts.simplify.*;
+import com.vividsolutions.jts.util.*;
+
+layer(String name) {return wc.layerManager.getLayer(name);}
+
+fc(String name) {return 
wc.layerManager.getLayer(name).featureCollectionWrapper;}
+
+ifc(String name) {return new IndexedFeatureCollection(fc(name), new 
STRtree());}
\ No newline at end of file

Added: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/BeanShellEditor.java
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/BeanShellEditor.java    
                            (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/BeanShellEditor.java    
    2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,1055 @@
+package fr.michaelm.bsheditor;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+import java.util.jar.*;
+import java.util.logging.*;
+import java.io.*;
+import javax.swing.event.CaretListener;
+import javax.swing.tree.*;
+import javax.swing.ImageIcon;
+
+import bsh.EvalError;
+import buoy.event.*;
+import buoy.widget.*;
+import org.syntax.jedit.JEditTextArea;
+import org.syntax.jedit.SyntaxStyle;
+import org.syntax.jedit.TextAreaDefaults;
+import org.syntax.jedit.tokenmarker.Token;
+import org.syntax.jedit.tokenmarker.JavaTokenMarker;
+import bsh.Interpreter;
+
+/**
+ * BeanShell script editor has :
+ * <ul>
+ * <li>A Script editor text area with new, open, save and save as commands</li>
+ * <li>A command line textfield to write and run one line beanshell 
scripts</li>
+ * <li>An output text area</li>
+ * <li>A Tree panel to easily access your script files directory (open your
+ * script file with a double-clicking in the tree panel)</li>
+ * <li>Easy loading/import of jar files located in a given jar directory
+ * (right-click on a jar file name to addClassPath and/or import package in the
+ * script file).</li>
+ * </ul>
+ * <p>
+ * This editor is ©2004 Michaël MICHAUD and published under the LGPL
+ * <p>
+ * It is based on (and would be nothing without) :
+ * <ul>
+ * <li>BeanShell, the java-based script library from Pat Niemeyer (LGPL)</li>
+ * <li>Buoy, the user interface library from Peter Eastman (Public Domain)</li>
+ * <li>JEditSyntax package from Slava Pestov (MIT licence)</li>
+ * </ul>
+ * <p>[TODO] Help and documentation
+ *
+ * @author Michaël MICHAUD
+ * @version 0.3 (2009-12-20)
+ * 0.2 (2009-03-20)
+ */
+//0.1 (2004-11-13) initial release
+//0.2 (2009-03-20) makes the code java 5.0 compatible (M. Michaud)
+//0.2.1 (2009-12-20) add initial statements capability
+//0.3.0 (2020-06-11) add option to change font size + bug fix
+public class BeanShellEditor extends BFrame {
+   
+   /**
+    * Properties of the BeanShellEditor are :
+    * <ul>
+    * <li>scriptsFolder directory path</li>
+    * <li>jarsFolder directory path</li>
+    * <li>start.bsh file path</li>
+    */
+    private Properties properties;
+   
+   /**
+    * Default interpreter. A new Interpreter is created each time the main bsh
+    * editor is run.
+    */
+    private Interpreter interpreter = new Interpreter();
+    
+    final private Logger log = Logger.getLogger("BshEditor");
+    private StreamHandler outputStreamHandler;
+    private final java.util.logging.Formatter formatter = new 
SimpleFormatter(){
+        public String format(LogRecord record) {
+            if (record.getLevel().intValue()>800) return 
"\n"+record.getMessage() + "!!!\n";
+            else if (record.getLevel().intValue()==500) return 
"\n\t"+record.getMessage();
+            else if (record.getLevel().intValue()==400) return 
"\n\t\t"+record.getMessage();
+            else if (record.getLevel().intValue()==300) return 
"\n\t\t\t"+record.getMessage();
+            else return "\n"+record.getMessage();
+        }
+    };
+    
+   /**
+    * Get the default locale of the jvm
+    * This value can be overloaded by -I18N argument of the main or constructor
+    */
+    final private Locale locale;
+    final private ResourceBundle i18n;
+
+   
+   /**
+    * Map defining a set of initial variables
+    */
+    Map<String,Object> bshEditorInitVariables = new HashMap<>();
+   
+   /**
+    * List of statements to execute after variable initialization and
+    * before the user script
+    */
+    List<String> bshEditorInitStatements = new ArrayList<>();
+   
+    // MENU BAR
+    BMenuBar menuBar;
+      BMenu fileMenu;
+        BMenuItem newScriptMenuItem;
+        BMenuItem openScriptMenuItem;
+        BMenuItem saveScriptMenuItem;
+        BMenuItem saveScriptAsMenuItem;
+            boolean overwriting;
+            
+      BMenu optionMenu;
+        BMenuItem chooseScriptsFolder;
+          File scriptsFolder;
+        BMenuItem chooseJarsFolder;
+          File jarsFolder;
+            Map<String,String> jarFileMap;
+            //Set importsSet;
+          File extFolder;
+        BMenuItem chooseStartFile;
+          File startFile;
+        BCheckBoxMenuItem startFileCBMI;
+            boolean alwaysStartFile = true;
+        BCheckBoxMenuItem verboseCBMI;
+            boolean verbose = false;
+      
+      BMenu helpMenu;
+          BMenuItem infoMenuItem;
+          BMenuItem helpMenuItem;
+    
+    // The main container for the UI contains
+    // - a zone for toolbars (north)
+    // - a split panel (center)
+    BorderContainer bc;
+    
+    // TOOLBAR
+    // TODO : replace button text by icons
+    ColumnContainer toolBars;
+    RowContainer mainToolBar;
+        BButton newButton;
+        BButton openButton;
+        BButton saveButton;
+        BButton saveAsButton;
+        BButton runScriptButton;
+        BButton clearOutputButton;
+        BLabel fontSizeLabel;
+        BComboBox fontSizeChooser;
+    RowContainer pluginsToolBar;
+        HashMap<String,BButton> plugins;
+    
+    BSplitPane mainPanel;
+    
+    // LEFT PANEL
+    BTabbedPane leftTabbedPane;
+        // Script files tree
+        BScrollPane bshScriptsScrollPane;
+        BTree bshScriptsTree;
+        // Jars list
+        BScrollPane jarsScrollPane;
+        ColumnContainer jarsContainer;
+        // Variables list
+        BScrollPane varsScrollPane;
+        ColumnContainer varListContainer;
+        BList variablesList;
+        
+    // MAIN PANEL
+    BSplitPane rightPanel;
+        BorderContainer northPanel;
+            BLabel scriptTitle;
+            JEditTextArea jEditTextArea;
+        BorderContainer southPanel;
+            FormContainer commandLineContainer;
+                BLabel commandLineLabel;
+                BTextField commandLine;
+                  List<String> commands = new ArrayList<>();
+                  int commandIndex = 0;
+                BButton runCommand;
+                BButton clearOutput;
+            BScrollPane outputScrollPane;
+                BTextArea outputTextArea;
+                  PrintStream out;
+    
+   /**
+    * Main method : create a BeanShellEditor.
+    * <p>When BeanShellEditor is launched as a standalone application, the
+    * WindowClosingEvent shut the jvm down
+    * @param args if args[0] is -i18n, args[1] and args[2] must be the language
+    * and the country 2 letters code
+    */
+    public static void main(String[] args) {
+        try {
+            Locale loc;
+            if (args.length>2 && args[0].equalsIgnoreCase("-i18n")) {
+                loc = new Locale(args[1], args[2]);
+            }
+            else loc = Locale.getDefault();
+            BeanShellEditor bshEditor = new BeanShellEditor(loc);
+            bshEditor.addEventLink(WindowClosingEvent.class, bshEditor, 
"exitJvm");
+        }
+        catch(Exception e) {e.printStackTrace();}
+    }
+    
+   /**
+    * Default constructor with no argument.
+    * <p>Used by main() method for standalone applications.
+    */
+    public BeanShellEditor(Locale loc) {
+        super("BeanShell Editor");
+        addEventLink(WindowClosingEvent.class, this, "exit");
+        addEventLink(WindowResizedEvent.class, this, "resize");
+        locale = loc==null?Locale.getDefault():loc;
+        i18n = ResourceBundle.getBundle("BeanShellEditor_i18n", locale);
+        initUI();
+        initProperties();
+        pack();
+        setVisible(true);
+        initInterpreter();
+        //startingScript();
+    }
+    
+   /**
+    * Constructor with a map argument used to create a plugin BeanShellEditor.
+    * <p>
+    * When BeanShellEditor is used as a plugin, vars may be used to initialize
+    * beanshell variables.<p>
+    * Typically, if BeanShellEditor is a plugin of MyApplication, one should
+    * initialize BeanShellEditor the following way :<ol>
+    * <li>MyApplication myApp = new MyApplication();</li>
+    * <li>Map map = new HashMap();</li>
+    * <li>map.put("application", myApp);</li>
+    * <li>BeanShellEditor bshEditor = new BeanShellEditor(map);</li>
+    * </ol>
+    * This way, BeanShellEditor may use the word "application" to access to
+    * the object myApp.
+    * @param vars parameter used to map interpreter variable names with objects
+    * from the main application when BeanShellEditor is used as a plugin
+    */
+    public BeanShellEditor(Map<String,Object> vars, Locale loc) {
+        super("BeanShell Editor");
+        addEventLink(WindowClosingEvent.class, this, "exit");
+        addEventLink(WindowResizedEvent.class, this, "resize");
+        locale = loc==null?Locale.getDefault():loc;
+        i18n = ResourceBundle.getBundle("BeanShellEditor_i18n", locale);
+        initUI();
+        initProperties();
+        pack();
+        setVisible(true);
+        bshEditorInitVariables.putAll(vars);
+        initInterpreter();
+    }
+
+   /**
+    * If the file defined by the start property exists, initialize the
+    * interpreter with the starting script
+    * this private method is just called once by the constructor
+    */
+    private void startingScript() {
+        String start = properties.getProperty("start");
+           try {
+            if (start!=null && new File(start).exists()) {
+                interpreter.source(start);
+            }
+        } catch(IOException | EvalError fnfe) {
+            fnfe.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+
+   /**
+    * User Interface Initialization
+    */
+    private void initUI() {
+        // MENUBAR ELEMENTS INITIALIZATION
+        menuBar = new BMenuBar();
+            fileMenu = new BMenu(i18n.getString("menu.file"));
+                newScriptMenuItem = new 
BMenuItem(i18n.getString("menu.file.new"), new Shortcut('N', 
Shortcut.CTRL_MASK));
+                    fileMenu.add(newScriptMenuItem);
+                    newScriptMenuItem.addEventLink(CommandEvent.class, this, 
"newScript");
+                openScriptMenuItem = new 
BMenuItem(i18n.getString("menu.file.open"), new Shortcut('O', 
Shortcut.CTRL_MASK));
+                    fileMenu.add(openScriptMenuItem);
+                    openScriptMenuItem.addEventLink(CommandEvent.class, this, 
"open");
+                saveScriptMenuItem = new 
BMenuItem(i18n.getString("menu.file.save"), new Shortcut('S', 
Shortcut.CTRL_MASK));
+                    fileMenu.add(saveScriptMenuItem);
+                    saveScriptMenuItem.addEventLink(CommandEvent.class, this, 
"save");
+                saveScriptAsMenuItem = new 
BMenuItem(i18n.getString("menu.file.saveas"),
+                        new Shortcut('S', 
Shortcut.CTRL_MASK|Shortcut.SHIFT_MASK));
+                    fileMenu.add(saveScriptAsMenuItem);
+                    saveScriptAsMenuItem.addEventLink(CommandEvent.class, 
this, "saveAs");
+            optionMenu = new BMenu(i18n.getString("menu.options"));
+                chooseScriptsFolder = new 
BMenuItem(i18n.getString("menu.options.scriptfolder"));
+                    scriptsFolder = new File(".");
+                    optionMenu.add(chooseScriptsFolder);
+                    chooseScriptsFolder.addEventLink(CommandEvent.class, this, 
"chooseScriptsFolder");
+                chooseJarsFolder = new 
BMenuItem(i18n.getString("menu.options.extlib"));
+                    jarsFolder = new File(".");
+                    //jarFiles = new TreeSet();
+                    jarFileMap = new HashMap<>();
+                    //importsSet = new TreeSet();
+                    optionMenu.add(chooseJarsFolder);
+                    chooseJarsFolder.addEventLink(CommandEvent.class, this, 
"changeJarsFolder");
+                chooseStartFile = new 
BMenuItem(i18n.getString("menu.options.startingscript"));
+                    startFile = new File("start.bsh");
+                    optionMenu.add(chooseStartFile);
+                    chooseStartFile.addEventLink(CommandEvent.class, this, 
"chooseStartFile");
+                startFileCBMI = new BCheckBoxMenuItem();
+                    
startFileCBMI.setText(i18n.getString("menu.options.startingscriptalways"));
+                    startFileCBMI.setState(true);
+                    optionMenu.add(startFileCBMI);
+                    startFileCBMI.addEventLink(CommandEvent.class, this, 
"changeAlwaysStartFile");
+                verboseCBMI = new BCheckBoxMenuItem();
+                    
verboseCBMI.setText(i18n.getString("menu.options.verboseoutput"));
+                    optionMenu.add(verboseCBMI);
+                    verboseCBMI.addEventLink(CommandEvent.class, this, 
"changeVerbose");
+            helpMenu = new BMenu(i18n.getString("menu.help"));
+                infoMenuItem = new BMenuItem(i18n.getString("menu.help.help"));
+                    helpMenu.add(infoMenuItem);
+                helpMenuItem = new BMenuItem(i18n.getString("menu.help.info"));
+                    helpMenu.add(helpMenuItem);
+        
+        menuBar.add(fileMenu);
+        menuBar.add(optionMenu);
+        menuBar.add(helpMenu);
+        this.setMenuBar(menuBar);
+        
+        // TOOLBAR ELEMENTS INITIALIZATION
+        toolBars = new ColumnContainer();
+        toolBars.setDefaultLayout(new LayoutInfo(LayoutInfo.NORTHWEST, 
LayoutInfo.NONE, new Insets(3,3,3,3), null));
+        // Standard toolbar
+        mainToolBar = new RowContainer();
+            ImageIcon newImageIcon = new 
ImageIcon(BeanShellEditor.class.getResource("images/New24.gif"));
+            newButton = new BButton(newImageIcon);
+            ImageIcon openImageIcon = new 
ImageIcon(BeanShellEditor.class.getResource("images/Open24.gif"));
+            openButton = new BButton(openImageIcon);
+            ImageIcon saveImageIcon = new 
ImageIcon(BeanShellEditor.class.getResource("images/Save24.gif"));
+            saveButton = new BButton(saveImageIcon);
+            ImageIcon saveAsImageIcon = new 
ImageIcon(BeanShellEditor.class.getResource("images/SaveAs24.gif"));
+            saveAsButton = new BButton(saveAsImageIcon);
+            ImageIcon runAsImageIcon = new 
ImageIcon(BeanShellEditor.class.getResource("images/Run24.gif"));
+            runScriptButton = new 
BButton(i18n.getString("toolbar.button.run"), runAsImageIcon);
+            ImageIcon clearOutputImageIcon = new 
ImageIcon(BeanShellEditor.class.getResource("images/edit_clear.png"));
+            Image image = 
clearOutputImageIcon.getImage().getScaledInstance(24,24, Image.SCALE_SMOOTH);
+            clearOutputButton = new BButton(new ImageIcon(image));
+            fontSizeLabel = new BLabel(i18n.getString("toolbar.fontSize"));
+            fontSizeChooser = new BComboBox(new 
Object[]{8,9,10,11,12,13,14,16,18});
+            fontSizeChooser.setSelectedValue(12);
+            fontSizeChooser.getComponent().setPrototypeDisplayValue(111);
+        mainToolBar.add(newButton);
+            newButton.addEventLink(CommandEvent.class, this, "newScript");
+        mainToolBar.add(openButton);
+            openButton.addEventLink(CommandEvent.class, this, "open");
+        mainToolBar.add(saveButton);
+            saveButton.addEventLink(CommandEvent.class, this, "save");
+        mainToolBar.add(saveAsButton);
+            saveAsButton.addEventLink(CommandEvent.class, this, "saveAs");
+        mainToolBar.add(runScriptButton);
+            runScriptButton.addEventLink(CommandEvent.class, this, 
"runScript");
+        mainToolBar.add(clearOutputButton);
+            clearOutputButton.addEventLink(CommandEvent.class, this, 
"clearOutput");
+        mainToolBar.add(fontSizeLabel);
+        mainToolBar.add(fontSizeChooser);
+            fontSizeChooser.addEventLink(ValueChangedEvent.class, this, 
"changeFont");
+        toolBars.add(mainToolBar);
+        // Plugin toolbar
+        pluginsToolBar = new RowContainer();
+            plugins = new HashMap<>();
+        toolBars.add(pluginsToolBar);
+        
+        // LEFT PANEL ELEMENTS INITIALIZATION
+        leftTabbedPane = new BTabbedPane(BTabbedPane.TOP);
+            bshScriptsScrollPane = new BScrollPane();
+                refreshScriptsTree(scriptsFolder);
+            jarsScrollPane = new BScrollPane();
+                jarsContainer = new ColumnContainer();
+                jarsContainer.setDefaultLayout(new 
LayoutInfo(LayoutInfo.NORTHWEST, LayoutInfo.NONE, new Insets(3,3,3,3), null));
+                jarsScrollPane.setContent(jarsContainer);
+            // namespace
+            varsScrollPane = new BScrollPane();
+                variablesList = new BList();
+                varListContainer = new ColumnContainer();
+                varListContainer.setDefaultLayout(new 
LayoutInfo(LayoutInfo.NORTHWEST, LayoutInfo.NONE, new Insets(0,0,0,0), null));
+                varsScrollPane.setContent(varListContainer);
+                //varsScrollPane.setContent(variablesList);
+        
+        leftTabbedPane.add(bshScriptsScrollPane,
+            
"<html><b>"+i18n.getString("manager.scriptfolder")+"</b><br></html>",null,0);
+        leftTabbedPane.add(jarsScrollPane,
+            
"<html><b>"+i18n.getString("manager.libraries")+"</b><br></html>",null,1);
+        leftTabbedPane.add(varsScrollPane,
+            
"<html><b>"+i18n.getString("manager.variables")+"</b><br></html>",null,2);
+        
+        // MAIN PANEL ELEMENTS INITIALIZATION
+        rightPanel = new BSplitPane(BSplitPane.VERTICAL);
+        rightPanel.setOneTouchExpandable(true);
+            // NORTHPANEL CONTAINS :
+            // - A TITLE LABEL CONTAINING THE FILE NAME
+            // - THE EDITOR (JEditTextArea)
+            // - A LABEL CONTAINING THE LINE NUMBER FOR DEBUGGING PURPOSES
+            northPanel = new BorderContainer();
+            northPanel.setDefaultLayout(new LayoutInfo(LayoutInfo.NORTH, 
LayoutInfo.BOTH, new Insets(3,3,3,3), null));
+                scriptTitle = new BLabel(i18n.getString("editor.title.new"));
+                TextAreaDefaults defaults = TextAreaDefaults.getDefaults();
+                defaults.cols = 48;
+                defaults.rows = 12;
+                defaults.electricScroll = 0;
+                SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
+                    styles[Token.COMMENT1] = new SyntaxStyle(new 
Color(0xDD0000),true,false);
+                    styles[Token.COMMENT2] = new SyntaxStyle(new 
Color(0xFF0000),true,false);
+                    styles[Token.KEYWORD1] = new SyntaxStyle(new 
Color(0x000066),false,true);
+                    styles[Token.KEYWORD2] = new 
SyntaxStyle(Color.black,false,true);
+                    styles[Token.KEYWORD3] = new SyntaxStyle(new 
Color(0x009900),false,true);
+                    styles[Token.LITERAL1] = new SyntaxStyle(new 
Color(0xCC0099),false,false);
+                    styles[Token.LITERAL2] = new SyntaxStyle(new 
Color(0xCC0099),false,true);
+                    styles[Token.LABEL] = new SyntaxStyle(new 
Color(0x990033),false,true);
+                    styles[Token.OPERATOR] = new 
SyntaxStyle(Color.black,false,true);
+                    styles[Token.INVALID] = new 
SyntaxStyle(Color.red,false,true);
+                defaults.styles = styles;
+                jEditTextArea = new JEditTextArea(defaults);
+                jEditTextArea.setText(i18n.getString("editor.writehere"));
+                jEditTextArea.setTokenMarker(new JavaTokenMarker());
+                final BLabel caretPos = new 
BLabel(i18n.getString("editor.status.numbering"));
+                northPanel.add(scriptTitle, BorderContainer.NORTH);
+                northPanel.add(new AWTWidget(jEditTextArea), 
BorderContainer.CENTER);
+                northPanel.add(caretPos, BorderContainer.SOUTH);
+                jEditTextArea.setFirstLine(0);
+                jEditTextArea.addCaretListener(new CaretListener(){
+                    public void caretUpdate(javax.swing.event.CaretEvent e){
+                        
caretPos.setText(i18n.getString("editor.status.numbering") + 
(jEditTextArea.getCaretLine()+1));
+                    }
+                });
+
+            southPanel = new BorderContainer();
+                southPanel.setDefaultLayout(new 
LayoutInfo(LayoutInfo.NORTHWEST, LayoutInfo.BOTH, new Insets(3,3,3,3), null));
+                commandLineContainer = new FormContainer(new 
double[]{0,1,0,0},new double[]{0});
+                commandLineLabel = new 
BLabel(i18n.getString("commandline.title"));
+                commandLine = new BTextField(32);
+                    commandLine.addEventLink(KeyPressedEvent.class, this, 
"runCommand");
+                runCommand = new 
BButton(i18n.getString("commandline.button.run"));
+                    runCommand.addEventLink(CommandEvent.class, this, 
"runCommand");
+                clearOutput = new 
BButton(i18n.getString("commandline.button.clearoutput"));
+                    clearOutput.addEventLink(CommandEvent.class, this, 
"clearOutput");
+                commandLineContainer.add(commandLineLabel,0,0);
+                commandLineContainer.add(commandLine,1,0, new 
LayoutInfo(LayoutInfo.WEST, LayoutInfo.HORIZONTAL, new Insets(3,3,3,3), null));
+                commandLineContainer.add(runCommand,2,0);
+                commandLineContainer.add(clearOutput,3,0);
+                outputTextArea = new BTextArea(2,100);
+                outputTextArea.setFont(new Font("Monospaced", Font.PLAIN, 
(Integer)fontSizeChooser.getSelectedValue()));
+                outputTextArea.setWrapStyle(BTextArea.WRAP_WORD);
+                    out = new PrintStream(new Output(outputTextArea));
+                outputScrollPane = new BScrollPane(outputTextArea);
+                outputScrollPane.setPreferredViewSize(new Dimension(400,100));
+                southPanel.add(commandLineContainer,BorderContainer.NORTH);
+                southPanel.    setChildLayout(BorderContainer.NORTH, new 
LayoutInfo(LayoutInfo.WEST, LayoutInfo.HORIZONTAL, new Insets(3,3,3,3), null));
+                southPanel.add(outputScrollPane, BorderContainer.CENTER);
+        rightPanel.add(northPanel,0);
+        rightPanel.add(southPanel,1);
+        
+        mainPanel = new BSplitPane(BSplitPane.HORIZONTAL);
+            mainPanel.setOneTouchExpandable(true);
+            //mainPanel.setDividerLocation(0.15);
+        mainPanel.add(leftTabbedPane,0);
+        mainPanel.add(rightPanel,1);
+        mainPanel.layoutChildren();
+        
+        bc = new BorderContainer();
+        bc.add(toolBars, BorderContainer.NORTH);
+        bc.add(mainPanel, BorderContainer.CENTER);
+        
+        this.setContent(bc);
+        layoutChildren();
+    }
+    
+    
+    private void initProperties() {
+        properties = new Properties();
+        try {
+            properties.load(new FileInputStream("BeanShellEditor.properties"));
+            extFolder = new File(properties.getProperty("extFolder","ext"));
+            if (!extFolder.exists()) extFolder = new File(".");
+            scriptsFolder  = new 
File(properties.getProperty("scriptsFolder","."));
+            if (!scriptsFolder.exists()) scriptsFolder = new File(".");
+            jarsFolder = new File(properties.getProperty("jarsFolder","."));
+            if (!jarsFolder.exists()) jarsFolder = new File(".");
+            refreshScriptsTree(scriptsFolder);
+            refreshJarsList();
+        } catch(FileNotFoundException fnfe) {
+            // if the file doesn't exist, refreshPropertiesFile()
+            // will create it with default properties
+            refreshPropertiesFile();
+        }
+        catch(IOException ioe) {
+            ioe.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+    public void addInitStatement(String statement) {
+        bshEditorInitStatements.add(statement);
+    }
+    
+    private void initInterpreter() {
+        try {
+            interpreter = new Interpreter();
+            interpreter.set("bshEditor", this);
+            interpreter.set("log", log);
+            // Reset the outputStreamHandler associated with the log object
+            if (outputStreamHandler!=null) 
log.removeHandler(outputStreamHandler);
+            out = new PrintStream(new Output(outputTextArea));
+            outputStreamHandler  = new StreamHandler(out, formatter) {
+                public void publish(LogRecord record) {super.publish(record); 
this.flush();}
+            };
+            log.addHandler(outputStreamHandler);
+            log.setLevel(Level.ALL);
+            outputStreamHandler.setLevel(Level.ALL);
+            interpreter.eval("void addPlugin(arg) {" + 
"\nbshEditor.addPlugin(arg);}");
+            interpreter.setOut(out);
+            interpreter.setErr(out);
+            Iterator it = bshEditorInitVariables.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String)it.next();
+                interpreter.set(key, bshEditorInitVariables.get(key));
+            }
+            it = bshEditorInitStatements.iterator();
+            while (it.hasNext()) {
+                interpreter.eval((String)it.next());
+            }
+            if (alwaysStartFile) {
+                startingScript();
+                //String start = properties.getProperty("start");
+                //if (start!=null && new File(start).exists()) 
{interpreter.source(start);}
+            }
+            refreshVarList();
+        }
+        catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+    private void newScript(){
+        scriptTitle.setText("New script");
+        jEditTextArea.setText("");
+    }
+    
+    private void open() {
+        BFileChooser chooser = new BFileChooser(BFileChooser.OPEN_FILE,"Select 
a bsh script");
+        chooser.showDialog(this);
+        File script = chooser.getSelectedFile();
+        openFile(script);
+    }
+    
+    private void openFile(File script) {
+        try {
+            long fileLength = script.length();
+            if(fileLength>1048576){
+                outputTextArea.append("\nERROR : Script files of more than 
1048576 bytes can't be read !!");
+                return;
+            }
+            FileReader fr = new FileReader(script);
+            char[] buff = new char[(int)fileLength];
+            fr.read(buff,0,(int)fileLength);
+            String string = new String(buff);
+            scriptTitle.setText(script.getAbsolutePath());
+            jEditTextArea.setText(string);
+            fr.close();
+            if (verbose) outputTextArea.append("\nOpen " + 
script.getAbsolutePath());
+        }
+        catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+    private void save() {
+        if (scriptTitle.getText().equals("newScript")) {saveAs();}
+        else {
+            File file = new File(scriptTitle.getText());
+            try {
+                FileWriter fr = new FileWriter(file);
+                
fr.write(jEditTextArea.getText(),0,jEditTextArea.getText().length());
+                fr.flush();
+                fr.close();
+            }
+            catch(Exception e) {
+                e.printStackTrace(new PrintWriter(out, true));
+            }
+        }
+    }
+    
+    private void saveAs() {
+        BFileChooser chooser = new BFileChooser(BFileChooser.SAVE_FILE,"Save 
current script as...");
+        chooser.showDialog(this);
+        File file = chooser.getSelectedFile();
+        if (file == null) return;
+        if (file.exists()) {
+            getBoolean("Overwrite existing file ?");
+            if (!overwriting) return;
+        }
+        try {
+            FileWriter fr = new FileWriter(file);
+            
fr.write(jEditTextArea.getText(),0,jEditTextArea.getText().length());
+            fr.flush();
+            fr.close();
+            scriptTitle.setText(file.getAbsolutePath());
+            refreshScriptsTree(scriptsFolder);
+        }
+        catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+   /**
+    * Execute a script.
+    * <p>For each script execution, BeanShellEditor :
+    * <ul>
+    * <li>initialize a new interpreter (create a new interpreter with some
+    * default variables and the variables passed to the constructor if 
any)</li>
+    * <li>evaluate the starting script if any</li>
+    * <li>evaluate the script</li>
+    * <li>reset the commandline</li>
+    */
+    public void runScript() {
+        try {
+            initInterpreter();
+            interpreter.eval(jEditTextArea.getText());
+            mainPanel.layoutChildren();
+            commandLine.setText("");
+            variablesList.removeAll();
+            refreshVarList();
+        }
+        catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+
+    /**
+     * Change font in the editor.
+     */
+    public void changeFont() {
+        try {
+            Font font = jEditTextArea.getPainter().getFont();
+            font = font.deriveFont(Float.parseFloat(
+                    fontSizeChooser.getSelectedValue().toString().trim()
+            ));
+            jEditTextArea.getPainter().setFont(font);
+            jEditTextArea.updateUI();
+            outputTextArea.setFont(font);
+            outputTextArea.repaint();
+        }
+        catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+   /**
+    * Used to execute a particular script file from a new button added in the 
ToolBar.
+    * <p>The pluginName must be the relative path of the script file without 
the
+    * extension.
+    * <p>[NOTE] I never used it, may be removed in future versions.
+    */
+    public void addPlugin(String pluginName) {
+        BButton pluginButton = new BButton(pluginName);
+        plugins.put(pluginName, pluginButton);
+        pluginButton.addEventLink(CommandEvent.class, this, "runPlugin");
+        refreshPluginsToolbar();
+        if (verbose) outputTextArea.append("\nPlugin \"" + pluginName + "\" 
has been added");
+    }
+    
+    public void removePlugin(String pluginName) {
+        plugins.remove(pluginName);
+        refreshPluginsToolbar();
+    }
+    
+    private void runPlugin(CommandEvent event) {
+        try {
+            String bsh = ((BButton)event.getWidget()).getText();
+            interpreter.source(scriptsFolder.getPath()+"/"+bsh+".bsh");
+        }
+        catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+    private void refreshPluginsToolbar() {
+        for (String s : plugins.keySet()) {
+            pluginsToolBar.add(plugins.get(s));
+        }
+        bc.layoutChildren();
+    }
+    
+   /**
+    * List of variables and methods available for the current interpreter
+    */
+    private void refreshVarList() {
+        try {
+            String[] var = (String[])interpreter.eval("this.variables");
+            Arrays.sort(var);
+            varListContainer.removeAll();
+            varListContainer.add(new BLabel("VARIABLES :"));
+            for (String s : var) {
+                BLabel l = new BLabel(s);
+                varListContainer.add(l);
+                l.addEventLink(MouseClickedEvent.class, this, "insertVar");
+            }
+            varListContainer.add(new BLabel(" "));  
+            varListContainer.add(new BLabel("METHODES :"));
+            String[] meth = (String[])interpreter.eval("this.methods");
+            Arrays.sort(meth);
+            for (String s : meth) {
+                BLabel l = new BLabel("#" + s);
+                varListContainer.add(l);
+                l.addEventLink(MouseClickedEvent.class, this, "insertMeth");
+            }
+        } catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+    private void insertVar(MouseClickedEvent ev) {
+        if (ev.getClickCount() == 1){
+            String oldText = commandLine.getText();
+            int pos = commandLine.getCaretPosition();
+            String insert = ((BLabel)ev.getWidget()).getText();
+            commandLine.setText(oldText.substring(0,pos)+ insert + 
oldText.substring(pos, oldText.length()));
+        }
+    }
+    
+    private void insertMeth(MouseClickedEvent ev) {
+        if (ev.getClickCount() == 1){
+            String oldText = commandLine.getText();
+            int pos = commandLine.getCaretPosition();
+            String insert = ((BLabel)ev.getWidget()).getText();
+            insert = insert.substring(1)+"()";
+            commandLine.setText(oldText.substring(0,pos)+ insert + 
oldText.substring(pos, oldText.length()));
+        }
+    }
+    
+   /**
+    * Run a command line when the user press the "run" button beside the 
command
+    * line or press the "return" key.
+    * <p>What is the difference between the script editor and the command line 
?
+    * <p>Each time you run a script, you evaluate it in a new interpreter
+    * (a "new" interpreter has a few default variables, the application
+    * variables passed to the constructor, and will first execute the starting
+    * script if any).<p>
+    * On the other hand, when you run a command line, all the methods and 
+    * variables defined during the last script run are available.<p>
+    * For example :
+    * Run a script containing<ul>
+    * <li>fact(int n){result = 
1;while(n>0)result=result*n--;print(result);}</li>
+    * </ul>
+    * <p>Then, in the command line editor, run<ul>
+    * <li>fact(6);</li>
+    * <li>fact(10);</li>
+    * <li>...</li>
+    * </ul>
+    */
+    public void runCommand(WidgetEvent event) {
+        if (event instanceof CommandEvent) {
+            try {
+                interpreter.eval(commandLine.getText());
+                commands.add(commandLine.getText());
+                commandIndex = commands.size();
+                mainPanel.layoutChildren();
+                commandLine.setText("");
+                variablesList.removeAll();
+                refreshVarList();
+            }
+            catch(Exception e) {
+                e.printStackTrace(new PrintWriter(out, true));
+            }
+        }
+        else if (event instanceof KeyPressedEvent) {
+            KeyPressedEvent k = (KeyPressedEvent)event;
+            if (k.getKeyCode()==KeyPressedEvent.VK_ENTER) {
+                try {
+                    interpreter.eval(commandLine.getText());
+                    commands.add(commandLine.getText());
+                    commandIndex = commands.size();
+                    mainPanel.layoutChildren();
+                    commandLine.setText("");
+                    variablesList.removeAll();
+                    refreshVarList();
+                }
+                catch(Exception e) {
+                    e.printStackTrace(new PrintWriter(out, true));
+                }
+            }
+            else if (k.getKeyCode()==KeyPressedEvent.VK_DOWN && 
commands.size()>0) {
+                commandIndex = 
(commandIndex==(commands.size()))?commandIndex:++commandIndex;
+                if (commandIndex==commands.size()) commandLine.setText("");
+                else commandLine.setText(commands.get(commandIndex));
+            }
+            else if (k.getKeyCode()==KeyPressedEvent.VK_UP && 
commands.size()>0) {
+                commandIndex = (commandIndex==0)?0:--commandIndex;
+                commandLine.setText(commands.get(commandIndex));
+            }
+        }
+    }
+    
+    public void clearOutput() {
+        outputTextArea.setText("");
+    }
+    
+    private void refreshScriptsTree(File folder) {
+        bshScriptsTree = new BTree(new 
DefaultMutableTreeNode(scriptsFolder.getName()));
+        bshScriptsTree.setRootNodeShown(true);
+        bshScriptsScrollPane.setContent(bshScriptsTree);
+        
+        DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer();
+        bshScriptsTree.setCellRenderer(treeRenderer);
+
+        File[] ff = folder.listFiles();
+        for (int i = 0 ; i < ff.length ; i++) {
+            DefaultMutableTreeNode node = new 
DefaultMutableTreeNode(ff[i].getName());
+            TreePath path = 
bshScriptsTree.addNode(bshScriptsTree.getRootNode(), node);
+            if(ff[i].isDirectory()) {
+                node.setAllowsChildren(true);
+                File[] fff = ff[i].listFiles();
+                for (int j = 0 ; j < fff.length ; j++) {
+                    DefaultMutableTreeNode node1 = new 
DefaultMutableTreeNode(fff[j].getName());
+                    TreePath path1 = bshScriptsTree.addNode(path, node1);
+                    if(fff[j].isDirectory()) {
+                        node1.setAllowsChildren(true);
+                        File[] ffff = fff[j].listFiles();
+                        for (int k = 0 ; k < ffff.length ; k++) {
+                            if(ffff[k].isDirectory()) continue;
+                            DefaultMutableTreeNode node2 = new 
DefaultMutableTreeNode(ffff[k].getName());
+                            node2.setAllowsChildren(false);
+                            bshScriptsTree.addNode(path1, node2);
+                        }
+                    }
+                    else {
+                        node1.setAllowsChildren(false);
+                    }
+                }
+            }
+            else {
+                node.setAllowsChildren(false);
+                
+            }
+        }
+        bshScriptsTree.addEventLink(MouseClickedEvent.class, new Object() {
+            void processEvent(MouseClickedEvent ev) {
+                if (ev.getClickCount() == 2){
+                    TreePath path = bshScriptsTree.findNode(ev.getPoint());
+                    if (path != null && bshScriptsTree.isLeafNode(path)) {
+                        StringBuilder filePath = new 
StringBuilder(scriptsFolder.getAbsolutePath()+"/");
+                        for (int i = 1 ; i < path.getPath().length ; i++) {
+                            filePath.append("/"+path.getPathComponent(i));
+                        }
+                        openFile(new File(filePath.toString()));
+                    }
+                }
+                bshScriptsScrollPane.layoutChildren();
+            }
+        });
+    }
+    
+    private void chooseScriptsFolder() {
+        BFileChooser chooser = new BFileChooser(BFileChooser.SELECT_FOLDER,
+            "Select folder for bsh scripts",
+            new File(System.getProperty("user.dir"))
+        );
+        chooser.showDialog(this);
+        File f =  chooser.getSelectedFile();
+        if (f == null) return;
+        scriptsFolder = f;
+        properties.put("scriptsFolder", scriptsFolder.getPath());
+        refreshScriptsTree(scriptsFolder);
+        refreshPropertiesFile();
+        if (verbose) outputTextArea.append("\nNew script folder = " +
+                                           scriptsFolder.getAbsolutePath());
+    }
+    
+    private void changeJarsFolder() {
+        BFileChooser chooser = new BFileChooser(
+            BFileChooser.SELECT_FOLDER,
+            "Select jars folder",
+            new File(System.getProperty("user.dir"))
+        );
+        chooser.showDialog(this);
+        File f =  chooser.getSelectedFile();
+        if (f == null) return;
+        jarsFolder = f;
+        properties.put("jarsFolder", jarsFolder.getPath());
+        refreshJarsList();
+        refreshPropertiesFile();
+        if (verbose) outputTextArea.append("\nNew jars folder = " + 
jarsFolder.getAbsolutePath());
+        jarsContainer.layoutChildren();
+    }
+    
+    private void chooseStartFile() {
+        BFileChooser chooser = new BFileChooser(
+            BFileChooser.OPEN_FILE,
+            "Select start script",
+            new File(System.getProperty("user.dir"))
+        );
+        chooser.showDialog(this);
+        File f =  chooser.getSelectedFile();
+        if (f == null) return;
+        startFile = f;
+        properties.put("start", f.getPath());
+        refreshPropertiesFile();
+        if (verbose) outputTextArea.append("\nNew start file = " + 
f.getPath());
+    }
+    
+   /**
+    * Refresh the jarFiles Set containing all the jar files from ext folder
+    * and from jarsFolder.
+    */
+    private void refreshJarsList() {
+        jarFileMap.clear();
+        jarsContainer.removeAll();
+        File[] ff = jarsFolder.listFiles();
+        for (int i = 0 ; i < ff.length ; i++) {
+            if(ff[i].getName().toUpperCase().endsWith(".JAR")) {
+                addJarFile(ff[i]);
+            }
+        }
+        File f = new File("ext");
+        if (!f.exists()) return;
+        ff = f.listFiles();
+        for (int i = 0 ; i < ff.length ; i++) {
+            if(ff[i].getName().toUpperCase().endsWith(".JAR")) {
+                addJarFile(ff[i]);
+            }
+        }
+        //importPackages();
+    }
+    
+    private void addJarFile(File jarFile) {
+        jarFileMap.put(jarFile.getName(), jarFile.getAbsolutePath());
+        BLabel label = new BLabel(jarFile.getName());
+        
+        BPopupMenu popup = new BPopupMenu();
+        BMenuItem item = new 
BMenuItem("addClassPath(\""+jarFile.getPath().replaceAll("\\\\","\\\\\\\\")+"\");");
+        item.addEventLink(CommandEvent.class, this, "insertImport");
+        popup.add(item);
+        Set<String> imports = new TreeSet<>();
+        try {
+            JarFile jar = new JarFile((String)jarFileMap.get(label.getText()));
+            Enumeration<JarEntry> enumeration = jar.entries();
+            while (enumeration.hasMoreElements()) {
+                String name = (enumeration.nextElement()).getName();
+                if (name.endsWith(".class")) {
+                    name = 
name.substring(0,name.length()-6).replaceAll("/",".");
+                    int index = Math.max(name.lastIndexOf("."),0);
+                    name = name.substring(0, index);
+                    imports.add(name);
+                }
+            }
+            for (String anImport : imports) {
+                item = new BMenuItem("import " + anImport + ".*;");
+                item.addEventLink(CommandEvent.class, this, "insertImport");
+                popup.add(item);
+            }
+        } catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+        
+        label.addEventLink(WidgetMouseEvent.class, popup, "show");
+        
+        jarsContainer.add(label);
+    }
+    
+    private void insertImport(CommandEvent event){
+        try {
+            String s = ((BMenuItem)event.getWidget()).getText()+"\n";
+            
jEditTextArea.getDocument().insertString(jEditTextArea.getCaretPosition(),s,null);
+        }
+        catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+    
+    private void changeVerbose(CommandEvent e) {
+        verbose = ((BCheckBoxMenuItem)e.getWidget()).getState();
+    }
+    
+    private void changeAlwaysStartFile(CommandEvent e) {
+        alwaysStartFile = ((BCheckBoxMenuItem)e.getWidget()).getState();
+    }
+    
+    private void refreshPropertiesFile() {
+        try {
+            properties.store(new 
FileOutputStream("BeanShellEditor.properties"), null);
+        }
+        catch(Exception e) {
+            e.printStackTrace(new PrintWriter(out, true));
+        }
+    }
+    
+    private void getBoolean(String question) {
+        BDialog dialog = new BDialog(this, question, true);
+        RowContainer row = new RowContainer();
+            row.setDefaultLayout(new LayoutInfo(LayoutInfo.CENTER, 
LayoutInfo.HORIZONTAL, new Insets(3,3,3,3), null));
+        BButton yes = new BButton("Yes");
+        yes.setName("Yes");
+            yes.addEventLink(CommandEvent.class, this, "setOverwriting");
+        BButton no = new BButton("No");
+        no.setName("No");
+            no.addEventLink(CommandEvent.class, this, "setOverwriting");
+        row.add(yes);
+        row.add(no);
+        dialog.setContent(row);
+        dialog.setBounds(new Rectangle(400,320,200,100));
+        dialog.pack();
+        dialog.setVisible(true);
+    }
+    
+    private void setOverwriting(CommandEvent event) {
+        overwriting = event.getWidget().getName().equals("Yes");
+        ((BDialog)event.getWidget().getParent().getParent()).dispose();
+    }
+    
+    private void exit(){
+        this.dispose();
+    }
+    
+    private void exitJvm(){System.exit(0);}
+    
+    private void resize() {
+        layoutChildren();
+        jarsScrollPane.layoutChildren();
+    };
+    
+    public OutputStream getBshOutputStream(){return out;}
+    public StreamHandler getOutputStreamHandler(){return outputStreamHandler;}
+    
+   /**
+    * Get a default logger.
+    * <p>A default logger is set up with a special text formatter and 
accessible
+    * from the BeanShellEditor.
+    * <p>To test it you may type the following lines in the editor and run it :
+    * <ul>
+    * <li>log.warning("This is a warning-level log test");</li>
+    * <li>log.info("This is a info-level log test");</li>
+    * <li>log.fine("This is a fine-level log test");</li>
+    * <li>log.finer("This is a finer-level log test");</li>
+    */
+    public Logger getLog() {return log;}
+    
+    private static class Output extends OutputStream {
+        BTextArea textArea;
+        
+        private Output(BTextArea textArea) {this.textArea = textArea;}
+      
+        public void write(int b) {
+            textArea.append(String.valueOf((char) b));
+        }
+      
+        public void write(byte b[], int off, int len) {
+            textArea.append(new String(b, off, len));
+        }
+        
+    }
+    
+    
+}

Added: plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/New24.gif
===================================================================
(Binary files differ)

Index: plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/New24.gif
===================================================================
--- plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/New24.gif    
2020-06-12 15:44:40 UTC (rev 6329)
+++ plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/New24.gif    
2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/New24.gif
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Open24.gif
===================================================================
(Binary files differ)

Index: plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Open24.gif
===================================================================
--- plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Open24.gif   
2020-06-12 15:44:40 UTC (rev 6329)
+++ plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Open24.gif   
2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Open24.gif
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Run24.gif
===================================================================
(Binary files differ)

Index: plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Run24.gif
===================================================================
--- plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Run24.gif    
2020-06-12 15:44:40 UTC (rev 6329)
+++ plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Run24.gif    
2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Run24.gif
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Save24.gif
===================================================================
(Binary files differ)

Index: plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Save24.gif
===================================================================
--- plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Save24.gif   
2020-06-12 15:44:40 UTC (rev 6329)
+++ plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Save24.gif   
2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Save24.gif
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/SaveAs24.gif
===================================================================
(Binary files differ)

Index: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/SaveAs24.gif
===================================================================
--- plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/SaveAs24.gif 
2020-06-12 15:44:40 UTC (rev 6329)
+++ plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/SaveAs24.gif 
2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/SaveAs24.gif
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Script16.gif
===================================================================
(Binary files differ)

Index: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Script16.gif
===================================================================
--- plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Script16.gif 
2020-06-12 15:44:40 UTC (rev 6329)
+++ plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Script16.gif 
2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/Script16.gif
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreeMinus16.gif
===================================================================
(Binary files differ)

Index: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreeMinus16.gif
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreeMinus16.gif  
    2020-06-12 15:44:40 UTC (rev 6329)
+++ 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreeMinus16.gif  
    2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreeMinus16.gif
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreePlus16.gif
===================================================================
(Binary files differ)

Index: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreePlus16.gif
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreePlus16.gif   
    2020-06-12 15:44:40 UTC (rev 6329)
+++ 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreePlus16.gif   
    2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/TreePlus16.gif
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/edit_clear.png
===================================================================
(Binary files differ)

Index: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/edit_clear.png
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/edit_clear.png   
    2020-06-12 15:44:40 UTC (rev 6329)
+++ 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/edit_clear.png   
    2020-06-12 20:15:39 UTC (rev 6330)

Property changes on: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/bsheditor/images/edit_clear.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/BeanShellEditorPlugIn.java
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/BeanShellEditorPlugIn.java
                             (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/BeanShellEditorPlugIn.java
     2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,42 @@
+package fr.michaelm.jump.bsheditor;
+
+import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
+import com.vividsolutions.jump.workbench.plugin.PlugInContext;
+import com.vividsolutions.jump.workbench.ui.MenuNames;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import fr.michaelm.bsheditor.BeanShellEditor;
+
+public class BeanShellEditorPlugIn extends AbstractPlugIn {
+    
+    public void initialize(PlugInContext context) {
+        context.getFeatureInstaller()
+                .addMainMenuPlugin(this,
+                        new String[] { MenuNames.CUSTOMIZE },
+                        getName() + "...",
+                        false,
+                        null,
+                        null);
+    }
+
+    public String getName() {
+        ResourceBundle i18n = ResourceBundle.getBundle(
+                "BeanShellEditor_i18n",
+                Locale.getDefault()
+        );
+        return i18n.getString("name");
+    }
+
+    public boolean execute(PlugInContext context) throws Exception {
+        Map map = new HashMap();
+        map.put("wc", context.getWorkbenchContext());
+        BeanShellEditor e = new BeanShellEditor(map, null);
+        e.addInitStatement("import com.vividsolutions.jump.feature.*;");
+        e.addInitStatement("import com.vividsolutions.jts.geom.*;");
+        e.addInitStatement("import 
com.vividsolutions.jump.workbench.model.*;");
+        return true;
+    }
+}

Added: 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/BshEditorPlugInExtension.java
===================================================================
--- 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/BshEditorPlugInExtension.java
                          (rev 0)
+++ 
plug-ins/BshEditor4Jump/trunk/src/fr/michaelm/jump/bsheditor/BshEditorPlugInExtension.java
  2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,14 @@
+package fr.michaelm.jump.bsheditor;
+
+import com.vividsolutions.jump.workbench.plugin.Extension;
+import com.vividsolutions.jump.workbench.plugin.PlugInContext;
+
+// v 0.2.4 (2012-11-12) fix the plugin name in the menu
+// v 0.2.3 (2012-mm-jj)
+public class BshEditorPlugInExtension extends Extension {
+    public void configure(PlugInContext context) throws Exception {
+        new BeanShellEditorPlugIn().initialize(context);
+    }
+    public String getName() {return "BeanShell Script Editor";}
+    public String getVersion() {return "0.3.0 (2020-06-12)";}
+}

Added: 
plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/DefaultInputHandler.java
===================================================================
--- plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/DefaultInputHandler.java 
                        (rev 0)
+++ plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/DefaultInputHandler.java 
2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,354 @@
+/*
+ * DefaultInputHandler.java - Default implementation of an input handler
+ * Copyright (C) 1999 Slava Pestov
+ *
+ * You may use and modify this package for any purpose. Redistribution is
+ * permitted, in both source and binary form, provided that this notice
+ * remains intact in all source distributions of this package.
+ */
+
+package org.syntax.jedit;
+
+import javax.swing.KeyStroke;
+import java.awt.event.*;
+import java.awt.Toolkit;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+/**
+ * The default input handler. It maps sequences of keystrokes into actions
+ * and inserts key typed events into the text area.
+ * @author Slava Pestov
+ * @version $Id: DefaultInputHandler.java,v 1.18 1999/12/13 03:40:30 sp Exp $
+ */
+public class DefaultInputHandler extends InputHandler
+{
+       /**
+        * Creates a new input handler with no key bindings defined.
+        */
+       public DefaultInputHandler()
+       {
+               bindings = currentBindings = new Hashtable();
+       }
+
+       /**
+        * Sets up the default key bindings.
+        */
+       public void addDefaultKeyBindings()
+       {
+               addKeyBinding("BACK_SPACE",BACKSPACE);
+               addKeyBinding("C+BACK_SPACE",BACKSPACE_WORD);
+               addKeyBinding("DELETE",DELETE);
+               addKeyBinding("C+DELETE",DELETE_WORD);
+
+               addKeyBinding("ENTER",INSERT_BREAK);
+               addKeyBinding("TAB",INSERT_TAB);
+
+               addKeyBinding("INSERT",OVERWRITE);
+               addKeyBinding("C+\\",TOGGLE_RECT);
+
+               addKeyBinding("HOME",HOME);
+               addKeyBinding("END",END);
+               addKeyBinding("C+A",SELECT_ALL);
+               addKeyBinding("S+HOME",SELECT_HOME);
+               addKeyBinding("S+END",SELECT_END);
+               addKeyBinding("C+HOME",DOCUMENT_HOME);
+               addKeyBinding("C+END",DOCUMENT_END);
+               addKeyBinding("CS+HOME",SELECT_DOC_HOME);
+               addKeyBinding("CS+END",SELECT_DOC_END);
+
+               addKeyBinding("PAGE_UP",PREV_PAGE);
+               addKeyBinding("PAGE_DOWN",NEXT_PAGE);
+               addKeyBinding("S+PAGE_UP",SELECT_PREV_PAGE);
+               addKeyBinding("S+PAGE_DOWN",SELECT_NEXT_PAGE);
+
+               addKeyBinding("LEFT",PREV_CHAR);
+               addKeyBinding("S+LEFT",SELECT_PREV_CHAR);
+               addKeyBinding("C+LEFT",PREV_WORD);
+               addKeyBinding("CS+LEFT",SELECT_PREV_WORD);
+               addKeyBinding("RIGHT",NEXT_CHAR);
+               addKeyBinding("S+RIGHT",SELECT_NEXT_CHAR);
+               addKeyBinding("C+RIGHT",NEXT_WORD);
+               addKeyBinding("CS+RIGHT",SELECT_NEXT_WORD);
+               addKeyBinding("UP",PREV_LINE);
+               addKeyBinding("S+UP",SELECT_PREV_LINE);
+               addKeyBinding("DOWN",NEXT_LINE);
+               addKeyBinding("S+DOWN",SELECT_NEXT_LINE);
+
+               addKeyBinding("C+ENTER",REPEAT);
+               
+               // Clipboard
+               addKeyBinding("C+C", CLIP_COPY);
+               addKeyBinding("C+V", CLIP_PASTE);
+               addKeyBinding("C+X", CLIP_CUT);
+       }
+
+       /**
+        * Adds a key binding to this input handler. The key binding is
+        * a list of white space separated key strokes of the form
+        * <i>[modifiers+]key</i> where modifier is C for Control, A for Alt,
+        * or S for Shift, and key is either a character (a-z) or a field
+        * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)
+        * @param keyBinding The key binding
+        * @param action The action
+        */
+       public void addKeyBinding(String keyBinding, ActionListener action)
+       {
+               Hashtable current = bindings;
+
+               StringTokenizer st = new StringTokenizer(keyBinding);
+               while(st.hasMoreTokens())
+               {
+                       KeyStroke keyStroke = parseKeyStroke(st.nextToken());
+                       if(keyStroke == null)
+                               return;
+
+                       if(st.hasMoreTokens())
+                       {
+                               Object o = current.get(keyStroke);
+                               if(o instanceof Hashtable)
+                                       current = (Hashtable)o;
+                               else
+                               {
+                                       o = new Hashtable();
+                                       current.put(keyStroke,o);
+                                       current = (Hashtable)o;
+                               }
+                       }
+                       else
+                               current.put(keyStroke,action);
+               }
+       }
+
+       /**
+        * Removes a key binding from this input handler. This is not yet
+        * implemented.
+        * @param keyBinding The key binding
+        */
+       public void removeKeyBinding(String keyBinding)
+       {
+               throw new InternalError("Not yet implemented");
+       }
+
+       /**
+        * Removes all key bindings from this input handler.
+        */
+       public void removeAllKeyBindings()
+       {
+               bindings.clear();
+       }
+
+       /**
+        * Returns a copy of this input handler that shares the same
+        * key bindings. Setting key bindings in the copy will also
+        * set them in the original.
+        */
+       public InputHandler copy()
+       {
+               return new DefaultInputHandler(this);
+       }
+
+       /**
+        * Handle a key pressed event. This will look up the binding for
+        * the key stroke and execute it.
+        */
+       public void keyPressed(KeyEvent evt)
+       {
+               int keyCode = evt.getKeyCode();
+               int modifiers = evt.getModifiers();
+
+               if(keyCode == KeyEvent.VK_CONTROL ||
+                       keyCode == KeyEvent.VK_SHIFT ||
+                       keyCode == KeyEvent.VK_ALT ||
+                       keyCode == KeyEvent.VK_META)
+                       return;
+
+               if((modifiers & ~KeyEvent.SHIFT_MASK) != 0
+                       || evt.isActionKey()
+                       || keyCode == KeyEvent.VK_BACK_SPACE
+                       || keyCode == KeyEvent.VK_DELETE
+                       || keyCode == KeyEvent.VK_ENTER
+                       || keyCode == KeyEvent.VK_TAB
+                       || keyCode == KeyEvent.VK_ESCAPE)
+               {
+                       if(grabAction != null)
+                       {
+                               handleGrabAction(evt);
+                               return;
+                       }
+
+                       KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode,
+                               modifiers);
+                       Object o = currentBindings.get(keyStroke);
+                       if(o == null)
+                       {
+                               // Don't beep if the user presses some
+                               // key we don't know about unless a
+                               // prefix is active. Otherwise it will
+                               // beep when caps lock is pressed, etc.
+                               if(currentBindings != bindings)
+                               {
+                                       Toolkit.getDefaultToolkit().beep();
+                                       // F10 should be passed on, but C+e F10
+                                       // shouldn't
+                                       repeatCount = 0;
+                                       repeat = false;
+                                       evt.consume();
+                               }
+                               currentBindings = bindings;
+                               return;
+                       }
+                       else if(o instanceof ActionListener)
+                       {
+                               currentBindings = bindings;
+
+                               executeAction(((ActionListener)o),
+                                       evt.getSource(),null);
+
+                               evt.consume();
+                               return;
+                       }
+                       else if(o instanceof Hashtable)
+                       {
+                               currentBindings = (Hashtable)o;
+                               evt.consume();
+                               return;
+                       }
+               }
+       }
+
+       /**
+        * Handle a key typed event. This inserts the key into the text area.
+        */
+       public void keyTyped(KeyEvent evt)
+       {
+               int modifiers = evt.getModifiers();
+               char c = evt.getKeyChar();
+               if(c != KeyEvent.CHAR_UNDEFINED &&
+                       (modifiers & KeyEvent.ALT_MASK) == 0)
+               {
+                       if(c >= 0x20 && c != 0x7f)
+                       {
+                               KeyStroke keyStroke = KeyStroke.getKeyStroke(
+                                       Character.toUpperCase(c));
+                               Object o = currentBindings.get(keyStroke);
+
+                               if(o instanceof Hashtable)
+                               {
+                                       currentBindings = (Hashtable)o;
+                                       return;
+                               }
+                               else if(o instanceof ActionListener)
+                               {
+                                       currentBindings = bindings;
+                                       executeAction((ActionListener)o,
+                                               evt.getSource(),
+                                               String.valueOf(c));
+                                       return;
+                               }
+
+                               currentBindings = bindings;
+
+                               if(grabAction != null)
+                               {
+                                       handleGrabAction(evt);
+                                       return;
+                               }
+
+                               // 0-9 adds another 'digit' to the repeat number
+                               if(repeat && Character.isDigit(c))
+                               {
+                                       repeatCount *= 10;
+                                       repeatCount += (c - '0');
+                                       return;
+                               }
+
+                               executeAction(INSERT_CHAR,evt.getSource(),
+                                       String.valueOf(evt.getKeyChar()));
+
+                               repeatCount = 0;
+                               repeat = false;
+                       }
+               }
+       }
+
+       /**
+        * Converts a string to a keystroke. The string should be of the
+        * form <i>modifiers</i>+<i>shortcut</i> where <i>modifiers</i>
+        * is any combination of A for Alt, C for Control, S for Shift
+        * or M for Meta, and <i>shortcut</i> is either a single character,
+        * or a keycode name from the <code>KeyEvent</code> class, without
+        * the <code>VK_</code> prefix.
+        * @param keyStroke A string description of the key stroke
+        */
+       public static KeyStroke parseKeyStroke(String keyStroke)
+       {
+               if(keyStroke == null)
+                       return null;
+               int modifiers = 0;
+               int index = keyStroke.indexOf('+');
+               if(index != -1)
+               {
+                       for(int i = 0; i < index; i++)
+                       {
+                               switch(Character.toUpperCase(keyStroke
+                                       .charAt(i)))
+                               {
+                               case 'A':
+                                       modifiers |= InputEvent.ALT_MASK;
+                                       break;
+                               case 'C':
+                                       modifiers |= InputEvent.CTRL_MASK;
+                                       break;
+                               case 'M':
+                                       modifiers |= InputEvent.META_MASK;
+                                       break;
+                               case 'S':
+                                       modifiers |= InputEvent.SHIFT_MASK;
+                                       break;
+                               }
+                       }
+               }
+               String key = keyStroke.substring(index + 1);
+               if(key.length() == 1)
+               {
+                       char ch = Character.toUpperCase(key.charAt(0));
+                       if(modifiers == 0)
+                               return KeyStroke.getKeyStroke(ch);
+                       else
+                               return KeyStroke.getKeyStroke(ch,modifiers);
+               }
+               else if(key.length() == 0)
+               {
+                       System.err.println("Invalid key stroke: " + keyStroke);
+                       return null;
+               }
+               else
+               {
+                       int ch;
+
+                       try
+                       {
+                               ch = KeyEvent.class.getField("VK_".concat(key))
+                                       .getInt(null);
+                       }
+                       catch(Exception e)
+                       {
+                               System.err.println("Invalid key stroke: "
+                                       + keyStroke);
+                               return null;
+                       }
+
+                       return KeyStroke.getKeyStroke(ch,modifiers);
+               }
+       }
+
+       // private members
+       private Hashtable bindings;
+       private Hashtable currentBindings;
+
+       private DefaultInputHandler(DefaultInputHandler copy)
+       {
+               bindings = currentBindings = copy.bindings;
+       }
+}

Added: plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/InputHandler.java
===================================================================
--- plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/InputHandler.java        
                        (rev 0)
+++ plug-ins/BshEditor4Jump/trunk/src/org/syntax/jedit/InputHandler.java        
2020-06-12 20:15:39 UTC (rev 6330)
@@ -0,0 +1,1115 @@
+/*
+ * InputHandler.java - Manages key bindings and executes actions
+ * Copyright (C) 1999 Slava Pestov
+ *
+ * You may use and modify this package for any purpose. Redistribution is
+ * permitted, in both source and binary form, provided that this notice
+ * remains intact in all source distributions of this package.
+ */
+
+package org.syntax.jedit;
+
+import javax.swing.text.*;
+import javax.swing.JPopupMenu;
+import java.awt.event.*;
+import java.awt.Component;
+import java.util.*;
+
+/**
+ * An input handler converts the user's key strokes into concrete actions.
+ * It also takes care of macro recording and action repetition.<p>
+ *
+ * This class provides all the necessary support code for an input
+ * handler, but doesn't actually do any key binding logic. It is up
+ * to the implementations of this class to do so.
+ * 
+ * @author Slava Pestov
+ * @version $Id: InputHandler.java,v 1.14 1999/12/13 03:40:30 sp Exp $
+ * @see org.syntax.jedit.DefaultInputHandler
+ * 
+ * 08/12/2002  Clipboard actions       (Oliver Henning)
+ * 20/03/2009 Makes the code java 5.0 compatible (M. Michaud)
+ */
+public abstract class InputHandler extends KeyAdapter
+{
+       /**
+        * If this client property is set to Boolean.TRUE on the text area,
+        * the home/end keys will support 'smart' BRIEF-like behaviour
+        * (one press = start/end of line, two presses = start/end of
+        * viewscreen, three presses = start/end of document). By default,
+        * this property is not set.
+        */
+       public static final String SMART_HOME_END_PROPERTY = 
"InputHandler.homeEnd";
+
+       public static final ActionListener BACKSPACE = new backspace();
+       public static final ActionListener BACKSPACE_WORD = new 
backspace_word();
+       public static final ActionListener DELETE = new delete();
+       public static final ActionListener DELETE_WORD = new delete_word();
+       public static final ActionListener END = new end(false);
+       public static final ActionListener DOCUMENT_END = new 
document_end(false);
+       public static final ActionListener SELECT_ALL = new select_all();
+       public static final ActionListener SELECT_END = new end(true);
+       public static final ActionListener SELECT_DOC_END = new 
document_end(true);
+       public static final ActionListener INSERT_BREAK = new insert_break();
+       public static final ActionListener INSERT_TAB = new insert_tab();
+       public static final ActionListener HOME = new home(false);
+       public static final ActionListener DOCUMENT_HOME = new 
document_home(false);
+       public static final ActionListener SELECT_HOME = new home(true);
+       public static final ActionListener SELECT_DOC_HOME = new 
document_home(true);
+       public static final ActionListener NEXT_CHAR = new next_char(false);
+       public static final ActionListener NEXT_LINE = new next_line(false);
+       public static final ActionListener NEXT_PAGE = new next_page(false);
+       public static final ActionListener NEXT_WORD = new next_word(false);
+       public static final ActionListener SELECT_NEXT_CHAR = new 
next_char(true);
+       public static final ActionListener SELECT_NEXT_LINE = new 
next_line(true);
+       public static final ActionListener SELECT_NEXT_PAGE = new 
next_page(true);
+       public static final ActionListener SELECT_NEXT_WORD = new 
next_word(true);
+       public static final ActionListener OVERWRITE = new overwrite();
+       public static final ActionListener PREV_CHAR = new prev_char(false);
+       public static final ActionListener PREV_LINE = new prev_line(false);
+       public static final ActionListener PREV_PAGE = new prev_page(false);
+       public static final ActionListener PREV_WORD = new prev_word(false);
+       public static final ActionListener SELECT_PREV_CHAR = new 
prev_char(true);
+       public static final ActionListener SELECT_PREV_LINE = new 
prev_line(true);
+       public static final ActionListener SELECT_PREV_PAGE = new 
prev_page(true);
+       public static final ActionListener SELECT_PREV_WORD = new 
prev_word(true);
+       public static final ActionListener REPEAT = new repeat();
+       public static final ActionListener TOGGLE_RECT = new toggle_rect();
+       // Clipboard
+       public static final ActionListener CLIP_COPY = new clip_copy();
+       public static final ActionListener CLIP_PASTE = new clip_paste();
+       public static final ActionListener CLIP_CUT = new clip_cut();
+
+       // Default action
+       public static final ActionListener INSERT_CHAR = new insert_char();
+
+       private static Hashtable actions;
+
+       static
+       {
+               actions = new Hashtable();
+               actions.put("backspace",BACKSPACE);
+               actions.put("backspace-word",BACKSPACE_WORD);
+               actions.put("delete",DELETE);
+               actions.put("delete-word",DELETE_WORD);
+               actions.put("end",END);
+               actions.put("select-all",SELECT_ALL);
+               actions.put("select-end",SELECT_END);
+               actions.put("document-end",DOCUMENT_END);
+               actions.put("select-doc-end",SELECT_DOC_END);
+               actions.put("insert-break",INSERT_BREAK);
+               actions.put("insert-tab",INSERT_TAB);
+               actions.put("home",HOME);
+               actions.put("select-home",SELECT_HOME);
+               actions.put("document-home",DOCUMENT_HOME);
+               actions.put("select-doc-home",SELECT_DOC_HOME);
+               actions.put("next-char",NEXT_CHAR);
+               actions.put("next-line",NEXT_LINE);
+               actions.put("next-page",NEXT_PAGE);
+               actions.put("next-word",NEXT_WORD);
+               actions.put("select-next-char",SELECT_NEXT_CHAR);
+               actions.put("select-next-line",SELECT_NEXT_LINE);
+               actions.put("select-next-page",SELECT_NEXT_PAGE);
+               actions.put("select-next-word",SELECT_NEXT_WORD);
+               actions.put("overwrite",OVERWRITE);
+               actions.put("prev-char",PREV_CHAR);
+               actions.put("prev-line",PREV_LINE);
+               actions.put("prev-page",PREV_PAGE);
+               actions.put("prev-word",PREV_WORD);
+               actions.put("select-prev-char",SELECT_PREV_CHAR);
+               actions.put("select-prev-line",SELECT_PREV_LINE);
+               actions.put("select-prev-page",SELECT_PREV_PAGE);
+               actions.put("select-prev-word",SELECT_PREV_WORD);
+               actions.put("repeat",REPEAT);
+               actions.put("toggle-rect",TOGGLE_RECT);
+               actions.put("insert-char",INSERT_CHAR);
+               actions.put("clipboard-copy",CLIP_COPY);
+               actions.put("clipboard-paste",CLIP_PASTE);
+               actions.put("clipboard-cut",CLIP_CUT);
+       }
+
+       /**
+        * Returns a named text area action.
+        * @param name The action name
+        */
+       public static ActionListener getAction(String name)
+       {
+               return (ActionListener)actions.get(name);
+       }
+
+       /**
+        * Returns the name of the specified text area action.
+        * @param listener The action
+        */
+       public static String getActionName(ActionListener listener)
+       {
+               Enumeration enumeration = getActions();
+               while(enumeration.hasMoreElements())
+               {
+                       String name = (String)enumeration.nextElement();
+                       ActionListener _listener = getAction(name);
+                       if(_listener == listener)
+                               return name;
+               }
+               return null;
+       }
+
+       /**
+        * Returns an enumeration of all available actions.
+        */
+       public static Enumeration getActions()
+       {
+               return actions.keys();
+       }
+
+       /**
+        * Adds the default key bindings to this input handler.
+        * This should not be called in the constructor of this
+        * input handler, because applications might load the
+        * key bindings from a file, etc.
+        */
+       public abstract void addDefaultKeyBindings();
+
+       /**
+        * Adds a key binding to this input handler.
+        * @param keyBinding The key binding (the format of this is
+        * input-handler specific)
+        * @param action The action
+        */
+       public abstract void addKeyBinding(String keyBinding, ActionListener 
action);
+
+       /**
+        * Removes a key binding from this input handler.
+        * @param keyBinding The key binding
+        */
+       public abstract void removeKeyBinding(String keyBinding);
+
+       /**
+        * Removes all key bindings from this input handler.
+        */
+       public abstract void removeAllKeyBindings();
+
+       /**
+        * Grabs the next key typed event and invokes the specified
+        * action with the key as a the action command.
+        * @param action The action
+        */
+       public void grabNextKeyStroke(ActionListener listener)
+       {
+               grabAction = listener;
+       }
+
+       /**
+        * Returns if repeating is enabled. When repeating is enabled,
+        * actions will be executed multiple times. This is usually
+        * invoked with a special key stroke in the input handler.
+        */
+       public boolean isRepeatEnabled()
+       {
+               return repeat;
+       }
+
+       /**
+        * Enables repeating. When repeating is enabled, actions will be
+        * executed multiple times. Once repeating is enabled, the input
+        * handler should read a number from the keyboard.
+        */
+       public void setRepeatEnabled(boolean repeat)
+       {
+               this.repeat = repeat;
+       }
+
+       /**
+        * Returns the number of times the next action will be repeated.
+        */
+       public int getRepeatCount()
+       {
+               return (repeat ? Math.max(1,repeatCount) : 1);
+       }
+
+       /**
+        * Sets the number of times the next action will be repeated.
+        * @param repeatCount The repeat count
+        */
+       public void setRepeatCount(int repeatCount)
+       {
+               this.repeatCount = repeatCount;
+       }
+
+       /**
+        * Returns the macro recorder. If this is non-null, all executed
+        * actions should be forwarded to the recorder.
+        */
+       public InputHandler.MacroRecorder getMacroRecorder()
+       {
+               return recorder;
+       }
+
+       /**
+        * Sets the macro recorder. If this is non-null, all executed
+        * actions should be forwarded to the recorder.
+        * @param recorder The macro recorder
+        */
+       public void setMacroRecorder(InputHandler.MacroRecorder recorder)
+       {
+               this.recorder = recorder;
+       }
+
+       /**
+        * Returns a copy of this input handler that shares the same
+        * key bindings. Setting key bindings in the copy will also
+        * set them in the original.
+        */
+       public abstract InputHandler copy();
+
+       /**
+        * Executes the specified action, repeating and recording it as
+        * necessary.
+        * @param listener The action listener
+        * @param source The event source
+        * @param actionCommand The action command
+        */
+       public void executeAction(ActionListener listener, Object source,
+               String actionCommand)
+       {
+               // create event
+               ActionEvent evt = new ActionEvent(source,
+                       ActionEvent.ACTION_PERFORMED,
+                       actionCommand);
+
+               // don't do anything if the action is a wrapper
+               // (like EditAction.Wrapper)
+               if(listener instanceof Wrapper)
+               {
+                       listener.actionPerformed(evt);
+                       return;
+               }
+
+               // remember old values, in case action changes them
+               boolean _repeat = repeat;
+               int _repeatCount = getRepeatCount();
+
+               // execute the action
+               if(listener instanceof InputHandler.NonRepeatable)
+                       listener.actionPerformed(evt);
+               else
+               {
+                       for(int i = 0; i < Math.max(1,repeatCount); i++)
+                               listener.actionPerformed(evt);
+               }
+
+               // do recording. Notice that we do no recording whatsoever
+               // for actions that grab keys
+               if(grabAction == null)
+               {
+                       if(recorder != null)
+                       {
+                               if(!(listener instanceof 
InputHandler.NonRecordable))
+                               {
+                                       if(_repeatCount != 1)
+                                               
recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount));
+
+                                       
recorder.actionPerformed(listener,actionCommand);
+                               }
+                       }
+
+                       // If repeat was true originally, clear it
+                       // Otherwise it might have been set by the action, etc
+                       if(_repeat)
+                       {
+                               repeat = false;
+                               repeatCount = 0;
+                       }
+               }
+       }
+
+       /**
+        * Returns the text area that fired the specified event.
+        * @param evt The event
+        */
+       public static JEditTextArea getTextArea(EventObject evt)
+       {
+               if(evt != null)
+               {
+                       Object o = evt.getSource();
+                       if(o instanceof Component)
+                       {
+                               // find the parent text area
+                               Component c = (Component)o;
+                               for(;;)
+                               {
+                                       if(c instanceof JEditTextArea)
+                                               return (JEditTextArea)c;
+                                       else if(c == null)
+                                               break;
+                                       if(c instanceof JPopupMenu)
+                                               c = ((JPopupMenu)c)
+                                                       .getInvoker();
+                                       else
+                                               c = c.getParent();
+                               }
+                       }
+               }
+
+               // this shouldn't happen
+               System.err.println("BUG: getTextArea() returning null");
+               System.err.println("Report this to Slava Pestov 
<s...@gjt.org>");
+               return null;
+       }
+
+       // protected members
+
+       /**
+        * If a key is being grabbed, this method should be called with
+        * the appropriate key event. It executes the grab action with
+        * the typed character as the parameter.
+        */
+       protected void handleGrabAction(KeyEvent evt)
+       {
+               // Clear it *before* it is executed so that executeAction()
+               // resets the repeat count
+               ActionListener _grabAction = grabAction;
+               grabAction = null;
+               executeAction(_grabAction,evt.getSource(),
+                       String.valueOf(evt.getKeyChar()));
+       }
+
+       // protected members
+       protected ActionListener grabAction;
+       protected boolean repeat;
+       protected int repeatCount;
+       protected InputHandler.MacroRecorder recorder;
+
+       /**
+        * If an action implements this interface, it should not be repeated.
+        * Instead, it will handle the repetition itself.
+        */
+       public interface NonRepeatable {}
+
+       /**
+        * If an action implements this interface, it should not be recorded
+        * by the macro recorder. Instead, it will do its own recording.
+        */
+       public interface NonRecordable {}
+
+       /**
+        * For use by EditAction.Wrapper only.
+        * @since jEdit 2.2final
+        */
+       public interface Wrapper {}
+
+       /**
+        * Macro recorder.
+        */
+       public interface MacroRecorder
+       {
+               void actionPerformed(ActionListener listener,
+                       String actionCommand);
+       }
+
+       public static class backspace implements ActionListener
+       {
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+
+                       if(!textArea.isEditable())
+                       {
+                               textArea.getToolkit().beep();
+                               return;
+                       }
+
+                       if(textArea.getSelectionStart()
+                          != textArea.getSelectionEnd())
+                       {
+                               textArea.setSelectedText("");
+                       }
+                       else
+                       {
+                               int caret = textArea.getCaretPosition();
+                               if(caret == 0)
+                               {
+                                       textArea.getToolkit().beep();
+                                       return;
+                               }
+                               try
+                               {
+                                       textArea.getDocument().remove(caret - 
1,1);
+                               }
+                               catch(BadLocationException bl)
+                               {
+                                       bl.printStackTrace();
+                               }
+                       }
+               }
+       }
+
+       public static class backspace_word implements ActionListener
+       {
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+                       int start = textArea.getSelectionStart();
+                       if(start != textArea.getSelectionEnd())
+                       {
+                               textArea.setSelectedText("");
+                       }
+
+                       int line = textArea.getCaretLine();
+                       int lineStart = textArea.getLineStartOffset(line);
+                       int caret = start - lineStart;
+
+                       String lineText = textArea.getLineText(textArea
+                               .getCaretLine());
+
+                       if(caret == 0)
+                       {
+                               if(lineStart == 0)
+                               {
+                                       textArea.getToolkit().beep();
+                                       return;
+                               }
+                               caret--;
+                       }
+                       else
+                       {
+                               String noWordSep = 
(String)textArea.getDocument().getProperty("noWordSep");
+                               caret = 
TextUtilities.findWordStart(lineText,caret,noWordSep);
+                       }
+
+                       try
+                       {
+                               textArea.getDocument().remove(
+                                               caret + lineStart,
+                                               start - (caret + lineStart));
+                       }
+                       catch(BadLocationException bl)
+                       {
+                               bl.printStackTrace();
+                       }
+               }
+       }
+
+       public static class delete implements ActionListener
+       {
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+
+                       if(!textArea.isEditable())
+                       {
+                               textArea.getToolkit().beep();
+                               return;
+                       }
+
+                       if(textArea.getSelectionStart()
+                          != textArea.getSelectionEnd())
+                       {
+                               textArea.setSelectedText("");
+                       }
+                       else
+                       {
+                               int caret = textArea.getCaretPosition();
+                               if(caret == textArea.getDocumentLength())
+                               {
+                                       textArea.getToolkit().beep();
+                                       return;
+                               }
+                               try
+                               {
+                                       textArea.getDocument().remove(caret,1);
+                               }
+                               catch(BadLocationException bl)
+                               {
+                                       bl.printStackTrace();
+                               }
+                       }
+               }
+       }
+
+       public static class delete_word implements ActionListener
+       {
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+                       int start = textArea.getSelectionStart();
+                       if(start != textArea.getSelectionEnd())
+                       {
+                               textArea.setSelectedText("");
+                       }
+
+                       int line = textArea.getCaretLine();
+                       int lineStart = textArea.getLineStartOffset(line);
+                       int caret = start - lineStart;
+
+                       String lineText = textArea.getLineText(textArea
+                               .getCaretLine());
+
+                       if(caret == lineText.length())
+                       {
+                               if(lineStart + caret == 
textArea.getDocumentLength())
+                               {
+                                       textArea.getToolkit().beep();
+                                       return;
+                               }
+                               caret++;
+                       }
+                       else
+                       {
+                               String noWordSep = 
(String)textArea.getDocument().getProperty("noWordSep");
+                               caret = 
TextUtilities.findWordEnd(lineText,caret,noWordSep);
+                       }
+
+                       try
+                       {
+                               textArea.getDocument().remove(start,
+                                       (caret + lineStart) - start);
+                       }
+                       catch(BadLocationException bl)
+                       {
+                               bl.printStackTrace();
+                       }
+               }
+       }
+
+       public static class end implements ActionListener
+       {
+               private boolean select;
+
+               public end(boolean select)
+               {
+                       this.select = select;
+               }
+
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+
+                       int caret = textArea.getCaretPosition();
+
+                       int lastOfLine = textArea.getLineEndOffset(
+                               textArea.getCaretLine()) - 1;
+                       int lastVisibleLine = textArea.getFirstLine()
+                               + textArea.getVisibleLines();
+                       if(lastVisibleLine >= textArea.getLineCount())
+                       {
+                               lastVisibleLine = 
Math.min(textArea.getLineCount() - 1,
+                                       lastVisibleLine);
+                       }
+                       else
+                               lastVisibleLine -= 
(textArea.getElectricScroll() + 1);
+
+                       int lastVisible = 
textArea.getLineEndOffset(lastVisibleLine) - 1;
+                       int lastDocument = textArea.getDocumentLength();
+
+                       if(caret == lastDocument)
+                       {
+                               textArea.getToolkit().beep();
+                               return;
+                       }
+                       else if(!Boolean.TRUE.equals(textArea.getClientProperty(
+                               SMART_HOME_END_PROPERTY)))
+                               caret = lastOfLine;
+                       else if(caret == lastVisible)
+                               caret = lastDocument;
+                       else if(caret == lastOfLine)
+                               caret = lastVisible;
+                       else
+                               caret = lastOfLine;
+
+                       if(select)
+                               
textArea.select(textArea.getMarkPosition(),caret);
+                       else
+                               textArea.setCaretPosition(caret);
+               }
+       }
+
+       public static class select_all implements ActionListener {
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+                       textArea.selectAll();
+               }
+       }
+       
+       public static class document_end implements ActionListener
+       {
+               private boolean select;
+
+               public document_end(boolean select)
+               {
+                       this.select = select;
+               }
+
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+                       if(select)
+                               textArea.select(textArea.getMarkPosition(),
+                                       textArea.getDocumentLength());
+                       else
+                               textArea.setCaretPosition(textArea
+                                       .getDocumentLength());
+               }
+       }
+
+       public static class home implements ActionListener
+       {
+               private boolean select;
+
+               public home(boolean select)
+               {
+                       this.select = select;
+               }
+
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+
+                       int caret = textArea.getCaretPosition();
+
+                       int firstLine = textArea.getFirstLine();
+
+                       int firstOfLine = textArea.getLineStartOffset(
+                               textArea.getCaretLine());
+                       int firstVisibleLine = (firstLine == 0 ? 0 :
+                               firstLine + textArea.getElectricScroll());
+                       int firstVisible = textArea.getLineStartOffset(
+                               firstVisibleLine);
+
+                       if(caret == 0)
+                       {
+                               textArea.getToolkit().beep();
+                               return;
+                       }
+                       else if(!Boolean.TRUE.equals(textArea.getClientProperty(
+                               SMART_HOME_END_PROPERTY)))
+                               caret = firstOfLine;
+                       else if(caret == firstVisible)
+                               caret = 0;
+                       else if(caret == firstOfLine)
+                               caret = firstVisible;
+                       else
+                               caret = firstOfLine;
+
+                       if(select)
+                               
textArea.select(textArea.getMarkPosition(),caret);
+                       else
+                               textArea.setCaretPosition(caret);
+               }
+       }
+
+       public static class document_home implements ActionListener
+       {
+               private boolean select;
+
+               public document_home(boolean select)
+               {
+                       this.select = select;
+               }
+
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+                       if(select)
+                               textArea.select(textArea.getMarkPosition(),0);
+                       else
+                               textArea.setCaretPosition(0);
+               }
+       }
+
+       public static class insert_break implements ActionListener
+       {
+               public void actionPerformed(ActionEvent evt)
+               {
+                       JEditTextArea textArea = getTextArea(evt);
+

@@ Diff output truncated at 100000 characters. @@


_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to