View Javadoc

    1   /*
    2    *  soapUI, copyright (C) 2004-2007 eviware.com
    3    *
    4    *  soapUI is free software; you can redistribute it and/or modify it under the
    5    *  terms of version 2.1 of the GNU Lesser General Public License as published by
    6    *  the Free Software Foundation.
    7    *
    8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
    9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    10   *  See the GNU Lesser General Public License for more details at gnu.org.
    11   */
    12
    13  package com.eviware.soapui.impl.wsdl.panels.teststeps.support;
    14
    15  import java.awt.BorderLayout;
    16  import java.awt.Color;
    17  import java.awt.Font;
    18  import java.awt.event.ActionEvent;
    19  import java.awt.event.ActionListener;
    20  import java.awt.event.FocusAdapter;
    21  import java.awt.event.FocusEvent;
    22
    23  import javax.swing.BorderFactory;
    24  import javax.swing.JCheckBoxMenuItem;
    25  import javax.swing.JComponent;
    26  import javax.swing.JPanel;
    27  import javax.swing.event.CaretListener;
    28  import javax.swing.text.Document;
    29
    30  import org.syntax.jedit.KeywordMap;
    31  import org.syntax.jedit.tokenmarker.CTokenMarker;
    32  import org.syntax.jedit.tokenmarker.GroovyTokenMarker;
    33  import org.syntax.jedit.tokenmarker.Token;
    34
    35  import com.eviware.soapui.model.settings.Settings;
    36  import com.eviware.soapui.model.settings.SettingsListener;
    37  import com.eviware.soapui.settings.UISettings;
    38  import com.eviware.soapui.support.DocumentListenerAdapter;
    39  import com.eviware.soapui.support.UISupport;
    40  import com.eviware.soapui.support.components.JEditorStatusBar.JEditorStatusBarTarget;
    41  import com.eviware.soapui.support.swing.JXEditAreaPopupMenu;
    42  import com.eviware.soapui.support.xml.JXEditTextArea;
    43
    44  /***
    45   * Groovy editor wrapper
    46   *
    47   * @author ole.matzura
    48   */
    49
    50  public class GroovyEditor extends JPanel implements JEditorStatusBarTarget
    51  {
    52  	private JXEditTextArea editArea;
    53  	private GroovyEditorModel model;
    54  	private InternalSettingsListener settingsListener;
    55  	private GroovyDocumentListener groovyDocumentListener;
    56  	private JCheckBoxMenuItem toggleLineNumbersMenuItem;
    57  	private JPanel lineNumbersPanel;
    58
    59  	public GroovyEditor( GroovyEditorModel model )
    60  	{
    61  		super( new BorderLayout() );
    62  		this.model = model;
    63
    64  		editArea = new JXEditTextArea( new CTokenMarker( false, initKeywords() ) );
    65  		editArea.setBorder( BorderFactory.createMatteBorder( 0, 2, 0, 0, Color.WHITE) );
    66
    67  		Settings settings = model.getSettings();
    68  		String editorFont = settings.getString( UISettings.EDITOR_FONT, UISettings.DEFAULT_EDITOR_FONT );
    69  		if( editorFont != null && editorFont.length() > 0 )
    70  			editArea.setFont(Font.decode(editorFont));
    71  		else
    72  			editArea.setFont( Font.decode( UISettings.DEFAULT_EDITOR_FONT ));
    73
    74  		editArea.setText( model.getScript() );
    75  		editArea.setCaretPosition(  0 );
    76  		ActionListener runAction = model.getRunAction();
    77  		if( runAction != null )
    78  			editArea.getInputHandler().addKeyBinding( "A+ENTER", runAction );
    79
    80  		groovyDocumentListener = new GroovyDocumentListener();
    81  		editArea.getDocument().addDocumentListener( groovyDocumentListener );
    82
    83  		settingsListener = new InternalSettingsListener();
    84  		settings.addSettingsListener( settingsListener );
    85
    86  		add( editArea );
    87  		add( buildLineNumbers(), BorderLayout.WEST );
    88
    89  		lineNumbersPanel.setVisible( settings.getBoolean( UISettings.SHOW_GROOVY_LINE_NUMBERS ) );
    90
    91  		addFocusListener( new FocusAdapter() {
    92
    93  			public void focusGained( FocusEvent e )
    94  			{
    95  				editArea.requestFocusInWindow();
    96  			}}
    97  		);
    98
    99  		JXEditAreaPopupMenu popup = JXEditAreaPopupMenu.add( editArea );
    100 		popup.add( editArea.getFindAndReplaceAction());
    101 		popup.addSeparator();
    102 		popup.add( editArea.getGoToLineAction() );
    103 		toggleLineNumbersMenuItem = new JCheckBoxMenuItem( "Show Line Numbers", lineNumbersPanel.isVisible() );
    104 		toggleLineNumbersMenuItem.setAccelerator( UISupport.getKeyStroke( "alt L" ) );
    105 		toggleLineNumbersMenuItem.addActionListener( new ActionListener() {
    106
    107 			public void actionPerformed( ActionEvent e )
    108 			{
    109 				lineNumbersPanel.setVisible( toggleLineNumbersMenuItem.isSelected() );
    110 			}} );
    111 		popup.add( toggleLineNumbersMenuItem );
    112 	}
    113
    114 	private JComponent buildLineNumbers()
    115 	{
    116 		editArea.getInputHandler().addKeyBinding( "A+L", new ActionListener() {
    117
    118 			public void actionPerformed( ActionEvent e )
    119 			{
    120 				lineNumbersPanel.setVisible( !lineNumbersPanel.isVisible() );
    121 				toggleLineNumbersMenuItem.setSelected( lineNumbersPanel.isVisible() );
    122 			}} );
    123
    124 		lineNumbersPanel = new LineNumbersPanel( editArea );
    125 		return lineNumbersPanel;
    126 	}
    127
    128 	public JXEditTextArea getEditArea()
    129 	{
    130 		return editArea;
    131 	}
    132
    133 	public void release()
    134 	{
    135 		model.getSettings().removeSettingsListener( settingsListener );
    136 		model = null;
    137 		editArea.getDocument().removeDocumentListener( groovyDocumentListener );
    138 		editArea.getInputHandler().removeAllKeyBindings();
    139 	}
    140
    141 	public void selectError(String message)
    142 	{
    143 		int ix = message == null ? -1 : message.indexOf( "@ line " );
    144 		if( ix >= 0 )
    145 		{
    146 			try
    147 			{
    148 				int ix2 = message.indexOf(',', ix);
    149 				int line = ix2 == -1 ? Integer.parseInt(message.substring(ix + 6).trim()) : Integer.parseInt(message
    150 						.substring(ix + 6, ix2).trim());
    151 				int column = 0;
    152 				if (ix2 != -1)
    153 				{
    154 					ix = message.indexOf("column ", ix2);
    155 					if (ix >= 0)
    156 					{
    157 						ix2 = message.indexOf('.', ix);
    158 						column = ix2 == -1 ? Integer.parseInt(message.substring(ix + 7).trim()) : Integer
    159 								.parseInt(message.substring(ix + 7, ix2).trim());
    160 					}
    161 				}
    162
    163 				editArea.setCaretPosition(editArea.getLineStartOffset(line - 1) + column - 1);
    164 			}
    165 			catch (Exception ex)
    166 			{
    167 			}
    168
    169 			editArea.requestFocus();
    170 		}
    171 	}
    172
    173 	private KeywordMap initKeywords()
    174 	{
    175 		KeywordMap keywords = GroovyTokenMarker.getKeywords();
    176
    177 		for( String keyword : model.getKeywords() )
    178 			keywords.add(keyword,Token.KEYWORD2);
    179 		return keywords;
    180 	}
    181
    182 	private final class GroovyDocumentListener extends DocumentListenerAdapter
    183 	{
    184 		public void update(Document document)
    185 		{
    186 			GroovyEditor.this.model.setScript( editArea.getText() );
    187 		}
    188 	}
    189
    190 	private final class InternalSettingsListener implements SettingsListener
    191 	{
    192 		public void settingChanged(String name, String newValue, String oldValue)
    193 		{
    194 			if( name.equals( UISettings.EDITOR_FONT ))
    195 			{
    196 				editArea.setFont( Font.decode( newValue ));
    197 				invalidate();
    198 			}
    199 		}
    200 	}
    201
    202 	public void addCaretListener( CaretListener listener )
    203 	{
    204 		editArea.addCaretListener( listener );
    205 	}
    206
    207 	public int getCaretPosition()
    208 	{
    209 		return editArea.getCaretPosition();
    210 	}
    211
    212 	public int getLineOfOffset( int offset ) throws Exception
    213 	{
    214 		return editArea.getLineOfOffset( offset );
    215 	}
    216
    217 	public int getLineStartOffset( int line ) throws Exception
    218 	{
    219 		return editArea.getLineStartOffset( line );
    220 	}
    221
    222 	public void removeCaretListener( CaretListener listener )
    223 	{
    224 		editArea.removeCaretListener( listener );
    225 	}
    226 }