Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.dynform / org.gvsig.tools.dynform.services / src / main / java / org / gvsig / tools / dynform / services / dynformset / base / BaseJDynFormSet.java @ 3018

History | View | Annotate | Download (33.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.tools.dynform.services.dynformset.base;
24

    
25
import java.awt.BorderLayout;
26
import java.awt.Color;
27
import java.awt.Component;
28
import java.awt.event.ActionEvent;
29
import java.awt.event.ActionListener;
30
import java.awt.event.MouseAdapter;
31
import java.awt.event.MouseEvent;
32
import java.util.ArrayList;
33
import java.util.Collections;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Objects;
37
import java.util.function.BooleanSupplier;
38
import javax.swing.AbstractAction;
39
import javax.swing.Action;
40
import javax.swing.BorderFactory;
41
import javax.swing.BoxLayout;
42

    
43
import javax.swing.JComponent;
44
import javax.swing.JLabel;
45
import javax.swing.JMenu;
46
import javax.swing.JMenuItem;
47
import javax.swing.JOptionPane;
48
import javax.swing.JPanel;
49
import javax.swing.JPopupMenu;
50
import org.apache.commons.lang3.StringUtils;
51
import org.gvsig.tools.ToolsLocator;
52

    
53
import org.gvsig.tools.dynform.AbortActionException;
54
import org.gvsig.tools.dynform.DynFormDefinition;
55
import org.gvsig.tools.dynform.JDynForm;
56
import org.gvsig.tools.dynform.JDynForm.JDynFormListener;
57
import org.gvsig.tools.dynform.JDynFormField;
58
import org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.FormSetListener;
59
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_CANCEL_NEW;
60
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_CLOSE;
61
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_DELETE;
62
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_FIRST;
63
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_LAST;
64
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_NEW;
65
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_NEXT;
66
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_PREVIOUS;
67
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_SAVE;
68
import static org.gvsig.tools.dynform.services.dynformset.base.FormSetButtonBar.ID_ACTION_SEARCH;
69
import org.gvsig.tools.dynform.spi.dynformset.AbstractJDynFormSet;
70
import org.gvsig.tools.dynform.spi.dynformset.ActionStore;
71
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
72
import org.gvsig.tools.dynform.spi.dynformset.JDynFormSetFactory;
73
import org.gvsig.tools.dynobject.DynObject;
74
import org.gvsig.tools.dynobject.DynObjectSet;
75
import org.gvsig.tools.dynobject.Tags;
76
import org.gvsig.tools.exception.BaseException;
77
import org.gvsig.tools.i18n.I18nManager;
78
import org.gvsig.tools.script.Script;
79
import org.gvsig.tools.swing.api.ToolsSwingLocator;
80
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
81
import org.gvsig.tools.swing.api.viewer.JViewer;
82
import org.gvsig.tools.swing.api.viewer.ViewerFactory;
83
import org.gvsig.tools.swing.api.windowmanager.Dialog;
84
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
85
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
86
import static org.gvsig.tools.swing.api.windowmanager.WindowManager_v2.BUTTON_OK;
87
import org.gvsig.tools.swing.icontheme.IconTheme;
88
import org.gvsig.tools.swing.icontheme.IconThemeManager;
89

    
90
@SuppressWarnings("UseSpecificCatch")
91
public class BaseJDynFormSet extends AbstractJDynFormSet implements FormSetListener, JDynFormListener {
92

    
93
    private JLabel jlabel_messages = null;
94
    private JDynForm form = null;
95
    private FormSetButtonBar buttonBar = null;
96
    private int current = 0;
97

    
98
    public BaseJDynFormSet(
99
            DynFormSPIManager manager,
100
            JDynFormSetFactory factory,
101
            JDynForm.DynFormContext context,
102
            DynFormDefinition definition,
103
            Tags contextTags
104
    ) {
105
        super(manager, factory, context, definition, contextTags);
106
    }
107

    
108
    @Override
109
    public JComponent asJComponent() {
110
        if (this.contents == null) {
111
            this.initComponents();
112
            if (this.buttonBar != null) {
113
                this.buttonBar.setReadOnly(this.isReadOnly());
114
            }
115
            if (this.form != null) {
116
                this.form.setReadOnly(this.isReadOnly());
117
            }
118
        }
119
        this.fireFormMovedToEvent(current);
120
        return this.contents;
121
    }
122

    
123
    public JDynForm getForm() {
124
        return this.form;
125
    }
126

    
127
    public JLabel getMessagesJLabel() {
128
        if (this.jlabel_messages == null) {
129
            this.jlabel_messages = new JLabel();
130
//                        this.jlabel_messages.setBorder( BorderFactory.createLoweredBevelBorder());
131
            this.jlabel_messages.setText(" ");
132
            this.jlabel_messages.addMouseListener(new MouseAdapter() {
133
                @Override
134
                public void mouseClicked(MouseEvent evt) {
135
                    int count = evt.getClickCount();
136
                    if (count == 2) {
137
                        JOptionPane.showMessageDialog(contents, jlabel_messages.getText(), "Status", JOptionPane.INFORMATION_MESSAGE);
138
                    }
139
                }
140
            });
141
        }
142
        return this.jlabel_messages;
143
    }
144

    
145
    @Override
146
    public void message() {
147
        this.getMessagesJLabel().setText(" ");
148
    }
149

    
150
    @Override
151
    public void message(String msg) {
152
        this.getMessagesJLabel().setText(msg);
153
    }
154

    
155
    private FormSetButtonBar getButtonBar() {
156
        if (this.buttonBar == null) {
157
            initComponents();
158
        }
159
        return this.buttonBar;
160
    }
161

    
162
    private void initComponents() {
163
        this.contents = new JPanel();
164
        this.contents.setBorder(BorderFactory.createLineBorder(Color.GRAY));
165
        this.contents.setLayout(new BorderLayout());
166

    
167
        this.form = this.getManager().getDynFormManager().createJDynForm(this.getContext(), this.getDefinition());
168
        this.form.setReadOnly(this.isReadOnly());
169
        this.form.setLayoutMode(this.getLayoutMode());
170
        this.form.setUseScrollBars(this.getUseScrollBars());
171
        this.form.addListener(this);
172

    
173
        if (!actionsBuffer.isEmpty()) {
174
            for (ActionStore actStore : actionsBuffer) {
175
                if (actStore.isSeparator()) {
176
                    form.addSeparatorToPopupMenu(
177
                            actStore.getDataType());
178
                } else {
179
                    form.addActionToPopupMenu(
180
                            actStore.getDataType(),
181
                            actStore.getActionName(),
182
                            actStore.getAction());
183
                }
184
            }
185
        }
186
        if (this.getUseScrollBars()) {
187
            if (this.formHeight > -1 && this.formWidth > -1) {
188
                this.setFormSize(this.formWidth, this.formHeight);
189
            }
190
        }
191
        this.form.setShowMessageStatus(false);
192
        //this.form.setLayoutMode(this.layoutMode);
193
        this.form.addListener(this);
194

    
195
        this.buttonBar = new FormSetButtonBar();
196
        this.buttonBar.addListener(this);
197
        this.buttonBar.setActionActive(ID_ACTION_DELETE, this.allowDelete());
198
        this.buttonBar.setActionActive(ID_ACTION_NEW, this.allowNew());
199
        this.buttonBar.setActionActive(ID_ACTION_CANCEL_NEW, this.allowNew());
200
        this.buttonBar.setActionActive(ID_ACTION_SAVE, this.allowUpdate());
201
        this.buttonBar.setActionActive(ID_ACTION_SEARCH, this.allowSearch());
202
        this.buttonBar.setActionActive(ID_ACTION_CLOSE, this.allowClose());
203
        this.buttonBar.setVisible(ID_ACTION_CANCEL_NEW, false);
204
        this.buttonBar.setReadOnly(this.isReadOnly());
205
        this.buttonBar.getActionButton(ACTION_SET_CURRENT_RECORD).setComponentPopupMenu(this.getFormsetPopupMenu());
206
        this.contents.add(this.form.asJComponent(), BorderLayout.CENTER);
207

    
208
        JPanel p = new JPanel();
209
        p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));
210
        this.buttonBar.asJComponent().setAlignmentX(Component.LEFT_ALIGNMENT);
211
        this.getMessagesJLabel().setAlignmentX(Component.LEFT_ALIGNMENT);
212
        p.add(this.buttonBar.asJComponent());
213
        p.add(this.getMessagesJLabel());
214
        this.contents.add(p, BorderLayout.SOUTH);
215

    
216
        doChangeValues();
217
    }
