Dépôt officiel du code source de l'ERP OpenConcerto
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/48.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/48.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/LabelPanel.java |
---|
15,11 → 15,9 |
import javax.swing.JPanel; |
import org.openconcerto.sql.model.SQLRowAccessor; |
public class LabelPanel extends JPanel implements Printable { |
private List<? extends SQLRowAccessor> list; |
private List<? extends Label> list; |
private int lines; |
private int columns; |
private Boolean[][] mask; |
29,7 → 27,7 |
private int topMargin; |
private int leftMargin; |
public LabelPanel(List<? extends SQLRowAccessor> list, int l, int c, LabelRenderer labelRenderer) { |
public LabelPanel(List<? extends Label> list, int l, int c, LabelRenderer labelRenderer) { |
this.list = list; |
this.renderer = labelRenderer; |
setSizeLayoutSize(l, c); |
48,6 → 46,11 |
}); |
} |
public void setList(List<? extends Label> list) { |
this.list = list; |
repaint(); |
} |
private void setSizeLayoutSize(int l, int c) { |
this.lines = l; |
this.columns = c; |
102,7 → 105,7 |
g.drawRect(x, y, w, h); |
// Label |
if (rowIndex < list.size()) { |
SQLRowAccessor row = list.get(rowIndex); |
Label row = list.get(rowIndex); |
renderer.paintLabel(g, row, x, y, w, h, 10f); |
} |
rowIndex++; |
169,7 → 172,7 |
for (int j = 0; j < this.columns; j++) { |
boolean mask = this.mask[i][j]; |
if (!mask && rowIndex < list.size()) { |
SQLRowAccessor row = list.get(rowIndex); |
Label row = list.get(rowIndex); |
renderer.paintLabel(g, row, j * w + imageableX, i * h + imageableY, w, h, 10f); |
} |
rowIndex++; |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/96.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/96.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/logo.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/logo.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/GS1Frame.java |
---|
New file |
0,0 → 1,1049 |
package org.openconcerto.modules.label; |
import java.awt.BasicStroke; |
import java.awt.Color; |
import java.awt.Component; |
import java.awt.Dimension; |
import java.awt.Graphics; |
import java.awt.Graphics2D; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.Image; |
import java.awt.Insets; |
import java.awt.RenderingHints; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.awt.event.WindowAdapter; |
import java.awt.event.WindowEvent; |
import java.awt.geom.AffineTransform; |
import java.awt.image.BufferedImage; |
import java.awt.print.PrinterException; |
import java.awt.print.PrinterJob; |
import java.beans.PropertyChangeEvent; |
import java.beans.PropertyChangeListener; |
import java.io.BufferedReader; |
import java.io.ByteArrayOutputStream; |
import java.io.DataOutputStream; |
import java.io.File; |
import java.io.FileInputStream; |
import java.io.FileNotFoundException; |
import java.io.FileOutputStream; |
import java.io.IOException; |
import java.io.InputStream; |
import java.io.StringReader; |
import java.net.Socket; |
import java.nio.charset.StandardCharsets; |
import java.text.SimpleDateFormat; |
import java.util.ArrayList; |
import java.util.Date; |
import java.util.List; |
import java.util.Properties; |
import javax.print.DocFlavor; |
import javax.print.DocPrintJob; |
import javax.print.PrintService; |
import javax.print.SimpleDoc; |
import javax.swing.ButtonGroup; |
import javax.swing.ImageIcon; |
import javax.swing.JButton; |
import javax.swing.JCheckBox; |
import javax.swing.JComponent; |
import javax.swing.JFrame; |
import javax.swing.JLabel; |
import javax.swing.JOptionPane; |
import javax.swing.JPanel; |
import javax.swing.JRadioButton; |
import javax.swing.JSeparator; |
import javax.swing.JSpinner; |
import javax.swing.JSplitPane; |
import javax.swing.JTabbedPane; |
import javax.swing.JTextField; |
import javax.swing.SpinnerNumberModel; |
import javax.swing.SwingConstants; |
import javax.swing.SwingUtilities; |
import javax.swing.UIManager; |
import javax.swing.UnsupportedLookAndFeelException; |
import javax.swing.event.ChangeEvent; |
import javax.swing.event.ChangeListener; |
import javax.swing.event.DocumentEvent; |
import javax.swing.event.DocumentListener; |
import javax.swing.text.AbstractDocument; |
import javax.swing.text.PlainDocument; |
import org.openconcerto.modules.label.filter.BatchDocumentFilter; |
import org.openconcerto.modules.label.filter.EANDocumentFilter; |
import org.openconcerto.modules.label.filter.LimitDocumentFilter; |
import org.openconcerto.modules.label.filter.NumberOfProductDocumentFilter; |
import org.openconcerto.modules.label.gs1.GS1AIElements; |
import org.openconcerto.modules.label.gs1.GS1Util; |
import org.openconcerto.ui.JDate; |
import uk.org.okapibarcode.backend.Code128; |
import uk.org.okapibarcode.backend.DataMatrix; |
import uk.org.okapibarcode.backend.DataMatrix.ForceMode; |
import uk.org.okapibarcode.backend.Ean; |
import uk.org.okapibarcode.backend.Symbol; |
import uk.org.okapibarcode.output.Java2DRenderer; |
public class GS1Frame extends JFrame { |
private final SimpleDateFormat dfDate = new SimpleDateFormat("yyMMdd"); |
private final JTextField textSupplier = new JTextField(20); |
private final JTextField textName = new JTextField(20); |
private final JTextField textEAN = new JTextField(14); |
private final JTextField textBatch = new JTextField(20); |
private final JSpinner portZPL = new JSpinner(new SpinnerNumberModel(9100, 24, 10000, 1)); |
private final JLabel labelEan = new JLabel("EAN 13/14", SwingConstants.RIGHT); |
private final JTextField textNumberOfProducts = new JTextField(12); |
private final JSpinner labelsSpinner = new JSpinner(new SpinnerNumberModel(5, 0, 9000, 1)); |
private final JTextField labelBarCode = new JTextField(64); |
private final JDate dateDLUODLC = new JDate(); |
private final JRadioButton b1 = new JRadioButton("DDM/DLUO"); |
private final JCheckBox checkIgnoreMargins = new JCheckBox("Ignorer les marges de l'imprimante"); |
private final JRadioButton twoPerPage = new JRadioButton("2"); |
private final JRadioButton fourPerPage = new JRadioButton("4"); |
private final JRadioButton radioZPLUSB = new JRadioButton("imprimante locale"); |
private final JTextField textIP = new JTextField(20); |
private final JTabbedPane tabs = new JTabbedPane(); |
private LabelPanel labelPanel; |
private BufferedImage barcodeImage = null; |
private BufferedImage barcodeImageBatch = null; |
private BufferedImage barcodeDatamatrix = null; |
private final Properties properties = new Properties(); |
public GS1Frame() { |
super("Code à barres GS1-128"); |
final File file = new File("openconcerto-gs1.properties"); |
if (file.exists()) { |
try { |
properties.load(new FileInputStream(file)); |
} catch (IOException e) { |
e.printStackTrace(); |
} |
} |
final JSplitPane split = new JSplitPane(); |
final JPanel left = createLeftContent(); |
final JComponent right = createRightContent(); |
split.setLeftComponent(left); |
split.setRightComponent(right); |
this.setContentPane(split); |
split.setEnabled(false); |
try { |
updateList(); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
this.addWindowListener(new WindowAdapter() { |
@Override |
public void windowClosing(WindowEvent e) { |
try { |
saveProperties(); |
} catch (IOException e1) { |
e1.printStackTrace(); |
} |
dispose(); |
} |
}); |
} |
public void saveProperties() throws FileNotFoundException, IOException { |
properties.setProperty("supplier", this.textSupplier.getText()); |
properties.setProperty("product", this.textName.getText()); |
properties.setProperty("ean", this.textEAN.getText()); |
properties.setProperty("nbOfProdcuts", this.textNumberOfProducts.getText()); |
properties.setProperty("batch", this.textBatch.getText()); |
final Date value = this.dateDLUODLC.getValue(); |
if (value != null) { |
properties.setProperty("sellByDate", String.valueOf(value.getTime())); |
} else { |
properties.setProperty("sellByDate", ""); |
} |
properties.setProperty("sellBy", b1.isSelected() ? "true" : "false"); |
properties.setProperty("nbLabels", this.labelsSpinner.getValue().toString()); |
properties.setProperty("labelsPerPage", fourPerPage.isSelected() ? "4" : "2"); |
properties.setProperty("ignoreMargin", checkIgnoreMargins.isSelected() ? "true" : "false"); |
properties.setProperty("usbPrinter", this.radioZPLUSB.isSelected() ? "true" : "false"); |
properties.setProperty("zplIP", this.textIP.getText()); |
properties.setProperty("zplPort", this.portZPL.getValue().toString()); |
properties.setProperty("tab", String.valueOf(tabs.getSelectedIndex())); |
final FileOutputStream out = new FileOutputStream("openconcerto-gs1.properties"); |
properties.store(out, ""); |
out.flush(); |
out.close(); |
} |
boolean isEANValid() { |
final String ean = this.textEAN.getText().trim(); |
if (ean.length() < 13) { |
return false; |
} |
final char cd1 = Ean.calcDigit(ean.substring(0, ean.length() - 1)); |
final char cd2 = ean.charAt(ean.length() - 1); |
return (cd1 == cd2); |
} |
private void updateList() throws Exception { |
this.barcodeImage = null; |
this.barcodeImageBatch = null; |
this.barcodeDatamatrix = null; |
this.labelPanel.setList(new ArrayList<>()); |
this.labelBarCode.setText(""); |
// Check EAN |
String ean = this.textEAN.getText().trim(); |
if (!isEANValid()) { |
this.labelEan.setForeground(Color.RED); |
} else { |
this.labelEan.setForeground(Color.BLACK); |
} |
if (ean.length() == 13) { |
this.labelEan.setText("EAN 13"); |
} else if (ean.length() == 14) { |
this.labelEan.setText("EAN 14"); |
} else { |
this.labelEan.setText("EAN invalide"); |
this.labelEan.setForeground(Color.RED); |
} |
if (!isEANValid()) { |
return; |
} |
int n = ((Number) this.labelsSpinner.getValue()).intValue(); |
this.labelBarCode.setText(this.getGS1().formatHumanReadable()); |
this.labelBarCode.setEditable(false); |
GS1Label l = new GS1Label(this.textSupplier.getText(), this.textName.getText(), this.getGS1()); |
List<GS1Label> list = new ArrayList<>(n); |
for (int i = 0; i < n; i++) { |
list.add(l); |
} |
this.labelPanel.setList(list); |
// Configure the barcode generator |
// adjust barcode width here |
// 32mm de hatu minimum |
// 0,495mm et 1,016mm pour largeur de barre |
GS1Util util = new GS1Util(); |
{ |
final GS1AIElements gs128 = getGS128(); |
Code128 dataMatrix = new Code128(); |
dataMatrix.setDataType(Symbol.DataType.GS1); |
dataMatrix.setBarHeight(70); |
dataMatrix.setContent(util.formatDataMatrix(gs128)); |
int magnification = 5; |
int borderSize = 3; |
this.barcodeImage = new BufferedImage((dataMatrix.getWidth() * magnification) + (2 * borderSize), (dataMatrix.getHeight() * magnification) + (2 * borderSize), BufferedImage.TYPE_INT_RGB); |
Graphics2D g2d = this.barcodeImage.createGraphics(); |
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
g2d.setColor(Color.WHITE); |
g2d.fillRect(0, 0, (dataMatrix.getWidth() * magnification) + (2 * borderSize), (dataMatrix.getHeight() * magnification) + (2 * borderSize)); |
Java2DRenderer renderer = new Java2DRenderer(g2d, magnification, Color.WHITE, Color.BLACK); |
renderer.render(dataMatrix); |
} |
final GS1AIElements gs128b = getGS128Batch(); |
if (!gs128b.isEmpty()) { |
Code128 dataMatrix = new Code128(); |
dataMatrix.setDataType(Symbol.DataType.GS1); |
dataMatrix.setBarHeight(90); |
dataMatrix.setContent(util.formatDataMatrix(gs128b)); |
int magnification = 4; |
int borderSize = 3; |
this.barcodeImageBatch = new BufferedImage((dataMatrix.getWidth() * magnification) + (2 * borderSize), (int) (dataMatrix.getHeight() * magnification) + (2 * borderSize), |
BufferedImage.TYPE_INT_RGB); |
Graphics2D g2d = this.barcodeImageBatch.createGraphics(); |
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
g2d.setColor(Color.WHITE); |
g2d.fillRect(0, 0, (dataMatrix.getWidth() * magnification) + (2 * borderSize), (dataMatrix.getHeight() * magnification) + (2 * borderSize)); |
Java2DRenderer renderer = new Java2DRenderer(g2d, magnification, Color.WHITE, Color.BLACK); |
renderer.render(dataMatrix); |
} |
{ |
String s = util.formatDataMatrix(getGS1()); |
DataMatrix dataMatrix = new DataMatrix(); |
dataMatrix.setDataType(Symbol.DataType.GS1); |
dataMatrix.setForceMode(ForceMode.SQUARE); |
dataMatrix.setContent(s); |
int magnification = 30; |
int borderSize = 3; |
this.barcodeDatamatrix = new BufferedImage((dataMatrix.getWidth() * magnification) + (2 * borderSize), (dataMatrix.getHeight() * magnification) + (2 * borderSize), |
BufferedImage.TYPE_INT_RGB); |
Graphics2D g2d = this.barcodeDatamatrix.createGraphics(); |
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
g2d.setColor(Color.WHITE); |
g2d.fillRect(0, 0, (dataMatrix.getWidth() * magnification) + (2 * borderSize), (dataMatrix.getHeight() * magnification) + (2 * borderSize)); |
Java2DRenderer renderer = new Java2DRenderer(g2d, magnification, Color.WHITE, Color.BLACK); |
renderer.render(dataMatrix); |
} |
// ImageIO.write(barcodeImage, "PNG", new File("barcode.png")); |
// ImageIO.write(barcodeImageBatch, "PNG", new File("barcode2.png")); |
// ImageIO.write(barcodeDatamatrix, "PNG", new File("datamatrix.png")); |
} |
private JPanel createLeftContent() { |
final JPanel p = new JPanel(); |
p.setLayout(new GridBagLayout()); |
final GridBagConstraints c = new GridBagConstraints(); |
c.fill = GridBagConstraints.BOTH; |
c.gridy = 0; |
c.gridx = 0; |
c.gridwidth = 3; |
p.add(createLogo(), c); |
c.fill = GridBagConstraints.HORIZONTAL; |
c.gridwidth = 1; |
c.gridy++; |
c.anchor = GridBagConstraints.WEST; |
c.insets = new Insets(2, 3, 2, 2); |
// |
c.weightx = 0; |
c.gridwidth = 1; |
p.add(new JLabel("Fournisseur / fabricant", SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 1; |
c.gridwidth = 2; |
this.textSupplier.setText(properties.getProperty("supplier", "")); |
((AbstractDocument) this.textSupplier.getDocument()).setDocumentFilter(new LimitDocumentFilter(22)); |
p.add(this.textSupplier, c); |
// |
c.gridx = 0; |
c.gridy++; |
c.weightx = 0; |
c.gridwidth = 1; |
p.add(new JLabel("Désignation du produit", SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 1; |
c.gridwidth = 2; |
this.textName.setText(properties.getProperty("product", "Biscuit Extra")); |
((AbstractDocument) this.textName.getDocument()).setDocumentFilter(new LimitDocumentFilter(22)); |
p.add(this.textName, c); |
// EAN 13/14 |
c.gridx = 0; |
c.gridy++; |
c.weightx = 0; |
c.gridwidth = 1; |
p.add(this.labelEan, c); |
c.gridx++; |
c.weightx = 1; |
c.gridwidth = 2; |
this.textEAN.setText(properties.getProperty("ean", "7612345678900")); |
((AbstractDocument) this.textEAN.getDocument()).setDocumentFilter(new EANDocumentFilter()); |
p.add(this.textEAN, c); |
// nb de produit |
c.gridx = 0; |
c.gridy++; |
c.weightx = 0; |
c.gridwidth = 1; |
p.add(new JLabel("Nombre par carton", SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 1; |
c.gridwidth = 2; |
c.fill = GridBagConstraints.NONE; |
PlainDocument doc = (PlainDocument) this.textNumberOfProducts.getDocument(); |
doc.setDocumentFilter(new NumberOfProductDocumentFilter()); |
this.textNumberOfProducts.setText(properties.getProperty("nbOfProdcuts", "10")); |
p.add(this.textNumberOfProducts, c); |
// Numéro de lot |
c.gridx = 0; |
c.gridy++; |
c.weightx = 0; |
c.gridwidth = 1; |
c.fill = GridBagConstraints.HORIZONTAL; |
p.add(new JLabel("Lot", SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 1; |
c.gridwidth = 2; |
((AbstractDocument) this.textBatch.getDocument()).setDocumentFilter(new BatchDocumentFilter()); |
this.textBatch.setText(properties.getProperty("batch", "")); |
p.add(this.textBatch, c); |
// DLC |
c.gridx = 1; |
c.gridy++; |
c.weightx = 0; |
c.gridwidth = 1; |
p.add(this.b1, c); |
c.gridx++; |
c.weightx = 1; |
this.dateDLUODLC.setFormat(new SimpleDateFormat("dd/MM/yyyy")); |
if (!properties.getProperty("sellByDate", "").isEmpty()) { |
this.dateDLUODLC.setDateInMillis(Long.parseLong(properties.getProperty("sellByDate"))); |
} |
p.add(this.dateDLUODLC, c); |
// DLUO |
c.gridx = 1; |
c.gridy++; |
c.weightx = 0; |
JRadioButton b2 = new JRadioButton("DLC"); |
p.add(b2, c); |
c.gridx++; |
c.weightx = 1; |
this.b1.setSelected(properties.getProperty("sellBy", "true").equals("true")); |
b2.setSelected(!properties.getProperty("sellBy", "true").equals("true")); |
// Barcode |
c.gridx = 0; |
c.gridy++; |
c.weightx = 0; |
c.gridwidth = 3; |
p.add(new JLabel("Code GS1 complet de l'étiquette", SwingConstants.LEFT), c); |
c.gridy++; |
c.weightx = 1; |
this.labelBarCode.setFont(this.textBatch.getFont()); |
this.labelBarCode.setEnabled(false); |
p.add(this.labelBarCode, c); |
// Nombre d'étiquettes |
c.gridx = 0; |
c.gridy++; |
c.weightx = 0; |
c.gridwidth = 1; |
p.add(new JLabel("Nombre d'étiquettes", SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 0; |
c.fill = GridBagConstraints.NONE; |
this.labelsSpinner.setValue(Integer.parseInt(properties.getProperty("nbLabels", "4"))); |
p.add(this.labelsSpinner, c); |
final JPanel spacer = new JPanel(); |
spacer.setOpaque(false); |
c.gridy++; |
c.weighty = 1; |
p.add(spacer, c); |
final ButtonGroup gr = new ButtonGroup(); |
gr.add(this.b1); |
gr.add(b2); |
// Listeners |
final ChangeListener changeListener = new ChangeListener() { |
@Override |
public void stateChanged(ChangeEvent e) { |
try { |
updateList(); |
} catch (Exception ex) { |
ex.printStackTrace(); |
} |
} |
}; |
this.labelsSpinner.addChangeListener(changeListener); |
final DocumentListener dListener = new DocumentListener() { |
@Override |
public void removeUpdate(DocumentEvent e) { |
changedUpdate(e); |
} |
@Override |
public void insertUpdate(DocumentEvent e) { |
changedUpdate(e); |
} |
@Override |
public void changedUpdate(DocumentEvent e) { |
try { |
updateList(); |
} catch (Exception ex) { |
ex.printStackTrace(); |
} |
} |
}; |
this.textSupplier.getDocument().addDocumentListener(dListener); |
this.textName.getDocument().addDocumentListener(dListener); |
this.textEAN.getDocument().addDocumentListener(dListener); |
this.textNumberOfProducts.getDocument().addDocumentListener(dListener); |
this.textBatch.getDocument().addDocumentListener(dListener); |
this.dateDLUODLC.addValueListener(new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
try { |
updateList(); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
}); |
this.b1.addChangeListener(changeListener); |
b2.addChangeListener(changeListener); |
return p; |
} |
private Component createLogo() { |
final Image i1 = new ImageIcon(this.getClass().getResource("logo.png")).getImage(); |
final Image i2 = new ImageIcon(this.getClass().getResource("oc-qrcode.png")).getImage(); |
return new JComponent() { |
@Override |
public void paint(Graphics g) { |
super.paint(g); |
g.setColor(Color.WHITE); |
g.fillRect(0, 0, getWidth(), getHeight()); |
g.drawImage(i1, 0, 3, null); |
g.drawImage(i2, getWidth() - i2.getWidth(null), 0, null); |
g.setColor(Color.GRAY); |
g.drawLine(0, 58, getWidth(), 58); |
} |
@Override |
public Dimension getPreferredSize() { |
return new Dimension(200, 59); |
} |
}; |
} |
private JComponent createRightContent() { |
final JPanel panelA4 = new JPanel(); |
panelA4.setOpaque(false); |
panelA4.setLayout(new GridBagLayout()); |
final GridBagConstraints c = new GridBagConstraints(); |
c.fill = GridBagConstraints.HORIZONTAL; |
c.insets = new Insets(2, 3, 2, 2); |
c.gridx = 0; |
c.gridy = 0; |
panelA4.add(createToolBar(), c); |
c.gridy++; |
// panelA4.add(createToolBar2(), c); |
// c.gridy++; |
c.insets = new Insets(0, 0, 0, 0); |
panelA4.add(new JSeparator(JSeparator.HORIZONTAL), c); |
c.gridy++; |
c.weightx = 1; |
c.weighty = 1; |
c.fill = GridBagConstraints.BOTH; |
final int columnCount = fourPerPage.isSelected() ? 2 : 1; |
this.labelPanel = new LabelPanel(new ArrayList<Label>(), 2, columnCount, createRenderer()) { |
@Override |
public Dimension getPreferredSize() { |
return new Dimension(190 * 3, 280 * 3); |
} |
}; |
this.labelPanel.setIgnoreMargins(checkIgnoreMargins.isSelected()); |
panelA4.add(this.labelPanel, c); |
tabs.addTab("Feuilles A4", panelA4); |
tabs.addTab("Imprimante ZPL", createZPLPanel()); |
tabs.setSelectedIndex(Integer.parseInt(properties.getProperty("tab", "0"))); |
return tabs; |
} |
private Component createZPLPanel() { |
final JPanel panelZPL = new JPanel(); |
panelZPL.setOpaque(false); |
panelZPL.setLayout(new GridBagLayout()); |
final GridBagConstraints c = new GridBagConstraints(); |
c.fill = GridBagConstraints.HORIZONTAL; |
c.insets = new Insets(2, 3, 2, 2); |
c.gridx = 0; |
c.gridy = 0; |
c.weightx = 0; |
c.gridwidth = 1; |
c.anchor = GridBagConstraints.EAST; |
radioZPLUSB.setOpaque(false); |
panelZPL.add(radioZPLUSB, c); |
c.gridx += 5; |
c.weightx = 1; |
c.fill = GridBagConstraints.NONE; |
c.insets = new Insets(4, 3, 2, 4); |
final JButton buttonPrintZPL = new JButton("Imprimer"); |
buttonPrintZPL.setOpaque(false); |
panelZPL.add(buttonPrintZPL, c); |
c.insets = new Insets(2, 3, 2, 2); |
c.gridx = 0; |
c.gridy++; |
c.weightx = 0; |
c.fill = GridBagConstraints.HORIZONTAL; |
final JRadioButton radioZPLNetwork = new JRadioButton("imprimante réseau"); |
radioZPLNetwork.setOpaque(false); |
panelZPL.add(radioZPLNetwork, c); |
c.gridx++; |
panelZPL.add(new JLabel("Adresse"), c); |
c.gridx++; |
textIP.setText(properties.getProperty("zplIP", "192.168.1.50")); |
panelZPL.add(textIP, c); |
c.gridx++; |
panelZPL.add(new JLabel("Port"), c); |
this.portZPL.setValue(Integer.parseInt(properties.getProperty("zplPort", "9100"))); |
c.gridx++; |
panelZPL.add(this.portZPL, c); |
c.gridx = 0; |
c.gridy++; |
c.gridwidth = 6; |
radioZPLUSB.setSelected(properties.getProperty("usbPrinter", "true").equals("true")); |
radioZPLNetwork.setSelected(!properties.getProperty("usbPrinter", "true").equals("true")); |
final ButtonGroup g = new ButtonGroup(); |
g.add(radioZPLUSB); |
g.add(radioZPLNetwork); |
c.anchor = GridBagConstraints.NORTHWEST; |
panelZPL.add(new JLabel("L'impression nécessite une imprimante d'étiquettes compatible ZPL (Zebra ou autre)."), c); |
c.gridy++; |
c.weighty = 1; |
panelZPL.add(new JLabel("Vous pouvez paramétrer l'impression par défaut (largeur 6\" à 203 dpi) dans le fichier zpl.txt ."), c); |
buttonPrintZPL.addActionListener(new ActionListener() { |
@Override |
public void actionPerformed(ActionEvent e) { |
if (!isEANValid()) { |
JOptionPane.showMessageDialog(GS1Frame.this, "EAN invalide"); |
return; |
} |
final String code = createZPLCode(); |
System.out.println("ZPL:"); |
System.out.println(code); |
byte[] data = code.getBytes(StandardCharsets.US_ASCII); |
if (radioZPLNetwork.isSelected()) { |
Socket socket = null; |
try { |
socket = new Socket(textIP.getText(), ((Number) GS1Frame.this.portZPL.getValue()).intValue()); |
final DataOutputStream out = new DataOutputStream(socket.getOutputStream()); |
final int nb = ((Number) labelsSpinner.getValue()).intValue(); |
for (int i = 0; i < nb; i++) { |
out.write(data); |
} |
} catch (Exception ex) { |
ex.printStackTrace(); |
JOptionPane.showMessageDialog(buttonPrintZPL, "Erreur d'impression réseau : " + ex.getMessage()); |
} finally { |
if (socket != null) { |
try { |
socket.close(); |
} catch (IOException e1) { |
e1.printStackTrace(); |
} |
} |
} |
} else { |
try { |
final PrinterJob pj1 = PrinterJob.getPrinterJob(); |
if (pj1.printDialog()) { |
final PrintService ps = pj1.getPrintService(); |
final DocPrintJob pj = ps.createPrintJob(); |
final SimpleDoc doc = new SimpleDoc(data, DocFlavor.BYTE_ARRAY.AUTOSENSE, null); |
final int nb = ((Number) labelsSpinner.getValue()).intValue(); |
for (int i = 0; i < nb; i++) { |
pj.print(doc, null); |
} |
} |
} catch (Exception ex) { |
ex.printStackTrace(); |
JOptionPane.showMessageDialog(buttonPrintZPL, "Erreur d'impression locale : " + ex.getMessage()); |
} |
} |
} |
}); |
return panelZPL; |
} |
private LabelRenderer createRenderer() { |
return new LabelRenderer() { |
@Override |
public void paintLabel(Graphics g, Label label, int x, int y, int gridWith, int gridHeight, float fontSize) { |
final Graphics2D g2d = (Graphics2D) g; |
g.setColor(Color.BLACK); |
g2d.setStroke(new BasicStroke(3)); |
String str1 = GS1Frame.this.textSupplier.getText().trim(); |
String str2 = GS1Frame.this.textName.getText(); |
int pos1 = 26; |
if (str1.isEmpty()) { |
str1 = GS1Frame.this.textName.getText(); |
str2 = ""; |
pos1 += 16; |
} |
final AffineTransform defaultAt = g2d.getTransform(); |
final AffineTransform at = ((AffineTransform) (g2d.getTransform().clone())); |
at.rotate(-Math.PI / 2); |
g2d.setTransform(at); |
g.setFont(getFont().deriveFont(15f)); |
final int d1 = 60; |
final int d2 = 60; |
g.drawString(str1, -y - gridHeight + d1, x + pos1); |
g.drawString(str2, -y - gridHeight + d2, x + 58); |
if (GS1Frame.this.barcodeDatamatrix != null) { |
float ratioDatamatrix = 15f; |
final int wd = (int) (GS1Frame.this.barcodeDatamatrix.getWidth() / ratioDatamatrix); |
final int hd = (int) (GS1Frame.this.barcodeDatamatrix.getHeight() / ratioDatamatrix); |
g.drawImage(GS1Frame.this.barcodeDatamatrix, -y - 10 - wd, x + 10, wd, hd, null); |
final int w1 = GS1Frame.this.barcodeImage.getWidth() / 4; |
final int h1 = GS1Frame.this.barcodeImage.getHeight() / 4; |
g.drawImage(GS1Frame.this.barcodeImage, -y + -gridHeight + 60, x + 70, w1, h1, null); |
} |
if (GS1Frame.this.barcodeImageBatch != null) { |
// GS1-128 numero de lot |
final int w2 = GS1Frame.this.barcodeImageBatch.getWidth() / 4; |
final int h2 = GS1Frame.this.barcodeImageBatch.getHeight() / 4; |
g.drawImage(GS1Frame.this.barcodeImageBatch, -y - gridHeight + 60, x + 180, w2, h2, null); |
} |
g2d.setTransform(defaultAt); |
} |
}; |
} |
public JPanel createToolBar() { |
final JPanel toolbar = new JPanel(); |
toolbar.setOpaque(false); |
toolbar.setLayout(new GridBagLayout()); |
final GridBagConstraints c = new GridBagConstraints(); |
c.fill = GridBagConstraints.HORIZONTAL; |
c.insets = new Insets(2, 3, 2, 2); |
c.gridx = 0; |
c.gridy = 0; |
c.weightx = 0; |
c.gridwidth = 1; |
toolbar.add(new JLabel("Etiquettes par page"), c); |
c.gridx++; |
twoPerPage.setOpaque(false); |
fourPerPage.setOpaque(false); |
final ButtonGroup g = new ButtonGroup(); |
g.add(twoPerPage); |
g.add(fourPerPage); |
if (properties.getProperty("labelsPerPage", "4").equals("4")) { |
fourPerPage.setSelected(true); |
} else { |
twoPerPage.setSelected(true); |
} |
toolbar.add(twoPerPage, c); |
c.gridx++; |
toolbar.add(fourPerPage, c); |
c.gridx++; |
checkIgnoreMargins.setOpaque(false); |
checkIgnoreMargins.setSelected(properties.getProperty("ignoreMargin", "false").equals("true")); |
c.gridx++; |
toolbar.add(checkIgnoreMargins, c); |
c.gridx++; |
c.weightx = 1; |
c.fill = GridBagConstraints.NONE; |
c.anchor = GridBagConstraints.NORTHEAST; |
final JButton printButton = new JButton("Imprimer"); |
printButton.setOpaque(false); |
toolbar.add(printButton, c); |
c.gridx++; |
twoPerPage.addActionListener(new ActionListener() { |
@Override |
public void actionPerformed(ActionEvent e) { |
if (twoPerPage.isSelected()) { |
GS1Frame.this.labelPanel.setColumnCount(1); |
} else { |
GS1Frame.this.labelPanel.setColumnCount(2); |
} |
} |
}); |
fourPerPage.addActionListener(new ActionListener() { |
@Override |
public void actionPerformed(ActionEvent e) { |
if (twoPerPage.isSelected()) { |
GS1Frame.this.labelPanel.setColumnCount(1); |
} else { |
GS1Frame.this.labelPanel.setColumnCount(2); |
} |
} |
}); |
printButton.addActionListener(new ActionListener() { |
@Override |
public void actionPerformed(ActionEvent e) { |
if (!isEANValid()) { |
JOptionPane.showMessageDialog(GS1Frame.this, "EAN invalide"); |
return; |
} |
final PrinterJob job = PrinterJob.getPrinterJob(); |
job.setPrintable(GS1Frame.this.labelPanel); |
boolean ok = job.printDialog(); |
if (ok) { |
try { |
job.print(); |
} catch (PrinterException ex) { |
JOptionPane.showMessageDialog(GS1Frame.this, "Print error :" + ex.getMessage()); |
} |
} |
} |
}); |
checkIgnoreMargins.addActionListener(new ActionListener() { |
@Override |
public void actionPerformed(ActionEvent e) { |
GS1Frame.this.labelPanel.setIgnoreMargins(checkIgnoreMargins.isSelected()); |
} |
}); |
return toolbar; |
} |
public JPanel createToolBar2() { |
final JPanel toolbar = new JPanel(); |
toolbar.setOpaque(false); |
toolbar.setLayout(new GridBagLayout()); |
final GridBagConstraints c = new GridBagConstraints(); |
c.insets = new Insets(2, 3, 2, 2); |
c.gridx = 0; |
c.gridy = 0; |
c.weightx = 0; |
c.gridwidth = 1; |
c.fill = GridBagConstraints.NONE; |
toolbar.add(new JLabel("Marge en haut (mm)"), c); |
c.gridx++; |
final JSpinner sLines = new JSpinner(new SpinnerNumberModel(0, 0, 200, 1)); |
toolbar.add(sLines, c); |
c.gridx++; |
toolbar.add(new JLabel("Marge à gauche (mm)"), c); |
c.gridx++; |
final JSpinner sColums = new JSpinner(new SpinnerNumberModel(0, 0, 200, 1)); |
c.weightx = 1; |
toolbar.add(sColums, c); |
c.gridx++; |
sLines.addChangeListener(new ChangeListener() { |
@Override |
public void stateChanged(ChangeEvent e) { |
final Number n = (Number) sLines.getValue(); |
if (n != null) { |
GS1Frame.this.labelPanel.setTopMargin(n.intValue()); |
} |
} |
}); |
sColums.addChangeListener(new ChangeListener() { |
@Override |
public void stateChanged(ChangeEvent e) { |
final Number n = (Number) sColums.getValue(); |
if (n != null) { |
GS1Frame.this.labelPanel.setLeftMargin(n.intValue()); |
} |
} |
}); |
return toolbar; |
} |
public String readZPLScript() { |
if (new File("zpl.txt").exists()) { |
try (InputStream in = new FileInputStream(new File("zpl.txt"))) { |
return readAscii(in); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} else { |
try (InputStream in = GS1Frame.class.getResourceAsStream("default-zpl.txt")) { |
return readAscii(in); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
return ""; |
} |
protected String createZPLCode() { |
final String script = readZPLScript(); |
final BufferedReader reader = new BufferedReader(new StringReader(script)); |
final StringBuilder builder = new StringBuilder(); |
final GS1Util u = new GS1Util(); |
try { |
String line = reader.readLine(); |
while (line != null) { |
if (line.contains("XXXXXXXXXX")) { |
if (!this.textSupplier.getText().isEmpty()) { |
line = line.replace("XXXXXXXXXX", this.textSupplier.getText()); |
builder.append(line); |
builder.append("\r\n"); |
} |
} else if (line.contains("YYYYYYYYYY")) { |
line = line.replace("YYYYYYYYYY", this.textName.getText()); |
builder.append(line); |
builder.append("\r\n"); |
} else if (line.contains("(02)7612345678900(15)201218(37)9999")) { |
line = line.replace("(02)7612345678900(15)201218(37)9999", getGS128().formatHumanReadable()); |
builder.append(line); |
builder.append("\r\n"); |
} else if (line.contains("(10)LLLLLLLLL")) { |
GS1AIElements batch = getGS128Batch(); |
if (!batch.isEmpty()) { |
line = line.replace("(10)LLLLLLLLL", batch.formatHumanReadable()); |
builder.append(line); |
builder.append("\r\n"); |
} |
} else if (line.contains("OPENCONCERTO")) { |
GS1AIElements all = getGS1(); |
line = line.replace("OPENCONCERTO", u.formatZPL(all)); |
builder.append(line); |
builder.append("\r\n"); |
} else { |
builder.append(line); |
builder.append("\r\n"); |
} |
line = reader.readLine(); |
} |
} catch (Exception e) { |
e.printStackTrace(); |
} |
return builder.toString(); |
} |
private GS1AIElements getGS1() { |
final GS1AIElements gs1 = new GS1AIElements(); |
final String ean = this.textEAN.getText().trim(); |
if (!ean.isEmpty()) { |
if (ean.length() == 13 || (ean.length() == 14 && ean.charAt(0) == '0')) { |
if (ean.length() == 13) { |
gs1.put("02", '0' + ean); |
} else { |
gs1.put("02", ean); |
} |
} else { |
gs1.put("01", ean); |
} |
} |
if (this.dateDLUODLC.getValue() != null) { |
String date = this.dfDate.format(this.dateDLUODLC.getValue()); |
if (this.b1.isSelected()) { |
gs1.put("15", date); |
} else { |
gs1.put("17", date); |
} |
} |
final String nbProducts = this.textNumberOfProducts.getText(); |
if (!nbProducts.trim().isEmpty()) { |
int n = Integer.parseInt(this.textNumberOfProducts.getText()); |
gs1.put("37", String.valueOf(n)); |
} |
final String batch = this.textBatch.getText().trim(); |
if (!batch.isEmpty()) { |
gs1.put("10", batch); |
} |
return gs1; |
} |
private GS1AIElements getGS128Batch() { |
final GS1AIElements gs1 = new GS1AIElements(); |
final String batch = this.textBatch.getText().trim(); |
if (!batch.isEmpty()) { |
gs1.put("10", batch); |
} |
return gs1; |
} |
private GS1AIElements getGS128() { |
final GS1AIElements gs1 = getGS1(); |
gs1.remove("10"); |
return gs1; |
} |
public String readAscii(final InputStream in) throws IOException { |
final ByteArrayOutputStream out = new ByteArrayOutputStream(); |
final byte[] buf = new byte[8192]; |
int length; |
while ((length = in.read(buf)) > 0) { |
out.write(buf, 0, length); |
} |
out.flush(); |
out.close(); |
return new String(out.toByteArray(), StandardCharsets.US_ASCII); |
} |
static List<Image> frameIcon; |
public static synchronized List<Image> getFrameIcon() { |
if (frameIcon == null) { |
frameIcon = new ArrayList<>(); |
final int[] sizes = { 16, 32, 48, 96 }; |
for (int i = 0; i < sizes.length; i++) { |
int v = sizes[i]; |
try { |
frameIcon.add(new ImageIcon(GS1Frame.class.getResource(v + ".png")).getImage()); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
} |
return frameIcon; |
} |
public static void main(String[] args) { |
if (!new File("zpl.txt").exists()) { |
final InputStream in = GS1Frame.class.getResourceAsStream("default-zpl.txt"); |
try (FileOutputStream fOut = new FileOutputStream(new File("zpl.txt"))) { |
byte[] buf = new byte[8192]; |
int length; |
while ((length = in.read(buf)) > 0) { |
fOut.write(buf, 0, length); |
} |
fOut.flush(); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
SwingUtilities.invokeLater(new Runnable() { |
@Override |
public void run() { |
try { |
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); |
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e1) { |
e1.printStackTrace(); |
} |
final GS1Frame f = new GS1Frame(); |
f.setIconImages(getFrameIcon()); |
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
f.pack(); |
f.setVisible(true); |
f.setLocationRelativeTo(null); |
f.setResizable(false); |
} |
}); |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/filter/LimitDocumentFilter.java |
---|
New file |
0,0 → 1,30 |
package org.openconcerto.modules.label.filter; |
import javax.swing.text.AttributeSet; |
import javax.swing.text.BadLocationException; |
import javax.swing.text.DocumentFilter; |
public class LimitDocumentFilter extends DocumentFilter { |
private int limit; |
public LimitDocumentFilter(int limit) { |
if (limit <= 0) { |
throw new IllegalArgumentException("Limit can not be <= 0"); |
} |
this.limit = limit; |
} |
@Override |
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { |
int currentLength = fb.getDocument().getLength(); |
int overLimit = (currentLength + text.length()) - limit - length; |
if (overLimit > 0) { |
text = text.substring(0, text.length() - overLimit); |
} |
if (text.length() > 0) { |
super.replace(fb, offset, length, text, attrs); |
} |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/filter/NumberOfProductDocumentFilter.java |
---|
New file |
0,0 → 1,47 |
package org.openconcerto.modules.label.filter; |
import javax.swing.text.AttributeSet; |
import javax.swing.text.BadLocationException; |
import javax.swing.text.DocumentFilter; |
public class NumberOfProductDocumentFilter extends DocumentFilter { |
private boolean isValid(String testText) { |
if (testText.length() > 8) { |
return false; |
} |
if (testText.isEmpty()) { |
return true; |
} |
int intValue = 0; |
try { |
intValue = Integer.parseInt(testText.trim()); |
} catch (NumberFormatException e) { |
return false; |
} |
if (intValue < 1 || intValue > 99999999) { |
return false; |
} |
return true; |
} |
@Override |
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { |
StringBuilder sb = new StringBuilder(); |
sb.append(fb.getDocument().getText(0, fb.getDocument().getLength())); |
sb.insert(offset, text); |
if (isValid(sb.toString())) { |
super.insertString(fb, offset, text, attr); |
} |
} |
@Override |
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { |
StringBuilder sb = new StringBuilder(); |
sb.append(fb.getDocument().getText(0, fb.getDocument().getLength())); |
int end = offset + length; |
sb.replace(offset, end, text); |
if (isValid(sb.toString())) { |
super.replace(fb, offset, length, text, attrs); |
} |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/filter/BatchDocumentFilter.java |
---|
New file |
0,0 → 1,23 |
package org.openconcerto.modules.label.filter; |
import javax.swing.text.AttributeSet; |
import javax.swing.text.BadLocationException; |
import org.openconcerto.modules.label.ISO646; |
public class BatchDocumentFilter extends LimitDocumentFilter { |
public BatchDocumentFilter() { |
super(20); |
} |
@Override |
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { |
super.insertString(fb, offset, ISO646.clean(text), attr); |
} |
@Override |
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { |
super.replace(fb, offset, length, ISO646.clean(text), attrs); |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/filter/EANDocumentFilter.java |
---|
New file |
0,0 → 1,36 |
package org.openconcerto.modules.label.filter; |
import javax.swing.text.AttributeSet; |
import javax.swing.text.BadLocationException; |
public class EANDocumentFilter extends LimitDocumentFilter { |
public EANDocumentFilter() { |
super(14); |
} |
@Override |
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { |
super.insertString(fb, offset, clean(text), attr); |
} |
@Override |
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { |
super.replace(fb, offset, length, clean(text), attrs); |
} |
public static String clean(String s) { |
final int length = s.length(); |
final StringBuilder b = new StringBuilder(length); |
for (int i = 0; i < length; i++) { |
final char charAt = s.charAt(i); |
if (Character.isDigit(charAt)) { |
b.append(s.charAt(i)); |
} else { |
b.append('0'); |
} |
} |
return b.toString(); |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/filter/ISO646DocumentFilter.java |
---|
New file |
0,0 → 1,19 |
package org.openconcerto.modules.label.filter; |
import javax.swing.text.AttributeSet; |
import javax.swing.text.BadLocationException; |
import javax.swing.text.DocumentFilter; |
import org.openconcerto.modules.label.ISO646; |
public class ISO646DocumentFilter extends DocumentFilter { |
@Override |
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { |
super.insertString(fb, offset, ISO646.clean(text), attr); |
} |
@Override |
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { |
super.replace(fb, offset, length, ISO646.clean(text), attrs); |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/LabelRenderer.java |
---|
2,8 → 2,6 |
import java.awt.Graphics; |
import org.openconcerto.sql.model.SQLRowAccessor; |
public interface LabelRenderer { |
public void paintLabel(Graphics g, SQLRowAccessor row, int x, int y, int gridWith, int gridHeight, float fontSize); |
public void paintLabel(Graphics g, Label label, int x, int y, int gridWith, int gridHeight, float fontSize); |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/gs1/GS1ParseException.java |
---|
New file |
0,0 → 1,18 |
package org.openconcerto.modules.label.gs1; |
public class GS1ParseException extends Exception { |
final String ai; |
final int errorCode; |
final String errorMessage; |
public GS1ParseException(final String ai, final int errorCode, final String errorMessage) { |
this.ai = ai; |
this.errorCode = errorCode; |
this.errorMessage = errorMessage; |
} |
@Override |
public String toString() { |
return "AI: " + ai + ", errorCode: " + errorCode + ", errorMessage: " + errorMessage; |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/gs1/GS1Util.java |
---|
New file |
0,0 → 1,243 |
package org.openconcerto.modules.label.gs1; |
import org.openconcerto.modules.label.ISO646; |
public class GS1Util { |
// ISO/IEC 15424 symbology identifiers |
// ]E0 : EAN-13, UPC-A, or UPC-E : 13 digits |
// ]E1 : Two-digit add-on symbol : 2 digits |
// ]E2 : Five-digit add-on symbol : 5 digits |
// ]E3 : EAN-13, UPC-A, or UPC-E with add-on symbol : 15 or 18 digits |
// ]E4 : EAN-8 : 8 digits |
// ]I1 : ITF-14 : 14 digits |
// ]C1 : GS1-128 : Standard AI element strings |
private static final String GS1_128_SCANNER_PREFIX = "]C1"; |
// ]e0 : GS1 DataBar : Standard AI element strings |
private static final String GS1_DATABAR_SCANNER_PREFIX = "]e0"; |
// ]e1 : GS1 Composite : Data packet containing the data + an encoded symbol separator |
// character. |
// ]e2 : GS1 Composite : Data packet containing the data following an escape mechanism |
// character. |
// ]d2 : GS1 DataMatrix : Standard AI element strings |
private static final String GS1_DATAMATRIX_SCANNER_PREFIX = "]d2"; |
// ]Q3 : GS1 QR Code : Standard AI element strings |
private static final String GS1_QRCODE_SCANNER_PREFIX = "]Q3"; |
// ]J1 : GS1 DotCode : Standard AI element strings |
static final int ERROR_CODE_INVALID_GS1_SCAN = 0; |
static final int ERROR_CODE_UNKNOWN_AI = 1; |
static final int ERROR_CODE_INCOMPLETE_AI = 2; |
static final int ERROR_CODE_NOT_FOUND_SEPARATOR = 3; |
static final int ERROR_CODE_INSUFFICIENT_VALUE_LENGTH = 4; |
static final int ERROR_CODE_EXCEEDED_VALUE_LENGTH = 5; |
static final int ERROR_CODE_CONVERT_DECIMAL_POINT = 5; |
static final int ERROR_CODE_WRONG_DECIMAL_POINT = 6; |
static final int ERROR_CODE_CONVERT_DECIMAL_VALUE = 7; |
public static final char GS_SEPARATOR = '\u001D'; |
// public static final char FNC1_SEPARATOR = 232; |
static final int SPACE_SEPARATOR = ' '; |
int separator; |
public GS1Util() { |
this(GS_SEPARATOR); |
} |
public GS1Util(int separator) { |
this.separator = separator; |
} |
public GS1AIElements parseFromScanner(String scan) throws GS1ParseException { |
if (scan.startsWith(GS1_DATAMATRIX_SCANNER_PREFIX) || scan.startsWith(GS1_128_SCANNER_PREFIX) || scan.startsWith(GS1_DATABAR_SCANNER_PREFIX) || scan.startsWith(GS1_QRCODE_SCANNER_PREFIX)) { |
return parse(scan.substring(3)); |
} |
return parse(scan); |
} |
public GS1AIElements parse(String barcode) throws GS1ParseException { |
if (barcode.length() < 3) { |
throw new GS1ParseException("", ERROR_CODE_INVALID_GS1_SCAN, "code too short"); |
} |
System.err.println("GS1Util.parse()" + barcode); |
GS1AIElements attr = new GS1AIElements(); |
StringBuilder ai = new StringBuilder(); |
int length = barcode.length(); |
for (int i = 0; i < length; ++i) { |
int aiLength = ai.length(); |
if (aiLength > 1) { |
GS1ApplicationIdentifier aii = GS1AIElements.getApplicationIdentifier(ai.toString()); |
if (aii == null) { |
if (aiLength < 4) |
ai.append(barcode.charAt(i)); |
else |
throw new GS1ParseException(ai.toString(), ERROR_CODE_UNKNOWN_AI, "Unknown AI"); |
} else { |
int decimalPoint = 0; |
if (aii.decimalPoint) { |
try { |
decimalPoint = Integer.valueOf(String.valueOf(barcode.charAt(i))); |
} catch (NumberFormatException e) { |
throw new GS1ParseException(ai.toString(), ERROR_CODE_CONVERT_DECIMAL_POINT, "Errow convert to decimal point"); |
} |
if (++i >= length) |
throw new GS1ParseException(ai.toString(), ERROR_CODE_INSUFFICIENT_VALUE_LENGTH, "Insufficient value length"); |
} |
String value; |
if (aii.variableLength) { |
int separatorIndex = barcode.indexOf(this.separator, i); |
if (separatorIndex < 0) { |
if (length - i > aii.length) |
throw new GS1ParseException(ai.toString(), ERROR_CODE_NOT_FOUND_SEPARATOR, "Not found separator"); |
else if (length - i < aii.minLength) |
throw new GS1ParseException(ai.toString(), ERROR_CODE_INSUFFICIENT_VALUE_LENGTH, "Insufficient value length"); |
else { |
value = barcode.substring(i); |
i = length; |
} |
} else if (separatorIndex - i > aii.length) |
throw new GS1ParseException(ai.toString(), ERROR_CODE_EXCEEDED_VALUE_LENGTH, "Exceeded value length"); |
else if (separatorIndex - i < aii.minLength) |
throw new GS1ParseException(ai.toString(), ERROR_CODE_INSUFFICIENT_VALUE_LENGTH, "Insufficient value length"); |
else { |
value = barcode.substring(i, separatorIndex); |
i = separatorIndex; |
} |
} else { |
if (i + aii.length > length) { |
throw new GS1ParseException(ai.toString(), ERROR_CODE_INSUFFICIENT_VALUE_LENGTH, "Insufficient value length"); |
} |
value = barcode.substring(i, i + aii.length); |
i += aii.length - 1; |
} |
if (aii.decimalPoint && decimalPoint > 0) { |
if (decimalPoint >= value.length()) |
throw new GS1ParseException(ai.toString(), ERROR_CODE_WRONG_DECIMAL_POINT, "Decimal point more then value length"); |
try { |
value = String.valueOf(Double.valueOf(value.substring(0, value.length() - decimalPoint) + "." + value.substring(value.length() - decimalPoint))); |
} catch (NumberFormatException e) { |
throw new GS1ParseException(ai.toString(), ERROR_CODE_CONVERT_DECIMAL_VALUE, "Error convert decimal point value"); |
} |
} |
attr.put(ai.toString(), value); |
ai.setLength(0); |
} |
} else |
ai.append(barcode.charAt(i)); |
} |
if (ai.length() > 0) |
throw new GS1ParseException(ai.toString(), ERROR_CODE_INCOMPLETE_AI, "Incomplete AI"); |
return attr; |
} |
public String format(GS1AIElements values) { |
StringBuilder b = new StringBuilder(); |
int size = values.size(); |
for (int i = 0; i < size; i++) { |
String k = values.getKey(i); |
GS1ApplicationIdentifier ai = GS1AIElements.getApplicationIdentifier(k); |
final String value = values.getValue(i); |
b.append(k); |
b.append(value); |
if (ai.variableLength && i < size - 1) { |
b.append((char) this.separator); |
} |
} |
return b.toString(); |
} |
public String formatZPL(GS1AIElements values) { |
StringBuilder b = new StringBuilder(); |
int size = values.size(); |
b.append("@1"); |
for (int i = 0; i < size; i++) { |
String k = values.getKey(i); |
GS1ApplicationIdentifier ai = GS1AIElements.getApplicationIdentifier(k); |
final String value = values.getValue(i); |
b.append(k); |
b.append(value); |
if (ai.variableLength && i < size - 1) { |
b.append("@d029"); |
} |
} |
return b.toString(); |
} |
public String formatDataMatrix(GS1AIElements values) { |
StringBuilder b = new StringBuilder(); |
int size = values.size(); |
// b.append(FNC1_SEPARATOR); |
for (int i = 0; i < size; i++) { |
String k = values.getKey(i); |
GS1ApplicationIdentifier ai = GS1AIElements.getApplicationIdentifier(k); |
final String value = values.getValue(i); |
b.append('['); |
b.append(k); |
b.append(']'); |
b.append(value); |
if (ai.variableLength && i < size - 1) { |
// b.append(GS_SEPARATOR); |
} |
} |
return b.toString(); |
} |
public static void main(String[] args) throws GS1ParseException { |
GS1Util p = new GS1Util('_'); |
System.out.println("GS1Util.main()" + (char) p.separator); |
String barcode = "0104607018700852111806051718062910180605_211"; |
// barcode = "01088888931021461712031510W1040190"; |
GS1AIElements values = p.parse(barcode); |
values.dump(System.out); |
values.put("391", "kookkk"); |
System.out.println(p.format(values)); |
System.out.println(values.formatHumanReadable()); |
GS1AIElements valuesMax = new GS1AIElements(); |
valuesMax.put("02", "01234567891234"); |
valuesMax.put("15", "201202"); |
valuesMax.put("37", "12345678"); |
valuesMax.put("10", "12345678901234567890"); |
GS1Util pStd = new GS1Util(); |
System.out.println(p.format(valuesMax)); |
System.out.println(p.format(valuesMax).length()); |
System.out.println(pStd.format(valuesMax)); |
System.out.println(pStd.format(valuesMax).length()); |
System.err.println("GS1Util.main() GS128 from barcode reader"); |
String gs1128 = "]C10207612345678900152012153745646578"; |
GS1Util p2 = new GS1Util(); |
values = p2.parseFromScanner(gs1128); |
values.dump(System.out); |
} |
public static String showAllChars(String s) { |
StringBuilder b = new StringBuilder(); |
for (int i = 0; i < s.length(); i++) { |
if (ISO646.isValid(s.charAt(i))) { |
b.append(s.charAt(i)); |
} else { |
b.append("[" + (int) s.charAt(i) + "]"); |
} |
} |
return b.toString(); |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/gs1/GS1AIElements.java |
---|
New file |
0,0 → 1,259 |
package org.openconcerto.modules.label.gs1; |
import java.io.PrintStream; |
import java.util.ArrayList; |
import java.util.HashMap; |
public class GS1AIElements { |
static final HashMap<String, GS1ApplicationIdentifier> GS1_128_AI = new HashMap<>(); |
static { |
GS1_128_AI.put("00", new GS1ApplicationIdentifier(0, 18, false, false)); |
GS1_128_AI.put("01", new GS1ApplicationIdentifier(0, 14, false, false)); |
GS1_128_AI.put("02", new GS1ApplicationIdentifier(0, 14, false, false)); |
GS1_128_AI.put("10", new GS1ApplicationIdentifier(0, 20, true, false)); |
GS1_128_AI.put("11", new GS1ApplicationIdentifier(0, 6, false, false)); |
GS1_128_AI.put("12", new GS1ApplicationIdentifier(0, 6, false, false)); |
GS1_128_AI.put("13", new GS1ApplicationIdentifier(0, 6, false, false)); |
GS1_128_AI.put("14", new GS1ApplicationIdentifier(0, 6, false, false)); |
GS1_128_AI.put("15", new GS1ApplicationIdentifier(0, 6, false, false)); |
GS1_128_AI.put("17", new GS1ApplicationIdentifier(0, 6, false, false)); |
GS1_128_AI.put("20", new GS1ApplicationIdentifier(0, 2, false, false)); |
GS1_128_AI.put("21", new GS1ApplicationIdentifier(0, 20, true, false)); |
GS1_128_AI.put("240", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("241", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("242", new GS1ApplicationIdentifier(0, 6, true, false)); |
GS1_128_AI.put("250", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("251", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("253", new GS1ApplicationIdentifier(13, 30, true, false)); |
GS1_128_AI.put("254", new GS1ApplicationIdentifier(0, 20, true, false)); |
GS1_128_AI.put("255", new GS1ApplicationIdentifier(13, 25, true, false)); |
GS1_128_AI.put("30", new GS1ApplicationIdentifier(0, 8, true, false)); |
GS1_128_AI.put("310", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("311", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("312", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("313", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("314", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("315", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("316", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("320", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("321", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("322", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("323", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("324", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("325", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("326", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("327", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("328", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("329", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("330", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("331", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("332", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("333", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("334", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("335", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("336", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("340", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("341", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("342", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("343", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("344", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("345", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("346", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("347", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("348", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("349", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("350", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("351", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("352", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("353", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("354", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("355", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("356", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("357", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("360", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("361", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("362", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("363", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("364", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("365", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("366", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("367", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("368", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("369", new GS1ApplicationIdentifier(0, 6, false, true)); |
GS1_128_AI.put("37", new GS1ApplicationIdentifier(0, 8, true, false)); |
GS1_128_AI.put("390", new GS1ApplicationIdentifier(0, 15, true, true)); |
GS1_128_AI.put("391", new GS1ApplicationIdentifier(3, 18, true, true)); |
GS1_128_AI.put("392", new GS1ApplicationIdentifier(0, 15, true, true)); |
GS1_128_AI.put("393", new GS1ApplicationIdentifier(3, 18, true, true)); |
GS1_128_AI.put("400", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("401", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("402", new GS1ApplicationIdentifier(0, 17, false, false)); |
GS1_128_AI.put("403", new GS1ApplicationIdentifier(3, 30, true, false)); |
GS1_128_AI.put("410", new GS1ApplicationIdentifier(0, 17, false, false)); |
GS1_128_AI.put("411", new GS1ApplicationIdentifier(0, 17, false, false)); |
GS1_128_AI.put("412", new GS1ApplicationIdentifier(0, 17, false, false)); |
GS1_128_AI.put("413", new GS1ApplicationIdentifier(0, 17, false, false)); |
GS1_128_AI.put("414", new GS1ApplicationIdentifier(0, 17, false, false)); |
GS1_128_AI.put("420", new GS1ApplicationIdentifier(0, 20, true, false)); |
GS1_128_AI.put("421", new GS1ApplicationIdentifier(0, 0, true, false)); |
GS1_128_AI.put("422", new GS1ApplicationIdentifier(0, 3, false, false)); |
GS1_128_AI.put("423", new GS1ApplicationIdentifier(3, 15, true, false)); |
GS1_128_AI.put("424", new GS1ApplicationIdentifier(0, 3, false, false)); |
GS1_128_AI.put("425", new GS1ApplicationIdentifier(0, 3, false, false)); |
GS1_128_AI.put("426", new GS1ApplicationIdentifier(0, 3, false, false)); |
GS1_128_AI.put("7001", new GS1ApplicationIdentifier(0, 13, false, false)); |
GS1_128_AI.put("7002", new GS1ApplicationIdentifier(0, 30, false, false)); |
GS1_128_AI.put("7003", new GS1ApplicationIdentifier(0, 10, false, false)); |
GS1_128_AI.put("7004", new GS1ApplicationIdentifier(0, 4, true, false)); |
GS1_128_AI.put("8001", new GS1ApplicationIdentifier(0, 14, false, false)); |
GS1_128_AI.put("8002", new GS1ApplicationIdentifier(0, 20, true, false)); |
GS1_128_AI.put("8003", new GS1ApplicationIdentifier(14, 30, true, false)); |
GS1_128_AI.put("8004", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("8005", new GS1ApplicationIdentifier(0, 6, false, false)); |
GS1_128_AI.put("8006", new GS1ApplicationIdentifier(0, 18, false, false)); |
GS1_128_AI.put("8007", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("8008", new GS1ApplicationIdentifier(8, 12, true, false)); |
GS1_128_AI.put("8018", new GS1ApplicationIdentifier(0, 18, false, false)); |
GS1_128_AI.put("8020", new GS1ApplicationIdentifier(0, 25, true, false)); |
GS1_128_AI.put("8100", new GS1ApplicationIdentifier(0, 6, false, false)); |
GS1_128_AI.put("8101", new GS1ApplicationIdentifier(0, 10, false, false)); |
GS1_128_AI.put("8102", new GS1ApplicationIdentifier(0, 2, false, false)); |
GS1_128_AI.put("8110", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("8200", new GS1ApplicationIdentifier(0, 70, true, false)); |
GS1_128_AI.put("90", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("91", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("92", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("93", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("94", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("95", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("96", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("97", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("98", new GS1ApplicationIdentifier(0, 30, true, false)); |
GS1_128_AI.put("99", new GS1ApplicationIdentifier(0, 30, true, false)); |
} |
private final ArrayList<String> keysAndValues = new ArrayList<>(); |
public GS1AIElements() { |
} |
public boolean isEmpty() { |
return this.keysAndValues.isEmpty(); |
} |
public boolean containsKey(String key) { |
final int size = this.keysAndValues.size(); |
for (int i = 0; i < size; i += 2) { |
if (this.keysAndValues.get(i).equals(key)) { |
return true; |
} |
} |
return false; |
} |
public boolean containsValue(String value) { |
final int size = this.keysAndValues.size(); |
for (int i = 1; i < size; i += 2) { |
if (this.keysAndValues.get(i).equals(value)) { |
return true; |
} |
} |
return false; |
} |
public String getKey(int index) { |
return this.keysAndValues.get(index * 2); |
} |
public String getValue(int index) { |
return this.keysAndValues.get(1 + index * 2); |
} |
public String get(String key) { |
final int size = this.keysAndValues.size(); |
for (int i = 0; i < size; i += 2) { |
if (this.keysAndValues.get(i).equals(key)) { |
return this.keysAndValues.get(i + 1); |
} |
} |
return null; |
} |
public String put(String key, String value) { |
GS1ApplicationIdentifier ai = GS1_128_AI.get(key); |
if (ai == null) { |
throw new IllegalArgumentException("AI " + key + " unknown"); |
} |
if (ai.variableLength) { |
if (value.length() < ai.minLength) { |
throw new IllegalArgumentException("AI " + key + " value length must >= " + ai.minLength + " but is " + value.length() + " for value " + value); |
} |
if (value.length() > ai.length) { |
throw new IllegalArgumentException("AI " + key + " value length must be <= " + ai.length + " but is " + value.length() + " for value " + value); |
} |
} else { |
if (value.length() != ai.length) { |
throw new IllegalArgumentException("AI " + key + " value length must be " + ai.length + " but is " + value.length() + " for value " + value); |
} |
} |
final int size = this.keysAndValues.size(); |
for (int i = 0; i < size; i += 2) { |
if (this.keysAndValues.get(i).equals(key)) { |
final String old = this.keysAndValues.get(i + 1); |
this.keysAndValues.set(i + 1, value); |
return old; |
} |
} |
this.keysAndValues.add(key); |
this.keysAndValues.add(value); |
return null; |
} |
public String remove(String key) { |
final int size = this.keysAndValues.size(); |
for (int i = 0; i < size; i += 2) { |
if (this.keysAndValues.get(i).equals(key)) { |
this.keysAndValues.remove(i); |
return this.keysAndValues.remove(i); |
} |
} |
return null; |
} |
public void clear() { |
this.keysAndValues.clear(); |
} |
public int size() { |
return this.keysAndValues.size() / 2; |
} |
public void dump(PrintStream out) { |
for (int i = 0; i < size(); i++) { |
out.print("("); |
out.print(getKey(i)); |
out.print(")"); |
out.println(getValue(i)); |
} |
out.flush(); |
} |
public static GS1ApplicationIdentifier getApplicationIdentifier(String k) { |
return GS1_128_AI.get(k); |
} |
public String formatHumanReadable() { |
StringBuilder b = new StringBuilder(); |
int size = size(); |
for (int i = 0; i < size; i++) { |
b.append('('); |
b.append(this.getKey(i)); |
b.append(')'); |
b.append(this.getValue(i)); |
} |
return b.toString(); |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/gs1/GS1ApplicationIdentifier.java |
---|
New file |
0,0 → 1,17 |
package org.openconcerto.modules.label.gs1; |
public class GS1ApplicationIdentifier { |
public final int minLength; |
public final int length; |
public final boolean variableLength; |
public final boolean decimalPoint; |
public GS1ApplicationIdentifier(int minLength, int length, boolean variableLength, boolean decimalPoint) { |
this.minLength = minLength; |
this.length = length; |
this.variableLength = variableLength; |
this.decimalPoint = decimalPoint; |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/graphicspl/GPLRenderer.java |
---|
New file |
0,0 → 1,166 |
package org.openconcerto.modules.label.graphicspl; |
import java.awt.Color; |
import java.awt.image.BufferedImage; |
import java.io.File; |
import java.io.IOException; |
import javax.imageio.ImageIO; |
import org.w3c.dom.Document; |
import org.w3c.dom.Element; |
import org.w3c.dom.Node; |
import org.w3c.dom.NodeList; |
public abstract class GPLRenderer { |
public static final int ALIGN_LEFT = 0; |
public static final int ALIGN_RIGHT = 1; |
public static final int ALIGN_CENTER = 2; |
public static final int BARCODE_EAN8 = 0; |
public static final int BARCODE_EAN13 = 1; |
public static final int BARCODE_CODE128 = 2; |
public static final int BARCODE_CODE128_GS1 = 3; |
public static final int BARCODE_DATAMATRIX = 4; |
public static final int BARCODE_QRCODE = 5; |
private final float ratio; |
public GPLRenderer(float ratio) { |
this.ratio = ratio; |
} |
public GPLRenderer() { |
this.ratio = 1.0f; |
} |
public float getRatio() { |
return ratio; |
} |
public void render(GraphicsPL graphicsPL) throws IOException { |
Document doc = graphicsPL.getDocument(); |
final int width = Integer.parseInt(doc.getDocumentElement().getAttribute("width")); |
NodeList nodeList = doc.getFirstChild().getChildNodes(); |
int size = nodeList.getLength(); |
for (int i = 0; i < size; i++) { |
if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE) { |
Element element = (Element) nodeList.item(i); |
String name = element.getNodeName(); |
if (name.equals("text")) { |
int x = Math.round(ratio * Integer.parseInt(element.getAttribute("x"))); |
int y = Math.round(ratio * Integer.parseInt(element.getAttribute("y"))); |
String txt = element.getTextContent(); |
Color color = Color.BLACK; |
if (element.hasAttribute("color")) { |
color = Color.decode(element.getAttribute("color")); |
} |
int fontSize = Math.round(ratio * Integer.parseInt(element.getAttribute("fontsize"))); |
String fontName = element.getAttribute("font"); |
int maxWidth = width - x; |
boolean wrap = false; |
int align = ALIGN_LEFT; |
if (element.hasAttribute("align")) { |
if (element.getAttribute("align").equals("right")) { |
align = ALIGN_RIGHT; |
} else if (element.getAttribute("align").equals("center")) { |
align = ALIGN_CENTER; |
} |
} |
if (!element.hasAttribute("visible") || element.getAttribute("visible").equals("true")) { |
drawText(x, y, txt, align, fontName, fontSize, color, maxWidth, wrap); |
} |
} else if (name.equals("rectangle")) { |
int x = Math.round(ratio * Integer.parseInt(element.getAttribute("x"))); |
int y = Math.round(ratio * Integer.parseInt(element.getAttribute("y"))); |
int w = Math.round(ratio * Integer.parseInt(element.getAttribute("width"))); |
int h = Math.round(ratio * Integer.parseInt(element.getAttribute("height"))); |
Color color = Color.BLACK; |
if (element.hasAttribute("color")) { |
color = Color.decode(element.getAttribute("color")); |
} |
if (element.hasAttribute("fill") && element.getAttribute("fill").equals("true")) { |
fillRectangle(x, y, w, h, color); |
} else { |
int lineWidth = Math.round(ratio); |
if (element.hasAttribute("linewidth")) { |
lineWidth = Math.round(ratio * Integer.parseInt(element.getAttribute("linewidth"))); |
} |
drawRectangle(x, y, w, h, color, lineWidth); |
} |
} else if (name.equals("image")) { |
String fileName = element.getAttribute("file"); |
int x = Math.round(ratio * Integer.parseInt(element.getAttribute("x"))); |
int y = Math.round(ratio * Integer.parseInt(element.getAttribute("y"))); |
BufferedImage img = ImageIO.read(new File(graphicsPL.getImageDir(), fileName)); |
int w = Math.round(ratio * img.getWidth()); |
int h = Math.round(ratio * img.getHeight()); |
if (element.hasAttribute("width")) { |
w = Math.round(ratio * Integer.parseInt(element.getAttribute("width"))); |
} |
if (element.hasAttribute("height")) { |
h = Math.round(ratio * Integer.parseInt(element.getAttribute("height"))); |
} |
drawImage(x, y, w, h, img); |
} else if (name.equals("barcode")) { |
int x = Math.round(ratio * Integer.parseInt(element.getAttribute("x"))); |
int y = Math.round(ratio * Integer.parseInt(element.getAttribute("y"))); |
int h = 0; |
if (element.hasAttribute("height")) { |
h = Math.round(ratio * Integer.parseInt(element.getAttribute("height"))); |
} |
String type = element.getAttribute("type"); |
String code = element.getTextContent(); |
int t; |
if (type.equals("ean8")) { |
t = BARCODE_EAN8; |
} else if (type.equals("ean13")) { |
t = BARCODE_EAN13; |
} else if (type.equals("ean128")) { |
t = BARCODE_CODE128; |
} else if (type.equals("gs1")) { |
t = BARCODE_CODE128_GS1; |
} else if (type.equals("datamatrix")) { |
t = BARCODE_DATAMATRIX; |
if (h != 0) { |
System.err.println("ignoring datamatrix height attribute"); |
} |
} else if (type.equals("qrcode")) { |
t = BARCODE_QRCODE; |
} else { |
throw new IllegalArgumentException("unsupported barcode type : " + type); |
} |
int fontSize = Math.round(ratio * 8); |
if (element.hasAttribute("fontsize")) { |
fontSize = Math.round(ratio * Integer.parseInt(element.getAttribute("fontsize"))); |
} |
int moduleWidth = Math.round(ratio); |
if (element.hasAttribute("modulewidth")) { |
moduleWidth = Math.round(ratio * Integer.parseInt(element.getAttribute("modulewidth"))); |
} |
drawBarcode(x, y, h, t, code, moduleWidth, fontSize); |
} else { |
throw new IllegalStateException("unsupported primitive : " + name); |
} |
} |
} |
} |
public abstract void drawText(int x, int y, String text, int align, String fontName, int fontSize, Color color, int maxWidth, boolean wrap); |
public abstract void drawImage(int x, int y, int w, int h, BufferedImage img); |
public abstract void fillRectangle(int x, int y, int w, int h, Color color); |
public abstract void drawRectangle(int x, int y, int w, int h, Color color, int lineWidth); |
public abstract void drawBarcode(int x, int y, int h, int type, String code, int moduleWidth, int fontSize); |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/graphicspl/GraphicsPL.java |
---|
New file |
0,0 → 1,128 |
package org.openconcerto.modules.label.graphicspl; |
import java.awt.Color; |
import java.awt.Graphics; |
import java.awt.Graphics2D; |
import java.awt.image.BufferedImage; |
import java.awt.print.PageFormat; |
import java.awt.print.Printable; |
import java.awt.print.PrinterException; |
import java.awt.print.PrinterJob; |
import java.io.ByteArrayInputStream; |
import java.io.File; |
import java.io.IOException; |
import java.nio.charset.StandardCharsets; |
import java.nio.file.Files; |
import javax.imageio.ImageIO; |
import javax.xml.parsers.DocumentBuilder; |
import javax.xml.parsers.DocumentBuilderFactory; |
import javax.xml.parsers.ParserConfigurationException; |
import org.w3c.dom.Document; |
import org.w3c.dom.Element; |
import org.xml.sax.SAXException; |
public class GraphicsPL { |
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><graphicspl height=\"400\" width=\"600\"/>"; |
Document doc; |
private File imgDir; |
public static void main(String[] args) throws Exception { |
GraphicsPL g = new GraphicsPL(); |
g.load(new File("Template/Labels/test.graphicspl")); |
BufferedImage img = g.createImage(10); |
ImageIO.write(img, "png", new File("gpl.png")); |
String zpl = g.getZPL(); |
System.out.println(zpl); |
Printable p = g.createPrintable(); |
PrinterJob job = PrinterJob.getPrinterJob(); |
job.setPrintable(p); |
boolean ok = job.printDialog(); |
if (ok) { |
job.print(); |
} |
} |
public Printable createPrintable() { |
final Element root = this.doc.getDocumentElement(); |
int dpi = 300; |
if (root.hasAttribute("dpi")) { |
dpi = Integer.parseInt(root.getAttribute("dpi")); |
} |
float printRatio = 1f; |
if (root.hasAttribute("printratio")) { |
printRatio = Float.parseFloat(root.getAttribute("printratio")); |
} |
return createPrintable(dpi, printRatio); |
} |
public Printable createPrintable(int dpi, float printRatio) { |
return new Printable() { |
@Override |
public int print(Graphics graphics, PageFormat pf, int pageIndex) throws PrinterException { |
if (pageIndex > 0) { |
return NO_SUCH_PAGE; |
} |
final Element root = GraphicsPL.this.doc.getDocumentElement(); |
final int width = Math.round(printRatio * Integer.parseInt(root.getAttribute("width"))); |
final int height = Math.round(printRatio * Integer.parseInt(root.getAttribute("height"))); |
final Graphics2D g2d = (Graphics2D) graphics; |
float ratio = (printRatio * dpi) / 72f; |
try { |
final BufferedImage img = createImage(ratio); |
g2d.drawImage(img, (int) Math.round(pf.getImageableX()), (int) Math.round(pf.getImageableY()), width, height, null); |
} catch (ParserConfigurationException | SAXException | IOException e) { |
throw new PrinterException(e.getMessage()); |
} |
return PAGE_EXISTS; |
} |
}; |
} |
private String getZPL() throws IOException { |
final ZPLRenderer renderer = new ZPLRenderer(); |
renderer.render(this); |
return renderer.getZPL(); |
} |
private BufferedImage createImage(float ratio) throws ParserConfigurationException, SAXException, IOException { |
final Element root = this.doc.getDocumentElement(); |
final int width = Math.round(ratio * Integer.parseInt(root.getAttribute("width"))); |
final int height = Math.round(ratio * Integer.parseInt(root.getAttribute("height"))); |
final BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
final Graphics2D graphics = (Graphics2D) img.getGraphics(); |
graphics.setColor(Color.WHITE); |
graphics.fillRect(0, 0, width, height); |
final Graphics2DRenderer renderer = new Graphics2DRenderer(graphics, ratio); |
renderer.render(this); |
graphics.dispose(); |
return img; |
} |
public Document getDocument() { |
return this.doc; |
} |
private void load(File file) throws ParserConfigurationException, SAXException, IOException { |
this.xml = new String(Files.readAllBytes(file.toPath())); |
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
// factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); |
final DocumentBuilder builder = factory.newDocumentBuilder(); |
final ByteArrayInputStream input = new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)); |
this.doc = builder.parse(input); |
this.doc.getDocumentElement().normalize(); |
this.imgDir = file.getParentFile(); |
} |
public File getImageDir() { |
return this.imgDir; |
} |
public void setImageDir(File dir) { |
this.imgDir = dir; |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/graphicspl/ZPLRenderer.java |
---|
New file |
0,0 → 1,234 |
package org.openconcerto.modules.label.graphicspl; |
import java.awt.Color; |
import java.awt.image.BufferedImage; |
import java.io.ByteArrayOutputStream; |
import java.io.IOException; |
import org.openconcerto.utils.ImageUtils; |
import org.openconcerto.utils.StringUtils; |
public class ZPLRenderer extends GPLRenderer { |
private StringBuilder sb = new StringBuilder(); |
public ZPLRenderer() { |
sb.append("^XA\n^CI28\n"); |
} |
@Override |
public void drawText(int x, int y, String text, int align, String fontName, int fontSize, Color color, int maxWidth, boolean wrap) { |
sb.append("^CF0,"); |
sb.append(fontSize); |
// |
if (align == ALIGN_RIGHT) { |
sb.append("^FO"); |
sb.append('0'); |
sb.append(','); |
sb.append(y); |
sb.append("^FB"); |
sb.append(x); |
sb.append(",9999,0"); |
sb.append(",R,0"); |
} else if (align == ALIGN_CENTER) { |
sb.append("^FO"); |
sb.append('0'); |
sb.append(','); |
sb.append(y); |
sb.append("^FB"); |
sb.append(x * 2); |
sb.append(",9999,0"); |
sb.append(",C,0"); |
} else { |
sb.append("^FO"); |
sb.append(x); |
sb.append(','); |
sb.append(y); |
// |
sb.append("^FB"); |
sb.append(maxWidth); |
sb.append(",9999,0"); |
sb.append(",L,0"); |
} |
// |
sb.append("^FD"); |
sb.append(text); |
if (align == ALIGN_CENTER) { |
sb.append("\\&"); |
} |
sb.append("^FS\n"); |
} |
@Override |
public void drawImage(int x, int y, int w, int h, BufferedImage img) { |
try { |
if (w != img.getWidth() || h != img.getHeight()) { |
img = ImageUtils.createQualityResizedImage(img, w, h); |
} |
final int bytesPerRow = (img.getWidth() + 7) / 8; |
int size = bytesPerRow * img.getHeight(); |
byte[] data = getData(img); |
sb.append("^FO"); |
sb.append(x); |
sb.append(","); |
sb.append(y); |
sb.append("^GFA"); |
sb.append(","); |
sb.append(size); |
sb.append(","); |
sb.append(size); |
sb.append(","); |
sb.append(bytesPerRow); |
sb.append(","); |
sb.append(StringUtils.bytesToHexString(data)); |
sb.append("^FS\n"); |
} catch (IOException e) { |
throw new IllegalStateException(e); |
} |
} |
byte[] getData(BufferedImage img) throws IOException { |
ByteArrayOutputStream out = new ByteArrayOutputStream(1024); |
int width = img.getWidth(); |
int height = img.getHeight(); |
// Lines |
for (int i = 0; i < height; i++) { |
int[] pixels = new int[width]; |
img.getRGB(0, i, width, 1, pixels, 0, 4); |
final byte[] encodedLine = encodeLine(pixels); |
out.write(encodedLine); |
} |
return out.toByteArray(); |
} |
private byte[] encodeLine(int[] pixels) throws IOException { |
final int bytesPerRow = (pixels.length + 7) / 8; |
byte[] bytesToEncode = new byte[bytesPerRow]; |
int index = 0; |
for (int i = 0; i < bytesToEncode.length; i++) { |
int points = 0; |
for (int j = 0; j < 8; j++) { |
int c = 0; |
if (index < pixels.length) { |
c = pixels[index]; |
int a = (c & 0xff000000) >> 24; |
int r = (c & 0x00ff0000) >> 16; |
int g = (c & 0x0000ff00) >> 8; |
int b = c & 0x000000ff; |
int grayScale = (int) (21.2671 * r + 71.5160 * g + 7.2169 * b); |
boolean isBlack = grayScale < 12000; |
points = points * 2; |
if (isBlack && a < 0) { |
points++; |
} |
} else { |
points = points * 2; |
} |
index++; |
} |
bytesToEncode[i] = (byte) points; |
} |
return bytesToEncode; |
} |
@Override |
public void fillRectangle(int x, int y, int w, int h, Color color) { |
sb.append("^FO"); |
sb.append(x); |
sb.append(','); |
sb.append(y); |
sb.append("^GB"); |
sb.append(w); |
sb.append(','); |
sb.append(h); |
sb.append(','); |
sb.append(Math.min(w, h)); |
sb.append("^FS\n"); |
} |
@Override |
public void drawRectangle(int x, int y, int w, int h, Color color, int lineWidth) { |
sb.append("^FO"); |
sb.append(x); |
sb.append(','); |
sb.append(y); |
sb.append("^GB"); |
sb.append(w); |
sb.append(','); |
sb.append(h); |
sb.append(','); |
sb.append(lineWidth); |
sb.append("^FS\n"); |
} |
@Override |
public void drawBarcode(int x, int y, int h, int type, String code, int moduleWidth, int fontSize) { |
code = code.trim(); |
sb.append("^FO"); |
sb.append(x); |
sb.append(','); |
sb.append(y); |
sb.append("^CF0,"); |
sb.append(fontSize); |
if (type == BARCODE_EAN13) { |
sb.append("^BY"); |
sb.append(moduleWidth); |
sb.append("^BEN,"); |
sb.append(h); |
sb.append(",Y,N"); |
} else if (type == BARCODE_EAN8) { |
sb.append("^BY"); |
sb.append(moduleWidth); |
sb.append("^B8N,"); |
sb.append(h); |
sb.append(",Y,N"); |
} else if (type == BARCODE_DATAMATRIX) { |
sb.append("^BXN,"); |
sb.append(moduleWidth); |
sb.append(",200"); |
} else if (type == BARCODE_CODE128) { |
sb.append("^BY"); |
sb.append(moduleWidth - 1); |
sb.append("^BCN,"); |
sb.append(h); |
sb.append(",Y,N,Y,D"); |
} else if (type == BARCODE_CODE128_GS1) { |
sb.append("^BY"); |
sb.append(moduleWidth - 1); |
sb.append("^BCN,"); |
sb.append(h); |
sb.append(",Y,N,Y,N"); |
} |
sb.append("^FD"); |
sb.append(code); |
sb.append("^FS\n"); |
} |
public String getZPL() { |
return sb.toString() + "\n^XZ"; |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/graphicspl/Graphics2DRenderer.java |
---|
New file |
0,0 → 1,116 |
package org.openconcerto.modules.label.graphicspl; |
import java.awt.BasicStroke; |
import java.awt.Color; |
import java.awt.Font; |
import java.awt.Graphics2D; |
import java.awt.RenderingHints; |
import java.awt.Stroke; |
import java.awt.geom.AffineTransform; |
import java.awt.image.BufferedImage; |
import uk.org.okapibarcode.backend.Code128; |
import uk.org.okapibarcode.backend.DataMatrix; |
import uk.org.okapibarcode.backend.Ean; |
import uk.org.okapibarcode.backend.QrCode; |
import uk.org.okapibarcode.backend.Symbol; |
import uk.org.okapibarcode.output.Java2DRenderer; |
public class Graphics2DRenderer extends GPLRenderer { |
private final Graphics2D g; |
public Graphics2DRenderer(Graphics2D g, float ratio) { |
super(ratio); |
this.g = g; |
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); |
} |
@Override |
public void drawText(int x, int y, String text, int align, String fontName, int fontSize, Color color, int maxWidth, boolean wrap) { |
final Font font = new Font(fontName, Font.PLAIN, fontSize); |
g.setFont(font.deriveFont(fontSize)); |
g.setColor(color); |
y += g.getFontMetrics().getAscent() - g.getFontMetrics().getDescent(); |
if (align == ALIGN_RIGHT) { |
int w = (int) g.getFontMetrics().getStringBounds(text, g).getWidth(); |
g.drawString(text, x - w, y); |
} else if (align == ALIGN_CENTER) { |
int w = (int) (g.getFontMetrics().getStringBounds(text, g).getWidth() / 2D); |
g.drawString(text, x - w, y); |
} else { |
g.drawString(text, x, y); |
} |
} |
@Override |
public void drawImage(int x, int y, int w, int h, BufferedImage img) { |
g.drawImage(img, x, y, x + w, y + h, 0, 0, img.getWidth(), img.getHeight(), null); |
} |
@Override |
public void fillRectangle(int x, int y, int w, int h, Color color) { |
g.setColor(color); |
g.fillRect(x, y, w, h); |
} |
@Override |
public void drawRectangle(int x, int y, int w, int h, Color color, int lineWidth) { |
Stroke s = g.getStroke(); |
g.setColor(color); |
if (lineWidth != 1) { |
g.setStroke(new BasicStroke(lineWidth)); |
} |
g.drawRect(x, y, w, h); |
g.setStroke(s); |
} |
@Override |
public void drawBarcode(int x, int y, int h, int type, String code, int moduleWidth, int fontSize) { |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); |
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); |
Symbol symbol = null; |
if (type == BARCODE_EAN8) { |
symbol = new Ean(); |
((Ean) symbol).setMode(Ean.Mode.EAN8); |
symbol.setBarHeight(h); |
} else if (type == BARCODE_EAN13) { |
symbol = new Ean(); |
((Ean) symbol).setMode(Ean.Mode.EAN13); |
symbol.setBarHeight(h); |
} else if (type == BARCODE_CODE128) { |
symbol = new Code128(); |
symbol.setDataType(Symbol.DataType.GS1); |
symbol.setBarHeight(h); |
} else if (type == BARCODE_CODE128_GS1) { |
symbol = new Code128(); |
symbol.setBarHeight(h); |
} else if (type == BARCODE_DATAMATRIX) { |
symbol = new DataMatrix(); |
} else if (type == BARCODE_QRCODE) { |
symbol = new QrCode(); |
} |
if (symbol == null) { |
return; |
} |
symbol.setModuleWidth(moduleWidth); |
symbol.setFontSize(fontSize); |
symbol.setContent(code.trim()); |
AffineTransform aT = g.getTransform(); |
g.setTransform(AffineTransform.getTranslateInstance(x, y)); |
Java2DRenderer renderer = new Java2DRenderer(g, 1, Color.WHITE, Color.BLACK); |
renderer.render(symbol); |
g.setTransform(aT); |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/oc-qrcode.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/oc-qrcode.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/Label.java |
---|
New file |
0,0 → 1,5 |
package org.openconcerto.modules.label; |
public class Label { |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/default-zpl.txt |
---|
New file |
0,0 → 1,20 |
^XA |
^FX Titre |
^CF0,42^FO150,43^FB750,1,0,L^FDXXXXXXXXXX^FS |
^FX DataMatrix |
^FO1010,20^BXN,7,200,,,,@^FDOPENCONCERTO^FS |
^FX Nom du produit |
^CF0,40 |
^FO150,140^FB700,1,0,L^FDYYYYYYYYYY^FS |
^FX Code barre |
^FO150,220 |
^BY3,2,300 |
^BCN,300,Y,N,Y,D |
^FD(02)7612345678900(15)201218(37)9999^FS |
^FO150,620^BY3,2,300^BCN,300,Y,N,Y,D^FD(10)LLLLLLLLL^FS |
^XZ |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/ModuleLabel.java |
---|
4,10 → 4,17 |
import java.awt.Graphics; |
import java.awt.event.ActionEvent; |
import java.awt.geom.Rectangle2D; |
import java.io.File; |
import java.io.IOException; |
import java.nio.charset.StandardCharsets; |
import java.util.ArrayList; |
import java.util.LinkedHashMap; |
import java.util.List; |
import java.util.Map.Entry; |
import java.util.TreeMap; |
import javax.swing.AbstractAction; |
import javax.swing.JFrame; |
import javax.swing.SwingWorker; |
import org.openconcerto.erp.generationDoc.provider.AdresseFullClientValueProvider; |
14,6 → 21,7 |
import org.openconcerto.erp.modules.AbstractModule; |
import org.openconcerto.erp.modules.ComponentsContext; |
import org.openconcerto.erp.modules.ModuleFactory; |
import org.openconcerto.sql.model.SQLRow; |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.model.SQLRowValuesListFetcher; |
23,10 → 31,12 |
import org.openconcerto.sql.view.list.IListeAction.IListeEvent; |
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction; |
import org.openconcerto.utils.ExceptionHandler; |
import org.openconcerto.utils.FileUtils; |
import org.openconcerto.utils.GestionDevise; |
import org.openconcerto.utils.StringUtils; |
public final class ModuleLabel extends AbstractModule { |
final LinkedHashMap<String, String> zplTemplates = new LinkedHashMap<String, String>(); |
public ModuleLabel(ModuleFactory f) throws IOException { |
super(f); |
34,6 → 44,9 |
@Override |
protected void setupComponents(ComponentsContext ctxt) { |
readTemplates(new File("Template/Labels")); |
readTemplates(new File("Configuration/Template/Labels")); |
final String actionName = "Imprimer les étiquettes"; |
final PredicateRowAction aArticle = new PredicateRowAction(new AbstractAction(actionName) { |
41,26 → 54,31 |
public void actionPerformed(ActionEvent arg0) { |
final IListe list = IListe.get(arg0); |
final List<Integer> selectedIDs = list.getSelection().getSelectedIDs(); |
final SwingWorker<List<SQLRowValues>, String> wworker = new SwingWorker<List<SQLRowValues>, String>() { |
final SQLTable tArticle = list.getSelectedRows().get(0).getTable(); |
final SwingWorker<List<RowValuesLabel>, String> wworker = new SwingWorker<List<RowValuesLabel>, String>() { |
@Override |
protected List<SQLRowValues> doInBackground() throws Exception { |
final SQLTable tArticle = list.getSelectedRows().get(0).getTable(); |
protected List<RowValuesLabel> doInBackground() throws Exception { |
final SQLRowValues graph = new SQLRowValues(tArticle); |
graph.putNulls("NOM", "PV_TTC"); |
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(graph); |
final List<SQLRowValues> values = fetcher.fetch(new Where(tArticle.getKey(), selectedIDs)); |
return values; |
final List<SQLRowValues> rows = fetcher.fetch(new Where(tArticle.getKey(), selectedIDs)); |
final List<RowValuesLabel> list = new ArrayList<>(rows.size()); |
for (SQLRowValues row : rows) { |
list.add(new RowValuesLabel(row)); |
} |
return list; |
} |
@Override |
protected void done() { |
try { |
final List<SQLRowValues> values = get(); |
final List<RowValuesLabel> values = get(); |
final LabelFrame f = new LabelFrame(values, new LabelRenderer() { |
@Override |
public void paintLabel(Graphics g, SQLRowAccessor row, int x, int y, int gridWith, int gridHeight, float fontSize) { |
public void paintLabel(Graphics g, Label label, int x, int y, int gridWith, int gridHeight, float fontSize) { |
g.setColor(Color.BLACK); |
g.setFont(g.getFont().deriveFont(fontSize)); |
// Labels borders |
67,6 → 85,7 |
final int hBorder = 12; |
final int vBorder = 8; |
// Product name |
SQLRowValues row = ((RowValuesLabel) label).getSQLRowValues(); |
final String text = row.getString("NOM"); |
final List<String> l = StringUtils.wrap(text, g.getFontMetrics(), gridWith - 2 * hBorder); |
final int lineHeight = g.getFontMetrics().getHeight(); |
73,7 → 92,7 |
int lineY = y; |
final int margin = gridHeight - l.size() * lineHeight; |
if (margin > 0) { |
lineY += (int) (margin / 2); |
lineY += margin / 2; |
} |
for (String line : l) { |
g.drawString(line, x + hBorder, lineY); |
95,8 → 114,8 |
} catch (Exception e) { |
ExceptionHandler.handle("Erreur d'impression", e); |
} |
} |
}; |
}; |
wworker.execute(); |
} |
107,11 → 126,11 |
public void actionPerformed(ActionEvent arg0) { |
final IListe list = IListe.get(arg0); |
final List<Integer> selectedIDs = list.getSelection().getSelectedIDs(); |
final SwingWorker<List<SQLRowValues>, String> wworker = new SwingWorker<List<SQLRowValues>, String>() { |
final SQLTable tClient = list.getSelectedRows().get(0).getTable(); |
final SwingWorker<List<RowValuesLabel>, String> wworker = new SwingWorker<List<RowValuesLabel>, String>() { |
@Override |
protected List<SQLRowValues> doInBackground() throws Exception { |
final SQLTable tClient = list.getSelectedRows().get(0).getTable(); |
protected List<RowValuesLabel> doInBackground() throws Exception { |
final SQLRowValues graph = new SQLRowValues(tClient); |
graph.putNulls("NOM"); |
final SQLRowValues a1 = graph.putRowValues("ID_ADRESSE"); |
119,17 → 138,24 |
final SQLRowValues a2 = graph.putRowValues("ID_ADRESSE_L"); |
a2.putNulls(a2.getTable().getFieldsName()); |
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(graph); |
final List<SQLRowValues> values = fetcher.fetch(new Where(tClient.getKey(), selectedIDs)); |
return values; |
final List<SQLRowValues> rows = fetcher.fetch(new Where(tClient.getKey(), selectedIDs)); |
final List<RowValuesLabel> list = new ArrayList<>(rows.size()); |
for (SQLRowValues row : rows) { |
list.add(new RowValuesLabel(row)); |
} |
return list; |
} |
@Override |
protected void done() { |
try { |
final List<SQLRowValues> values = get(); |
final List<RowValuesLabel> values = get(); |
final LabelFrame f = new LabelFrame(values, new LabelRenderer() { |
@Override |
public void paintLabel(Graphics g, SQLRowAccessor row, int x, int y, int gridWith, int gridHeight, float fontSize) { |
public void paintLabel(Graphics g, Label label, int x, int y, int gridWith, int gridHeight, float fontSize) { |
SQLRowValues row = ((RowValuesLabel) label).getSQLRowValues(); |
SQLRowAccessor rAddr = row.getForeign("ID_ADRESSE_L"); |
if (rAddr == null || rAddr.isUndefined()) { |
rAddr = row.getForeign("ID_ADRESSE"); |
165,8 → 191,8 |
} catch (Exception e) { |
ExceptionHandler.handle("Erreur d'impression", e); |
} |
} |
}; |
}; |
wworker.execute(); |
} |
176,13 → 202,94 |
aClient.setPredicate(IListeEvent.createSelectionCountPredicate(1, Integer.MAX_VALUE)); |
ctxt.getElement("ARTICLE").getRowActions().add(aArticle); |
ctxt.getElement("CLIENT").getRowActions().add(aClient); |
if (!this.zplTemplates.isEmpty()) { |
for (final Entry<String, String> entry : this.zplTemplates.entrySet()) { |
final String zpl = entry.getValue(); |
final PredicateRowAction action = new PredicateRowAction(new AbstractAction("Imprimer l'étiquette " + entry.getKey()) { |
@Override |
public void actionPerformed(ActionEvent arg0) { |
final ZPLPrinterPanel p = new ZPLPrinterPanel(zpl); |
final JFrame f = new JFrame(); |
final IListe list = IListe.get(arg0); |
final int idProduct = list.getSelection().getSelectedID(); |
final SQLTable tArticle = list.getSelectedRows().get(0).getTable(); |
final SwingWorker<SQLRowValues, String> wworker = new SwingWorker<SQLRowValues, String>() { |
@Override |
protected SQLRowValues doInBackground() throws Exception { |
final SQLRow row = tArticle.getRow(idProduct); |
row.fetchValues(); |
return row.asRowValues(); |
} |
@Override |
protected void done() { |
try { |
final SQLRowValues values = get(); |
p.initUI(values); |
f.setTitle(entry.getKey()); |
f.setContentPane(p); |
f.pack(); |
f.setLocationRelativeTo(null); |
f.setVisible(true); |
} catch (Exception e) { |
ExceptionHandler.handle("Erreur d'impression", e); |
} |
} |
}; |
wworker.execute(); |
} |
}, true, false); |
action.setPredicate(IListeEvent.createSelectionCountPredicate(1, 1)); |
ctxt.getElement("ARTICLE").getRowActions().add(action); |
} |
} |
} |
@Override |
protected void start() { |
} |
private void readTemplates(File templatesDir) { |
System.out.println("ModuleLabel.readTemplates() " + templatesDir.getAbsolutePath()); |
if (templatesDir.exists() && templatesDir.isDirectory()) { |
System.err.println("ModuleLabel.readTemplates() " + templatesDir.getAbsolutePath()); |
File[] files = templatesDir.listFiles(); |
if (files != null) { |
LinkedHashMap<String, String> map = new LinkedHashMap<>(); |
for (File f : files) { |
if (f.getName().endsWith(".zpl")) { |
try { |
String zpl = FileUtils.read(f, StandardCharsets.UTF_8); |
String name = f.getName().substring(0, f.getName().length() - 4).trim(); |
map.put(name, zpl); |
System.err.println("ModuleLabel.readTemplates() add " + name); |
} catch (Exception e) { |
System.err.println(this.getClass().getCanonicalName() + "start() cannot read zpl template : " + f.getAbsolutePath() + " : " + e.getMessage()); |
} |
} |
} |
// Tri de la map par clef |
final TreeMap<String, String> copy = new TreeMap<>(map); |
this.zplTemplates.clear(); |
this.zplTemplates.putAll(copy); |
} |
} else { |
System.err.println("ModuleLabel.readTemplates() " + templatesDir.getAbsolutePath() + " missing"); |
} |
} |
@Override |
protected void stop() { |
// nothing |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/32.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/32.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/RowValuesLabel.java |
---|
New file |
0,0 → 1,16 |
package org.openconcerto.modules.label; |
import org.openconcerto.sql.model.SQLRowValues; |
public class RowValuesLabel extends Label { |
private SQLRowValues row; |
public RowValuesLabel(SQLRowValues row) { |
this.row = row; |
} |
public SQLRowValues getSQLRowValues() { |
return row; |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/16.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/16.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/ZPLPrinterPanel.java |
---|
New file |
0,0 → 1,409 |
package org.openconcerto.modules.label; |
import java.awt.FlowLayout; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.awt.print.PrinterJob; |
import java.io.BufferedReader; |
import java.io.DataOutputStream; |
import java.io.File; |
import java.io.FileInputStream; |
import java.io.FileOutputStream; |
import java.io.IOException; |
import java.io.StringReader; |
import java.net.Socket; |
import java.nio.charset.StandardCharsets; |
import java.text.DecimalFormat; |
import java.util.ArrayList; |
import java.util.HashMap; |
import java.util.HashSet; |
import java.util.List; |
import java.util.Map; |
import java.util.Properties; |
import java.util.Set; |
import javax.print.DocFlavor; |
import javax.print.DocPrintJob; |
import javax.print.PrintService; |
import javax.print.SimpleDoc; |
import javax.swing.ButtonGroup; |
import javax.swing.JButton; |
import javax.swing.JFrame; |
import javax.swing.JLabel; |
import javax.swing.JOptionPane; |
import javax.swing.JPanel; |
import javax.swing.JRadioButton; |
import javax.swing.JSpinner; |
import javax.swing.JTextField; |
import javax.swing.SpinnerNumberModel; |
import javax.swing.SwingConstants; |
import javax.swing.SwingUtilities; |
import javax.swing.UIManager; |
import javax.swing.UnsupportedLookAndFeelException; |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.JLabelBold; |
import org.openconcerto.utils.BaseDirs; |
import org.openconcerto.utils.ExceptionHandler; |
import org.openconcerto.utils.FileUtils; |
import org.openconcerto.utils.ProductInfo; |
public class ZPLPrinterPanel extends JPanel { |
private final HashMap<String, String> mapName = new HashMap<>(); |
private final List<String> variables; |
private final List<String> knownVariables = new ArrayList<>(); |
private Map<String, JTextField> editorMap = new HashMap<>(); |
private String zpl; |
private final Properties properties = new Properties(); |
public static void main(String[] args) throws IOException { |
// final File f = new File("Templates/Labels", "50x50.zpl"); |
final File file = new File("Template/Labels", "57x32.zpl"); |
String zpl = FileUtils.read(file); |
SwingUtilities.invokeLater(new Runnable() { |
@Override |
public void run() { |
try { |
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); |
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { |
e.printStackTrace(); |
} |
ZPLPrinterPanel p = new ZPLPrinterPanel(zpl); |
p.initUI(null); |
JFrame f = new JFrame(); |
f.setTitle(file.getName()); |
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
f.setContentPane(p); |
f.pack(); |
f.setLocationRelativeTo(null); |
f.setVisible(true); |
} |
}); |
} |
public ZPLPrinterPanel(String zpl) { |
this.zpl = zpl; |
this.variables = getVariables(zpl); |
knownVariables.add("product.code"); |
knownVariables.add("product.name"); |
knownVariables.add("product.material"); |
knownVariables.add("product.ean13"); |
knownVariables.add("product.price"); |
knownVariables.add("product.pricewithtax"); |
// |
mapName.put("product.name", "Nom"); |
mapName.put("product.code", "Code"); |
mapName.put("product.ean13", "Code à barres"); |
mapName.put("product.price", "Prix HT"); |
mapName.put("product.pricewithtax", "Prix TTC"); |
mapName.put("product.treatment", "Traitement"); |
mapName.put("product.origin", "Origine"); |
mapName.put("product.batch", "Lot"); |
mapName.put("product.size", "Taille"); |
mapName.put("product.color", "Couleur"); |
mapName.put("product.material", "Matière"); |
} |
private final File getPrefFile() { |
final File prefsFolder = BaseDirs.create(ProductInfo.getInstance()).getPreferencesFolder(); |
if (!prefsFolder.exists()) { |
prefsFolder.mkdirs(); |
} |
return new File(prefsFolder, "labels.properties"); |
} |
protected void initUI(SQLRowAccessor row) { |
final File prefsFolder = BaseDirs.create(ProductInfo.getInstance()).getPreferencesFolder(); |
if (!prefsFolder.exists()) { |
prefsFolder.mkdirs(); |
} |
final File file = getPrefFile(); |
System.out.println(file.getAbsolutePath()); |
if (file.exists()) { |
try { |
properties.load(new FileInputStream(file)); |
} catch (IOException e) { |
e.printStackTrace(); |
} |
} |
this.setLayout(new GridBagLayout()); |
GridBagConstraints c = new DefaultGridBagConstraints(); |
c.fill = GridBagConstraints.HORIZONTAL; |
this.removeAll(); |
// Fields |
Set<String> added = new HashSet<>(); |
for (String v : this.knownVariables) { |
if (variables.contains(v)) { |
// Non editable |
String label = getName(v); |
c.gridx = 0; |
c.weightx = 0; |
this.add(new JLabel(label, SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 1; |
String value = getValueAsString(row, v); |
JTextField txt = new JTextField(20); |
if (value != null) { |
txt.setText(value); |
txt.setEditable(false); |
} |
editorMap.put(v, txt); |
this.add(txt, c); |
added.add(v); |
c.gridy++; |
} |
} |
for (String v : this.variables) { |
if (!added.contains(v)) { |
// Editable |
String label = getName(v); |
c.gridx = 0; |
c.weightx = 0; |
this.add(new JLabel(label, SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 1; |
JTextField txt = new JTextField(20); |
editorMap.put(v, txt); |
this.add(txt, c); |
added.add(v); |
c.gridy++; |
} |
} |
c.gridwidth = 2; |
c.gridx = 0; |
this.add(new JLabelBold("Paramètres d'impression"), c); |
// Printer selector |
c.gridx = 0; |
c.gridy++; |
final JPanel l1 = new JPanel(); |
l1.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0)); |
l1.add(new JLabel("Nombre d'étiquettes")); |
final JSpinner nbLabels = new JSpinner(new SpinnerNumberModel(1, 1, 1000, 10)); |
l1.add(nbLabels); |
this.add(l1, c); |
// Delay |
l1.add(new JLabel(" Pause entre chaque impression")); |
final JSpinner delayLabels = new JSpinner(new SpinnerNumberModel(800, 100, 10000, 100)); |
l1.add(delayLabels); |
this.add(l1, c); |
l1.add(new JLabel("ms")); |
c.gridy++; |
final JPanel lPrintNetwork = new JPanel(); |
lPrintNetwork.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0)); |
JRadioButton radioNetworkPrinter = new JRadioButton("imprimante réseau IP :"); |
lPrintNetwork.add(radioNetworkPrinter); |
JTextField textPrinterIP = new JTextField(16); |
lPrintNetwork.add(textPrinterIP); |
lPrintNetwork.add(new JLabel(" Port :")); |
JSpinner portZPL = new JSpinner(new SpinnerNumberModel(9100, 24, 10000, 1)); |
lPrintNetwork.add(portZPL); |
this.add(lPrintNetwork, c); |
c.gridy++; |
final JPanel lPrintLocal = new JPanel(); |
lPrintLocal.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0)); |
JRadioButton radioLocalPrinter = new JRadioButton("imprimante locale"); |
lPrintLocal.add(radioLocalPrinter); |
radioLocalPrinter.setSelected(true); |
this.add(lPrintLocal, c); |
final ButtonGroup gr = new ButtonGroup(); |
gr.add(radioLocalPrinter); |
gr.add(radioNetworkPrinter); |
c.gridy++; |
c.weighty = 1; |
c.gridx = 1; |
c.fill = GridBagConstraints.NONE; |
c.anchor = GridBagConstraints.SOUTHEAST; |
// Restore state from properties |
if (properties.getOrDefault("printerType", "local").equals("local")) { |
radioLocalPrinter.setSelected(true); |
} else { |
radioNetworkPrinter.setSelected(true); |
} |
textPrinterIP.setText(properties.getOrDefault("printerIp", "").toString()); |
portZPL.setValue(Long.parseLong(properties.getOrDefault("printerPort", "9100").toString())); |
nbLabels.setValue(Long.parseLong(properties.getOrDefault("nbLabels", "1").toString())); |
delayLabels.setValue(Long.parseLong(properties.getOrDefault("delay", "800").toString())); |
JButton printButton = new JButton("Imprimer"); |
this.add(printButton, c); |
printButton.addActionListener(new ActionListener() { |
@Override |
public void actionPerformed(ActionEvent e) { |
try { |
if (radioLocalPrinter.isSelected()) { |
properties.put("printerType", "local"); |
} else { |
properties.put("printerType", "network"); |
properties.put("printerIp", textPrinterIP.getText()); |
properties.put("printerPort", portZPL.getValue().toString()); |
} |
properties.put("nbLabels", nbLabels.getValue().toString()); |
properties.put("delay", delayLabels.getValue().toString()); |
// Save Prefs |
properties.store(new FileOutputStream(getPrefFile()), ""); |
} catch (Exception e1) { |
ExceptionHandler.handle("Erreur de sauvegarde de " + getPrefFile().getAbsolutePath(), e1); |
} |
final String code = createZPLCode(); |
System.out.println("ZPL:"); |
System.out.println(code); |
byte[] data = code.getBytes(StandardCharsets.UTF_8); |
if (radioNetworkPrinter.isSelected()) { |
Socket socket = null; |
try { |
socket = new Socket(textPrinterIP.getText(), ((Number) portZPL.getValue()).intValue()); |
final DataOutputStream out = new DataOutputStream(socket.getOutputStream()); |
final int nb = ((Number) nbLabels.getValue()).intValue(); |
for (int i = 0; i < nb; i++) { |
out.write(data); |
} |
} catch (Exception ex) { |
ex.printStackTrace(); |
JOptionPane.showMessageDialog(printButton, "Erreur d'impression réseau : " + ex.getMessage()); |
} finally { |
if (socket != null) { |
try { |
socket.close(); |
} catch (IOException e1) { |
e1.printStackTrace(); |
} |
} |
} |
} else { |
try { |
final PrinterJob pj1 = PrinterJob.getPrinterJob(); |
if (pj1.printDialog()) { |
final PrintService ps = pj1.getPrintService(); |
final DocPrintJob pj = ps.createPrintJob(); |
final SimpleDoc doc = new SimpleDoc(data, DocFlavor.BYTE_ARRAY.AUTOSENSE, null); |
final int nb = ((Number) nbLabels.getValue()).intValue(); |
for (int i = 0; i < nb; i++) { |
pj.print(doc, null); |
Thread.sleep(((Number) delayLabels.getValue()).intValue()); |
} |
} |
} catch (Exception ex) { |
ex.printStackTrace(); |
JOptionPane.showMessageDialog(printButton, "Erreur d'impression locale : " + ex.getMessage()); |
} |
} |
} |
}); |
} |
private String createZPLCode() { |
final BufferedReader reader = new BufferedReader(new StringReader(this.zpl)); |
final StringBuilder builder = new StringBuilder(); |
try { |
String line = reader.readLine(); |
while (line != null) { |
if (line.contains("${")) { |
boolean add = false; |
for (String v : this.editorMap.keySet()) { |
if (line.contains("${" + v + "}")) { |
final String value = this.editorMap.get(v).getText(); |
line = line.replace("${" + v + "}", value); |
if (!value.trim().isEmpty()) { |
add = true; |
} |
} |
} |
if (add) { |
builder.append(line); |
builder.append("\n"); |
} |
} else { |
builder.append(line); |
builder.append("\n"); |
} |
line = reader.readLine(); |
} |
} catch (Exception e) { |
e.printStackTrace(); |
} |
return builder.toString(); |
} |
public String getValueAsString(SQLRowAccessor row, String variableName) { |
if (row == null) { |
return null; |
} |
if (variableName.equals("product.code")) { |
return row.getString("CODE"); |
} else if (variableName.equals("product.name")) { |
return row.getString("NOM"); |
} else if (variableName.equals("product.ean13")) { |
return row.getString("CODE_BARRE"); |
} else if (variableName.equals("product.price")) { |
return new DecimalFormat("#0.00").format(row.getBigDecimal("PV_HT")); |
} else if (variableName.equals("product.pricewithtax")) { |
return new DecimalFormat("#0.00").format(row.getBigDecimal("PV_TTC")); |
} else if (variableName.equals("product.material")) { |
return row.getString("MATIERE"); |
} |
return ""; |
} |
public String getName(String variableName) { |
String n = mapName.get(variableName); |
if (n == null) { |
return variableName; |
} |
return n; |
} |
public List<String> getVariables(String str) { |
final List<String> result = new ArrayList<>(); |
if (str == null || str.length() < 4) { |
return result; |
} |
final int l = str.length() - 1; |
int start = 0; |
boolean inName = false; |
for (int i = 0; i < l; i++) { |
char c1 = str.charAt(i); |
char c2 = str.charAt(i + 1); |
if (!inName) { |
if (c1 == '$' && c2 == '{') { |
start = i + 2; |
inName = true; |
} |
} else if (c2 == '}') { |
final int stop = i + 1; |
String v = str.substring(start, stop); |
result.add(v); |
inName = false; |
} |
} |
return result; |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/GS1Label.java |
---|
New file |
0,0 → 1,16 |
package org.openconcerto.modules.label; |
import org.openconcerto.modules.label.gs1.GS1AIElements; |
public class GS1Label extends Label { |
String text; |
String text2; |
GS1AIElements gs1; |
public GS1Label(String text, String text2, GS1AIElements gs1) { |
this.text = text; |
this.text2 = text2; |
this.gs1 = gs1; |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/ISO646.java |
---|
New file |
0,0 → 1,30 |
package org.openconcerto.modules.label; |
public class ISO646 { |
public static final String ALLOWED_CHARS = "!\"%&'()*+,-./01234567989:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; |
public static boolean isValid(char c) { |
final int length = ALLOWED_CHARS.length(); |
for (int i = 0; i < length; i++) { |
if (c == ALLOWED_CHARS.charAt(i)) { |
return true; |
} |
} |
return false; |
} |
public static String clean(String s) { |
final int length = s.length(); |
final StringBuilder b = new StringBuilder(length); |
for (int i = 0; i < length; i++) { |
final char charAt = s.charAt(i); |
if (isValid(charAt)) { |
b.append(s.charAt(i)); |
} else { |
b.append('_'); |
} |
} |
return b.toString(); |
} |
} |
/trunk/Modules/Module Label/src/org/openconcerto/modules/label/LabelFrame.java |
---|
20,7 → 20,6 |
import javax.swing.event.ChangeEvent; |
import javax.swing.event.ChangeListener; |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.utils.ExceptionHandler; |
30,7 → 29,7 |
private static final int DEFAULT_COLS = 4; |
final LabelPanel labelPanel; |
public LabelFrame(List<? extends SQLRowAccessor> list, LabelRenderer labelRenderer) { |
public LabelFrame(List<? extends Label> list, LabelRenderer labelRenderer) { |
final JPanel p = new JPanel(); |
p.setLayout(new GridBagLayout()); |
final GridBagConstraints c = new DefaultGridBagConstraints(); |