Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.swing / org.gvsig.expressionevaluator.swing.impl / src / main / java / org / gvsig / expressionevaluator / swing / impl / DefaultJExpressionBuilder.java @ 44006

History | View | Annotate | Download (28.5 KB)

1
package org.gvsig.expressionevaluator.swing.impl;
2

    
3
import java.awt.BorderLayout;
4
import java.awt.Dimension;
5
import java.awt.event.ActionEvent;
6
import java.awt.event.ActionListener;
7
import java.awt.event.KeyAdapter;
8
import java.awt.event.KeyEvent;
9
import java.awt.event.MouseAdapter;
10
import java.awt.event.MouseEvent;
11
import java.net.URL;
12
import java.util.ArrayList;
13
import java.util.Collection;
14
import java.util.Date;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Objects;
18
import javax.swing.DefaultListCellRenderer;
19
import javax.swing.ImageIcon;
20
import javax.swing.JComponent;
21
import javax.swing.JEditorPane;
22
import javax.swing.JLabel;
23
import javax.swing.JList;
24
import javax.swing.JOptionPane;
25
import javax.swing.JTree;
26
import javax.swing.SwingUtilities;
27
import javax.swing.event.ListSelectionEvent;
28
import javax.swing.event.ListSelectionListener;
29
import javax.swing.event.TreeModelEvent;
30
import javax.swing.event.TreeModelListener;
31
import javax.swing.event.TreeSelectionEvent;
32
import javax.swing.event.TreeSelectionListener;
33
import javax.swing.tree.DefaultTreeCellRenderer;
34
import javax.swing.tree.TreeModel;
35
import javax.swing.tree.TreePath;
36
import org.apache.commons.io.FilenameUtils;
37
import org.apache.commons.lang3.StringUtils;
38
import org.apache.commons.lang.StringEscapeUtils;
39
import org.gvsig.expressionevaluator.Expression;
40
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
41
import org.gvsig.expressionevaluator.Function;
42
import org.gvsig.expressionevaluator.SymbolTable;
43
import org.gvsig.expressionevaluator.swing.Element;
44
import org.gvsig.expressionevaluator.swing.Element.CalculatedElement;
45
import org.gvsig.expressionevaluator.swing.Element.ConstantElement;
46
import org.gvsig.expressionevaluator.swing.Element.FunctionElement;
47
import org.gvsig.expressionevaluator.swing.Element.GroupElement;
48
import org.gvsig.expressionevaluator.swing.Element.SimpleElement;
49
import org.gvsig.expressionevaluator.swing.Element.VariableElement;
50
import org.gvsig.expressionevaluator.swing.ExpressionBuilderConfig;
51
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
52
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
53
import org.gvsig.tools.ToolsLocator;
54
import org.gvsig.tools.script.Script;
55
import org.gvsig.tools.swing.api.Component;
56
import org.gvsig.tools.swing.api.ListElement;
57
import org.gvsig.tools.swing.api.ToolsSwingLocator;
58
import org.gvsig.tools.swing.api.ToolsSwingManager;
59
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
60
import org.gvsig.tools.swing.api.script.ScriptSwingManager;
61
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
62
import org.gvsig.tools.swing.icontheme.IconTheme;
63

    
64
/**
65
 *
66
 * @author jjdelcerro
67
 */
68
public class DefaultJExpressionBuilder
69
        extends DefaultJExpressionBuilderView
