OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 144 | 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)) {
171
                    final Map<String, JComponent> additionalFields = this.getElement().getAdditionalFields();
172
                    for (String field : additionalFields.keySet()) {
94 ilm 173
                        Item item = new Item(field, new LayoutHints(false, false, true, false, true, false));
174
                        int fill = c.fill;
175
                        double weightx = c.weightx;
176
                        c.weightx = 1;
177
                        c.fill = GridBagConstraints.HORIZONTAL;
93 ilm 178
                        layout(item, 100, x, level + 1, c, panel);
94 ilm 179
                        c.weightx = weightx;
180
                        c.fill = fill;
93 ilm 181
                    }
182
                }
183
            }
67 ilm 184
            for (int i = 0; i < stop; i++) {
185
                final Item subGroup = currentGroup.getItem(i);
186
                final Integer subGroupOrder = currentGroup.getOrder(i);
80 ilm 187
                layout(subGroup, subGroupOrder, x, level + 1, c, panel);
67 ilm 188
            }
80 ilm 189
            if (this.tabGroup && level == this.tabDepth) {
190
                JPanel spacer = new JPanel();
191
                spacer.setOpaque(false);
192
                c.gridy++;
193
                c.weighty = 0.0001;
194
                panel.add(spacer, c);
195
            }
196
 
67 ilm 197
        } else {
25 ilm 198
            c.gridwidth = 1;
199
            if (size.showLabel()) {
200
                c.weightx = 0;
65 ilm 201
                c.weighty = 0;
25 ilm 202
                // Label
90 ilm 203
                if (size.isSplit()) {
25 ilm 204
                    c.gridwidth = 4;
80 ilm 205
                    c.weightx = 1;
25 ilm 206
                    c.fill = GridBagConstraints.NONE;
207
                } else {
208
                    c.fill = GridBagConstraints.HORIZONTAL;
209
                }
80 ilm 210
                panel.add(getLabel(id), c);
90 ilm 211
                if (size.isSplit()) {
25 ilm 212
                    c.gridy++;
65 ilm 213
                    c.gridx = 0;
25 ilm 214
                } else {
215
                    c.gridx++;
216
                }
217
            }
218
            // Editor
41 ilm 219
            final JComponent editor = getEditor(id);
220
 
65 ilm 221
            if (size.fillWidth() && size.fillHeight()) {
25 ilm 222
                c.fill = GridBagConstraints.BOTH;
65 ilm 223
            } else if (size.fillWidth()) {
25 ilm 224
                c.fill = GridBagConstraints.HORIZONTAL;
65 ilm 225
            } else if (size.fillHeight()) {
25 ilm 226
                c.fill = GridBagConstraints.VERTICAL;
227
            } else {
228
                c.fill = GridBagConstraints.NONE;
41 ilm 229
                DefaultGridBagConstraints.lockMinimumSize(editor);
25 ilm 230
            }
65 ilm 231
            if (size.fillHeight()) {
25 ilm 232
                c.weighty = 1;
65 ilm 233
            } else {
234
                c.weighty = 0;
25 ilm 235
            }
65 ilm 236
            if (size.largeWidth()) {
91 ilm 237
                if (size.isSplit() || !size.showLabel()) {
65 ilm 238
                    c.gridwidth = this.columns * 2;
239
                } else {
240
                    c.gridwidth = this.columns * 2 - 1;
241
                }
242
            } else {
90 ilm 243
                if (size.showLabel() && !size.isSplit()) {
73 ilm 244
                    c.gridwidth = 1;
245
                } else {
246
                    c.gridwidth = 2;
247
                }
65 ilm 248
            }
41 ilm 249
            if (c.gridx % 2 == 1) {
250
                c.weightx = 1;
251
            }
80 ilm 252
 
253
            panel.add(editor, c);
254
 
41 ilm 255
            try {
80 ilm 256
                JComponent comp = editor;
257
                if (editor instanceof JScrollPane) {
258
                    JScrollPane pane = (JScrollPane) editor;
259
                    comp = (JComponent) pane.getViewport().getView();
260
                }
261
                this.addView(comp, id);
132 ilm 262
                // avoid collapsing of Mode de réglement in client
263
                if (comp instanceof ElementSQLObject)
264
                    DefaultGridBagConstraints.lockMinimumSize(editor);
41 ilm 265
            } catch (final Exception e) {
73 ilm 266
                Log.get().warning(e.getMessage());
41 ilm 267
            }
65 ilm 268
 
269
            if (size.largeWidth()) {
90 ilm 270
                if (size.isSplit()) {
65 ilm 271
                    c.gridx += 4;
272
                } else {
273
                    c.gridx += 3;
274
                }
275
            } else {
276
                c.gridx++;
277
            }
278
 
90 ilm 279
            if (c.gridx >= this.columns * 2 || size.isSeparated()) {
25 ilm 280
                c.gridx = 0;
281
                c.gridy++;
65 ilm 282
                x = 0;
25 ilm 283
            }
284
 
285
        }