218

    
219
    @Override
220
    public void setAllowDelete(boolean allowDelete) {
221
        super.setAllowDelete(allowDelete);
222
        if (this.buttonBar != null) {
223
            this.buttonBar.setActionActive(ID_ACTION_DELETE, this.allowDelete());
224
        }
225
    }
226

    
227
    @Override
228
    public void setAllowNew(boolean allowNew) {
229
        super.setAllowNew(allowNew);
230
        if (this.buttonBar != null) {
231
            this.buttonBar.setActionActive(ID_ACTION_NEW, this.allowNew());
232
        }
233
    }
234

    
235
    @Override
236
    public void setAllowSearch(boolean allowSearch) {
237
        super.setAllowSearch(allowSearch);
238
        if (this.buttonBar != null) {
239
            this.buttonBar.setActionActive(ID_ACTION_SEARCH, this.allowNew());
240
        }
241
    }
242

    
243
    @Override
244
    public void setAllowUpdate(boolean allowUpdate) {
245
        super.setAllowUpdate(allowUpdate);
246
        if (this.buttonBar != null) {
247
            this.buttonBar.setActionActive(ID_ACTION_SAVE, this.allowNew());
248
        }
249
    }
250

    
251
    @Override
252
    public void setAllowClose(boolean allowClose) {
253
        super.setAllowClose(allowClose);
254
        if (this.buttonBar != null) {
255
            this.buttonBar.setActionActive(ID_ACTION_CLOSE, this.allowNew());
256
        }
257
    }
