OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 174 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
25 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.sql.element;
15
 
73 ilm 16
import org.openconcerto.sql.Log;
80 ilm 17
import org.openconcerto.sql.PropsConfiguration;
18
import org.openconcerto.sql.model.FieldMapper;
41 ilm 19
import org.openconcerto.sql.model.SQLField;
20
import org.openconcerto.sql.model.SQLType;
57 ilm 21
import org.openconcerto.sql.request.RowItemDesc;
41 ilm 22
import org.openconcerto.sql.sqlobject.ElementComboBox;
93 ilm 23
import org.openconcerto.sql.users.rights.UserRightsManager;
41 ilm 24
import org.openconcerto.ui.DefaultGridBagConstraints;
25
import org.openconcerto.ui.JDate;
26
import org.openconcerto.ui.JLabelBold;
132 ilm 27
import org.openconcerto.ui.component.ITextArea;
41 ilm 28
import org.openconcerto.ui.group.Group;
67 ilm 29
import org.openconcerto.ui.group.Item;
41 ilm 30
import org.openconcerto.ui.group.LayoutHints;
80 ilm 31
import org.openconcerto.utils.i18n.TranslationManager;
41 ilm 32
 
25 ilm 33
import java.awt.Color;
80 ilm 34
import java.awt.Component;
25 ilm 35
import java.awt.GridBagConstraints;
36
import java.awt.GridBagLayout;
41 ilm 37
import java.awt.event.ActionEvent;
38
import java.awt.event.ActionListener;
39
import java.awt.event.MouseAdapter;
40
import java.awt.event.MouseEvent;
83 ilm 41
import java.util.ArrayList;
93 ilm 42
import java.util.Collection;
41 ilm 43
import java.util.Date;
44
import java.util.HashMap;
83 ilm 45
import java.util.List;
41 ilm 46
import java.util.Map;
25 ilm 47
import java.util.Set;
48
 
41 ilm 49
import javax.swing.JCheckBox;
25 ilm 50
import javax.swing.JComponent;
51
import javax.swing.JLabel;
41 ilm 52
import javax.swing.JMenu;
53
import javax.swing.JMenuItem;
80 ilm 54
import javax.swing.JPanel;
41 ilm 55
import javax.swing.JPopupMenu;
80 ilm 56
import javax.swing.JScrollPane;
57
import javax.swing.JTabbedPane;
25 ilm 58
import javax.swing.JTextField;
59
import javax.swing.SwingConstants;
60
 
