Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.swing / org.gvsig.scripting.swing.impl / src / main / java / org / gvsig / scripting / swing / impl / composer / SuggestionController.java @ 591

History | View | Annotate | Download (13.6 KB)

1
package org.gvsig.scripting.swing.impl.composer;
2

    
3
import java.awt.BorderLayout;
4
import java.awt.Dimension;
5
import java.awt.Point;
6
import java.awt.event.KeyEvent;
7
import java.awt.event.KeyListener;
8
import java.awt.event.WindowEvent;
9
import java.awt.event.WindowFocusListener;
10
import java.util.ArrayList;
11
import java.util.HashSet;
12
import java.util.List;
13
import java.util.Set;
14
import javax.swing.DefaultListModel;
15
import javax.swing.JFrame;
16
import javax.swing.JOptionPane;
17
import javax.swing.JTextArea;
18
import javax.swing.ListModel;
19
import javax.swing.SwingUtilities;
20
import javax.swing.event.ListSelectionEvent;
21
import javax.swing.event.ListSelectionListener;
22
import org.apache.commons.lang3.StringUtils;
23
import org.gvsig.scripting.ScriptingHelpManager;
24
import org.gvsig.scripting.ScriptingHelpManager.ScriptingHelpClass;
25
import org.slf4j.Logger;
26
import org.slf4j.LoggerFactory;
27

    
28
public class SuggestionController extends SuggestionView {
29

    
30
    protected static final Logger logger = LoggerFactory.getLogger(SuggestionController.class);
31
    
32
    private static final List<ScriptingHelpClass> recentClasses = new ArrayList<ScriptingHelpClass>();
33
    private static final int MAX_RECENT_CLASSES = 10;
34
    
35
    private final JTextArea editor;
36
    private final String searchtext;
37
    private final ScriptingHelpManager manager;
38
    private final List<ScriptingHelpClass> helpClasses;
39
    private JFrame window;
40
    private int show_retries = 0;
41
    
42
    public SuggestionController(ScriptingHelpManager manager, JTextArea editor, String searchtext) {
43
        super();
44
        this.editor = editor;
45
        this.searchtext = searchtext;
46
        this.manager = manager;
47
        this.helpClasses = this.manager.getHelpClasses();
48

    
49
        this.initComponents();
50
    }
51

    
52
    private void initComponents() {
53

    
54
        this.lstClasses.addListSelectionListener(new ListSelectionListener() {
55

    
56
            @Override
57
            public void valueChanged(ListSelectionEvent e) {
58
                doUpdateMethodsList();
59
            }
60

    
61
        });
62
        this.lstClasses.addKeyListener(new KeyListener() {
63

    
64
            @Override
65
            public void keyTyped(KeyEvent e) {
66
                char ch = e.getKeyChar();
67
                if (ch == ' ' || ch == '\n') {
68
                    doUpdateMethodsList();
69
                    doToMethods();
70
                }
71
            }
72

    
73
            @Override
74
            public void keyPressed(KeyEvent e) {
75
            }
76

    
77
            @Override
78
            public void keyReleased(KeyEvent e) {
79
                switch (e.getKeyCode()) {
80
                    case KeyEvent.VK_ESCAPE:
81
                        doClose();
82
                        break;
83
                    case KeyEvent.VK_F1:
84
                        ScriptingHelpClass helpClass = getCurrentClass();
85
                        if( helpClass!=null ) {
86
                            JOptionPane.showMessageDialog(editor,"Oh!, falta por implementar. \nAqui sacar la ayuda de la clase '"+helpClass.getName()+"'.");
87
                        }
88
                        break;
89
                    case KeyEvent.VK_F2:
90
                        doToFilterClass();
91
                        break;
92
                    case KeyEvent.VK_F3:
93
                        doToMethods();
94
                        break;
95
                    case KeyEvent.VK_UP:
96
                        if( SuggestionController.this.lstClasses.getSelectedIndex()<1 ) {
97
                            doToFilterClass();
98
                        }
99
                        break;
100
                    case KeyEvent.VK_RIGHT:
101
                        doToMethods();
102
                        break;
103
                }
104
            }
105

    
106
        });
107

    
108
        this.txtClassFilter.addKeyListener(new KeyListener() {
109

    
110
            @Override
111
            public void keyTyped(KeyEvent e) {
112
                char ch = e.getKeyChar();
113
                if (ch == ' ' || ch == '\n') {
114
                    doUpdateClassesList();
115
                }
116
            }
117

    
118
            @Override
119
            public void keyPressed(KeyEvent e) {
120
            }
121

    
122
            @Override
123
            public void keyReleased(KeyEvent e) {
124
                switch (e.getKeyCode()) {
125
                    case KeyEvent.VK_ESCAPE:
126
                        doClose();
127
                        break;
128
                    case KeyEvent.VK_F2:
129
                    case KeyEvent.VK_DOWN:
130
                        doToClasses();
131
                        break;
132
                    case KeyEvent.VK_F3:
133
                        doToMethods();
134
                        break;
135
                    case KeyEvent.VK_RIGHT:
136
                        doToFilterMethod();
137
                        break;
138
                }
139
            }
140

    
141
        });
142
        
143
        this.lstMethods.addKeyListener(new KeyListener() {
144

    
145
            @Override
146
            public void keyTyped(KeyEvent e) {
147
                char ch = e.getKeyChar();
148
                if (ch == ' ' || ch == '\n') {
149
                    doSelectMethod();
150
                }
151
            }
152

    
153
            @Override
154
            public void keyPressed(KeyEvent e) {
155
            }
156

    
157
            @Override
158
            public void keyReleased(KeyEvent e) {
159
                switch (e.getKeyCode()) {
160
                    case KeyEvent.VK_ESCAPE:
161
                        doClose();
162
                        break;
163
                    case KeyEvent.VK_F2:
164
                        doToClasses();
165
                        break;
166
                    case KeyEvent.VK_F3:
167
                        doToFilterMethod();
168
                        break;
169
                    case KeyEvent.VK_LEFT:
170
                        doToClasses();
171
                        break;
172
                    case KeyEvent.VK_UP:
173
                        if( SuggestionController.this.lstMethods.getSelectedIndex()<1 ) {
174
                            doToFilterMethod();
175
                        }
176
                        break;
177
                }
178
            }
179

    
180
        });
181
        this.txtMethodFilter.addKeyListener(new KeyListener() {
182

    
183
            @Override
184
            public void keyTyped(KeyEvent e) {
185
                char ch = e.getKeyChar();
186
                if (ch == ' ' || ch == '\n') {
187
                    doUpdateMethodsList();
188
                }
189
            }
190

    
191
            @Override
192
            public void keyPressed(KeyEvent e) {
193
            }
194

    
195
            @Override
196
            public void keyReleased(KeyEvent e) {
197
                switch (e.getKeyCode()) {
198
                    case KeyEvent.VK_ESCAPE:
199
                        doClose();
200
                        break;
201
                    case KeyEvent.VK_F2:
202
                        doToClasses();
203
                        break;
204
                    case KeyEvent.VK_F3:
205
                    case KeyEvent.VK_DOWN:
206
                        doToMethods();
207
                        break;
208
                    case KeyEvent.VK_LEFT:
209
                        doToFilterClass();
210
                        break;
211
                }
212
            }
213

    
214
        });
215
        this.doUpdateClassesList();
216
        if( !StringUtils.isEmpty(searchtext) ) {
217
            this.txtMethodFilter.setText(searchtext);
218
            doUpdateMethodsList();
219
            doToMethods();
220
        }
221
    }
222

    
223
    private ScriptingHelpClass getCurrentClass() {
224
        return (ScriptingHelpClass) (this.lstClasses.getSelectedValue());
225
    }
226
    
227
    private void addToRecentClasses(ScriptingHelpClass helpClass) {
228
        recentClasses.add(0, helpClass);
229
        while( recentClasses.size()>MAX_RECENT_CLASSES ) {
230
            recentClasses.remove(MAX_RECENT_CLASSES-1);
231
        }
232
    }
233
    
234
    private void doToMethods() {
235
        this.lstMethods.requestFocus();
236
    }
237

    
238
    private void doToClasses() {
239
        this.lstClasses.requestFocus();
240
    }
241

    
242
    private void doToFilterClass() {
243
        this.txtClassFilter.requestFocus();
244
        this.txtClassFilter.setSelectionStart(0);
245
        this.txtClassFilter.setSelectionEnd(this.txtClassFilter.getText().length());
246
        this.lstClasses.setSelectedIndex(-1);
247
    }
248
    
249
    private void doToFilterMethod() {
250
        this.txtMethodFilter.requestFocus();
251
        this.txtMethodFilter.setSelectionStart(0);
252
        this.txtMethodFilter.setSelectionEnd(this.txtMethodFilter.getText().length());
253
        this.lstMethods.setSelectedIndex(-1);
254
    }
255

    
256
    private void doClose() {
257
        int end = editor.getSelectionEnd();
258
        editor.setSelectionStart(end);
259
        editor.setSelectionEnd(end);
260
        this.window.setVisible(false);
261
    }
262

    
263
    private void doUpdateClassesList() {
264
        Set<ScriptingHelpClass>addeds = new HashSet<ScriptingHelpClass>();
265

    
266
        String filter = this.txtClassFilter.getText();
267
        DefaultListModel modelClasses = new DefaultListModel();
268
        for (ScriptingHelpClass helpClass : recentClasses) {
269
            if( addeds.contains(helpClass) ) {
270
                continue;
271
            }
272
            if( StringUtils.isEmpty(filter) ) {
273
                modelClasses.addElement(helpClass);
274
                addeds.add(helpClass);
275
            } else {
276
                if( filter.contains("*") ) {
277
                    if( helpClass.getName().matches(filter.replace("[*]", ".*")) ) {
278
                        modelClasses.addElement(helpClass);
279
                    }
280
                } else {
281
                    // if( StringUtils.getJaroWinklerDistance(helpClass.getName(), filter) > 0.70 ) {
282
                    if( StringUtils.containsIgnoreCase(helpClass.getName(), filter) ) {
283
                        modelClasses.addElement(helpClass);
284
                        addeds.add(helpClass);
285
                    }                
286
                }
287
            }
288
        }
289
        for (ScriptingHelpClass helpClass : helpClasses) {
290
            if( addeds.contains(helpClass) ) {
291
                continue;
292
            }
293
            if( StringUtils.isEmpty(filter) ) {
294
                modelClasses.addElement(helpClass);
295
                addeds.add(helpClass);
296
            } else {
297
                if( filter.contains("*") ) {
298
                    if( helpClass.getName().toLowerCase().matches(filter.toLowerCase().replace("*", ".*")) ) {
299
                        modelClasses.addElement(helpClass);
300
                    }
301
                } else {
302
                    // if( StringUtils.getJaroWinklerDistance(helpClass.getName(), filter) > 0.70 ) {
303
                    if( StringUtils.containsIgnoreCase(helpClass.getName(), filter) ) {
304
                        modelClasses.addElement(helpClass);
305
                        addeds.add(helpClass);
306
                    }                
307
                }
308
            }
309
        }
310
        this.lstClasses.setModel(modelClasses);
311
        if( !modelClasses.isEmpty() ) {
312
            this.lstClasses.setSelectedIndex(0);            
313
        }
314
    }
315

    
316
    public boolean isEmpty() {
317
        ListModel model = this.lstClasses.getModel();
318
        return model.getSize() < 1;
319
    }
320
    
321
    private void doUpdateMethodsList() {
322
        ScriptingHelpClass helpClass = (ScriptingHelpClass) (this.lstClasses.getSelectedValue());
323
        if (helpClass != null) {
324
            String filter = this.txtMethodFilter.getText();
325
            DefaultListModel methodsModel = new DefaultListModel();
326
            for (String methodname : helpClass.getMethods()) {
327
                if( StringUtils.isEmpty(filter) ) {                   
328
                    methodsModel.addElement(methodname);
329
                } else {
330
                    if( filter.contains("*") ) {
331
                        if( methodname.toLowerCase().matches(filter.toLowerCase().replace("*", ".*")) ) {
332
                            methodsModel.addElement(methodname);
333
                        }
334
                    } else {
335
                        if( methodname.toLowerCase().startsWith(filter.toLowerCase())) {
336
                            methodsModel.addElement(methodname);
337
                        }
338
                    }
339
                }
340
            }
341
            this.lstMethods.setModel(methodsModel); 
342
            if( !methodsModel.isEmpty() ) {
343
                this.lstMethods.setSelectedIndex(0);            
344
            }
345
        }
346
    }
347

    
348
    private void doSelectMethod() {
349
        String methodname = (String) (this.lstMethods.getSelectedValue());
350
        if (methodname != null) {
351
            ScriptingHelpClass helpClass = (ScriptingHelpClass) (this.lstClasses.getSelectedValue());
352
            if (helpClass != null) {
353
                addToRecentClasses(helpClass);
354
            }
355
            editor.replaceSelection(methodname);
356
            doClose();
357
        }
358
    }
359

    
360
    public void showSuggestion() {
361
        Point p = editor.getCaret().getMagicCaretPosition();
362
        if( p==null ) {
363
            // A veces getMagicCaretPosition retorna null
364
            // Lo reintentamos cuando se pueda otra vez hasta 5 veces.
365
            //logger.info("Retry showSuggestion(), retriy "+this.show_retries);
366
            if( this.show_retries >5 ) {
367
                return;
368
            }
369
            SwingUtilities.invokeLater(new Runnable() {
370

    
371
                @Override
372
                public void run() {
373
                    show_retries++;
374
                    showSuggestion();
375
                }
376
            });
377
            return;
378
        }
379
        SwingUtilities.convertPointToScreen(p, editor);
380
        p.x = p.x + 2;
381
        p.y = p.y + 20;
382

    
383
        this.window = new JFrame("Suggestions Window");
384

    
385
        window.addWindowFocusListener(new WindowFocusListener() {
386
            public void windowGainedFocus(WindowEvent e) {
387

    
388
            }
389

    
390
            public void windowLostFocus(WindowEvent e) {
391
                doClose();
392
            }
393
        });
394
        window.setUndecorated(true);
395
        window.setLayout(new BorderLayout());
396
        window.setSize(new Dimension(300, 200));
397
        window.add(this, BorderLayout.CENTER);
398
        window.pack();
399
        window.setLocation(p.x,p.y);
400
        window.setVisible(true);
401
    }
402
}