70
        implements JExpressionBuilder {
71

    
72
    private final ExpressionEvaluatorSwingManager manager;
73
    private GroupElement currentGroup;
74
    private PickerController<List<Script>> scriptPicker;
75
    private ScriptSwingManager.ScriptEditor scriptEditor;
76
    
77
    private final ExpressionBuilderConfig config;
78
    private ElementsTreeModel treeModel;
79
    private java.awt.Component infoPanel = null;
80
    private JEditorPane txtDescription;
81
    private ImageIcon defaultIconGroup;
82
    private ImageIcon defaultIconElement;
83
    
84
    private class ElementsTreeModel implements TreeModel {
85

    
86
        private final GroupElement root;
87
        private final HashSet<TreeModelListener> listeners;
88

    
89
        public ElementsTreeModel(GroupElement root) {
90
            this.root = root;
91
            this.listeners = new HashSet<>();
92
        }
93

    
94
        @Override
95
        public Object getRoot() {
96
            return this.root;
97
        }
98

    
99
        public void reload() {
100
            this.reload(this.root);
101
            this.fireTreeChanged();
102
        }
103
        
104
        private void reload(Element element) {
105
            if (element instanceof Element) {
106
                if (element instanceof GroupElement) {
107
                    reload(element);
108
                }
109
                element.reload();
110
            }
111
        }
112
        
113
        private List<Element> getChilds(final GroupElement node) {
114
            List<Element> x = new ArrayList<>();
115
            for (Element element : node.getElements()) {
116
                if (element instanceof GroupElement) {
117
                    x.add(element);
118
                }
119
            }
120
            return x; //node.getElements();
121
        }
122

    
123
        @Override
124
        public Object getChild(Object parent, int index) {
125
            List<Element> childs = getChilds((GroupElement) parent);
126
            Element child = childs.get(index);
127
            return child;
128
        }
129

    
130
        @Override
131
        public int getChildCount(Object parent) {
132
            List<Element> childs = getChilds((GroupElement) parent);
133
            return childs.size();
134
        }
135

    
136
        @Override
137
        public boolean isLeaf(Object node) {
138
            if( node instanceof GroupElement ) {
139
                return !((GroupElement) node).hasSubgroups();
140
            }
141
            return false;
142
        }
143

    
144
        @Override
145
        public void valueForPathChanged(TreePath path, Object newValue) {
146
        }
147

    
148
        @Override
149
        public int getIndexOfChild(Object parent, Object child) {
150
            List<Element> childs = getChilds((GroupElement) parent);
151
            int n = childs.indexOf(child);
152
            return n;
153
        }
154

    
155
        @Override
156
        public void addTreeModelListener(TreeModelListener l) {
157
            this.listeners.add(l);
158
        }
159

    
160
        @Override
161
        public void removeTreeModelListener(TreeModelListener l) {
162
            this.listeners.remove(l);
163
        }
164

    
165
        protected void fireTreeChanged() {
166
            for (TreeModelListener listener : listeners) {
167
                TreeModelEvent e = new TreeModelEvent(this, new Object[] {this.root});
168
                listener.treeNodesChanged(e);
169
            }
170
        }
171
    }
172

    
173
    public DefaultJExpressionBuilder(ExpressionEvaluatorSwingManager manager, ExpressionBuilderConfig config) {
174
        this.manager = manager;
175
        if( config == null ) {
176
            this.config = new DefaultExpressionBuilderConfig(manager);
177
        } else {
178
            this.config = config;
179
        }
180
        this.initComponents();
181
    }
182
    
183
    @Override
184
    public ImageIcon loadImage(String imageName) {
185
        String name = FilenameUtils.getBaseName(imageName);
186
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
187
        if (theme.exists(name)) {
188
            return theme.get(name);
189
        }
190
        URL url = this.getClass().getResource(name + ".png");
191
        if (url == null) {
192
            return null;
193
        }
194
        return new ImageIcon(url);
195
    }
196

    
197
    private void initComponents() {
198
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
199
        final IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
200
        
201
        this.defaultIconGroup = theme.get("expressionbuilder-element-group");
202
        this.defaultIconElement = theme.get("expressionbuilder-element");
203
        
204
        this.txtDescription = new JEditorPane();
205
        
206
        toolsSwingManager.setDefaultPopupMenu(this.txtExpression);
207
        toolsSwingManager.setDefaultPopupMenu(this.txtGroupElement);
208
        toolsSwingManager.setDefaultPopupMenu(this.txtSimpleElementFilter);
209
        toolsSwingManager.setDefaultPopupMenu(this.txtDescription);
210
        toolsSwingManager.addClearButton(this.txtExpression);
211
        toolsSwingManager.addClearButton(this.txtSimpleElementFilter, new ActionListener() {
212
            @Override
213
            public void actionPerformed(ActionEvent e) {
214
                txtSimpleElementFilter.setText("");
215
                doFilter();
216
            }
217
        });
218
        this.pnlDescription.setLayout(new BorderLayout());
219
        this.pnlDescription.setBackground(this.txtDescription.getBackground());
220
        
221
        this.treeElements.setCellRenderer(new DefaultTreeCellRenderer() {
222
            @Override
223
            public java.awt.Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
224
                JLabel label = (JLabel) super.getTreeCellRendererComponent(tree,value, selected, expanded, leaf, row, hasFocus);
225
                if( value instanceof Element ) {
226
                    Element element = (Element) value;
227
                    if( element.getIconName()==null ) {
228
                        if( element instanceof GroupElement ) {
229
                            label.setIcon(defaultIconGroup);
230
                        } else {
231
                            label.setIcon(defaultIconElement);
232
                        }
233
                    } else {
234
                        label.setIcon(element.getIcon());
235
                    }
236
                    label.setText(element.getName());
237
                } else {
238
                    label.setIcon(null);
239
                    label.setText(Objects.toString(value, ""));
240
                }
241
                return label;
242
            }
243
        });
244
        
245
        this.treeElements.addTreeSelectionListener(new TreeSelectionListener() {
246
            @Override
247
            public void valueChanged(TreeSelectionEvent e) {
248
                TreePath path = e.getPath();
249
                Element element = (Element) path.getLastPathComponent();
250
                if (element instanceof GroupElement) {
251
                    updateSimpleElementsList((GroupElement) element);
252
                }
253
            }
254
        });
255
        this.btnGroupElementInsert.addActionListener(new ActionListener() {
256
            @Override
257
            public void actionPerformed(ActionEvent e) {
258
                doInsert(txtGroupElement.getText());
259
            }
260
        });
261
        this.btnSimpleElementInsert.addActionListener(new ActionListener() {
262
            @Override
263
            public void actionPerformed(ActionEvent e) {
264
                ListElement<SimpleElement> element = (ListElement<SimpleElement>) lstSimpleElement.getSelectedValue();
265
                if (element != null) {
266
                    doInsert(element.getValue());
267
                }
268
            }
269
        });
270
        this.btnSimpleElementFilter.addActionListener(new ActionListener() {
271
            @Override
272
            public void actionPerformed(ActionEvent e) {
273
                doFilter();
274
            }
275
        });
276
        
277
        this.lstSimpleElement.setModel(new FilteredListModel());
278
        this.lstSimpleElement.setCellRenderer(new DefaultListCellRenderer() {
279
            @Override
280
            public java.awt.Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
281
                JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
282
                Element element = null;
283
                if( value instanceof ListElement ) {
284
                    if( ((ListElement) value).getValue() instanceof Element ) {
285
                        element = (Element) ((ListElement) value).getValue();
286
                    }
287
                }
288
                if( element !=null ) {
289
                    if( element.getIconName()==null ) {
290
                        if( element instanceof GroupElement ) {
291
                            label.setIcon(defaultIconGroup);
292
                        } else {
293
                            label.setIcon(defaultIconElement);
294
                        }
295
                    } else {
296
                        label.setIcon(element.getIcon());
297
                    }
298
                    label.setText(element.getName());
299
                } else {
300
                    label.setIcon(null);
301
                    label.setText(Objects.toString(value, ""));
302
                }
303
                return label;
304
            }
305
        });
