OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 18 | Rev 21 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
18 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.erp.panel;
15
 
16
import org.openconcerto.sql.Configuration;
17
import org.openconcerto.sql.element.SQLElement;
18
import org.openconcerto.sql.model.SQLRow;
19
import org.openconcerto.sql.model.SQLRowValues;
20
import org.openconcerto.sql.model.SQLSelect;
21
import org.openconcerto.sql.model.SQLTable;
22
import org.openconcerto.sql.model.SQLTableListener;
23
import org.openconcerto.sql.request.SQLRowItemView;
24
import org.openconcerto.sql.sqlobject.itemview.RowItemViewComponent;
25
import org.openconcerto.sql.view.EditFrame;
26
import org.openconcerto.ui.FrameUtil;
27
import org.openconcerto.ui.valuewrapper.ValueWrapper;
28
import org.openconcerto.utils.checks.EmptyListener;
29
import org.openconcerto.utils.checks.EmptyObject;
30
import org.openconcerto.utils.checks.EmptyObjectHelper;
31
import org.openconcerto.utils.checks.ValidListener;
32
 
33
import java.awt.event.ActionEvent;
34
import java.awt.event.MouseEvent;
35
import java.awt.event.MouseListener;
36
import java.beans.PropertyChangeListener;
37
import java.beans.PropertyChangeSupport;
38
import java.sql.SQLException;
39
import java.util.HashMap;
40
import java.util.List;
41
import java.util.Map;
42
 
43
import javax.swing.AbstractAction;
44
import javax.swing.JComponent;
45
import javax.swing.JPopupMenu;
46
import javax.swing.JTree;
47
import javax.swing.event.TreeSelectionEvent;
48
import javax.swing.event.TreeSelectionListener;
49
import javax.swing.tree.DefaultTreeCellRenderer;
50
import javax.swing.tree.DefaultTreeModel;
51
import javax.swing.tree.TreePath;
52
import javax.swing.tree.TreeSelectionModel;
53
 
54
import org.apache.commons.collections.Predicate;
55
import org.apache.commons.dbutils.handlers.ArrayListHandler;
56
 
