1
2
3
4
5
6
7
8
9
10
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 }