174 ilm 286
        if (id.equals(this.startTabAfter)) {
287
            if (this.tabGroup) {
93 ilm 288
                throw new IllegalArgumentException("ID " + id + " already set as tab");
289
            }
174 ilm 290
            this.tabGroup = true;
291
            this.tabDepth = level;
292
            this.pane = new JTabbedPane();
80 ilm 293
            c.gridx = 0;
294
            c.gridy++;
295
            c.weightx = 1;
296
            c.weighty = 1;
297
            c.fill = GridBagConstraints.BOTH;
298
            c.gridwidth = 4;
174 ilm 299
            panel.add(this.pane, c);
80 ilm 300
        }
301
 
25 ilm 302
    }
303
 
83 ilm 304
    public final void setTabEnabledAt(final String groupID, final boolean enabled) {
305
        this.pane.setEnabledAt(this.tabsGroupIDs.indexOf(groupID), enabled);
306
    }
307
 
308
    public final boolean isTabEnabledAt(final String groupID) {
309
        return this.pane.isEnabledAt(this.tabsGroupIDs.indexOf(groupID));
310
    }
311
 
312
    public final void selectTabEnabled() {
313
        final int index = this.pane.getSelectedIndex();
314
        if (!this.pane.isEnabledAt(index)) {
315
            final int count = this.pane.getTabCount();
316
            // 1 since index is disabled
317
            for (int i = 1; i < count; i++) {
318
                final int mod = (index + i) % count;
319
                if (this.pane.isEnabledAt(mod)) {
320
                    this.pane.setSelectedIndex(mod);
321
                    return;
322
                }
323
            }
324
        }
325
    }
326
 
80 ilm 327
    @Override
328
    public Component addView(JComponent comp, String id) {
329
        final FieldMapper fieldMapper = PropsConfiguration.getInstance().getFieldMapper();
330
        SQLField field = null;
331
        if (fieldMapper != null) {
332
            field = fieldMapper.getSQLFieldForItem(id);
333
        }
334
        // Maybe the id is a field name (deprecated)
335
        if (field == null) {
336
            field = this.getTable().getFieldRaw(id);
337
        }
132 ilm 338
        // allow to add components in the UI which aren't in the request
339
        if (field != null)
340
            return super.addView(comp, field.getName());
341
        else
342
            return comp;
80 ilm 343
    }
344
 