306
        this.lstSimpleElement.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
307
            @Override
308
            public void valueChanged(ListSelectionEvent e) {
309
                ListElement<SimpleElement> element = (ListElement<SimpleElement>) lstSimpleElement.getSelectedValue();
310
                if (element != null) {
311
                    doSelectElement(element.getValue());
312
                }
313
            }
314
        });
315
        this.lstSimpleElement.addMouseListener(new MouseAdapter() {
316
            @Override
317
            public void mouseClicked(MouseEvent e) {
318
                if( e.getButton()==MouseEvent.BUTTON1 && e.getClickCount()==2 ) {
319
                    ListElement<SimpleElement> element = (ListElement<SimpleElement>) lstSimpleElement.getSelectedValue();
320
                    if (element != null) {
321
                        doSelectElement(element.getValue());
322
                        doInsert(element.getValue());
323
                    }
324
                }
325
            }
326
        });
327
        this.lstSimpleElement.addKeyListener(new KeyAdapter() {
328
            @Override
329
            public void keyReleased(KeyEvent e) {
330
                if( e.getKeyCode()==KeyEvent.VK_ENTER ) {
331
                    ListElement<SimpleElement> element = (ListElement<SimpleElement>) lstSimpleElement.getSelectedValue();
332
                    if (element != null) {
333
                        doSelectElement(element.getValue());
334
                        doInsert(element.getValue());
335
                    }
336
                }
337
            }
338
        });
