OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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