258

    
259
    private void doChangeValues() {
260
        this.current = 0;
261
        if (this.values == null || this.values.isEmpty()) {
262
            this.form.setReadOnly(true);
263
            this.getButtonBar().setEnabled(ID_ACTION_DELETE, false);
264
            this.getButtonBar().setEnabled(ID_ACTION_SAVE, false);
265
            this.getButtonBar().setEnabled(ID_ACTION_NEW,
266
                    this.allowNew() && !this.isReadOnly());
267
            this.getButtonBar().setNumrecords(0);
268
            this.form.clear();
269
        } else {
270
            this.form.setValues((DynObject) this.values.get(this.current));
271
            this.getButtonBar().setEnabled(ID_ACTION_DELETE,
272
                    this.allowDelete() && !this.isReadOnly());
273
            this.getButtonBar().setEnabled(ID_ACTION_SAVE,
274
                    this.allowUpdate() && !this.isReadOnly());
275
            this.getButtonBar().setNumrecords(this.values.size());
276
        }
277
        this.getButtonBar().setCurrent(this.current);
278
    }
279

    
280
    @Override
281
    public void setValues(List values) {
282
        super.setValues(values);
283
        if (this.contents != null) {
284
            doChangeValues();
285
        }
286
    }
287

    
288
    @Override
289
    public void setValues(DynObjectSet values) {
290
        super.setValues(values);
291
        if (this.contents != null) {
292
            doChangeValues();
293
        }
294
    }
295

    
296
    @Override
297
    public void setReadOnly(boolean readOnly) {
298
//        if( this.isReadOnly() == readOnly ) {
299
//            return;
300
//        }
301
        super.setReadOnly(readOnly);
302
        if (this.buttonBar != null) {
303
            this.buttonBar.setReadOnly(readOnly);
304
        }
305
        if (this.form != null) {
306
            this.form.setReadOnly(readOnly);
307
        }
308
    }
309

    
310
    @Override
311
    public boolean doActionFirst() {
312
        if (this.values.isEmpty()) {
313
            return false;
314
        }
315

    
316
        if (autosave) {
317
            if (this.form.isModified() || this.isInNewState()) {
318
                if (!doActionSave()) {
319
                    return false;
320
                }
321
            }
322
        }
323
        callUserEvent("form_beforeFirst", this.getForm());
324
        this.current = 0;
325
        this.form.setValues((DynObject) this.values.get(this.current));
326
        this.buttonBar.setCurrent(this.current);
327
        try {
328
            this.getButtonBar().setEnabled(ID_ACTION_DELETE,
329
                    this.allowDelete() && !this.isReadOnly());
330
            this.getButtonBar().setEnabled(ID_ACTION_SAVE,
331
                    this.allowUpdate() && !this.isReadOnly());
332
        } catch (Exception ex) {
333
            LOGGER.warn("Can't enable/disable delete and save buttons", ex);
334
        }
335
        callUserEvent("form_afterFirst", this.getForm());
336
        doButtonBarStateChanged();
337
        this.fireFormMovedToEvent(this.current);
338
        return true;
339
    }