61
public class GroupSQLComponent extends BaseSQLComponent {
62
 
142 ilm 63
    public static final String ITEM_RIGHT_CODE = "GROUP_ITEM_SHOW";
64
 
41 ilm 65
    private final Group group;
66
    private final int columns = 2;
174 ilm 67
    private final Map<String, JComponent> labels = new HashMap<>();
68
    private final Map<String, JComponent> editors = new HashMap<>();
80 ilm 69
    private String startTabAfter = null;
70
    private boolean tabGroup;
71
    private int tabDepth;
72
    private JTabbedPane pane;
83 ilm 73
    private final List<String> tabsGroupIDs = new ArrayList<String>();
93 ilm 74
    private Group additionnalFieldsGroup;
75
    private final boolean hasAdditionnalFields;
25 ilm 76
 
93 ilm 77
    public GroupSQLComponent(final SQLElement element) {
78
        this(element, element.getDefaultGroup());
79
    }
80
 
41 ilm 81
    public GroupSQLComponent(final SQLElement element, final Group group) {
25 ilm 82
        super(element);
174 ilm 83
        if (element == null) {
84
            throw new IllegalArgumentException("null SQLElement");
85
        }
86
        if (group == null) {
87
            throw new IllegalArgumentException("null group (SQLElement : " + element + ")");
88
        }
25 ilm 89
        this.group = group;
93 ilm 90
        this.hasAdditionnalFields = this.getElement().getAdditionalFields().size() > 0;
94 ilm 91
        this.additionnalFieldsGroup = getAdditionalFieldsGroup(group.getDescendantGroups());
25 ilm 92
    }
93
 
94 ilm 94
    private Group getAdditionalFieldsGroup(Collection<Group> items) {
95
        for (Group g : items) {
96
            if (g.getId().endsWith("additionalElementFields")) {
97
                return g;
93 ilm 98
            }
99
        }
100
        return null;
101
    }
102
 
83 ilm 103
    protected final Group getGroup() {
104
        return this.group;
105
    }
106
 
80 ilm 107
    public void startTabGroupAfter(String id) {
174 ilm 108
        this.startTabAfter = id;
80 ilm 109
    }
110
 
25 ilm 111
    @Override
112
    protected void addViews() {
113
        this.setLayout(new GridBagLayout());
41 ilm 114
        final GridBagConstraints c = new DefaultGridBagConstraints();
65 ilm 115
        c.fill = GridBagConstraints.NONE;
80 ilm 116
        this.tabGroup = false;
117
        this.tabDepth = 0;
93 ilm 118
        // On laisse la place en haut pour les additionnals fields
119
        if (this.hasAdditionnalFields) {
120
            c.gridy = this.getElement().getAdditionalFields().size() / 2 + 1;
121
        }
122
 
80 ilm 123
        layout(this.group, 0, 0, 0, c, this);
25 ilm 124
    }
125
 
80 ilm 126
    public void layout(final Item currentItem, final Integer order, int x, final int level, GridBagConstraints c, JPanel panel) {
67 ilm 127
        final String id = currentItem.getId();
80 ilm 128
 
67 ilm 129
        final LayoutHints size = currentItem.getLocalHint();
73 ilm 130
        if (!size.isVisible()) {
131
            return;
132
        }
133
 
90 ilm 134
        if (size.isSeparated() || size.isSplit()) {
65 ilm 135
            x = 0;
136
            c.gridx = 0;
137
            c.gridy++;
138
        }
67 ilm 139
        if (currentItem instanceof Group) {
73 ilm 140
            final Group currentGroup = (Group) currentItem;
67 ilm 141
            final int stop = currentGroup.getSize();
80 ilm 142
            c.weighty = 0;
143
            if (this.tabGroup && level == this.tabDepth) {
144
                panel = new JPanel();
145
                panel.setLayout(new GridBagLayout());
146
                panel.setOpaque(false);
147
                c = new DefaultGridBagConstraints();
73 ilm 148
                x = 0;
80 ilm 149
                c.fill = GridBagConstraints.NONE;
150
                String label = TranslationManager.getInstance().getTranslationForItem(id);// getRIVDescForId(id).getLabel();
151
                if (label == null) {
152
                    label = id;
153
                }
154
                this.pane.addTab(label, panel);
83 ilm 155
                this.tabsGroupIDs.add(currentGroup.getId());
80 ilm 156
            } else {
157
                if (size.showLabel() && getLabel(id) != null) {
158
                    x = 0;
159
                    c.gridy++;
160
                    c.fill = GridBagConstraints.HORIZONTAL;
161
                    c.gridx = 0;
162
                    c.weightx = 1;
163
                    c.gridwidth = 4;
174 ilm 164
                    JComponent comp = getLabel(id);
165
                    panel.add(comp, c);
80 ilm 166
                    c.gridy++;
167
                }
73 ilm 168
            }
93 ilm 169
            if (this.hasAdditionnalFields) {
170
                if ((currentGroup == this.group && this.additionnalFieldsGroup == null) || (currentGroup == this.additionnalFieldsGroup)) {
180 ilm 171
                    for (String field : this.getElement().getAdditionalFields().keySet()) {
94 ilm 172
                        Item item = new Item(field, new LayoutHints(false, false, true, false, true, false));
173
                        int fill = c.fill;
174
                        double weightx = c.weightx;
175
                        c.weightx = 1;
176
                        c.fill = GridBagConstraints.HORIZONTAL;
93 ilm 177
                        layout(item, 100, x, level + 1, c, panel);
94 ilm 178
                        c.weightx = weightx;
179
                        c.fill = fill;
93 ilm 180
                    }
181
                }
182
            }
67 ilm 183
            for (int i = 0; i < stop; i++) {
184
                final Item subGroup = currentGroup.getItem(i);
185
                final Integer subGroupOrder = currentGroup.getOrder(i);
80 ilm 186
                layout(subGroup, subGroupOrder, x, level + 1, c, panel);
67 ilm 187
            }
80 ilm 188
            if (this.tabGroup && level == this.tabDepth) {
189
                JPanel spacer = new JPanel();
190
                spacer.setOpaque(false);
191
                c.gridy++;
192
                c.weighty = 0.0001;
193
                panel.add(spacer, c);
194
            }
195
 
67 ilm 196
        } else {
25 ilm 197
            c.gridwidth = 1;
198
            if (size.showLabel()) {
199
                c.weightx = 0;
65 ilm 200
                c.weighty = 0;
25 ilm 201
                // Label
90 ilm 202
                if (size.isSplit()) {
25 ilm 203
                    c.gridwidth = 4;
80 ilm 204
                    c.weightx = 1;
25 ilm 205
                    c.fill = GridBagConstraints.NONE;
206
                } else {
207
                    c.fill = GridBagConstraints.HORIZONTAL;
208
                }
80 ilm 209
                panel.add(getLabel(id), c);
90 ilm 210
                if (size.isSplit()) {
25 ilm 211
                    c.gridy++;
65 ilm 212
                    c.gridx = 0;
25 ilm 213
                } else {
214
                    c.gridx++;
215
                }
216
            }
217
            // Editor
41 ilm 218
            final JComponent editor = getEditor(id);
219
 
65 ilm 220
            if (size.fillWidth() && size.fillHeight()) {
25 ilm 221
                c.fill = GridBagConstraints.BOTH;
65 ilm 222
            } else if (size.fillWidth()) {
25 ilm 223
                c.fill = GridBagConstraints.HORIZONTAL;
65 ilm 224
            } else if (size.fillHeight()) {
25 ilm 225
                c.fill = GridBagConstraints.VERTICAL;
226
            } else {
227
                c.fill = GridBagConstraints.NONE;
41 ilm 228
                DefaultGridBagConstraints.lockMinimumSize(editor);
25 ilm 229
            }
65 ilm 230
            if (size.fillHeight()) {
25 ilm 231
                c.weighty = 1;
65 ilm 232
            } else {
233
                c.weighty = 0;
25 ilm 234
            }
65 ilm 235
            if (size.largeWidth()) {
91 ilm 236
                if (size.isSplit() || !size.showLabel()) {
65 ilm 237
                    c.gridwidth = this.columns * 2;
238
                } else {
239
                    c.gridwidth = this.columns * 2 - 1;
240
                }
241
            } else {
90 ilm 242
                if (size.showLabel() && !size.isSplit()) {
73 ilm 243
                    c.gridwidth = 1;
244
                } else {
245
                    c.gridwidth = 2;
246
                }
65 ilm 247
            }
41 ilm 248
            if (c.gridx % 2 == 1) {
249
                c.weightx = 1;
250
            }
80 ilm 251
 
252
            panel.add(editor, c);
253
 
41 ilm 254
            try {
80 ilm 255
                JComponent comp = editor;
256
                if (editor instanceof JScrollPane) {
257
                    JScrollPane pane = (JScrollPane) editor;
258
                    comp = (JComponent) pane.getViewport().getView();
259
                }
260
                this.addView(comp, id);
132 ilm 261
                // avoid collapsing of Mode de réglement in client
262
                if (comp instanceof ElementSQLObject)
263
                    DefaultGridBagConstraints.lockMinimumSize(editor);
41 ilm 264
            } catch (final Exception e) {
73 ilm 265
                Log.get().warning(e.getMessage());
41 ilm 266
            }
65 ilm 267
 
268
            if (size.largeWidth()) {
90 ilm 269
                if (size.isSplit()) {
65 ilm 270
                    c.gridx += 4;
271
                } else {
272
                    c.gridx += 3;
273
                }
274
            } else {
275
                c.gridx++;
276
            }
277
 
90 ilm 278
            if (c.gridx >= this.columns * 2 || size.isSeparated()) {
25 ilm 279
                c.gridx = 0;
280
                c.gridy++;
65 ilm 281
                x = 0;
25 ilm 282
            }
283
 
284
        }
174 ilm 285
        if (id.equals(this.startTabAfter)) {
286
            if (this.tabGroup) {
93 ilm 287
                throw new IllegalArgumentException("ID " + id + " already set as tab");
288
            }
174 ilm 289
            this.tabGroup = true;
290
            this.tabDepth = level;
291
            this.pane = new JTabbedPane();
80 ilm 292
            c.gridx = 0;
293
            c.gridy++;
294
            c.weightx = 1;
295
            c.weighty = 1;
296
            c.fill = GridBagConstraints.BOTH;
297
            c.gridwidth = 4;
174 ilm 298
            panel.add(this.pane, c);
80 ilm 299
        }
300
 
25 ilm 301
    }
302
 
83 ilm 303
    public final void setTabEnabledAt(final String groupID, final boolean enabled) {
304
        this.pane.setEnabledAt(this.tabsGroupIDs.indexOf(groupID), enabled);
305
    }
306
 
307
    public final boolean isTabEnabledAt(final String groupID) {
308
        return this.pane.isEnabledAt(this.tabsGroupIDs.indexOf(groupID));
309
    }
310
 
311
    public final void selectTabEnabled() {
312
        final int index = this.pane.getSelectedIndex();
313
        if (!this.pane.isEnabledAt(index)) {
314
            final int count = this.pane.getTabCount();
315
            // 1 since index is disabled
316
            for (int i = 1; i < count; i++) {
317
                final int mod = (index + i) % count;
318
                if (this.pane.isEnabledAt(mod)) {
319
                    this.pane.setSelectedIndex(mod);
320
                    return;
321
                }
322
            }
323
        }
324
    }
325
 
80 ilm 326
    @Override
327
    public Component addView(JComponent comp, String id) {
328
        final FieldMapper fieldMapper = PropsConfiguration.getInstance().getFieldMapper();
329
        SQLField field = null;
330
        if (fieldMapper != null) {
331
            field = fieldMapper.getSQLFieldForItem(id);
332
        }
333
        // Maybe the id is a field name (deprecated)
334
        if (field == null) {
335
            field = this.getTable().getFieldRaw(id);
336
        }
132 ilm 337
        // allow to add components in the UI which aren't in the request
338
        if (field != null)
339
            return super.addView(comp, field.getName());
340
        else
341
            return comp;
80 ilm 342
    }
343
 
41 ilm 344
    public JComponent createEditor(final String id) {
144 ilm 345
        if (GlobalMapper.getInstance().get(id + ".editor") != null) {
346
            try {
347
                final Class<?> cl = (Class<?>) GlobalMapper.getInstance().get(id + ".editor");
348
                return (JComponent) cl.newInstance();
349
            } catch (final Exception e) {
350
                e.printStackTrace();
351
            }
352
        }
25 ilm 353
        if (id.startsWith("(") && id.endsWith(")*")) {
354
            try {
41 ilm 355
                final String table = id.substring(1, id.length() - 2).trim();
356
                final String idEditor = GlobalMapper.getInstance().getIds(table).get(0) + ".editor";
357
                final Class<?> cl = (Class<?>) GlobalMapper.getInstance().get(idEditor);
25 ilm 358
                return (JComponent) cl.newInstance();
41 ilm 359
            } catch (final Exception e) {
25 ilm 360
                e.printStackTrace();
361
            }
362
        }
363
 
80 ilm 364
        final FieldMapper fieldMapper = PropsConfiguration.getInstance().getFieldMapper();
365
        SQLField field = null;
366
        if (fieldMapper != null) {
367
            field = fieldMapper.getSQLFieldForItem(id);
368
        }
369
        // Maybe the id is a field name (deprecated)
25 ilm 370
        if (field == null) {
80 ilm 371
            field = this.getTable().getFieldRaw(id);
372
 
373
        }
374
        if (field == null) {
25 ilm 375
            final JLabel jLabel = new JLabelBold("No field " + id);
376
            jLabel.setForeground(Color.RED.darker());
377
            String t = "<html>";
378
 
379
            final Set<SQLField> fields = this.getTable().getFields();
380
 
41 ilm 381
            for (final SQLField sqlField : fields) {
25 ilm 382
                t += sqlField.getFullName() + "<br>";
383
            }
384
            t += "</html>";
385
            jLabel.setToolTipText(t);
386
            return jLabel;
387
        }
73 ilm 388
 
41 ilm 389
        final SQLType type = field.getType();
25 ilm 390
 
41 ilm 391
        final JComponent comp;
392
 
393
        if (getElement().getPrivateElement(field.getName()) != null) {
394
            // private
395
            final SQLComponent sqlcomp = this.getElement().getPrivateElement(field.getName()).createDefaultComponent();
396
            final DefaultElementSQLObject dobj = new DefaultElementSQLObject(this, sqlcomp);
397
            dobj.setDecorated(false);
398
            dobj.showSeparator(false);
399
            DefaultGridBagConstraints.lockMinimumSize(sqlcomp);
400
            comp = dobj;
401
        } else if (field.isKey()) {
402
            // foreign
80 ilm 403
 
404
            final SQLElement foreignElement = getElement().getForeignElement(field.getName());
405
            if (foreignElement == null) {
406
                comp = new JLabelBold("no element for foreignd " + id);
407
                comp.setForeground(Color.RED.darker());
408
                Log.get().severe("no element for foreign " + field.getName());
409
            } else {
410
                comp = new ElementComboBox();
411
                ((ElementComboBox) comp).init(foreignElement);
412
            }
41 ilm 413
            comp.setOpaque(false);
414
        } else {
415
            if (Boolean.class.isAssignableFrom(type.getJavaType())) {
416
                // TODO hack to view the focus (should try to paint around the button)
417
                comp = new JCheckBox(" ");
418
                comp.setOpaque(false);
419
            } else if (Date.class.isAssignableFrom(type.getJavaType())) {
420
                comp = new JDate();
421
                comp.setOpaque(false);
132 ilm 422
            } else if (String.class.isAssignableFrom(type.getJavaType()) && type.getSize() >= 500) {
423
                comp = new ITextArea();
41 ilm 424
            } else {
425
                comp = new JTextField(Math.min(30, type.getSize()));
426
            }
25 ilm 427
        }
428
 
41 ilm 429
        return comp;
25 ilm 430
    }
431
 
57 ilm 432
    protected JComponent createLabel(final String id) {
433
        final JLabel jLabel = new JLabel();
25 ilm 434
        jLabel.setHorizontalAlignment(SwingConstants.RIGHT);
435
        return jLabel;
436
    }
41 ilm 437
 
438
    private void registerPopupMenu(final JComponent label, final String id) {
439
        label.addMouseListener(new MouseAdapter() {
440
 
441
            @Override
442
            public void mouseReleased(final MouseEvent e) {
443
                if (e.getButton() == MouseEvent.BUTTON3 && e.getModifiersEx() == 128) {
444
 
445
                    final JPopupMenu popMenu = new JPopupMenu();
446
                    final JMenu menuItemInfo = new JMenu("Information");
447
                    menuItemInfo.add(new JMenuItem("id: " + id));
90 ilm 448
                    menuItemInfo.add(new JMenuItem("label: " + getLabel(id).getClass().getName() + ":" + getLabel(id)));
449
                    menuItemInfo.add(new JMenuItem("editor: " + getEditor(id).getClass().getName() + ":" + getEditor(id)));
41 ilm 450
                    popMenu.add(menuItemInfo);
451
                    final JMenuItem menuItemDoc = new JMenuItem("Modifier la documentation");
452
                    menuItemDoc.addActionListener(new ActionListener() {
453
 
454
                        @Override
455
                        public void actionPerformed(final ActionEvent e) {
57 ilm 456
                            new DocumentationEditorFrame(GroupSQLComponent.this, id).setVisible(true);
41 ilm 457
 
458
                        }
459
                    });
460
 
461
                    popMenu.add(menuItemDoc);
462
                    popMenu.show(label, e.getX(), e.getY());
463
                }
464
 
465
            }
466
 
467
        });
468
 
469
    }
470
 
57 ilm 471
    @Override
472
    protected void updateUI(String id, RowItemDesc desc) {
473
        super.updateUI(id, desc);
474
        updateUI(id, getLabel(id), desc, Color.RED.darker());
41 ilm 475
    }
476
 
477
    public JComponent getLabel(final String id) {
478
        JComponent label = this.labels.get(id);
479
        if (label == null) {
480
            label = createLabel(id);
142 ilm 481
            if (!UserRightsManager.getCurrentUserRights().haveRight(ITEM_RIGHT_CODE, id)
482
                    || !UserRightsManager.getCurrentUserRights().haveRight(ITEM_RIGHT_CODE, getElement().getTable().getName() + "." + id)) {
93 ilm 483
                label.setVisible(false);
484
            }
485
 
41 ilm 486
            this.labels.put(id, label);
90 ilm 487
            registerPopupMenu(label, id);
80 ilm 488
            final RowItemDesc rivDesc = getRIVDescForId(id);
489
            updateUI(id, rivDesc);
41 ilm 490
        }
491
        return label;
492
    }
493
 
142 ilm 494
    public RowItemDesc getRIVDescForId(final String id) {
93 ilm 495
        if (TranslationManager.getInstance().getLocale() != null) {
496
            final String t = TranslationManager.getInstance().getTranslationForItem(id);
497
            if (t != null) {
498
                return new RowItemDesc(t, t);
499
            }
80 ilm 500
        }
501
        String fieldName = null;
93 ilm 502
        final FieldMapper fieldMapper = PropsConfiguration.getInstance().getFieldMapper();
80 ilm 503
        if (fieldMapper != null) {
504
            final SQLField sqlFieldForItem = fieldMapper.getSQLFieldForItem(id);
505
            if (sqlFieldForItem != null) {
506
                fieldName = sqlFieldForItem.getName();
507
            }
508
        }
509
        if (fieldName == null) {
510
            fieldName = id;
511
        }
512
        final RowItemDesc rivDesc = getRIVDesc(fieldName);
513
        return rivDesc;
514
    }
515
 
41 ilm 516
    public JComponent getEditor(final String id) {
517
        JComponent editor = this.editors.get(id);
518
        if (editor == null) {
519
            editor = createEditor(id);
142 ilm 520
            if (!UserRightsManager.getCurrentUserRights().haveRight(ITEM_RIGHT_CODE, id)
521
                    || !UserRightsManager.getCurrentUserRights().haveRight(ITEM_RIGHT_CODE, getElement().getTable().getName() + "." + id)) {
93 ilm 522
                editor.setVisible(false);
523
            }
41 ilm 524
            this.editors.put(id, editor);
525
        }
526
        return editor;
527
    }
25 ilm 528
}