OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 149 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
83 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.core.sales.pos.ui;
15
 
16
import org.openconcerto.erp.core.sales.pos.model.Article;
17
import org.openconcerto.erp.core.sales.pos.model.Categorie;
18
import org.openconcerto.ui.touch.ScrollableList;
19
 
174 ilm 20
import java.awt.BorderLayout;
83 ilm 21
import java.awt.Color;
142 ilm 22
import java.awt.FlowLayout;
83 ilm 23
import java.awt.Font;
24
import java.awt.Graphics;
25
import java.awt.Graphics2D;
26
import java.awt.GridBagConstraints;
27
import java.awt.GridBagLayout;
28
import java.awt.RenderingHints;
142 ilm 29
import java.awt.event.ActionEvent;
30
import java.awt.event.ActionListener;
83 ilm 31
import java.awt.event.MouseAdapter;
32
import java.awt.event.MouseEvent;
33
import java.util.HashMap;
34
import java.util.HashSet;
35
import java.util.Map;
36
import java.util.Set;
37
 
142 ilm 38
import javax.swing.BorderFactory;
83 ilm 39
import javax.swing.ImageIcon;
40
import javax.swing.JLabel;
41
import javax.swing.JPanel;
42
import javax.swing.JTextField;
43
import javax.swing.event.DocumentEvent;
44
import javax.swing.event.DocumentListener;
45
import javax.swing.event.ListSelectionEvent;
46
import javax.swing.event.ListSelectionListener;
47
 
