Dépôt officiel du code source de l'ERP OpenConcerto
Rev 149 | Go to most recent revision | 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();
}
}
}
}