340

    
341
    @Override
342
    public boolean doActionPrevious() {
343
        if (this.values.isEmpty()) {
344
            return false;
345
        }
346

    
347
        if (autosave) {
348
            if (this.form.isModified() || this.isInNewState()) {
349
                if (!doActionSave()) {
350
                    return false;
351
                }
352
            }
353
        }
354
        callUserEvent("form_beforePrevious", this.getForm());
355
        if (this.current > 0) {
356
            this.current--;
357
        }
358
        this.form.setValues((DynObject) this.values.get(this.current));
359
        this.buttonBar.setCurrent(this.current);
360
        callUserEvent("form_afterPrevious", this.getForm());
361
        doButtonBarStateChanged();
362
        this.fireFormMovedToEvent(this.current);
363
        return true;
364
    }
365

    
366
    @Override
367
    public boolean doActionNext() {
368
        if (this.values.isEmpty()) {
369
            return false;
370
        }
371

    
372
        if (autosave) {
373
            if (this.form.isModified() || this.isInNewState()) {
374
                if (!doActionSave()) {
375
                    return false;
376
                }
377
            }
378
        }
379
        callUserEvent("form_beforeNext", this.getForm());
380
        if (this.current < this.values.size() - 1) {
381
            this.current++;
382
        }
383
        this.form.setValues((DynObject) this.values.get(this.current));
384
        this.buttonBar.setCurrent(this.current);
385
        callUserEvent("form_afterNext", this.getForm());
386
        doButtonBarStateChanged();
387
        this.fireFormMovedToEvent(this.current);
388
        return true;
389
    }
390

    
391
    @Override
392
    public boolean doActionLast() {
393
        if (this.values.isEmpty()) {
394
            return false;
395
        }
396

    
397
        if (autosave) {
398
            if (this.form.isModified() || this.isInNewState()) {
399
                if (!doActionSave()) {
400
                    return false;
401
                }
402
            }
403
        }
404
        callUserEvent("form_beforeLast", this.getForm());
405
        this.current = this.values.size() - 1;
406
        this.form.setValues((DynObject) this.values.get(this.current));
407
        this.buttonBar.setCurrent(this.current);
408
        callUserEvent("form_afterLast", this.getForm());
409
        doButtonBarStateChanged();
410
        this.fireFormMovedToEvent(this.current);
411
        return true;
412
    }
413

    
414
    @Override
415
    public boolean doActionSave() {
416
        if (!this.isInNewState() && this.values.isEmpty()) {
417
            return false;
418
        }
419
        try {
420
            this.listeners.accept((Object listener) -> {
421
                ((JDynFormSetListener) listener).formBeforeSave(BaseJDynFormSet.this);
422
            });
423
        } catch (AbortActionException e) {
424
            return false;
425
        } catch (BaseException e) {
426
            LOGGER.warn("Can't notify to listeners before save.", e);
427
            return false;
428
        }
429
        callUserEvent("form_beforeSave", this.getForm());
430

    
431
        List<String> fieldsName = new ArrayList<>();
432
        if (!this.form.hasValidValues(fieldsName)) {
433
            String errores = "";
434
            Iterator<String> it = fieldsName.iterator();
435
            while (it.hasNext()) {
436
                String name = (String) it.next();
437
                errores = errores + "     - " + name + "\n";
438
            }
439
            int r = confirmDialog(
440
                    "There are incorrect data in the following fields:\n" + errores + "\nContinuing the incorrect values โ€‹will not be saved. Do you want to continue?", "warning",
441
                    JOptionPane.WARNING_MESSAGE,
442
                    JOptionPane.YES_NO_OPTION);
443
            if (r != JOptionPane.YES_OPTION) {
444
                return false;
445
            }
446
        }
447
        if (!this.isInNewState()) {
448
            if (this.current >= 0 && this.current < this.values.size()) {
449
                this.form.getValues((DynObject) this.values.get(this.current));
450
            } else {
451
                LOGGER.warn("current out of range.");
452
            }
453
        }
454

    
455
        this.leaveTheNewState();
456
        callUserEvent("form_afterSave", this.getForm());
457
    
458
        doButtonBarStateChanged();
459
        try {
460
            this.listeners.accept((Object listener) -> {
461
                ((JDynFormSetListener) listener).formAfterSave(BaseJDynFormSet.this);
462
            });
463
        } catch (AbortActionException e) {
464
            return false;
465
        } catch (BaseException e) {
466
            LOGGER.warn("Can't notify to listeners after save.",e);
467
            return false;
468
        }
469
        return true;
470
    }
