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.event.PopupMenuListener;
29 import javax.swing.text.Document;
30
31 import org.syntax.jedit.KeywordMap;
32 import org.syntax.jedit.tokenmarker.CTokenMarker;
33 import org.syntax.jedit.tokenmarker.GroovyTokenMarker;
34 import org.syntax.jedit.tokenmarker.Token;
35
36 import com.eviware.soapui.model.settings.Settings;
37 import com.eviware.soapui.model.settings.SettingsListener;
38 import com.eviware.soapui.settings.UISettings;
39 import com.eviware.soapui.support.DocumentListenerAdapter;
40 import com.eviware.soapui.support.UISupport;
41 import com.eviware.soapui.support.components.JEditorStatusBar.JEditorStatusBarTarget;
42 import com.eviware.soapui.support.swing.JXEditAreaPopupMenu;
43 import com.eviware.soapui.support.xml.JXEditTextArea;
44
45 /***
46 * Groovy editor wrapper
47 *
48 * @author ole.matzura
49 */
50
51 public class GroovyEditor extends JPanel implements JEditorStatusBarTarget
52 {
53 private JXEditTextArea editArea;
54 private GroovyEditorModel model;
55 private InternalSettingsListener settingsListener;
56 private GroovyDocumentListener groovyDocumentListener;
57 private JCheckBoxMenuItem toggleLineNumbersMenuItem;
58 private JPanel lineNumbersPanel;
59
60 public GroovyEditor( GroovyEditorModel model )
61 {
62 super( new BorderLayout() );
63 this.model = model;
64
65 editArea = new JXEditTextArea( new CTokenMarker( false, initKeywords() ) );
66 editArea.setBorder( BorderFactory.createMatteBorder( 0, 2, 0, 0, Color.WHITE) );
67
68 Settings settings = model.getSettings();
69 String editorFont = settings.getString( UISettings.EDITOR_FONT, UISettings.DEFAULT_EDITOR_FONT );
70 if( editorFont != null && editorFont.length() > 0 )
71 editArea.setFont(Font.decode(editorFont));
72 else
73 editArea.setFont( Font.decode( UISettings.DEFAULT_EDITOR_FONT ));
74
75 editArea.setText( model.getScript() );
76 editArea.setCaretPosition( 0 );
77 ActionListener runAction = model.getRunAction();
78 if( runAction != null )
79 editArea.getInputHandler().addKeyBinding( "A+ENTER", runAction );
80
81 groovyDocumentListener = new GroovyDocumentListener();
82 editArea.getDocument().addDocumentListener( groovyDocumentListener );
83
84 settingsListener = new InternalSettingsListener();
85 settings.addSettingsListener( settingsListener );
86
87 add( editArea );
88 add( buildLineNumbers(), BorderLayout.WEST );
89
90 lineNumbersPanel.setVisible( settings.getBoolean( UISettings.SHOW_GROOVY_LINE_NUMBERS ) );
91
92 addFocusListener( new FocusAdapter() {
93
94 public void focusGained( FocusEvent e )
95 {
96 editArea.requestFocusInWindow();
97 }}
98 );
99
100 JXEditAreaPopupMenu popup = JXEditAreaPopupMenu.add( editArea );
101 popup.add( editArea.getFindAndReplaceAction());
102 popup.addSeparator();
103 popup.add( editArea.getGoToLineAction() );
104 toggleLineNumbersMenuItem = new JCheckBoxMenuItem( "Show Line Numbers", lineNumbersPanel.isVisible() );
105 toggleLineNumbersMenuItem.setAccelerator( UISupport.getKeyStroke( "alt L" ) );
106 toggleLineNumbersMenuItem.addActionListener( new ActionListener() {
107
108 public void actionPerformed( ActionEvent e )
109 {
110 lineNumbersPanel.setVisible( toggleLineNumbersMenuItem.isSelected() );
111 }} );
112
113 popup.add( toggleLineNumbersMenuItem );
114 }
115
116 private JComponent buildLineNumbers()
117 {
118 editArea.getInputHandler().addKeyBinding( "A+L", new ActionListener() {
119
120 public void actionPerformed( ActionEvent e )
121 {
122 lineNumbersPanel.setVisible( !lineNumbersPanel.isVisible() );
123 toggleLineNumbersMenuItem.setSelected( lineNumbersPanel.isVisible() );
124 }} );
125
126 lineNumbersPanel = new LineNumbersPanel( editArea );
127 return lineNumbersPanel;
128 }
129
130 public JXEditTextArea getEditArea()
131 {
132 return editArea;
133 }
134
135 public void release()
136 {
137 model.getSettings().removeSettingsListener( settingsListener );
138 model = null;
139 editArea.getDocument().removeDocumentListener( groovyDocumentListener );
140 editArea.getInputHandler().removeAllKeyBindings();
141 editArea.getRightClickPopup().removeAll();
142 for( PopupMenuListener listener : editArea.getRightClickPopup().getPopupMenuListeners() )
143 {
144 editArea.getRightClickPopup().removePopupMenuListener( listener );
145 }
146 }
147
148 public void selectError(String message)
149 {
150 int ix = message == null ? -1 : message.indexOf( "@ line " );
151 if( ix >= 0 )
152 {
153 try
154 {
155 int ix2 = message.indexOf(',', ix);
156 int line = ix2 == -1 ? Integer.parseInt(message.substring(ix + 6).trim()) : Integer.parseInt(message
157 .substring(ix + 6, ix2).trim());
158 int column = 0;
159 if (ix2 != -1)
160 {
161 ix = message.indexOf("column ", ix2);
162 if (ix >= 0)
163 {
164 ix2 = message.indexOf('.', ix);
165 column = ix2 == -1 ? Integer.parseInt(message.substring(ix + 7).trim()) : Integer
166 .parseInt(message.substring(ix + 7, ix2).trim());
167 }
168 }
169
170 editArea.setCaretPosition(editArea.getLineStartOffset(line - 1) + column - 1);
171 }
172 catch (Exception ex)
173 {
174 }
175
176 editArea.requestFocus();
177 }
178 }
179
180 private KeywordMap initKeywords()
181 {
182 KeywordMap keywords = GroovyTokenMarker.getKeywords();
183
184 for( String keyword : model.getKeywords() )
185 keywords.add(keyword,Token.KEYWORD2);
186 return keywords;
187 }
188
189 private final class GroovyDocumentListener extends DocumentListenerAdapter
190 {
191 public void update(Document document)
192 {
193 GroovyEditor.this.model.setScript( editArea.getText() );
194 }
195 }
196
197 private final class InternalSettingsListener implements SettingsListener
198 {
199 public void settingChanged(String name, String newValue, String oldValue)
200 {
201 if( name.equals( UISettings.EDITOR_FONT ))
202 {
203 editArea.setFont( Font.decode( newValue ));
204 invalidate();
205 }
206 }
207 }
208
209 public void addCaretListener( CaretListener listener )
210 {
211 editArea.addCaretListener( listener );
212 }
213
214 public int getCaretPosition()
215 {
216 return editArea.getCaretPosition();
217 }
218
219 public int getLineOfOffset( int offset ) throws Exception
220 {
221 return editArea.getLineOfOffset( offset );
222 }
223
224 public int getLineStartOffset( int line ) throws Exception
225 {
226 return editArea.getLineStartOffset( line );
227 }
228
229 public void removeCaretListener( CaretListener listener )
230 {
231 editArea.removeCaretListener( listener );
232 }
233 }