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 @ 43989

History | View | Annotate | Download (25.8 KB)

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

    
3
import java.awt.BorderLayout;
4
import java.awt.Component;
5
import java.awt.Dimension;
6
import java.awt.event.ActionEvent;
7
import java.awt.event.ActionListener;
8
import java.awt.event.KeyAdapter;
9
import java.awt.event.KeyEvent;
10
import java.awt.event.MouseAdapter;
11
import java.awt.event.MouseEvent;
12
import java.net.URL;
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.Date;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Objects;
19
import javax.swing.DefaultListCellRenderer;
20
import javax.swing.ImageIcon;
21
import javax.swing.JComponent;
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.ConstantElement;
45
import org.gvsig.expressionevaluator.swing.Element.FunctionElement;
46
import org.gvsig.expressionevaluator.swing.Element.GroupElement;
47
import org.gvsig.expressionevaluator.swing.Element.SimpleElement;
48
import org.gvsig.expressionevaluator.swing.Element.VariableElement;
49
import org.gvsig.expressionevaluator.swing.ExpressionBuilderConfig;
50
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
51
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
52
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.script.Script;
54
import org.gvsig.tools.swing.api.ListElement;
55
import org.gvsig.tools.swing.api.ToolsSwingLocator;
56
import org.gvsig.tools.swing.api.ToolsSwingManager;
57
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
58
import org.gvsig.tools.swing.api.script.ScriptSwingManager;
59
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
60
import org.gvsig.tools.swing.icontheme.IconTheme;
61

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

    
70
    private final ExpressionEvaluatorSwingManager manager;
71
    private GroupElement currentGroup;
72
    private PickerController<List<Script>> scriptPicker;
73
    private ScriptSwingManager.ScriptEditor scriptEditor;
74
    
75
    private final ExpressionBuilderConfig config;
76
    private ElementsTreeModel treeModel;
77
    
78
    private class ElementsTreeModel implements TreeModel {
79

    
80
        private final GroupElement root;
81
        private final HashSet<TreeModelListener> listeners;
82

    
83
        public ElementsTreeModel(GroupElement root) {
84
            this.root = root;
85
            this.listeners = new HashSet<>();
86
        }
87

    
88
        @Override
89
        public Object getRoot() {
90
            return this.root;
91
        }
92

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

    
117
        @Override
118
        public Object getChild(Object parent, int index) {
119
            List<Element> childs = getChilds((GroupElement) parent);
120
            Element child = childs.get(index);
121
            return child;
122
        }
123

    
124
        @Override
125
        public int getChildCount(Object parent) {
126
            List<Element> childs = getChilds((GroupElement) parent);
127
            return childs.size();
128
        }
129

    
130
        @Override
131
        public boolean isLeaf(Object node) {
132
            if( node instanceof GroupElement ) {
133
                return !((GroupElement) node).hasSubgroups();
134
            }
135
            return false;
136
        }
137

    
138
        @Override
139
        public void valueForPathChanged(TreePath path, Object newValue) {
140
        }
141

    
142
        @Override
143
        public int getIndexOfChild(Object parent, Object child) {
144
            List<Element> childs = getChilds((GroupElement) parent);
145
            int n = childs.indexOf(child);
146
            return n;
147
        }
148

    
149
        @Override
150
        public void addTreeModelListener(TreeModelListener l) {
151
            this.listeners.add(l);
152
        }
153

    
154
        @Override
155
        public void removeTreeModelListener(TreeModelListener l) {
156
            this.listeners.remove(l);
157
        }
158

    
159
        protected void fireTreeChanged() {
160
            for (TreeModelListener listener : listeners) {
161
                TreeModelEvent e = new TreeModelEvent(this, new Object[] {this.root});
162
                listener.treeNodesChanged(e);
163
            }
164
        }
165
    }
166

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

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

    
311
        this.btnSimpleElementTimeLimit.addActionListener(new ActionListener() {
312
            @Override
313
            public void actionPerformed(ActionEvent e) {
314
                doSetTimeLimit();
315
            }
316
        });
317
        this.btnSimpleElementSortDown.addActionListener(new ActionListener() {
318
            @Override
319
            public void actionPerformed(ActionEvent e) {
320
                FilteredListModel model = (FilteredListModel) lstSimpleElement.getModel();
321
                model.sort(false);
322
            }
323
        });
324
        this.btnSimpleElementSortUp.addActionListener(new ActionListener() {
325
            @Override
326
            public void actionPerformed(ActionEvent e) {
327
                FilteredListModel model = (FilteredListModel) lstSimpleElement.getModel();
328
                model.sort(true);
329
            }
330
        });