471

    
472
    @Override
473
    public boolean doActionNew() {
474
        try {
475
            this.listeners.accept((Object listener) -> {
476
                ((JDynFormSetListener) listener).formBeforeNew(BaseJDynFormSet.this);
477
            });
478
        } catch (BaseException e) {
479
            return true;
480
        }
481
        callUserEvent("form_beforeNew", this.getForm());
482
        this.enterStateNew();
483
        callUserEvent("form_afterNew", this.getForm());
484
        doButtonBarStateChanged();
485
        try {
486
            this.listeners.accept((Object listener) -> {
487
                ((JDynFormSetListener) listener).formAfterNew(BaseJDynFormSet.this);
488
            });
489
        } catch (BaseException e) {
490
            return true;
491
        } 
492
        return true;
493
    }
494

    
495
    @Override
496
    public boolean doActionCancelNew() {
497
        try {
498
            this.listeners.accept((Object listener) -> {
499
                ((JDynFormSetListener) listener).formBeforeCancelNew(BaseJDynFormSet.this);
500
            });
501
        } catch (BaseException e) {
502
            return true;
503
        }
504
        callUserEvent("form_beforeCancelNew", this.getForm());
505
        this.leaveTheNewState();
506
        callUserEvent("form_afterCancelNew", this.getForm());
507
        doButtonBarStateChanged();
508
        try {
509
            this.listeners.accept((Object listener) -> {
510
                ((JDynFormSetListener) listener).formAfterCancelNew(BaseJDynFormSet.this);
511
            });
512
        } catch (BaseException e) {
513
            return true;
514
        } 
515
        return true;
516
    }
517

    
518
    @Override
519
    protected void enterStateNew() {
520
        if (this.isInNewState()) {
521
            return;
522
        }
523
        try {
524
            FormSetButtonBar bar = this.getButtonBar();
525
            super.enterStateNew();
526
            bar.setCurrentLabel(ToolsLocator.getI18nManager().getTranslation("nuevo"));
527
            bar.setNumrecords(this.countValues());
528

    
529
            bar.setVisible(ID_ACTION_CANCEL_NEW, true);
530
            bar.setVisible(ID_ACTION_NEW, false);
531

    
532
            bar.setEnabled(ID_ACTION_SAVE, true);
533
            bar.setEnabled(ID_ACTION_CANCEL_NEW, true);
534
            bar.setEnabled(ID_ACTION_DELETE, false);
535
            bar.setEnabled(ID_ACTION_FIRST, false);
536
            bar.setEnabled(ID_ACTION_NEXT, false);
537
            bar.setEnabled(ID_ACTION_PREVIOUS, false);
538
            bar.setEnabled(ID_ACTION_LAST, false);
539
            bar.setEnabled(ID_ACTION_SEARCH, false);
540
        } catch (Exception ex) {
541
            LOGGER.warn("Can't enable/disable delete and save buttons", ex);
542
        }
543
    }
544

    
545
    @Override
546
    protected void leaveTheNewState() {
547
        if (!(this.isInNewState())) {
548
            return;
549
        }
550
        super.leaveTheNewState();
551
        try {
552
            FormSetButtonBar bar = this.getButtonBar();
553

    
554
            bar.setVisible(ID_ACTION_CANCEL_NEW, false);
555
            bar.setVisible(ID_ACTION_NEW, true);
556

    
557
            bar.setEnabled(ID_ACTION_SAVE, true);
558
            bar.setEnabled(ID_ACTION_NEW, true);
559
            bar.setEnabled(ID_ACTION_DELETE, true);
560
            bar.setEnabled(ID_ACTION_SEARCH, true);
561

    
562
            bar.setCurrentLabel(null);
563
            bar.setNumrecords(this.countValues());
564
            bar.setCurrent(this.current);
565
        } catch (Exception ex) {
566
            LOGGER.warn("Can't enable/disable delete and save buttons", ex);
567
        }
568
    }
569

    
570
    @Override