339

    
340
        this.btnSimpleElementTimeLimit.addActionListener(new ActionListener() {
341
            @Override
342
            public void actionPerformed(ActionEvent e) {
343
                doSetTimeLimit();
344
            }
345
        });
346
        this.btnSimpleElementSortDown.addActionListener(new ActionListener() {
347
            @Override
348
            public void actionPerformed(ActionEvent e) {
349
                FilteredListModel model = (FilteredListModel) lstSimpleElement.getModel();
350
                model.sort(false);
351
            }
352
        });
353
        this.btnSimpleElementSortUp.addActionListener(new ActionListener() {
354
            @Override
355
            public void actionPerformed(ActionEvent e) {
356
                FilteredListModel model = (FilteredListModel) lstSimpleElement.getModel();
357
                model.sort(true);
358
            }
359
        });
360
        this.txtSimpleElementFilter.addKeyListener(new KeyAdapter() {
361
            @Override
362
            public void keyTyped(KeyEvent e) {
363
                if (e.getKeyChar() == '\n') {
364
                    doFilter();
365
                }
366
            }
367
        });
368
        this.btnAdd.addActionListener(new ActionListener() {
369
            @Override
370
            public void actionPerformed(ActionEvent e) {
371
                doInsert(" + ");
372
            }
373
        });
374
        this.btnDiv.addActionListener(new ActionListener() {
375
            @Override
376
            public void actionPerformed(ActionEvent e) {
377
                doInsert(" / ");
378
            }
379
        });
380
        this.btnEq.addActionListener(new ActionListener() {
381
            @Override
382
            public void actionPerformed(ActionEvent e) {
383
                doInsert(" = ");
384
            }
385
        });
386
        this.btnMult.addActionListener(new ActionListener() {
387
            @Override
388
            public void actionPerformed(ActionEvent e) {
389
                doInsert(" * ");
390
            }
391
        });
392
        this.btnNeq.addActionListener(new ActionListener() {
393
            @Override
394
            public void actionPerformed(ActionEvent e) {
395
                doInsert(" <> ");
396
            }
397
        });
398
        this.btnParentClose.addActionListener(new ActionListener() {
399
            @Override
400
            public void actionPerformed(ActionEvent e) {
401
                doInsert(" ) ");
402
            }
403
        });
404
        this.btnParentOpen.addActionListener(new ActionListener() {
405
            @Override
406
            public void actionPerformed(ActionEvent e) {
407
                doInsert(" ( ");
408
            }
409
        });
410
        this.btnSubst.addActionListener(new ActionListener() {
411
            @Override
412
            public void actionPerformed(ActionEvent e) {
413
                doInsert(" - ");
414
            }
415
        });
416
        ScriptSwingManager scriptSwingManager = ToolsSwingLocator.getScriptSwingManager();
417
        this.scriptPicker = scriptSwingManager.createListScriptPickerController(
418
                cboPickerScripts,
419
                btnPickerRemove,
420
                btnPickerSelectScript
421
        );
422
        this.scriptEditor = scriptSwingManager.createScriptEditor();
423
        this.pnlScriptEditorContainer.setLayout(new BorderLayout());
424
        this.pnlScriptEditorContainer.add(this.scriptEditor.asJComponent(), BorderLayout.CENTER);
425
    
426
        this.tabExpressionBuilder.setEnabledAt(0, this.config.getScriptsEnabled());
427
        this.setPreferredSize(new Dimension(650, 350));
428
        this.txtDescription.setPreferredSize(new Dimension(200,200));