331
        this.txtSimpleElementFilter.addKeyListener(new KeyAdapter() {
332
            @Override
333
            public void keyTyped(KeyEvent e) {
334
                if (e.getKeyChar() == '\n') {
335
                    doFilter();
336
                }
337
            }
338
        });
339
        this.btnAdd.addActionListener(new ActionListener() {
340
            @Override
341
            public void actionPerformed(ActionEvent e) {
342
                doInsert(" + ");
343
            }
344
        });
345
        this.btnDiv.addActionListener(new ActionListener() {
346
            @Override
347
            public void actionPerformed(ActionEvent e) {
348
                doInsert(" / ");
349
            }
350
        });
351
        this.btnEq.addActionListener(new ActionListener() {
352
            @Override
353
            public void actionPerformed(ActionEvent e) {
354
                doInsert(" = ");
355
            }
356
        });
357
        this.btnMult.addActionListener(new ActionListener() {
358
            @Override
359
            public void actionPerformed(ActionEvent e) {
360
                doInsert(" * ");
361
            }
362
        });
363
        this.btnNeq.addActionListener(new ActionListener() {
364
            @Override
365
            public void actionPerformed(ActionEvent e) {
366
                doInsert(" <> ");
367
            }
368
        });
369
        this.btnParentClose.addActionListener(new ActionListener() {
370
            @Override
371
            public void actionPerformed(ActionEvent e) {
372
                doInsert(" ) ");
373
            }
374
        });
375
        this.btnParentOpen.addActionListener(new ActionListener() {
376
            @Override
377
            public void actionPerformed(ActionEvent e) {
378
                doInsert(" ( ");
379
            }
380
        });
381
        this.btnSubst.addActionListener(new ActionListener() {
382
            @Override
383
            public void actionPerformed(ActionEvent e) {
384
                doInsert(" - ");
385
            }
386
        });
387
        ScriptSwingManager scriptSwingManager = ToolsSwingLocator.getScriptSwingManager();
388
        this.scriptPicker = scriptSwingManager.createListScriptPickerController(
389
                cboPickerScripts,
390
                btnPickerRemove,
391
                btnPickerSelectScript
392
        );
393
        this.scriptEditor = scriptSwingManager.createScriptEditor();
394
        this.pnlScriptEditorContainer.setLayout(new BorderLayout());
395
        this.pnlScriptEditorContainer.add(this.scriptEditor.asJComponent(), BorderLayout.CENTER);
396
    
397
        this.tabExpressionBuilder.setEnabledAt(0, this.config.getScriptsEnabled());
398
        this.setPreferredSize(new Dimension(650, 350));
399
        this.txtDescription.setPreferredSize(new Dimension(200,200));
400
    }
401

    
402
    private String removeCursorMark(String s) {
403
        s = s.replace("{{", "");
404
        s = s.replace("}}", "");
405
        return s;
406
    }
407

    
408
    private void doInsert(String s) {
409
        this.txtExpression.replaceSelection(s);
410
        String ss = this.txtExpression.getText();
411
        int start = ss.indexOf("{{");
412
        int end = ss.indexOf("}}");
413
        if (start > 0 && end > 0) {
414
            this.txtExpression.replaceRange("", end, end + 2);
415
            this.txtExpression.replaceRange("", start, start + 2);
416
            this.txtExpression.setSelectionStart(start);
417
            this.txtExpression.setSelectionEnd(end - 2);
418
        }
419
        this.txtExpression.requestFocusInWindow();
420
    }
421

    
422
    private void doInsert(SimpleElement element) {
423
        if( element instanceof FunctionElement ) {
424
            Function function = ((FunctionElement)element).getFunction();
425
            if (function == null) {
426
                doInsert(element.getName());
427
            } else {
428
                doInsert(function.template() == null ? function.name() + "({{}})" : function.template());
429
            }
430
        } else if( element instanceof ConstantElement) {
431
            doInsert(" "+repr(((ConstantElement) element).getValue())+" ");
432
        } else {
433
            doInsert(" "+element.getName()+" ");
434
        }
435
    }
436

    
437
    private void doFilter() {
438
        FilteredListModel model = (FilteredListModel) this.lstSimpleElement.getModel();
439
        model.setFilter(this.txtSimpleElementFilter.getText());
440
    }