571
    public boolean doActionDelete() {
572
        if (this.values.isEmpty()) {
573
            return false;
574
        }
575

    
576
        if (this.countValues() < 1) {
577
            return true;
578
        }
579
        try {
580
            this.listeners.accept((Object listener) -> {
581
                ((JDynFormSetListener) listener).formBeforeDelete(BaseJDynFormSet.this);
582
            });
583
        } catch (BaseException e) {
584
            return true;
585
        }
586

    
587
        if (this.current >= countValues()) {
588
            this.current = countValues() - 1;
589
        }
590
        if (this.current > -1) {
591
            this.form.setValues((DynObject) this.values.get(this.current));
592
        }
593
        this.buttonBar.setNumrecords(this.countValues());
594
        this.buttonBar.setCurrent(this.current);
595

    
596
        doButtonBarStateChanged();
597
        try {
598
            this.listeners.accept((Object listener) -> {
599
                ((JDynFormSetListener) listener).formAfterDelete(BaseJDynFormSet.this);
600
            });
601
        } catch (BaseException e) {
602
            return true;
603
        } 
604
        return true;
605
    }
606

    
607
    @Override
608
    public boolean doActionSearch() {
609
        if (this.values.isEmpty()) {
610
            return false;
611
        }
612

    
613
        try {
614
            this.listeners.accept((Object listener) -> {
615
                ((JDynFormSetListener) listener).formBeforeSearch(BaseJDynFormSet.this);
616
            });
617
        } catch (BaseException e) {
618
            return true;
619
        }
620
        // Do search
621
        try {
622
            this.listeners.accept((Object listener) -> {
623
                ((JDynFormSetListener) listener).formAfterSearch(BaseJDynFormSet.this);
624
            });
625
        } catch (BaseException e) {
626
            return true;
627
        }
628
        return true;
629
    }
630

    
631
    @Override
632
    public boolean doActionClose() {
633
        fireCloseEvent();
634
        return true;
635
    }
636

    
637
    @Override
638
    public void doSetCurrentRecord(int index) {
639
        this.setCurrentIndex(index);
640
        doButtonBarStateChanged();
641
    }
642

    
643
    public JPopupMenu getFormsetPopupMenu() {
644
        I18nManager i18n = ToolsLocator.getI18nManager();
645
        JPopupMenu popup = new JPopupMenu();
646
        JMenu moveMenu = new JMenu(i18n.getTranslation("_Move"));
647
        moveMenu.add(new JMenuItem(createAction(
648
                ACTION_FIRST,
649
                "_first",
650
                null,
651
                "common-form-first",
652
                () -> this.buttonBar.isEnabled(ACTION_FIRST),
653
                (ActionEvent e) -> doActionFirst()
654
        )));
655
        moveMenu.add(new JMenuItem(createAction(
656
                ACTION_PREVIOUS,
657
                "_back",
658
                null,
659
                "common-form-previous",
660
                () -> this.buttonBar.isEnabled(ACTION_PREVIOUS),
661
                (ActionEvent e) -> doActionPrevious()
662
        )));
663
        moveMenu.add(new JMenuItem(createAction(
664
                ACTION_SET_CURRENT_RECORD,
665
                "_first",
666
                null,
667
                "common-form-first",
668
                () -> this.buttonBar.isEnabled(ACTION_SET_CURRENT_RECORD),
669
                (ActionEvent e) -> this.buttonBar.doGoRecord()
670
        )));
671
        moveMenu.add(new JMenuItem(createAction(
672
                ACTION_NEXT,
673
                "_next",
674
                null,
675
                "common-form-next",
676
                () -> this.buttonBar.isEnabled(ACTION_NEXT),
677
                (ActionEvent e) -> doActionNext()
678
        )));
679
        moveMenu.add(new JMenuItem(createAction(
680
                ACTION_LAST,
681
                "_last",
682
                null,
683
                "common-form-last",
684
                () -> this.buttonBar.isEnabled(ACTION_LAST),
685
                (ActionEvent e) -> doActionFirst()
686
        )));
687
        popup.add(moveMenu);
688
        popup.addSeparator();
689
        popup.add(new JMenuItem(createAction(
690
                ACTION_SAVE,
691
                "guardar",
692
                null,
693
                "common-form-save",
694
                () -> this.buttonBar.isEnabled(ACTION_SAVE),
695
                (ActionEvent e) -> doActionSave()
696
        )));
697
        popup.add(new JMenuItem(createAction(
698
                ACTION_NEW,
699
                "nuevo",
700
                null,
701
                "common-form-new",
702
                () -> this.buttonBar.isEnabled(ACTION_NEW),
703
                (ActionEvent e) -> doActionNew()
704
        )));
705
        popup.add(new JMenuItem(createAction(
706
                ACTION_CANCEL_NEW,
707
                "cancelar nuevo",
708
                null,
709
                "common-form-cancelnew",
710
                () -> this.buttonBar.isEnabled(ACTION_CANCEL_NEW),
711
                (ActionEvent e) -> doActionCancelNew()
712
        )));
713
        popup.add(new JMenuItem(createAction(
714
                ACTION_DELETE,
715
                "borrar",
716
                null,
717
                "common-form-delete",
718
                () -> this.buttonBar.isEnabled(ACTION_DELETE),
719
                (ActionEvent e) -> doActionDelete()
720
        )));
721
        popup.add(new JMenuItem(createAction(
722
                ACTION_SEARCH,
723
                "search",
724
                null,
725
                "common-form-search",
726
                () -> this.buttonBar.isEnabled(ACTION_SEARCH),
727
                (ActionEvent e) -> doActionSearch()
728
        )));
729
        popup.addSeparator();
730
        popup.add(new JMenuItem(createAction("SHOW_SCRIPT",
731
                "_Show_script",
732
                null,
733
                null,
734
                () -> this.form.getScript() != null,
735
                (ActionEvent e) -> doShowScript()
736
        )));
737
        return popup;
738
    }