174 ilm 48
public class ArticleSearchPanel extends JPanel implements CaisseListener {
83 ilm 49
    private final ScrollableList list;
50
    private final CaisseControler controler;
149 ilm 51
    private final JTextField textField = new JTextField();
83 ilm 52
 
53
    public ArticleSearchPanel(final CaisseControler controler) {
54
        this.controler = controler;
55
        this.controler.addCaisseListener(this);
56
        this.setLayout(new GridBagLayout());
57
        final GridBagConstraints c = new GridBagConstraints();
58
        final FilteredListModel model = new FilteredListModel();
174 ilm 59
        final Font f1;
60
        final Font f2;
61
 
62
        if (this.controler.getPOSConf().getScreenWidth() < 1280) {
63
            f1 = new Font("Arial", Font.PLAIN, 21);
64
            f2 = new Font("Arial", Font.PLAIN, 14);
65
        } else {
66
            f1 = new Font("Arial", Font.PLAIN, 24);
67
            f2 = new Font("Arial", Font.PLAIN, 16);
68
        }
69
 
70
        setBackground(new Color(230, 230, 230));
71
        this.list = new ScrollableList(model) {
83 ilm 72
            @Override
73
            public void paint(Graphics g) {
74
                super.paint(g);
174 ilm 75
                g.setColor(Color.LIGHT_GRAY);
83 ilm 76
                g.drawLine(0, 0, 0, this.getHeight());
77
            }
78
 
79
            @Override
80
            public void paintCell(Graphics g, Object object, int index, boolean isSelected, int posY) {
81
                if (object instanceof Article) {
82
                    Article article = (Article) object;
83
                    ArticleSelector.paintArticle(f1, g, article, isSelected, posY, this.getWidth(), this.getCellHeight(), 36, 10);
149 ilm 84
                    if (Categorie.getFavoriteProducts().contains(article)) {
85
                        g.setColor(Color.ORANGE);
86
                        g.fillRect(0, posY, 6, this.getCellHeight());
87
                    }
83 ilm 88
                } else if (object instanceof Categorie) {
89
                    Categorie c = (Categorie) object;
90
                    paintCategorie(f1, f2, g, c, isSelected, posY, this.getWidth(), this.getCellHeight());
91
 
92
                }
93
            }
149 ilm 94
 
95
            @Override
96
            public void mouseReleased(MouseEvent event) {
97
                if ((event.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK) {
98
                    final Object obj = getSelectedValue();
174 ilm 99
                    if (obj instanceof Article) {
149 ilm 100
                        Article product = (Article) obj;
101
                        Categorie.toggleFavoriteState(product);
102
                        controler.saveFavoriteProductsIds(Categorie.getFavoriteProducts());
174 ilm 103
                        model.setFilter(ArticleSearchPanel.this.textField.getText());
104
                        ArticleSearchPanel.this.list.scrollToOffset(0);
149 ilm 105
                    }
106
                } else {
107
                    super.mouseReleased(event);
108
                }
109
            }
83 ilm 110
        };
111
 
112
        // Bar
113
        c.gridx = 0;
114
        c.gridy = 0;
115
        c.weightx = 1;
142 ilm 116
        final StatusBar bar = new StatusBar();
117
        final POSButton bSwitch = new POSButton("-");
118
        bSwitch.setForeground(Color.WHITE);
119
        bSwitch.setBackground(CaissePanel.DARK_BLUE);
120
        bar.setLayout(new FlowLayout(FlowLayout.LEFT));
121
        bar.add(bSwitch);
122
        bSwitch.addActionListener(new ActionListener() {
123
 
83 ilm 124
            @Override
142 ilm 125
            public void actionPerformed(ActionEvent e) {
83 ilm 126
                controler.switchListMode();
142 ilm 127
 
83 ilm 128
            }
129
        });
142 ilm 130
 
83 ilm 131
        bar.setTitle("Articles");
149 ilm 132
        bar.addMouseListener(new MouseAdapter() {
133
            @Override
134
            public void mousePressed(MouseEvent e) {
174 ilm 135
                ArticleSearchPanel.this.list.scrollToOffset(0);
149 ilm 136
            }
137
        });
138
 
83 ilm 139
        c.fill = GridBagConstraints.BOTH;
140
        c.gridwidth = 2;
141
        this.add(bar, c);
142
 
143
        // List
144
        c.weighty = 1;
145
        c.gridy++;
174 ilm 146
        this.list.setBackground(new Color(240, 240, 240));
147
        this.add(this.list, c);
148
 
83 ilm 149
        // Separator
150
        c.weighty = 0;
151
 
174 ilm 152
        JPanel pBottom = new JPanel();
153
        pBottom.setOpaque(true);
154
        pBottom.setBackground(CaissePanel.DARK_BLUE);
155
        pBottom.setLayout(new BorderLayout(3, 3));
156
 
83 ilm 157
        // Icon and text
174 ilm 158
 
83 ilm 159
        final JLabel label = new JLabel(new ImageIcon(this.getClass().getResource("search.png")));
149 ilm 160
 
174 ilm 161
        pBottom.add(label, BorderLayout.WEST);
162
        pBottom.setBorder(BorderFactory.createLineBorder(CaissePanel.DARK_BLUE, 3));
163
        this.textField.setBorder(BorderFactory.createLineBorder(CaissePanel.DARK_BLUE, 1));
164
        this.textField.setFont(f1);
165
 
166
        this.textField.setFont(f1);
167
        pBottom.add(this.textField, BorderLayout.CENTER);
168
        c.gridy++;
83 ilm 169
        c.weightx = 1;
174 ilm 170
        c.gridwidth = 2;
171
        this.add(pBottom, c);
83 ilm 172
 
174 ilm 173
        this.textField.getDocument().addDocumentListener(new DocumentListener() {
83 ilm 174
 
175
            @Override
176
            public void removeUpdate(DocumentEvent e) {
177
                changedUpdate(e);
178
            }
179
 
180
            @Override
181
            public void insertUpdate(DocumentEvent e) {
182
                changedUpdate(e);
183
            }
184
 
185
            @Override
186
            public void changedUpdate(DocumentEvent e) {
174 ilm 187
                model.setFilter(ArticleSearchPanel.this.textField.getText());
149 ilm 188
                controler.setArticleSelected(null);
83 ilm 189
            }
190
        });
174 ilm 191
        this.list.addListSelectionListener(new ListSelectionListener() {
83 ilm 192
 
193
            @Override
174 ilm 194
            public void valueChanged(ListSelectionEvent e) {
195
                Object sel = ArticleSearchPanel.this.list.getSelectedValue();
196
                if (sel != null && !e.getValueIsAdjusting()) {
197
                    if (sel instanceof Article) {
198
                        Article article = (Article) sel;
199
                        controler.setArticleSelected(article);
200
 
201
                    }
202
                }
203
 
204
            }
205
        });
206
 
207
        this.list.addMouseListener(new MouseAdapter() {
208
            @Override
83 ilm 209
            public void mouseClicked(MouseEvent e) {
174 ilm 210
                Object sel = ArticleSearchPanel.this.list.getSelectedValue();
211
                if (sel != null) {
212
                    int nb = e.getClickCount();
213
                    if (nb == 1) {
214
                        if (sel instanceof Article) {
215
                            Article article = (Article) sel;
216
                            controler.setArticleSelected(article);
217
                            controler.addArticle(article);
218
                        }
219
                    } else if (nb > 1) {
83 ilm 220
                        Article article = (Article) sel;
221
                        controler.incrementArticle(article);
222
                        controler.setArticleSelected(article);
223
                    }
224
                }
174 ilm 225
 
83 ilm 226
            }
227
        });
228
 
229
    }
230
 
231
    public void paintCategorie(final Font f, Font f2, Graphics g, Categorie c, boolean isSelected, int posY, int cellWidth, int cellHeight) {
232
        g.setFont(f);
233
 
234
        g.setColor(Color.WHITE);
235
 
236
        g.fillRect(0, posY, cellWidth, cellHeight);
237
 
238
        //
239
        g.setColor(Color.GRAY);
240
        g.drawLine(0, posY + cellHeight - 1, cellWidth, posY + cellHeight - 1);
241
 
242
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
243
 
244
        String label = c.getName();
245
        final int MAX_WIDTH = 36;
246
        final int MAX_WIDTH2 = 48;
247
        if (label.length() > MAX_WIDTH * 2) {
248
            label = label.substring(0, MAX_WIDTH * 2) + "...";
249
        }
250
        String label2 = getCategoriePath(c);
251
        if (label2 != null) {
252
 
253
            if (label2.length() > MAX_WIDTH2) {
254
                label2 = label2.substring(0, MAX_WIDTH2) + "...";
255
            }
256
        }
257
        g.setColor(Color.BLACK);
258
        if (label2 == null) {
259
            g.drawString(label, 10, posY + 39);
260
        } else {
261
            g.drawString(label, 10, posY + 26);
262
            g.setColor(Color.DARK_GRAY);
263
            g.setFont(f2);
264
            g.drawString(label2, 10, posY + 52);
265
        }
266
    }
267
 
268
    private Map<Categorie, String> categoryCache = new HashMap<Categorie, String>();
269
 
270
    private String getCategoriePath(Categorie c) {
271
        if (c.getParent() == null) {
272
            return null;
273
        }
174 ilm 274
        String storedString = this.categoryCache.get(c);
83 ilm 275
        if (storedString != null) {
276
            return storedString;
277
        }
278
 
279
        Categorie parent = c.getParent();
280
        String s = "";
281
 
282
        Set<Categorie> set = new HashSet<Categorie>();
283
        set.add(c);
284
        while (parent != null) {
285
            if (set.contains(parent)) {
286
                System.err.println("ArticleSearchPanel.getCategoriePath() loop detected for category " + c + " " + parent + " already in " + set);
287
                break;
288
            }
289
            set.add(parent);
290
            if (s.length() > 0) {
291
                s = parent.getName() + " / " + s;
292
            } else {
293
                s = parent.getName();
294
            }
295
 
296
            parent = c.getParent();
297
 
298
        }
174 ilm 299
        this.categoryCache.put(c, s);
83 ilm 300
        return s;
301
    }
302
 
303
    @Override
304
    public void caisseStateChanged() {
174 ilm 305
        final Article articleSelected = this.controler.getArticleSelected();
149 ilm 306
        System.err.println("ArticleSearchPanel.caisseStateChanged() article selected : " + articleSelected);
83 ilm 307
        if (articleSelected == null) {
174 ilm 308
            this.list.clearSelection();
83 ilm 309
            return;
310
        }
311
        Object selectedValue = null;
312
        try {
174 ilm 313
            selectedValue = this.list.getSelectedValue();
83 ilm 314
        } catch (Exception e) {
315
            e.printStackTrace();
316
        }
149 ilm 317
        if (selectedValue == null || !articleSelected.equals(selectedValue)) {
174 ilm 318
            boolean found = this.list.setSelectedValue(articleSelected, true);
149 ilm 319
            if (!found) {
174 ilm 320
                this.list.clearSelection();
149 ilm 321
            }
83 ilm 322
        }
323
    }
324
}