OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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