441

    
442
    private void doSelectElement(SimpleElement element) {
443
        StringBuilder html = new StringBuilder();
444
        html.append("<html>\n");
445
        if( element instanceof ConstantElement ) {
446
            Object value = ((ConstantElement)element).getValue();
447
            if( value == null ) {
448
                html.append("<b>Constant</b><br>\n<br>\n");
449
                html.append("<b>Value</b> NULL<br>\n");
450
            } else {
451
                html.append("<b>Constant</b><br>\n<br>\n");
452
                html.append("<b>Value</b> ").append(repr(value)).append("<br>\n");
453
                html.append("<b>Type</b> ").append(value.getClass().getSimpleName()).append("<br>\n");
454
            }
455
            
456
        } else if( element instanceof VariableElement ) {
457
                VariableElement var = (VariableElement)element;
458
                html.append("<b>").append(var.getLabel()).append("</b><br>\n<br>\n");
459
                html.append("<b>Source</b> ").append(var.getSource()).append("<br>\n");
460
                html.append("<b>Name</b> ").append(var.getName()).append("<br>\n");
461
                html.append("<b>Type</b> ").append(var.getTypeName()).append("<br>\n");
462
            
463
        } else if( element instanceof FunctionElement ) {
464
            Function function = ((FunctionElement)element).getFunction();
465
            if (function == null) {
466
                html.append("<b>Function</b> ").append(element.getName()).append("<br>\n<br>\n");
467
                html.append("<b>Return</b> Object<br>\n<br>\n");
468
                html.append("<b>Template:</b> ").append(element.getName()).append("()<br>\n");
469
            } else {
470
                html.append("<b>Function</b> ").append(element.getName()).append("<br>\n<br>\n");
471
                html.append("<b>Return</b> ");
472
                html.append(StringUtils.isEmpty(function.returnType())?"Objec": function.returnType());
473
                html.append("<br>\n");
474
                html.append("<b>Template</b> ");
475
                html.append(StringUtils.isEmpty(function.template())?element.getName()+"()": removeCursorMark(function.template()));
476
                html.append("<br>\n");
477

    
478
                String[] args = function.descriptionArgs();
479
                if (args != null) {
480
                    html.append("<b>Arguments:</b> ").append("<ul>\n");
481
                    for (String arg : args) {
482
                        html.append("<li>").append(arg).append("</li>\n");
483
                    }
484
                    html.append("</ul>\n");
485
                    html.append("<br>\n");
486
                }
487
            }
488
        } else {
489
            html.append("<b>Generic element<br>\n<br>\n");
490
            html.append("<b>Name</b> ").append(element.getName()).append("</br>\n");
491
            
492
        }
493

    
494
        if( element.getDescription()!=null ) {
495
            html.append("<b>Description</b><br>\n");
496
            html.append(element.getDescription().replace("\n", "<br>")).append("<br>\n");
497
        }
498
        html.append("</html>\n");
499
        this.txtDescription.setContentType("text/html");
500
        this.txtDescription.setText(html.toString());
501
        this.txtDescription.setCaretPosition(0);
502
    }
503

    
504
    private void updateSimpleElementsList(GroupElement group) {
505
        FilteredListModel model = new FilteredListModel();
506
        model.addElement("Loading...");
507
        this.currentGroup = group;
508
        this.txtGroupElement.setText(group.getName());
509
        this.txtSimpleElementFilter.setText("");
510
        this.txtDescription.setText("");
511
        if (group instanceof SimpleElement) {
512
            this.btnGroupElementInsert.setEnabled(true);
513
        } else {
514
            this.btnGroupElementInsert.setEnabled(false);
515
        }
516
        this.lstSimpleElement.setEnabled(false);
517
        this.lstSimpleElement.setModel(model);
518

    
519
        Thread th = new Thread(new Runnable() {
520
            @Override
521
            public void run() {
522
                simpleElementsUpdater();
523
            }
524
        }, "ExpressionBuilderSimpleElementsUpdater");
525
        th.start();
526
    }
527

    
528
    private void simpleElementsUpdater() {
529
        final GroupElement group = this.currentGroup;
530
        final FilteredListModel model = new FilteredListModel();
531
        for (Element child : group) {
532
            if (group != this.currentGroup) {
533
                return;
534
            }
535
            if (child instanceof SimpleElement) {
536
                String label = child.getName();
537
                Function function = child instanceof FunctionElement?  ((FunctionElement)child).getFunction(): null;
538
                if (function != null && !StringUtils.isEmpty(function.returnType())) {
539
                    label = "<html><b>" + label + "</b> return " + function.returnType() + "</html>";
540
//                    label = label + " return " + function.returnType();
541
                }
542
                model.addElement(new ListElement<>(label, child));
543
            }
544
        }
545
        model.sort(true);
546
        SwingUtilities.invokeLater(new Runnable() {
547
            @Override
548
            public void run() {
549
                if (group != currentGroup) {
550
                    return;
551
                }
552
                if( group.hasMoreElements() ) {
553
                    lblSimpleElementsMsg.setText("More elements...");
554
                } else {
555
                    lblSimpleElementsMsg.setText("");
556
                }
557
                lstSimpleElement.setEnabled(true);
558
                lstSimpleElement.setModel(model);
559
            }
560
        });
561

    
562
    }
