OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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