739
    
740
    private void doShowScript() {
741
        Script script = this.form.getScript();
742
        if( script == null ) {
743
            return;
744
        }
745
        String source = script.getCode();
746
        ViewerFactory editorFactory = ToolsSwingLocator.getTextEditorManager();
747

    
748
        I18nManager i18n = ToolsLocator.getI18nManager();
749
        final boolean isEditable = !this.getForm().isReadOnly() && editorFactory.isEditable();
750
        String title = (isEditable?
751
                i18n.getTranslation("_Script_editor"):
752
                i18n.getTranslation("_Script_viewer")) + " " + script.getName();
753
        try {
754
            JViewer viewer = editorFactory.createViewer();
755
            viewer.setContents(source);
756
            viewer.setEditable(isEditable);
757
            viewer.setEnabled(true);
758

    
759
            WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
760
            Dialog dialog = winmanager.createDialog(
761
                    viewer.asJComponent(), 
762
                    title, 
763
                    null, 
764
                    WindowManager_v2.BUTTONS_OK_CANCEL
765
            );
766
            dialog.setButtonEnabled(BUTTON_OK, isEditable);
767
            dialog.addActionListener((ActionEvent e) -> {
768
                if( isEditable && dialog.getAction()==WindowManager_v2.BUTTONS_OK ) {
769
                    try {
770
                        this.form.putScript(Objects.toString(viewer.getContents(),null));
771
                    } catch(Exception ex) {
772
                        LOGGER.warn("Can't bytes from editor.",ex);
773
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
774
                        dialogs.messageDialog(
775
                                i18n.getTranslation("_Cant_get_save_script") + 
776
                                        "\n\n" +
777
                                        BaseException.getHTMLMessageStack(ex),
778
                                title,
779
                                JOptionPane.WARNING_MESSAGE
780
                        );
781
                    }
782
                }
783
            });
784
            dialog.show(WindowManager.MODE.WINDOW);
785

    
786
        } catch(Exception ex) {
787
            LOGGER.warn("Can't show editor.",ex);
788
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
789
            dialogs.messageDialog(
790
                    i18n.getTranslation("_Cant_show_viewer"), 
791
                    title, 
792
                    JOptionPane.WARNING_MESSAGE
793
            );
794
            return;
795
        }
796
    }
797
    
798
    
799
    @Override
800
    public void setFormSize(int width, int height) {
801
        super.setFormSize(width, height);
802
        if (this.form != null) {
803
            this.form.setFormSize(width, height);
804
        }
805
    }
806

    
807
    @Override
808
    public int getCurrentIndex() {
809
        return this.current;
810
    }
811

    
812
    @Override
813
    public void setCurrentIndex(int index) {
814
        if (index < 0 || index > countValues()) {
815
            throw new IndexOutOfBoundsException("Index (" + index + ") out of range [0.." + countValues() + "].");
816
        }
817
        // Don't call doActionSave, crash with stack overflow
818
        this.current = index;
819
        this.form.setValues((DynObject) this.values.get(this.current));
820
        this.buttonBar.setCurrent(this.current);
821
        this.fireFormMovedToEvent(this.current);
822
    }
823

    
824
    @Override