41 ilm 345
    public JComponent createEditor(final String id) {
144 ilm 346
        if (GlobalMapper.getInstance().get(id + ".editor") != null) {
347
            try {
348
                final Class<?> cl = (Class<?>) GlobalMapper.getInstance().get(id + ".editor");
349
                return (JComponent) cl.newInstance();
350
            } catch (final Exception e) {
351
                e.printStackTrace();
352
            }
353
        }
25 ilm 354
        if (id.startsWith("(") && id.endsWith(")*")) {
355
            try {
41 ilm 356
                final String table = id.substring(1, id.length() - 2).trim();
357
                final String idEditor = GlobalMapper.getInstance().getIds(table).get(0) + ".editor";
358
                final Class<?> cl = (Class<?>) GlobalMapper.getInstance().get(idEditor);
25 ilm 359
                return (JComponent) cl.newInstance();
41 ilm 360
            } catch (final Exception e) {
25 ilm 361
                e.printStackTrace();
362
            }
363
        }
364
 
80 ilm 365
        final FieldMapper fieldMapper = PropsConfiguration.getInstance().getFieldMapper();
366
        SQLField field = null;
367
        if (fieldMapper != null) {
368
            field = fieldMapper.getSQLFieldForItem(id);
369
        }
370
        // Maybe the id is a field name (deprecated)
25 ilm 371
        if (field == null) {
80 ilm 372
            field = this.getTable().getFieldRaw(id);
373
 
374
        }
375
        if (field == null) {
25 ilm 376
            final JLabel jLabel = new JLabelBold("No field " + id);
377
            jLabel.setForeground(Color.RED.darker());
378
            String t = "<html>";
379
 
380
            final Set<SQLField> fields = this.getTable().getFields();
381
 
41 ilm 382
            for (final SQLField sqlField : fields) {
25 ilm 383
                t += sqlField.getFullName() + "<br>";
384
            }
385
            t += "</html>";
386
            jLabel.setToolTipText(t);
387
            return jLabel;
388
        }
73 ilm 389
 
41 ilm 390
        final SQLType type = field.getType();
25 ilm 391
 
41 ilm 392
        final JComponent comp;
393
 
394
        if (getElement().getPrivateElement(field.getName()) != null) {
395
            // private
396
            final SQLComponent sqlcomp = this.getElement().getPrivateElement(field.getName()).createDefaultComponent();
397
            final DefaultElementSQLObject dobj = new DefaultElementSQLObject(this, sqlcomp);
398
            dobj.setDecorated(false);
399
            dobj.showSeparator(false);
400
            DefaultGridBagConstraints.lockMinimumSize(sqlcomp);
401
            comp = dobj;
402
        } else if (field.isKey()) {
403
            // foreign
80 ilm 404
 
405
            final SQLElement foreignElement = getElement().getForeignElement(field.getName());
406
            if (foreignElement == null) {
407
                comp = new JLabelBold("no element for foreignd " + id);
408
                comp.setForeground(Color.RED.darker());
409
                Log.get().severe("no element for foreign " + field.getName());
410
            } else {
411
                comp = new ElementComboBox();
412
                ((ElementComboBox) comp).init(foreignElement);
413
            }
41 ilm 414
            comp.setOpaque(false);
415
        } else {
416
            if (Boolean.class.isAssignableFrom(type.getJavaType())) {
417
                // TODO hack to view the focus (should try to paint around the button)
418
                comp = new JCheckBox(" ");
419
                comp.setOpaque(false);
420
            } else if (Date.class.isAssignableFrom(type.getJavaType())) {
421
                comp = new JDate();
422
                comp.setOpaque(false);
132 ilm 423
            } else if (String.class.isAssignableFrom(type.getJavaType()) && type.getSize() >= 500) {
424
                comp = new ITextArea();
41 ilm 425
            } else {
426
                comp = new JTextField(Math.min(30, type.getSize()));
427
            }
25 ilm 428
        }
429
 
41 ilm 430
        return comp;
25 ilm 431
    }
432
 
57 ilm 433
    protected JComponent createLabel(final String id) {
434
        final JLabel jLabel = new JLabel();
25 ilm 435
        jLabel.setHorizontalAlignment(SwingConstants.RIGHT);
436
        return jLabel;
437
    }
41 ilm 438
 
