OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */
 
 package org.openconcerto.erp.core.sales.pos.ui;

import org.openconcerto.erp.core.sales.pos.model.Article;
import org.openconcerto.erp.core.sales.pos.model.Categorie;
import org.openconcerto.ui.touch.ScrollableList;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class ArticleSearchPanel extends JPanel implements CaisseListener {
    private final ScrollableList list;
    private final CaisseControler controler;
    private final JTextField textField = new JTextField();

    public ArticleSearchPanel(final CaisseControler controler) {
        this.controler = controler;
        this.controler.addCaisseListener(this);
        this.setLayout(new GridBagLayout());
        final GridBagConstraints c = new GridBagConstraints();
        final FilteredListModel model = new FilteredListModel();
        final Font f1;
        final Font f2;

        if (this.controler.getPOSConf().getScreenWidth() < 1280) {
            f1 = new Font("Arial", Font.PLAIN, 21);
            f2 = new Font("Arial", Font.PLAIN, 14);
        } else {
            f1 = new Font("Arial", Font.PLAIN, 24);
            f2 = new Font("Arial", Font.PLAIN, 16);
        }

        setBackground(new Color(230, 230, 230));
        this.list = new ScrollableList(model) {
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                g.setColor(Color.LIGHT_GRAY);
                g.drawLine(0, 0, 0, this.getHeight());
            }

            @Override
            public void paintCell(Graphics g, Object object, int index, boolean isSelected, int posY) {
                if (object instanceof Article) {
                    Article article = (Article) object;
                    ArticleSelector.paintArticle(f1, g, article, isSelected, posY, this.getWidth(), this.getCellHeight(), 36, 10);
                    if (Categorie.getFavoriteProducts().contains(article)) {
                        g.setColor(Color.ORANGE);
                        g.fillRect(0, posY, 6, this.getCellHeight());
                    }
                } else if (object instanceof Categorie) {
                    Categorie c = (Categorie) object;
                    paintCategorie(f1, f2, g, c, isSelected, posY, this.getWidth(), this.getCellHeight());

                }
            }

            @Override
            public void mouseReleased(MouseEvent event) {
                if ((event.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK) {
                    final Object obj = getSelectedValue();
                    if (obj instanceof Article) {
                        Article product = (Article) obj;
                        Categorie.toggleFavoriteState(product);
                        controler.saveFavoriteProductsIds(Categorie.getFavoriteProducts());
                        model.setFilter(ArticleSearchPanel.this.textField.getText());
                        ArticleSearchPanel.this.list.scrollToOffset(0);
                    }
                } else {
                    super.mouseReleased(event);
                }
            }
        };

        // Bar
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        final StatusBar bar = new StatusBar();
        final POSButton bSwitch = new POSButton("-");
        bSwitch.setForeground(Color.WHITE);
        bSwitch.setBackground(CaissePanel.DARK_BLUE);
        bar.setLayout(new FlowLayout(FlowLayout.LEFT));
        bar.add(bSwitch);
        bSwitch.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                controler.switchListMode();

            }
        });

        bar.setTitle("Articles");
        bar.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                ArticleSearchPanel.this.list.scrollToOffset(0);
            }
        });

        c.fill = GridBagConstraints.BOTH;
        c.gridwidth = 2;
        this.add(bar, c);

        // List
        c.weighty = 1;
        c.gridy++;
        this.list.setBackground(new Color(240, 240, 240));
        this.add(this.list, c);

        // Separator
        c.weighty = 0;

        JPanel pBottom = new JPanel();
        pBottom.setOpaque(true);
        pBottom.setBackground(CaissePanel.DARK_BLUE);
        pBottom.setLayout(new BorderLayout(3, 3));

        // Icon and text

        final JLabel label = new JLabel(new ImageIcon(this.getClass().getResource("search.png")));

        pBottom.add(label, BorderLayout.WEST);
        pBottom.setBorder(BorderFactory.createLineBorder(CaissePanel.DARK_BLUE, 3));
        this.textField.setBorder(BorderFactory.createLineBorder(CaissePanel.DARK_BLUE, 1));
        this.textField.setFont(f1);

        this.textField.setFont(f1);
        pBottom.add(this.textField, BorderLayout.CENTER);
        c.gridy++;
        c.weightx = 1;
        c.gridwidth = 2;
        this.add(pBottom, c);

        this.textField.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void removeUpdate(DocumentEvent e) {
                changedUpdate(e);
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                changedUpdate(e);
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                model.setFilter(ArticleSearchPanel.this.textField.getText());
                controler.setArticleSelected(null);
            }
        });
        this.list.addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                Object sel = ArticleSearchPanel.this.list.getSelectedValue();
                if (sel != null && !e.getValueIsAdjusting()) {
                    if (sel instanceof Article) {
                        Article article = (Article) sel;
                        controler.setArticleSelected(article);

                    }
                }

            }
        });

        this.list.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                Object sel = ArticleSearchPanel.this.list.getSelectedValue();
                if (sel != null) {
                    int nb = e.getClickCount();
                    if (nb == 1) {
                        if (sel instanceof Article) {
                            Article article = (Article) sel;
                            controler.setArticleSelected(article);
                            controler.addArticle(article);
                        }
                    } else if (nb > 1) {
                        Article article = (Article) sel;
                        controler.incrementArticle(article);
                        controler.setArticleSelected(article);
                    }
                }

            }
        });

    }

    public void paintCategorie(final Font f, Font f2, Graphics g, Categorie c, boolean isSelected, int posY, int cellWidth, int cellHeight) {
        g.setFont(f);

        g.setColor(Color.WHITE);

        g.fillRect(0, posY, cellWidth, cellHeight);

        //
        g.setColor(Color.GRAY);
        g.drawLine(0, posY + cellHeight - 1, cellWidth, posY + cellHeight - 1);

        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        String label = c.getName();
        final int MAX_WIDTH = 36;
        final int MAX_WIDTH2 = 48;
        if (label.length() > MAX_WIDTH * 2) {
            label = label.substring(0, MAX_WIDTH * 2) + "...";
        }
        String label2 = getCategoriePath(c);
        if (label2 != null) {

            if (label2.length() > MAX_WIDTH2) {
                label2 = label2.substring(0, MAX_WIDTH2) + "...";
            }
        }
        g.setColor(Color.BLACK);
        if (label2 == null) {
            g.drawString(label, 10, posY + 39);
        } else {
            g.drawString(label, 10, posY + 26);
            g.setColor(Color.DARK_GRAY);
            g.setFont(f2);
            g.drawString(label2, 10, posY + 52);
        }
    }

    private Map<Categorie, String> categoryCache = new HashMap<Categorie, String>();

    private String getCategoriePath(Categorie c) {
        if (c.getParent() == null) {
            return null;
        }
        String storedString = this.categoryCache.get(c);
        if (storedString != null) {
            return storedString;
        }

        Categorie parent = c.getParent();
        String s = "";

        Set<Categorie> set = new HashSet<Categorie>();
        set.add(c);
        while (parent != null) {
            if (set.contains(parent)) {
                System.err.println("ArticleSearchPanel.getCategoriePath() loop detected for category " + c + " " + parent + " already in " + set);
                break;
            }
            set.add(parent);
            if (s.length() > 0) {
                s = parent.getName() + " / " + s;
            } else {
                s = parent.getName();
            }

            parent = c.getParent();

        }
        this.categoryCache.put(c, s);
        return s;
    }

    @Override
    public void caisseStateChanged() {
        final Article articleSelected = this.controler.getArticleSelected();
        System.err.println("ArticleSearchPanel.caisseStateChanged() article selected : " + articleSelected);
        if (articleSelected == null) {
            this.list.clearSelection();
            return;
        }
        Object selectedValue = null;
        try {
            selectedValue = this.list.getSelectedValue();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (selectedValue == null || !articleSelected.equals(selectedValue)) {
            boolean found = this.list.setSelectedValue(articleSelected, true);
            if (!found) {
                this.list.clearSelection();
            }
        }
    }
}