57
// TODO Drag'n drop des nodes
58
public class ITreeSelection extends JTree implements MouseListener, EmptyObject, ValueWrapper<Integer>, RowItemViewComponent {
59
 
60
    private SQLElement element;
61
 
62
    private ITreeSelectionNode rootNode;
63
    private DefaultTreeModel model;
64
 
65
    // Map <Id, Node>
66
    private Map<Integer, ITreeSelectionNode> mapNode = new HashMap<Integer, ITreeSelectionNode>();
67
 
68
    protected static final int EMPTY_ID = SQLRow.MIN_VALID_ID - 1;
69
    private EmptyObjectHelper helper;
70
    private final PropertyChangeSupport supp;
71
 
72
    public ITreeSelection() {
73
 
74
        this(null);
75
    }
76
 
77
    public ITreeSelection(SQLElement element) {
78
        super();
79
        DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
80
        renderer.setOpenIcon(null);
81
        renderer.setClosedIcon(null);
82
        renderer.setLeafIcon(null);
83
        this.setCellRenderer(renderer);
84
 
85
        this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
86
        this.element = element;
87
 
88
        this.supp = new PropertyChangeSupport(this);
89
 
90
        // Value changed
91
        this.addTreeSelectionListener(new TreeSelectionListener() {
92
            public void valueChanged(TreeSelectionEvent e) {
93
                ITreeSelection.this.supp.firePropertyChange("value", null, getUncheckedValue());
94
            }
95
        });
96
 
97
    }
98
 
99
    private void initTree() {
100
        if (this.element == null) {
101
            this.rootNode = new ITreeSelectionNode(null);
102
        } else {
103
            SQLRow row = this.element.getTable().getRow(element.getTable().getUndefinedID());
104
            this.rootNode = new ITreeSelectionNode(row);
105
        }
106
        this.model = new DefaultTreeModel(this.rootNode);
107
        this.setModel(this.model);
108
        loadTree();
109
        this.expandRow(0);
110
        setTableListener();
111
        this.addMouseListener(this);
112
    }
113
 
114
    public void mouseClicked(MouseEvent e) {
115
        // TODO Auto-generated method stub
116
 
117
    }
118
 
119
    public void mouseEntered(MouseEvent e) {
120
        // TODO Auto-generated method stub
121
 
122
    }
123
 
124
    public void mouseExited(MouseEvent e) {
125
        // TODO Auto-generated method stub
126
 
127
    }
128
 
129
    public void mousePressed(MouseEvent e) {
130
 
131
        TreePath path = this.getSelectionPath();
132
        if (path != null) {
133
            Object o = path.getLastPathComponent();
134
 
135
            int id = 1;
136
 
137
            if (e.getButton() == MouseEvent.BUTTON3) {
138
 
139
                final int idSelect = getSelectedID();
140
 
141
                // Ajouter, supprimer, modifier un élément dans l'arbre
142
 
143
                JPopupMenu menu = new JPopupMenu();
144
                menu.add(new AbstractAction("Ajouter un élément") {
145
                    public void actionPerformed(ActionEvent e) {
146
                        addElement(idSelect);
147
                    }
148
                });
149
 
150
                if (idSelect > 1) {
151
                    menu.add(new AbstractAction("Modifier") {
152
                        public void actionPerformed(ActionEvent e) {
153
                            modifyElement(idSelect);
154
                        }
155
                    });
156
 
157
                    menu.add(new AbstractAction("Supprimer") {
158
                        public void actionPerformed(ActionEvent e) {
159
                            removeElement(idSelect);
160
                        }
161
                    });
162
                }
163
                menu.show(e.getComponent(), e.getPoint().x, e.getPoint().y);
164
            }
165
        }
166
    }
167
 
168
    public int getSelectedID() {
169
        TreePath path = this.getSelectionPath();
170
        int id = 1;
171
        if (path != null) {
172
            Object o = path.getLastPathComponent();
173
 
174
            if (o instanceof ITreeSelectionNode) {
175
 
176
                final ITreeSelectionNode nodeSelect = (ITreeSelectionNode) o;
177
                id = nodeSelect.getId();
178
            }
179
        }
180
        return id;
181
    }
182
 
183
    /**
184
     * Ajouter une feuille
185
     */
186
    public void addElement(int idRoot) {
187
        EditFrame frameAdd = new EditFrame(element, EditFrame.CREATION);
188
        SQLRowValues rowVals = new SQLRowValues(element.getTable());
189
        if (idRoot > 1) {
190
            rowVals.put("ID_" + element.getTable().getName() + "_PERE", idRoot);
191
            frameAdd.getSQLComponent().select(rowVals);
192
        }
193
        FrameUtil.showPacked(frameAdd);
194
 
195
    }
196
 
197
    /**
198
     * Supprimer la feuille
199
     */
200
    public void removeElement(int id) {
201
        if (id > 1) {
202
            try {
203
                element.archive(id);
204
            } catch (SQLException e1) {
205
                e1.printStackTrace();
206
            }
207
        }
208
    }
209
 
210
    /**
211
     * Modifier la feuille
212
     */
213
    public void modifyElement(int id) {
214
        if (id > 1) {
215
            EditFrame frameModFamille = new EditFrame(element, EditFrame.MODIFICATION);
216
            frameModFamille.selectionId(id, 1);
217
            FrameUtil.showPacked(frameModFamille);
218
        }
219
    }
220
 
221
    public void mouseReleased(MouseEvent e) {
222
        // TODO Auto-generated method stub
223
 
224
    }
225
 
226
    public JComponent getComp() {
227
        return this;
228
    }
229
 
230
    public void resetValue() {
231
        this.setValue(1);
232
    }
233
 
234
    public void addEmptyListener(EmptyListener l) {
235
        this.helper.addListener(l);
236
    }
237
 
238
    public void addValueListener(PropertyChangeListener l) {
239
        this.supp.addPropertyChangeListener(l);
240
    }
241
 
242
    @Override
243
    public void rmValueListener(PropertyChangeListener l) {
244
        this.supp.removePropertyChangeListener(l);
245
    }
246
 
247
    public Integer getUncheckedValue() {
248
 
249
        int id = 1;
250
        TreePath path = this.getSelectionPath();
251
 
252
        if (path != null) {
253
            Object o = path.getLastPathComponent();
254
 
255
            if (o instanceof ITreeSelectionNode) {
256
                final ITreeSelectionNode nodeSelect = (ITreeSelectionNode) o;
257
                id = nodeSelect.getId();
258
            }
259
        }
260
        return id;
261
    }
262
 
263
    public Integer getValue() throws IllegalStateException {
264
        return ((Number) this.helper.getValue()).intValue();
265
    }
266
 
267
    public boolean isEmpty() {
268
        return this.helper.isEmpty();
269
    }
270
 
271
    public void addValidListener(ValidListener l) {
272
        // TODO Auto-generated method stub
273
    }
274
 
19 ilm 275
    @Override
276
    public void removeValidListener(ValidListener l) {
277
        // TODO Auto-generated method stub
278
    }
279
 
18 ilm 280
    public boolean isValidated() {
281
 
282
        return true;
283
    }
284
 
285
    @Override
286
    public void init(SQLRowItemView v) {
287
        // final SQLElement element;
288
        if (this.element == null) {
289
            final SQLTable foreignTable = v.getField().getTable().getDBSystemRoot().getGraph().getForeignTable(v.getField());
290
            this.element = Configuration.getInstance().getDirectory().getElement(foreignTable);
291
        }
292
        // else
293
        // element = this.element;
294
        this.helper = new EmptyObjectHelper(this, new Predicate() {
295
            public boolean evaluate(Object object) {
296
                final Integer val = ((Number) object).intValue();
297
                return val.intValue() <= EMPTY_ID;
298
            }
299
        });
300
        initTree();
301
    }
302
 
303
    public void setValue(Integer val) {
304
        if (val == null)
305
            val = EMPTY_ID;
306
        // TODO Auto-generated method stub
307
        ITreeSelectionNode v = this.mapNode.get(val);
308
        if (v.getId() == val) {
309
            this.setExpandsSelectedPaths(true);
310
            this.setSelectionPath(new TreePath(v.getPath()));
311
        }
312
 
313
        // System.err.println("Set value Tree " + val);
314
        // if (this.rootNode != null) {
315
        // for (int i = 0; i < this.rootNode.getChildCount(); i++) {
316
        // Object o = this.rootNode.getChildAt(i);
317
        // if (o instanceof FamilleTreeNode) {
318
        // FamilleTreeNode v = (FamilleTreeNode) o;
319
        // if (v.getId() == val) {
320
        // System.err.println("Select TreeNode row Id " + val);
321
        // this.setExpandsSelectedPaths(true);
322
        // this.setSelectionPath(new TreePath(v.getPath()));
323
        // }
324
        // }
325
        // }
326
        // }
327
    }
328
 
329
    private void loadTree() {
330
 
331
        SQLTable table = this.element.getTable();
332
        SQLSelect sel = new SQLSelect(table.getBase());
333
 
334
        sel.addSelect(table.getKey());
335
        sel.addSelect(table.getField("ID_" + table.getName() + "_PERE"));
336
 
337
        List l = (List) table.getBase().getDataSource().execute(sel.asString(), new ArrayListHandler());
338
 
339
        if (l != null) {
340
            for (int i = 0; i < l.size(); i++) {
341
                Object[] tmp = (Object[]) l.get(i);
342
                addNewNode(((Number) tmp[0]).intValue(), ((Number) tmp[1]).intValue());
343
            }
344
        }
345
    }
346
 
347
    /**
348
     * Ajoute une famille dans l'arbre
349
     *
350
     * @param id
351
     * @param idPere
352
     */
353
    private void addNewNode(int id, int idPere) {
354
        SQLTable table = this.element.getTable();
355
        ITreeSelectionNode nodePere = this.mapNode.get(Integer.valueOf(idPere));
356
        SQLRow row = table.getRow(id);
357
        ITreeSelectionNode newNode = new ITreeSelectionNode(row);
358
        this.mapNode.put(Integer.valueOf(id), newNode);
359
 
360
        if (id > 1) {
361
            if (nodePere != null && idPere > 1) {
362
                addNode(newNode, nodePere);
363
            } else {
364
                if (idPere == 1) {
365
                    addNode(newNode, rootNode);
366
                }
367
            }
368
        }
369
    }
370
 
371
    /**
372
     * Ajoute un noeud dans l'arbre dans l'ordre alphabétique
373
     *
374
     * @param nodeToAdd
375
     * @param nodeParent
376
     */
377
    private void addNode(ITreeSelectionNode nodeToAdd, ITreeSelectionNode nodeParent) {
378
        int n = 0;
379
        for (; n < nodeParent.getChildCount(); n++) {
380
            if (nodeToAdd.toString().compareToIgnoreCase(nodeParent.getChildAt(n).toString()) < 0) {
381
                break;
382
            }
383
        }
384
        model.insertNodeInto(nodeToAdd, nodeParent, n);
385
    }
386
 
387
    /**
388
     *
389
     * @param row
390
     * @param nodeParent
391
     */
392
    private void modifyNode(SQLRow row, ITreeSelectionNode node) {
393
        // for (int i = 0; i < node.getChildCount(); i++) {
394
        //
395
        // ITreeSelectionNode v = (ITreeSelectionNode) node.getChildAt(i);
396
        // if (v.getId() == row.getID()) {
397
        // v.setRow(row);
398
        // model.nodeChanged(v);
399
        // }
400
        //
401
        // }
402
        if (row.isArchived()) {
403
            // node.removeFromParent();
404
            model.removeNodeFromParent(node);
405
        } else {
406
            node.setRow(row);
407
            model.nodeChanged(node);
408
        }
409
    }
410
 
411
    /**
412
     * Suppression d'un noeud
413
     *
414
     * @param row
415
     * @param nodeParent
416
     */
417
    private void removeNode(SQLRow row, ITreeSelectionNode nodeParent) {
418
        for (int i = 0; i < nodeParent.getChildCount(); i++) {
419
 
420
            ITreeSelectionNode v = (ITreeSelectionNode) nodeParent.getChildAt(i);
421
            if (v.getId() == row.getID()) {
422
                model.removeNodeFromParent(v);
423
            }
424
 
425
        }
426
    }
427
 
428
    /**
429
     * Table listener permettant de rafraichir l'arbre
430
     *
431
     */
432
    private void setTableListener() {
433
        SQLTableListener listener = new SQLTableListener() {
434
            public void rowModified(SQLTable table, int id) {
435
                ITreeSelectionNode node = mapNode.get(Integer.valueOf(id));
436
                if (node != null) {
437
                    modifyNode(table.getRow(id), node);
438
                }
439
            }
440
 
441
            public void rowAdded(SQLTable table, int id) {
442
                SQLRow row = table.getRow(id);
443
                int idPere = row.getInt("ID_" + element.getTable().getName() + "_PERE");
444
 
445
                addNewNode(id, idPere);
446
            }
447
 
448
            public void rowDeleted(SQLTable table, int id) {
449
                ITreeSelectionNode node = mapNode.get(Integer.valueOf(id));
450
                for (int i = 0; i < node.getChildCount(); i++) {
451
                    removeNode(table.getRow(id), node);
452
                }
453
            }
454
        };
455
 
456
        this.element.getTable().addTableListener(listener);
457
    }
458
 
459
    public String getValidationText() {
460
        return "Aucune valeur sélectionnée dans l'arbre";
461
    }
462
}