439
    private void registerPopupMenu(final JComponent label, final String id) {
440
        label.addMouseListener(new MouseAdapter() {
441
 
442
            @Override
443
            public void mouseReleased(final MouseEvent e) {
444
                if (e.getButton() == MouseEvent.BUTTON3 && e.getModifiersEx() == 128) {
445
 
446
                    final JPopupMenu popMenu = new JPopupMenu();
447
                    final JMenu menuItemInfo = new JMenu("Information");
448
                    menuItemInfo.add(new JMenuItem("id: " + id));
90 ilm 449
                    menuItemInfo.add(new JMenuItem("label: " + getLabel(id).getClass().getName() + ":" + getLabel(id)));
450
                    menuItemInfo.add(new JMenuItem("editor: " + getEditor(id).getClass().getName() + ":" + getEditor(id)));
41 ilm 451
                    popMenu.add(menuItemInfo);
452
                    final JMenuItem menuItemDoc = new JMenuItem("Modifier la documentation");
453
                    menuItemDoc.addActionListener(new ActionListener() {
454
 
455
                        @Override
456
                        public void actionPerformed(final ActionEvent e) {
57 ilm 457
                            new DocumentationEditorFrame(GroupSQLComponent.this, id).setVisible(true);
41 ilm 458
 
459
                        }
460
                    });
461
 
462
                    popMenu.add(menuItemDoc);
463
                    popMenu.show(label, e.getX(), e.getY());
464
                }
465
 
466
            }
467
 
468
        });
469
 
470
    }
471
 
57 ilm 472
    @Override
473
    protected void updateUI(String id, RowItemDesc desc) {
474
        super.updateUI(id, desc);
475
        updateUI(id, getLabel(id), desc, Color.RED.darker());
41 ilm 476
    }
477
 
478
    public JComponent getLabel(final String id) {
479
        JComponent label = this.labels.get(id);
480
        if (label == null) {
481
            label = createLabel(id);
142 ilm 482
            if (!UserRightsManager.getCurrentUserRights().haveRight(ITEM_RIGHT_CODE, id)
483
                    || !UserRightsManager.getCurrentUserRights().haveRight(ITEM_RIGHT_CODE, getElement().getTable().getName() + "." + id)) {
93 ilm 484
                label.setVisible(false);
485
            }
486
 
41 ilm 487
            this.labels.put(id, label);
90 ilm 488
            registerPopupMenu(label, id);
80 ilm 489
            final RowItemDesc rivDesc = getRIVDescForId(id);
490
            updateUI(id, rivDesc);
41 ilm 491
        }
492
        return label;
493
    }
494
 
142 ilm 495
    public RowItemDesc getRIVDescForId(final String id) {
93 ilm 496
        if (TranslationManager.getInstance().getLocale() != null) {
497
            final String t = TranslationManager.getInstance().getTranslationForItem(id);
498
            if (t != null) {
499
                return new RowItemDesc(t, t);
500
            }
80 ilm 501
        }
502
        String fieldName = null;
93 ilm 503
        final FieldMapper fieldMapper = PropsConfiguration.getInstance().getFieldMapper();
80 ilm 504
        if (fieldMapper != null) {
505
            final SQLField sqlFieldForItem = fieldMapper.getSQLFieldForItem(id);
506
            if (sqlFieldForItem != null) {
507
                fieldName = sqlFieldForItem.getName();
508
            }
509
        }
510
        if (fieldName == null) {
511
            fieldName = id;
512
        }
513
        final RowItemDesc rivDesc = getRIVDesc(fieldName);
514
        return rivDesc;
515
    }
516
 
41 ilm 517
    public JComponent getEditor(final String id) {
518
        JComponent editor = this.editors.get(id);
519
        if (editor == null) {
520
            editor = createEditor(id);
142 ilm 521
            if (!UserRightsManager.getCurrentUserRights().haveRight(ITEM_RIGHT_CODE, id)
522
                    || !UserRightsManager.getCurrentUserRights().haveRight(ITEM_RIGHT_CODE, getElement().getTable().getName() + "." + id)) {
93 ilm 523
                editor.setVisible(false);
524
            }
41 ilm 525
            this.editors.put(id, editor);
526
        }
527
        return editor;
528
    }
25 ilm 529
}