429
    }
430

    
431
    private String removeCursorMark(String s) {
432
        s = s.replace("{{", "");
433
        s = s.replace("}}", "");
434
        return s;
435
    }
436

    
437
    private void doInsert(String s) {
438
        this.txtExpression.replaceSelection(s);
439
        String ss = this.txtExpression.getText();
440
        int start = ss.indexOf("{{");
441
        int end = ss.indexOf("}}");
442
        if (start > 0 && end > 0) {
443
            this.txtExpression.replaceRange("", end, end + 2);
444
            this.txtExpression.replaceRange("", start, start + 2);
445
            this.txtExpression.setSelectionStart(start);
446
            this.txtExpression.setSelectionEnd(end - 2);
447
        }
448
        this.txtExpression.requestFocusInWindow();
449
    }
450

    
451
    private void doInsert(SimpleElement element) {
452
        if( element instanceof FunctionElement ) {
453
            Function function = ((FunctionElement)element).getFunction();
454
            if (function == null) {
455
                doInsert(element.getName());
456
            } else {
457
                doInsert(function.template() == null ? function.name() + "({{}})" : function.template());
458
            }
459
        } else if( element instanceof CalculatedElement) {
460
            Object value = ((CalculatedElement) element).getValue();
461
            if( value != null ) {
462
                doInsert(" "+value.toString()+" ");
463
            }
464
        } else if( element instanceof ConstantElement) {
465
            Object value = ((ConstantElement) element).getValue();
466
            doInsert(" "+repr(value)+" ");
467
        } else {
468
            doInsert(" "+element.getName()+" ");
469
        }
470
    }
471

    
472
    private void doFilter() {
473
        FilteredListModel model = (FilteredListModel) this.lstSimpleElement.getModel();
474
        model.setFilter(this.txtSimpleElementFilter.getText());
475
    }
476

    
477
    private void doSelectElement(SimpleElement element) {
478
        Component aditionalPanel = element.getAditionalPanel();
479
        java.awt.Component newInfoPanel = null;
480
        if( aditionalPanel == null ) {
481
            StringBuilder html = new StringBuilder();
482
            html.append("<html>\n");
483
            if( element instanceof ConstantElement ) {
484
                Object value = ((ConstantElement)element).getValue();
485
                if( value == null ) {
486
                    html.append("<b>Constant</b><br>\n<br>\n");
487
                    html.append("<b>Value</b> NULL<br>\n");
488
                } else {
489
                    html.append("<b>Constant</b><br>\n<br>\n");
490
                    html.append("<b>Value</b> ").append(repr(value)).append("<br>\n");
491
                    html.append("<b>Type</b> ").append(value.getClass().getSimpleName()).append("<br>\n");
492
                }
493

    
494
            } else if( element instanceof VariableElement ) {
495
                    VariableElement var = (VariableElement)element;
496
                    html.append("<b>").append(var.getLabel()).append("</b><br>\n<br>\n");
497
                    html.append("<b>Source</b> ").append(var.getSource()).append("<br>\n");
498
                    html.append("<b>Name</b> ").append(var.getName()).append("<br>\n");
499
                    html.append("<b>Type</b> ").append(var.getTypeName()).append("<br>\n");
500

    
501
            } else if( element instanceof FunctionElement ) {
502
                Function function = ((FunctionElement)element).getFunction();
503
                if (function == null) {
504
                    html.append("<b>Function</b> ").append(element.getName()).append("<br>\n<br>\n");
505
                    html.append("<b>Return</b> Object<br>\n<br>\n");
506
                    html.append("<b>Template:</b> ").append(element.getName()).append("()<br>\n");
507
                } else {
508
                    html.append("<b>Function</b> ").append(element.getName()).append("<br>\n<br>\n");
509
                    html.append("<b>Return</b> ");
510
                    html.append(StringUtils.isEmpty(function.returnType())?"Objec": function.returnType());
511
                    html.append("<br>\n");
512
                    html.append("<b>Template</b> ");
513
                    html.append(StringUtils.isEmpty(function.template())?element.getName()+"()": removeCursorMark(function.template()));
514
                    html.append("<br>\n");
515

    
516
                    String[] args = function.descriptionArgs();
517
                    if (args != null) {
518
                        html.append("<b>Arguments:</b> ").append("<ul>\n");
519
                        for (String arg : args) {
520
                            html.append("<li>").append(arg).append("</li>\n");
521
                        }
522
                        html.append("</ul>\n");
523
                        html.append("<br>\n");
524
                    }
525
                }
526
            } else {
527
                html.append("<b>Generic element<br>\n<br>\n");
528
                html.append("<b>Name</b> ").append(element.getName()).append("</br>\n");
529

    
530
            }
531

    
532
            if( element.getDescription()!=null ) {
533
                html.append("<b>Description</b><br>\n");
534
                html.append(element.getDescription().replace("\n", "<br>")).append("<br>\n");
535
            }
536
            html.append("</html>\n");
537
            this.txtDescription.setContentType("text/html");
538
            this.txtDescription.setText(html.toString());
539
            this.txtDescription.setCaretPosition(0);
540
            newInfoPanel = this.txtDescription;
541
        } else {
542
            newInfoPanel = aditionalPanel.asJComponent();
543
        }
544
        
545
        if( this.infoPanel != newInfoPanel ) {
546
            this.pnlDescription.removeAll();
547
            this.pnlDescription.add(newInfoPanel, BorderLayout.CENTER);
548
            this.pnlDescription.revalidate();
549
            this.pnlDescription.repaint();
550
            this.infoPanel = newInfoPanel;
551
        }
552
        
553
    }