825
    public void fieldChanged(JDynFormField field) {
826
        LOGGER.debug("Ha cambiado el field: " + field.getName() + " con el valor => " + field.getValue());
827
    }
828

    
829
    @Override
830
    public DynObject get(int position) {
831
        LOGGER.debug("Recojo el field: " + position);
832
        return (DynObject) this.values.get(position);
833
    }
834

    
835
    @Override
836
    public List getValues() {
837
        if (this.current >= 0 && this.current < this.values.size()) {
838
            this.form.getValues((DynObject) this.values.get(this.current));
839
        }
840
        return this.values;
841
    }
842

    
843
    @Override
844
    public boolean hasValidValues() {
845
        return this.form.hasValidValues();
846
    }
847

    
848
    @Override
849
    public boolean hasValidValues(List<String> fieldsName) {
850
        return this.form.hasValidValues(fieldsName);
851
    }
852

    
853
    public void clear() {
854
        if (this.form != null) {
855
            this.form.clear();
856
        }
857
    }
858

    
859
    @Override
860
    public void getFormValues(DynObject values) {
861
        this.form.getValues(values);
862
    }
863

    
864
    @Override
865
    public void addAction(Action action) {
866
        this.getButtonBar().addAction(action);
867
    }
868

    
869
    @Override
870
    public Action getAction(String actionId) {
871
        if (this.buttonBar == null) {
872
            return null;
873
        }
874
        return this.getButtonBar().getAction(actionId);
875
    }
876

    
877
    @Override
878
    public List<Action> getActions() {
879
        if (this.buttonBar == null) {
880
            return Collections.EMPTY_LIST;
881
        }
882
        return this.getButtonBar().getActions();
883
    }
884

    
885
    @Override
886
    public void setActionVisible(String action, boolean visible) {
887
        this.getButtonBar().setVisible(action, visible);
888
    }
889

    
890
    @Override
891
    public void setActionEnabled(String action, boolean enabled) {
892
        this.getButtonBar().setEnabled(action, enabled);
893
    }
894

    
895
    @Override
896
    public boolean isActionEnabled(String action) {
897
        return this.getButtonBar().isEnabled(action);
898
    }
899

    
900
    @Override
901
    public boolean isActionVisible(String action) {
902
        return this.getButtonBar().isVisible(action);
903
    }
904

    
905
    @Override
906
    public JComponent getActionButton(String action) {
907
        return this.getButtonBar().getActionButton(action);
908
    }
909

    
910
    @Override
911
    public void fireEvent(String action, Object value) {
912
        this.getButtonBar().fireEvent(action, value);
913
    }
914

    
915
    private static Action createAction(
916
            String name,
917
            String text,
918
            String tip,
919
            String image,
920
            BooleanSupplier isEnabled,
921
            ActionListener actionListener) {
922
        AbstractAction action = new AbstractAction() {
923
            @Override
924
            public void actionPerformed(ActionEvent e) {
925
                if (actionListener != null) {
926
                    actionListener.actionPerformed(e);
927
                }
928
            }
929

    
930
            @Override
931
            public boolean isEnabled() {
932
                if (isEnabled == null) {
933
                    return super.isEnabled();
934
                }
935
                return (boolean) isEnabled.getAsBoolean();
936
            }
937

    
938
            @Override
939
            public Object getValue(String key) {
940
                if (isEnabled != null && StringUtils.equals(key, "enabled")) {
941
                    return (boolean) isEnabled.getAsBoolean();
942
                }
943
                return super.getValue(key);
944
            }
945

    
946
        };
947
        if (StringUtils.isNotBlank(image)) {
948
            IconThemeManager iconThemeManager = ToolsSwingLocator.getIconThemeManager();
949
            IconTheme theme = iconThemeManager.getCurrent();
950
            action.putValue(Action.SMALL_ICON, theme.get(image));
951
        }
952
        if (StringUtils.isNotBlank(tip)) {
953
            action.putValue(Action.SHORT_DESCRIPTION, tip);
954
        }
955
        if (StringUtils.isNotBlank(text)) {
956
            if (text.startsWith("_")) {
957
                text = ToolsLocator.getI18nManager().getTranslation(text);
958
            }
959
            action.putValue(Action.NAME, text);
960
        }
961
        return action;
962
    }
963
    
964
    private void doButtonBarStateChanged() {
965
        this.buttonBar.getActionButton(ACTION_SET_CURRENT_RECORD).setComponentPopupMenu(this.getFormsetPopupMenu());
966
    }
967
}