563

    
564
    @Override
565
    public Expression getExpression() {
566
        String phrase = this.txtExpression.getText();
567
        if (StringUtils.isEmpty(phrase)) {
568
            return null;
569
        }
570
        Expression expression = ExpressionEvaluatorLocator.getManager().createExpression();
571
        expression.setPhrase(phrase);
572
        Script script = ToolsLocator.getScriptManager().createScript("UserScript", "", "python");
573
        this.scriptEditor.fetch(script);
574
        if( !StringUtils.isEmpty(script.getCode()) ) {
575
            expression.setUserScript(script);
576
        }
577
        return expression;
578
    }
579

    
580
    @Override
581
    public void setExpression(Expression expression) {
582
        this.txtExpression.setText(expression.getPhrase());
583
        if( expression.getUserScript()!=null ) {
584
            this.scriptEditor.set(expression.getUserScript());
585
        }
586
        if( expression.getScripts()!=null ) {
587
            this.scriptPicker.set(expression.getScripts().toList());
588
        }
589
    }
590
    
591
    @Override
592
    public int getSimpleElementsLimit() {
593
        return this.config.getSimpleElementsLimit();
594
    }
595

    
596
    @Override
597
    public void setSimpleElementsLimit(int limit) {
598
        this.config.setSimpleElementsLimit(limit);
599
    }
600
    
601
    @Override
602
    public List<Element> getElements() {
603
        return this.config.getElements();
604
    }
605

    
606
    @Override
607
    public Collection<SymbolTable> getSymbolTables() {
608
        return this.config.getSymbolTables();
609
    }
610
    
611
    @Override
612
    public void addSymbolTable(String name) {
613
        this.config.addSymbolTable(name);
614
    }
615
    
616
    @Override
617
    public void addSymbolTable(SymbolTable symbolTable) {
618
        this.config.addSymbolTable(symbolTable);
619
    }
620

    
621
    @Override
622
    public void removeAllSymbolTables() {
623
        this.config.removeAllSymbolTables();
624
    }
625

    
626
    @Override
627
    public void removeSymbolTable(String name) {
628
        this.config.removeSymbolTable(name);
629
    }
630

    
631
    @Override
632
    public void setScriptsEnabled(boolean enabled) {
633
        this.config.setScriptsEnabled(enabled);
634
        this.tabExpressionBuilder.setEnabledAt(0, this.config.getScriptsEnabled());
635
    }
636

    
637
    @Override
638
    public boolean getScriptsEnabled() {
639
        return this.config.getScriptsEnabled();
640
    }
641
    
642
    @Override
643
    public JComponent asJComponent() {
644
        if( this.treeModel == null ) {
645
            this.treeModel = new ElementsTreeModel(
646
                    this.manager.createGroupElement("_Elements", this.getElements())
647
            );
648
            this.treeElements.setModel(this.treeModel);
649
        }
650
        return this;
651
    }
652

    
653
    private String repr(Object value)  {
654
        if (value == null) {
655
            return "NULL";
656
        } else if (value instanceof Date) {
657
            return "DATE('" + value + "')";
658
        } else if (value instanceof Boolean) {
659
            return value.toString();
660
        } else if (value instanceof String) {
661
            return "'" + StringEscapeUtils.escapeSql((String) value) + "'";
662
        } else {
663
            return StringEscapeUtils.escapeSql(value.toString());
664
        }
665
        
666
    }
667
    
668
    private void doSetTimeLimit() {
669
        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
670
        String s = dialogs.inputDialog(
671
                "Indicate the time limit in seconds for calculating the elements", 
672
                "Time limit", 
673
                JOptionPane.QUESTION_MESSAGE, 
674
                String.valueOf(this.config.getSimpleElementsLimit())
675
        );
676
        if( StringUtils.isBlank(s) ) {
677
            return;
678
        }
679
        try {
680
            int n = Integer.parseInt(s);
681
            this.config.setSimpleElementsLimit(n);
682
            this.treeModel.reload();
683
        } catch(Exception ex) {
684
            dialogs.messageDialog(
685
                "Invalid time limit '"+s+"'.", 
686
                "Time limit", 
687
                JOptionPane.WARNING_MESSAGE
688
            );                    
689
        }
690
    }
691
}