554

    
555
    private void updateSimpleElementsList(GroupElement group) {
556
        FilteredListModel model = new FilteredListModel();
557
        model.addElement("Loading...");
558
        this.currentGroup = group;
559
        this.txtGroupElement.setText(group.getName());
560
        this.txtSimpleElementFilter.setText("");
561
        this.txtDescription.setText("");
562
        if( this.infoPanel != this.txtDescription ) {
563
            this.pnlDescription.removeAll();
564
            this.pnlDescription.add(this.txtDescription, BorderLayout.CENTER);
565
            this.pnlDescription.repaint();
566
            this.infoPanel = this.txtDescription;
567
        }
568
        if (group instanceof SimpleElement) {
569
            this.btnGroupElementInsert.setEnabled(true);
570
        } else {
571
            this.btnGroupElementInsert.setEnabled(false);
572
        }
573
        this.lstSimpleElement.setEnabled(false);
574
        this.lstSimpleElement.setModel(model);
575

    
576
        Thread th = new Thread(new Runnable() {
577
            @Override
578
            public void run() {
579
                simpleElementsUpdater();
580
            }
581
        }, "ExpressionBuilderSimpleElementsUpdater");
582
        th.start();
583
    }
584

    
585
    private void simpleElementsUpdater() {
586
        final GroupElement group = this.currentGroup;
587
        final FilteredListModel model = new FilteredListModel();
588
        for (Element child : group) {
589
            if (group != this.currentGroup) {
590
                return;
591
            }
592
            if (child instanceof SimpleElement) {
593
                String label = child.getName();
594
                Function function = child instanceof FunctionElement?  ((FunctionElement)child).getFunction(): null;
595
                if (function != null && !StringUtils.isEmpty(function.returnType())) {
596
                    label = "<html><b>" + label + "</b> return " + function.returnType() + "</html>";
597
//                    label = label + " return " + function.returnType();
598
                }
599
                model.addElement(new ListElement<>(label, child));
600
            }
601
        }
602
        model.sort(true);
603
        SwingUtilities.invokeLater(new Runnable() {
604
            @Override
605
            public void run() {
606
                if (group != currentGroup) {
607
                    return;
608
                }
609
                if( group.hasMoreElements() ) {
610
                    lblSimpleElementsMsg.setText("More elements...");
611
                } else {
612
                    lblSimpleElementsMsg.setText("");
613
                }
614
                lstSimpleElement.setEnabled(true);
615
                lstSimpleElement.setModel(model);
616
            }
617
        });
618

    
619
    }
620

    
621
    @Override
