OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 19 | Go to most recent revision | Details | 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
 
275
    public boolean isValidated() {
276
 
277
        return true;
278
    }
279
 
280
    @Override
281
    public void init(SQLRowItemView v) {
282
        // final SQLElement element;
283
        if (this.element == null) {
284
            final SQLTable foreignTable = v.getField().getTable().getDBSystemRoot().getGraph().getForeignTable(v.getField());
285
            this.element = Configuration.getInstance().getDirectory().getElement(foreignTable);
286
        }
287
        // else
288
        // element = this.element;
289
        this.helper = new EmptyObjectHelper(this, new Predicate() {
290
            public boolean evaluate(Object object) {
291
                final Integer val = ((Number) object).intValue();
292
                return val.intValue() <= EMPTY_ID;
293
            }
294
        });
295
        initTree();
296
    }
297
 
298
    public void setValue(Integer val) {
299
        if (val == null)
300
            val = EMPTY_ID;
301
        // TODO Auto-generated method stub
302
        ITreeSelectionNode v = this.mapNode.get(val);
303
        if (v.getId() == val) {
304
            this.setExpandsSelectedPaths(true);
305
            this.setSelectionPath(new TreePath(v.getPath()));
306
        }
307
 
308
        // System.err.println("Set value Tree " + val);
309
        // if (this.rootNode != null) {
310
        // for (int i = 0; i < this.rootNode.getChildCount(); i++) {
311
        // Object o = this.rootNode.getChildAt(i);
312
        // if (o instanceof FamilleTreeNode) {
313
        // FamilleTreeNode v = (FamilleTreeNode) o;
314
        // if (v.getId() == val) {
315
        // System.err.println("Select TreeNode row Id " + val);
316
        // this.setExpandsSelectedPaths(true);
317
        // this.setSelectionPath(new TreePath(v.getPath()));
318
        // }
319
        // }
320
        // }
321
        // }
322
    }
323
 
324
    private void loadTree() {
325
 
326
        SQLTable table = this.element.getTable();
327
        SQLSelect sel = new SQLSelect(table.getBase());
328
 
329
        sel.addSelect(table.getKey());
330
        sel.addSelect(table.getField("ID_" + table.getName() + "_PERE"));
331
 
332
        List l = (List) table.getBase().getDataSource().execute(sel.asString(), new ArrayListHandler());
333
 
334
        if (l != null) {
335
            for (int i = 0; i < l.size(); i++) {
336
                Object[] tmp = (Object[]) l.get(i);
337
                addNewNode(((Number) tmp[0]).intValue(), ((Number) tmp[1]).intValue());
338
            }
339
        }
340
    }
341
 
342
    /**
343
     * Ajoute une famille dans l'arbre
344
     *
345
     * @param id
346
     * @param idPere
347
     */
348
    private void addNewNode(int id, int idPere) {
349
        SQLTable table = this.element.getTable();
350
        ITreeSelectionNode nodePere = this.mapNode.get(Integer.valueOf(idPere));
351
        SQLRow row = table.getRow(id);
352
        ITreeSelectionNode newNode = new ITreeSelectionNode(row);
353
        this.mapNode.put(Integer.valueOf(id), newNode);
354
 
355
        if (id > 1) {
356
            if (nodePere != null && idPere > 1) {
357
                addNode(newNode, nodePere);
358
            } else {
359
                if (idPere == 1) {
360
                    addNode(newNode, rootNode);
361
                }
362
            }
363
        }
364
    }
365
 
366
    /**
367
     * Ajoute un noeud dans l'arbre dans l'ordre alphabétique
368
     *
369
     * @param nodeToAdd
370
     * @param nodeParent
371
     */
372
    private void addNode(ITreeSelectionNode nodeToAdd, ITreeSelectionNode nodeParent) {
373
        int n = 0;
374
        for (; n < nodeParent.getChildCount(); n++) {
375
            if (nodeToAdd.toString().compareToIgnoreCase(nodeParent.getChildAt(n).toString()) < 0) {
376
                break;
377
            }
378
        }
379
        model.insertNodeInto(nodeToAdd, nodeParent, n);
380
    }
381
 
382
    /**
383
     *
384
     * @param row
385
     * @param nodeParent
386
     */
387
    private void modifyNode(SQLRow row, ITreeSelectionNode node) {
388
        // for (int i = 0; i < node.getChildCount(); i++) {
389
        //
390
        // ITreeSelectionNode v = (ITreeSelectionNode) node.getChildAt(i);
391
        // if (v.getId() == row.getID()) {
392
        // v.setRow(row);
393
        // model.nodeChanged(v);
394
        // }
395
        //
396
        // }
397
        if (row.isArchived()) {
398
            // node.removeFromParent();
399
            model.removeNodeFromParent(node);
400
        } else {
401
            node.setRow(row);
402
            model.nodeChanged(node);
403
        }
404
    }
405
 
406
    /**
407
     * Suppression d'un noeud
408
     *
409
     * @param row
410
     * @param nodeParent
411
     */
412
    private void removeNode(SQLRow row, ITreeSelectionNode nodeParent) {
413
        for (int i = 0; i < nodeParent.getChildCount(); i++) {
414
 
415
            ITreeSelectionNode v = (ITreeSelectionNode) nodeParent.getChildAt(i);
416
            if (v.getId() == row.getID()) {
417
                model.removeNodeFromParent(v);
418
            }
419
 
420
        }
421
    }
422
 
423
    /**
424
     * Table listener permettant de rafraichir l'arbre
425
     *
426
     */
427
    private void setTableListener() {
428
        SQLTableListener listener = new SQLTableListener() {
429
            public void rowModified(SQLTable table, int id) {
430
                ITreeSelectionNode node = mapNode.get(Integer.valueOf(id));
431
                if (node != null) {
432
                    modifyNode(table.getRow(id), node);
433
                }
434
            }
435
 
436
            public void rowAdded(SQLTable table, int id) {
437
                SQLRow row = table.getRow(id);
438
                int idPere = row.getInt("ID_" + element.getTable().getName() + "_PERE");
439
 
440
                addNewNode(id, idPere);
441
            }
442
 
443
            public void rowDeleted(SQLTable table, int id) {
444
                ITreeSelectionNode node = mapNode.get(Integer.valueOf(id));
445
                for (int i = 0; i < node.getChildCount(); i++) {
446
                    removeNode(table.getRow(id), node);
447
                }
448
            }
449
        };
450
 
451
        this.element.getTable().addTableListener(listener);
452
    }
453
 
454
    public String getValidationText() {
455
        return "Aucune valeur sélectionnée dans l'arbre";
456
    }
457
}