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