622
    public Expression getExpression() {
623
        String phrase = this.txtExpression.getText();
624
        if (StringUtils.isEmpty(phrase)) {
625
            return null;
626
        }
627
        Expression expression = ExpressionEvaluatorLocator.getManager().createExpression();
628
        expression.setPhrase(phrase);
629
        Script script = ToolsLocator.getScriptManager().createScript("UserScript", "", "python");
630
        this.scriptEditor.fetch(script);
631
        if( !StringUtils.isEmpty(script.getCode()) ) {
632
            expression.setUserScript(script);
633
        }
634
        return expression;
635
    }
636

    
637
    @Override
638
    public void setExpression(Expression expression) {
639
        this.txtExpression.setText(expression.getPhrase());
640
        if( expression.getUserScript()!=null ) {
641
            this.scriptEditor.set(expression.getUserScript());
642
        }
643
        if( expression.getScripts()!=null ) {
644
            this.scriptPicker.set(expression.getScripts().toList());
645
        }
646
    }
647
    
648
    @Override
649
    public int getSimpleElementsLimit() {
650
        return this.config.getSimpleElementsLimit();
651
    }
652

    
653
    @Override
654
    public void setSimpleElementsLimit(int limit) {
655
        this.config.setSimpleElementsLimit(limit);
656
    }
657
    
658
    @Override
659
    public List<Element> getElements() {
660
        return this.config.getElements();
661
    }
662

    
663
    @Override
664
    public Collection<SymbolTable> getSymbolTables() {
665
        return this.config.getSymbolTables();
666
    }
667
    
668
    @Override
669
    public void addSymbolTable(String name) {
670
        this.config.addSymbolTable(name);
671
    }
672
    
673
    @Override
674
    public void addSymbolTable(SymbolTable symbolTable) {
675
        this.config.addSymbolTable(symbolTable);
676
    }
677

    
678
    @Override
679
    public void removeAllSymbolTables() {
680
        this.config.removeAllSymbolTables();
681
    }
682

    
683
    @Override
684
    public void removeSymbolTable(String name) {
685
        this.config.removeSymbolTable(name);
686
    }
687

    
688
    @Override
689
    public void setScriptsEnabled(boolean enabled) {
690
        this.config.setScriptsEnabled(enabled);
691
        this.tabExpressionBuilder.setEnabledAt(0, this.config.getScriptsEnabled());
692
    }
693

    
694
    @Override
695
    public boolean getScriptsEnabled() {
696
        return this.config.getScriptsEnabled();
697
    }
698
    
699
    @Override
700
    public JComponent asJComponent() {
701
        if( this.treeModel == null ) {
702
            this.treeModel = new ElementsTreeModel(
703
                    this.manager.createGroupElement("_Elements", this.getElements())
704
            );
705
            this.treeElements.setModel(this.treeModel);
706
        }
707
        return this;
708
    }
709

    
710
    private String repr(Object value)  {
711
        if (value == null) {
712
            return "NULL";
713
        } else if (value instanceof Date) {
714
            return "DATE('" + value + "')";
715
        } else if (value instanceof Boolean) {
716
            return value.toString();
717
        } else if (value instanceof String) {
718
            return "'" + StringEscapeUtils.escapeSql((String) value) + "'";
719
        } else {
720
            return StringEscapeUtils.escapeSql(value.toString());
721
        }
722
        
723
    }
724
    
725
    private void doSetTimeLimit() {
726
        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
727
        String s = dialogs.inputDialog(
728
                "Indicate the time limit in seconds for calculating the elements", 
729
                "Time limit", 
730
                JOptionPane.QUESTION_MESSAGE, 
731
                String.valueOf(this.config.getSimpleElementsLimit())
732
        );
733
        if( StringUtils.isBlank(s) ) {
734
            return;
735
        }
736
        try {
737
            int n = Integer.parseInt(s);
738
            this.config.setSimpleElementsLimit(n);
739
            this.treeModel.reload();
740
        } catch(Exception ex) {
741
            dialogs.messageDialog(
742
                "Invalid time limit '"+s+"'.", 
743
                "Time limit", 
744
                JOptionPane.WARNING_MESSAGE
745
            );                    
746
        }
747
    }
748
}