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 editArea.setFont(UISupport.getEditorFont( settings ));
70
71 editArea.setText( model.getScript() );
72 editArea.setCaretPosition( 0 );
73 ActionListener runAction = model.getRunAction();
74 if( runAction != null )
75 editArea.getInputHandler().addKeyBinding( "A+ENTER", runAction );
76
77 groovyDocumentListener = new GroovyDocumentListener();
78 editArea.getDocument().addDocumentListener( groovyDocumentListener );
79
80 settingsListener = new InternalSettingsListener();
81 settings.addSettingsListener( settingsListener );
82
83 add( editArea );
84 add( buildLineNumbers(), BorderLayout.WEST );
85
86 lineNumbersPanel.setVisible( settings.getBoolean( UISettings.SHOW_GROOVY_LINE_NUMBERS ) );
87
88 addFocusListener( new FocusAdapter() {
89
90 public void focusGained( FocusEvent e )
91 {
92 editArea.requestFocusInWindow();
93 }}
94 );
95
96 JXEditAreaPopupMenu popup = JXEditAreaPopupMenu.add( editArea );
97 popup.add( editArea.getFindAndReplaceAction());
98 popup.addSeparator();
99 popup.add( editArea.getGoToLineAction() );
100 toggleLineNumbersMenuItem = new JCheckBoxMenuItem( "Show Line Numbers", lineNumbersPanel.isVisible() );
101 toggleLineNumbersMenuItem.setAccelerator( UISupport.getKeyStroke( "alt L" ) );
102 toggleLineNumbersMenuItem.addActionListener( new ActionListener() {
103
104 public void actionPerformed( ActionEvent e )
105 {
106 lineNumbersPanel.setVisible( toggleLineNumbersMenuItem.isSelected() );
107 }} );
108
109 popup.add( toggleLineNumbersMenuItem );
110 }
111
112 private JComponent buildLineNumbers()
113 {
114 editArea.getInputHandler().addKeyBinding( "A+L", new ActionListener() {
115
116 public void actionPerformed( ActionEvent e )
117 {
118 lineNumbersPanel.setVisible( !lineNumbersPanel.isVisible() );
119 toggleLineNumbersMenuItem.setSelected( lineNumbersPanel.isVisible() );
120 }} );
121
122 lineNumbersPanel = new LineNumbersPanel( editArea );
123 return lineNumbersPanel;
124 }
125
126 public JXEditTextArea getEditArea()
127 {
128 return editArea;
129 }
130
131 public void release()
132 {
133 model.getSettings().removeSettingsListener( settingsListener );
134 model = null;
135 editArea.getDocument().removeDocumentListener( groovyDocumentListener );
136 editArea.getInputHandler().removeAllKeyBindings();
137 editArea.getRightClickPopup().removeAll();
138 for( PopupMenuListener listener : editArea.getRightClickPopup().getPopupMenuListeners() )
139 {
140 editArea.getRightClickPopup().removePopupMenuListener( listener );
141 }
142 }
143
144 public void selectError(String message)
145 {
146 int ix = message == null ? -1 : message.indexOf( "@ line " );
147 if( ix >= 0 )
148 {
149 try
150 {
151 int ix2 = message.indexOf(',', ix);
152 int line = ix2 == -1 ? Integer.parseInt(message.substring(ix + 6).trim()) : Integer.parseInt(message
153 .substring(ix + 6, ix2).trim());
154 int column = 0;
155 if (ix2 != -1)
156 {
157 ix = message.indexOf("column ", ix2);
158 if (ix >= 0)
159 {
160 ix2 = message.indexOf('.', ix);
161 column = ix2 == -1 ? Integer.parseInt(message.substring(ix + 7).trim()) : Integer
162 .parseInt(message.substring(ix + 7, ix2).trim());
163 }
164 }
165
166 editArea.setCaretPosition(editArea.getLineStartOffset(line - 1) + column - 1);
167 }
168 catch (Exception ex)
169 {
170 }
171
172 editArea.requestFocus();
173 }
174 }
175
176 private KeywordMap initKeywords()
177 {
178 KeywordMap keywords = GroovyTokenMarker.getKeywords();
179
180 String[] kw = model.getKeywords();
181 if( kw != null )
182 {
183 for( String keyword : kw )
184 keywords.add(keyword,Token.KEYWORD2);
185 }
186
187 return keywords;
188 }
189
190 private final class GroovyDocumentListener extends DocumentListenerAdapter
191 {
192 public void update(Document document)
193 {
194 GroovyEditor.this.model.setScript( editArea.getText() );
195 }
196 }
197
198 private final class InternalSettingsListener implements SettingsListener
199 {
200 public void settingChanged(String name, String newValue, String oldValue)
201 {
202 if( name.equals( UISettings.EDITOR_FONT ))
203 {
204 editArea.setFont( Font.decode( newValue ));
205 invalidate();
206 }
207 }
208 }
209
210 public void addCaretListener( CaretListener listener )
211 {
212 editArea.addCaretListener( listener );
213 }
214
215 public int getCaretPosition()
216 {
217 return editArea.getCaretPosition();
218 }
219
220 public int getLineOfOffset( int offset ) throws Exception
221 {
222 return editArea.getLineOfOffset( offset );
223 }
224
225 public int getLineStartOffset( int line ) throws Exception
226 {
227 return editArea.getLineStartOffset( line );
228 }
229
230 public void removeCaretListener( CaretListener listener )
231 {
232 editArea.removeCaretListener( listener );
233 }
234 }