OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Compare Revisions

Regard whitespace Rev 180 → Rev 181

/trunk/Modules/Module Time Tracking/src/org/openconcerto/modules/timetracking/Module.java
52,7 → 52,6
import org.openconcerto.utils.PrefType;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.cc.ITransformer;
import org.openconcerto.utils.i18n.TranslationManager;
 
public final class Module extends AbstractModule {
 
86,7 → 85,6
@Override
protected void setupElements(SQLElementDirectory dir) {
super.setupElements(dir);
TranslationManager.getInstance().addTranslationStreamFromClass(this.getClass());
 
GlobalMapper.getInstance().map(ProjectTimeTrackingSQLElement.ELEMENT_CODE + ".default", new ProjectTimeTrackingGroup());
final ProjectTimeTrackingSQLElement element = new ProjectTimeTrackingSQLElement();
119,7 → 117,7
 
private RowAction getSendMailTempsAffaireAction() {
 
final PredicateRowAction action = new PredicateRowAction(new AbstractAction() {
final PredicateRowAction action = new PredicateRowAction(new AbstractAction("Envoyer les temps par mail") {
 
@Override
public void actionPerformed(ActionEvent e) {
187,7 → 185,7
}
 
private RowAction getCreateTempsAffaireAction() {
PredicateRowAction action = new PredicateRowAction(new AbstractAction() {
PredicateRowAction action = new PredicateRowAction(new AbstractAction("Saisir un temps") {
 
@Override
public void actionPerformed(ActionEvent e) {
213,7 → 211,7
}
 
private RowAction getReportingAction() {
final PredicateRowAction action = new PredicateRowAction(new AbstractAction() {
final PredicateRowAction action = new PredicateRowAction(new AbstractAction("Reporting") {
 
@Override
public void actionPerformed(ActionEvent e) {
/trunk/Modules/Module Exchange Rates/src/org/openconcerto/modules/finance/accounting/exchangerates/ExchangeRatesDownloader.java
116,7 → 116,7
}
 
public static String downloadXML() {
final String urlString = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml";
final String urlString = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml";
BufferedInputStream in = null;
ByteArrayOutputStream fout = null;
try {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/ActionMainPanel.java
13,6 → 13,6
 
@Override
public JComponent createLeftComponent() {
return new ActionListPanel(extension, this);
return new ActionListPanel(this.extension, this);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/ActionItemEditor.java
44,8 → 44,8
 
c.weightx = 1;
 
textId = new JTextField();
this.add(textId, c);
this.textId = new JTextField();
this.add(this.textId, c);
 
//
final List<ComponentDescritor> l = extension.getCreateComponentList();
63,16 → 63,18
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Composant", SwingConstants.RIGHT), c);
c.gridx++;
comboComponent = new JComboBox(v);
comboComponent.setRenderer(new DefaultListCellRenderer() {
this.comboComponent = new JComboBox(v);
this.comboComponent.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value != null) {
value = ((ComponentDescritor) value).getId();
}
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
});
c.fill = GridBagConstraints.NONE;
this.add(comboComponent, c);
this.add(this.comboComponent, c);
 
c.gridx = 0;
c.gridy++;
81,9 → 83,9
this.add(new JLabel("Table", SwingConstants.RIGHT), c);
c.gridx++;
c.fill = GridBagConstraints.NONE;
textTable = new JTextField(30);
textTable.setEnabled(false);
this.add(textTable, c);
this.textTable = new JTextField(30);
this.textTable.setEnabled(false);
this.add(this.textTable, c);
// Location
c.gridx = 0;
c.gridy++;
92,8 → 94,8
this.add(new JLabel("Emplacement", SwingConstants.RIGHT), c);
c.gridx++;
c.fill = GridBagConstraints.NONE;
comboLocation = new JComboBox(new String[] { "Bouton et clic droit", "clic droit uniquement", "bouton uniquement" });
this.add(comboLocation, c);
this.comboLocation = new JComboBox(new String[] { "Bouton et clic droit", "clic droit uniquement", "bouton uniquement" });
this.add(this.comboLocation, c);
c.gridy++;
c.weighty = 1;
this.add(new JPanel(), c);
100,25 → 102,25
 
initUIFrom(actionDescriptor);
 
comboComponent.addActionListener(new ActionListener() {
this.comboComponent.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
final ComponentDescritor componentDescritor = getComponentDescritor(comboComponent.getSelectedItem().toString());
final ComponentDescritor componentDescritor = getComponentDescritor(ActionItemEditor.this.comboComponent.getSelectedItem().toString());
if (componentDescritor != null) {
textTable.setText(componentDescritor.getTable());
ActionItemEditor.this.textTable.setText(componentDescritor.getTable());
actionDescriptor.setComponentId(componentDescritor.getId());
actionDescriptor.setTable(componentDescritor.getTable());
} else {
textTable.setText("");
ActionItemEditor.this.textTable.setText("");
}
}
});
comboLocation.addActionListener(new ActionListener() {
this.comboLocation.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
int index = comboLocation.getSelectedIndex();
int index = ActionItemEditor.this.comboLocation.getSelectedIndex();
if (index == 0) {
actionDescriptor.setLocation(ActionDescriptor.LOCATION_HEADER_POPUP);
} else if (index == 1) {
129,7 → 131,7
 
}
});
textId.getDocument().addDocumentListener(new DocumentListener() {
this.textId.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
145,7 → 147,7
 
@Override
public void changedUpdate(DocumentEvent e) {
actionDescriptor.setId(textId.getText());
actionDescriptor.setId(ActionItemEditor.this.textId.getText());
}
});
 
153,24 → 155,24
 
private void initUIFrom(ActionDescriptor item) {
 
textId.setText(item.getId());
this.textId.setText(item.getId());
final ComponentDescritor componentDescritor = getComponentDescritor(item.getComponentId());
if (componentDescritor != null) {
comboComponent.setSelectedItem(componentDescritor);
this.comboComponent.setSelectedItem(componentDescritor);
}
textTable.setText(item.getTable());
this.textTable.setText(item.getTable());
String loc = item.getLocation();
if (loc.equals(ActionDescriptor.LOCATION_HEADER_POPUP)) {
comboLocation.setSelectedIndex(0);
this.comboLocation.setSelectedIndex(0);
} else if (loc.equals(ActionDescriptor.LOCATION_HEADER)) {
comboLocation.setSelectedIndex(2);
this.comboLocation.setSelectedIndex(2);
} else {
comboLocation.setSelectedIndex(1);
this.comboLocation.setSelectedIndex(1);
}
}
 
private ComponentDescritor getComponentDescritor(String componentId) {
List<ComponentDescritor> l = extension.getCreateComponentList();
List<ComponentDescritor> l = this.extension.getCreateComponentList();
for (ComponentDescritor componentDescritor : l) {
if (componentDescritor.getId().equals(componentId)) {
return componentDescritor;
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/AllKnownActionsListModel.java
6,9 → 6,18
import org.openconcerto.ui.DefaultListModel;
 
public class AllKnownActionsListModel extends DefaultListModel {
private final Extension extension;
 
public AllKnownActionsListModel(Extension module) {
List<ActionDescriptor> l = module.getActionDescriptors();
public AllKnownActionsListModel(Extension extension) {
final List<ActionDescriptor> l = extension.getActionDescriptors();
this.addAll(l);
this.extension = extension;
}
 
public void addAction() {
final ActionDescriptor obj = new ActionDescriptor("Action_" + this.size());
this.addElement(obj);
this.extension.addCreateAction(obj);
 
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/ActionListPanel.java
15,14 → 15,14
 
public class ActionListPanel extends EditableListPanel {
 
private ActionMainPanel tableTranslationPanel;
private ActionMainPanel actionPanel;
private Extension extension;
 
public ActionListPanel(Extension extension, ActionMainPanel tableTranslationPanel) {
super(new AllKnownActionsListModel(extension), "Actions", "", true, true);
public ActionListPanel(Extension extension, ActionMainPanel actionPanel) {
super(new AllKnownActionsListModel(extension), "Actions", "Ajouter une action", true, true);
this.extension = extension;
this.tableTranslationPanel = tableTranslationPanel;
list.setCellRenderer(new DefaultListCellRenderer() {
this.actionPanel = actionPanel;
this.list.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
value = ((ActionDescriptor) value).getId();
33,9 → 33,16
 
@Override
public void addNewItem() {
((AllKnownActionsListModel) this.dataModel).addAction();
}
 
@Override
public void removeItem(Object item) {
((AllKnownActionsListModel) this.dataModel).removeElement(item);
this.extension.removeCreateAction((ActionDescriptor) item);
}
 
@Override
public void renameItem(Object item) {
final ActionDescriptor e = (ActionDescriptor) item;
final Window w = SwingUtilities.windowForComponent(this);
42,19 → 49,16
final String s = (String) JOptionPane.showInputDialog(w, "Nouveau nom", "Renommer la liste", JOptionPane.PLAIN_MESSAGE, null, null, e.getId());
if ((s != null) && (s.length() > 0)) {
e.setId(s);
reload();
}
}
 
@Override
public void removeItem(Object item) {
}
 
@Override
public void itemSelected(Object item) {
if (item != null) {
tableTranslationPanel.setRightPanel(new JScrollPane(new ActionItemEditor((ActionDescriptor) item, extension)));
this.actionPanel.setRightPanel(new JScrollPane(new ActionItemEditor((ActionDescriptor) item, this.extension)));
} else {
tableTranslationPanel.setRightPanel(new JPanel());
this.actionPanel.setRightPanel(new JPanel());
}
}
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/ActionDescriptor.java
3,9 → 3,9
public class ActionDescriptor {
 
private String id;
private String location; // header, popup, both
private String table;
private String componentId;
private String location = LOCATION_HEADER_POPUP; // header, popup, both
private String table = "";
private String componentId = "";
public static final String LOCATION_HEADER = "header";
public static final String LOCATION_POPUP = "popup";
public static final String LOCATION_HEADER_POPUP = "header,popup";
15,7 → 15,7
}
 
public String getId() {
return id;
return this.id;
}
 
public void setId(String id) {
23,7 → 23,7
}
 
public String getLocation() {
return location;
return this.location;
}
 
public void setLocation(String location) {
31,7 → 31,7
}
 
public String getTable() {
return table;
return this.table;
}
 
public void setTable(String table) {
39,7 → 39,7
}
 
public String getComponentId() {
return componentId;
return this.componentId;
}
 
public void setComponentId(String componentId) {
46,4 → 46,11
this.componentId = componentId;
}
 
@Override
public boolean equals(Object obj) {
if (obj instanceof ActionDescriptor) {
return this.id.equals(((ActionDescriptor) obj).id);
}
return super.equals(obj);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/CreateTableListModel.java
30,18 → 30,18
// FIXME: ensure table does not exists
final TableDescritor obj = new TableDescritor("TABLE_" + this.size());
this.addElement(obj);
extension.addCreateTable(obj);
this.extension.addCreateTable(obj);
}
 
@Override
public boolean removeElement(Object obj) {
extension.removeCreateTable((TableDescritor) obj);
this.extension.removeCreateTable((TableDescritor) obj);
return super.removeElement(obj);
}
 
@Override
public void stateChanged(ChangeEvent e) {
this.loadContent(extension);
this.loadContent(this.extension);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/ElementDescriptor.java
10,15 → 10,15
}
 
public String getId() {
return id;
return this.id;
}
 
public String getTableName() {
return tableName;
return this.tableName;
}
 
@Override
public String toString() {
return "ElementDescriptor id: " + id + " table: " + tableName;
return "ElementDescriptor id: " + this.id + " table: " + this.tableName;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/FieldDescriptorEditor.java
1,16 → 1,22
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.Vector;
 
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
54,30 → 60,30
this.add(new JLabel("Type"), c);
c.gridx++;
 
comboType = new JComboBox(types);
comboType.setOpaque(false);
this.add(comboType, c);
this.comboType = new JComboBox(this.types);
this.comboType.setOpaque(false);
this.add(this.comboType, c);
c.gridx++;
this.add(new JLabel("Nom"), c);
c.gridx++;
c.weightx = 1;
fieldName = new JTextField(10);
this.add(fieldName, c);
this.fieldName = new JTextField(10);
this.add(this.fieldName, c);
c.weightx = 0;
c.gridx++;
labelOption = new JLabel("Longeur max");
this.add(labelOption, c);
this.labelOption = new JLabel("Longeur max");
this.add(this.labelOption, c);
c.gridx++;
textOption = new JTextField(6);
this.textOption = new JTextField(6);
c.gridx++;
this.add(textOption, c);
comboOption = new JComboBox();
this.add(this.textOption, c);
this.comboOption = new JComboBox();
 
this.add(comboOption, c);
this.add(this.comboOption, c);
 
updateFrom(fd);
comboType.addActionListener(this);
fieldName.getDocument().addDocumentListener(new DocumentListener() {
this.comboType.addActionListener(this);
this.fieldName.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
97,8 → 103,8
 
}
});
comboOption.addActionListener(this);
textOption.getDocument().addDocumentListener(new DocumentListener() {
this.comboOption.addActionListener(this);
this.textOption.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
125,7 → 131,7
if (text.trim().length() > 0) {
this.fd.setName(text);
}
extension.setChanged();
this.extension.setChanged();
 
}
 
136,128 → 142,127
switch (this.comboType.getSelectedIndex()) {
 
case TYPE_STRING:
fd.setLength(text);
fd.setDefaultValue(null);
fd.setForeignTable(null);
fd.setLink(null);
this.fd.setLength(text);
this.fd.setDefaultValue(null);
this.fd.setForeignTable(null);
this.fd.setLink(null);
break;
case TYPE_INTEGER:
fd.setLength(null);
this.fd.setLength(null);
try {
int i = Integer.parseInt(text);
fd.setDefaultValue(text);
this.fd.setDefaultValue(text);
} catch (Exception e) {
fd.setDefaultValue("0");
this.fd.setDefaultValue("0");
}
fd.setForeignTable(null);
fd.setLink(null);
this.fd.setForeignTable(null);
this.fd.setLink(null);
case TYPE_DECIMAL:
fd.setLength(null);
this.fd.setLength(null);
try {
text = text.replace(',', '.');
float i = Float.parseFloat(text);
fd.setDefaultValue(text);
this.fd.setDefaultValue(text);
} catch (Exception e) {
fd.setDefaultValue("0");
this.fd.setDefaultValue("0");
}
fd.setForeignTable(null);
fd.setLink(null);
this.fd.setForeignTable(null);
this.fd.setLink(null);
break;
 
}
extension.setChanged();
this.extension.setChanged();
 
}
}
 
protected void comboOptionModified() {
final int index = comboOption.getSelectedIndex();
final int index = this.comboOption.getSelectedIndex();
 
switch (this.comboType.getSelectedIndex()) {
 
case TYPE_BOOLEAN:
fd.setLength(null);
this.fd.setLength(null);
if (index == 0) {
fd.setDefaultValue("true");
this.fd.setDefaultValue("true");
} else {
fd.setDefaultValue("false");
this.fd.setDefaultValue("false");
}
fd.setForeignTable(null);
fd.setLink(null);
this.fd.setForeignTable(null);
this.fd.setLink(null);
break;
case TYPE_DATE:
case TYPE_TIME:
case TYPE_DATE_TIME:
fd.setLength(null);
this.fd.setLength(null);
if (index == 0) {
fd.setDefaultValue(null);
this.fd.setDefaultValue(null);
} else {
fd.setDefaultValue("now");
this.fd.setDefaultValue("now");
}
fd.setForeignTable(null);
fd.setLink(null);
this.fd.setForeignTable(null);
this.fd.setLink(null);
break;
case TYPE_REF:
fd.setLength(null);
fd.setDefaultValue(null);
fd.setDefaultValue("now");
fd.setForeignTable(comboOption.getSelectedItem().toString());
fd.setLink(null);
this.fd.setLength(null);
this.fd.setDefaultValue(null);
this.fd.setForeignTable(this.comboOption.getSelectedItem().toString());
this.fd.setLink(null);
break;
 
}
extension.setChanged();
this.extension.setChanged();
 
}
 
private void updateFrom(FieldDescriptor fd) {
if (fd.getType().equals("string")) {
comboType.setSelectedIndex(TYPE_STRING);
labelOption.setText("Longueur max");
textOption.setVisible(true);
textOption.setText(fd.getLength());
comboOption.setVisible(false);
this.comboType.setSelectedIndex(TYPE_STRING);
this.labelOption.setText("Longueur max");
this.textOption.setVisible(true);
this.textOption.setText(fd.getLength());
this.comboOption.setVisible(false);
} else if (fd.getType().equals("integer")) {
comboType.setSelectedIndex(TYPE_INTEGER);
labelOption.setText("Valeur par défaut");
textOption.setVisible(true);
textOption.setText(fd.getDefaultValue());
comboOption.setVisible(false);
this.comboType.setSelectedIndex(TYPE_INTEGER);
this.labelOption.setText("Valeur par défaut");
this.textOption.setVisible(true);
this.textOption.setText(fd.getDefaultValue());
this.comboOption.setVisible(false);
} else if (fd.getType().equals("decimal")) {
comboType.setSelectedIndex(TYPE_DECIMAL);
labelOption.setText("Valeur par défaut");
textOption.setVisible(true);
textOption.setText(fd.getDefaultValue());
comboOption.setVisible(false);
this.comboType.setSelectedIndex(TYPE_DECIMAL);
this.labelOption.setText("Valeur par défaut");
this.textOption.setVisible(true);
this.textOption.setText(fd.getDefaultValue());
this.comboOption.setVisible(false);
} else if (fd.getType().equals("boolean")) {
comboType.setSelectedIndex(TYPE_BOOLEAN);
labelOption.setText("Valeur par défaut");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(vBoolean));
this.comboType.setSelectedIndex(TYPE_BOOLEAN);
this.labelOption.setText("Valeur par défaut");
this.textOption.setVisible(false);
this.comboOption.setVisible(true);
this.comboOption.setModel(new DefaultComboBoxModel(vBoolean));
if (fd.getDefaultValue().equals("true")) {
comboOption.setSelectedIndex(0);
this.comboOption.setSelectedIndex(0);
} else {
comboOption.setSelectedIndex(1);
this.comboOption.setSelectedIndex(1);
}
 
} else if (fd.getType().equals("date")) {
comboType.setSelectedIndex(TYPE_DATE);
labelOption.setText("Valeur par défaut");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(vDate));
this.comboType.setSelectedIndex(TYPE_DATE);
this.labelOption.setText("Valeur par défaut");
this.textOption.setVisible(false);
this.comboOption.setVisible(true);
this.comboOption.setModel(new DefaultComboBoxModel(vDate));
if (fd.getDefaultValue() == null || !fd.getDefaultValue().equals("now")) {
comboOption.setSelectedIndex(0);
this.comboOption.setSelectedIndex(0);
} else {
comboOption.setSelectedIndex(1);
this.comboOption.setSelectedIndex(1);
}
} else if (fd.getType().equals("time")) {
comboType.setSelectedIndex(TYPE_TIME);
labelOption.setText("Valeur par défaut");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(vTime));
this.comboType.setSelectedIndex(TYPE_TIME);
this.labelOption.setText("Valeur par défaut");
this.textOption.setVisible(false);
this.comboOption.setVisible(true);
this.comboOption.setModel(new DefaultComboBoxModel(vTime));
if (fd.getDefaultValue() == null || !fd.getDefaultValue().equals("now")) {
comboOption.setSelectedIndex(0);
} else {
279,8 → 284,27
labelOption.setText("Table");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(getTables()));
final Vector<String> tables = new Vector<String>();
tables.addAll(Arrays.asList(getTables()));
String tableName = fd.getForeignTable();
if (!tables.contains(tableName)) {
tables.add(tableName);
}
comboOption.setModel(new DefaultComboBoxModel<String>(tables));
comboOption.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value.toString().trim().isEmpty()) {
value = "!! non renseignée !!";
}
DefaultListCellRenderer r = (DefaultListCellRenderer) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (!tables.contains(value)) {
r.setForeground(Color.RED);
}
return r;
}
 
});
comboOption.setSelectedItem(tableName);
} else {
throw new IllegalArgumentException("Unknow type " + fd.getType());
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableModifyLeftPanel.java
53,24 → 53,24
 
private JComponent createModifiedTableList(final Extension extension) {
final ModifiedTableListModel dataModel = new ModifiedTableListModel(extension);
listTableModified = new JList(dataModel);
listTableModified.addListSelectionListener(new ListSelectionListener() {
this.listTableModified = new JList(dataModel);
this.listTableModified.addListSelectionListener(new ListSelectionListener() {
 
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
final TableDescritor tableDesc = (TableDescritor) listTableModified.getSelectedValue();
final TableDescritor tableDesc = (TableDescritor) TableModifyLeftPanel.this.listTableModified.getSelectedValue();
if (tableDesc != null) {
System.out.println("TableModifyLeftPanel.createModifiedTableList.valueChanged():" + tableDesc);
final TableModifyPanel p = new TableModifyPanel(extension.getSQLTable(tableDesc), tableDesc, extension, TableModifyLeftPanel.this);
tableModifyMainPanel.setRightPanel(p);
listTableAll.clearSelection();
TableModifyLeftPanel.this.tableModifyMainPanel.setRightPanel(p);
TableModifyLeftPanel.this.listTableAll.clearSelection();
}
}
 
}
});
final JScrollPane comp2 = new JScrollPane(listTableModified);
final JScrollPane comp2 = new JScrollPane(this.listTableModified);
comp2.setMinimumSize(new Dimension(250, 150));
comp2.setPreferredSize(new Dimension(250, 150));
return comp2;
78,25 → 78,25
 
private JComponent createAllTableList(final Extension extension) {
final AllTableListModel dataModel = new AllTableListModel(extension);
listTableAll = new JList(dataModel);
listTableAll.addListSelectionListener(new ListSelectionListener() {
this.listTableAll = new JList(dataModel);
this.listTableAll.addListSelectionListener(new ListSelectionListener() {
 
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
final SQLTable table = (SQLTable) listTableAll.getSelectedValue();
final SQLTable table = (SQLTable) TableModifyLeftPanel.this.listTableAll.getSelectedValue();
if (table != null) {
System.out.println("TableModifyLeftPanel.createAllTableList.valueChanged():" + table);
final TableModifyPanel p = new TableModifyPanel(table, extension.getOrCreateTableDescritor(table.getName()), extension, TableModifyLeftPanel.this);
tableModifyMainPanel.setRightPanel(p);
listTableModified.clearSelection();
TableModifyLeftPanel.this.tableModifyMainPanel.setRightPanel(p);
TableModifyLeftPanel.this.listTableModified.clearSelection();
}
}
 
}
});
listTableAll.setCellRenderer(new SQLTableListCellRenderer());
final JScrollPane comp2 = new JScrollPane(listTableAll);
this.listTableAll.setCellRenderer(new SQLTableListCellRenderer());
final JScrollPane comp2 = new JScrollPane(this.listTableAll);
comp2.setMinimumSize(new Dimension(150, 150));
comp2.setPreferredSize(new Dimension(150, 150));
return comp2;
105,11 → 105,11
public void selectTable(String tableName) {
System.out.println("TableModifyLeftPanel.selectTable():" + tableName);
if (tableName != null) {
TableDescritor tableDesc = extension.getOrCreateTableDescritor(tableName);
final TableModifyPanel p = new TableModifyPanel(extension.getSQLTable(tableDesc), tableDesc, extension, TableModifyLeftPanel.this);
tableModifyMainPanel.setRightPanel(p);
listTableAll.clearSelection();
listTableModified.clearSelection();
TableDescritor tableDesc = this.extension.getOrCreateTableDescritor(tableName);
final TableModifyPanel p = new TableModifyPanel(this.extension.getSQLTable(tableDesc), tableDesc, this.extension, TableModifyLeftPanel.this);
this.tableModifyMainPanel.setRightPanel(p);
this.listTableAll.clearSelection();
this.listTableModified.clearSelection();
}
}
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableCreatePanel.java
70,7 → 70,7
 
c.weightx = 1;
c.gridx = 0;
final FieldDescriptorEditor editor = new FieldDescriptorEditor(extension, field);
final FieldDescriptorEditor editor = new FieldDescriptorEditor(this.extension, field);
p.add(editor, c);
 
c.gridx++;
86,7 → 86,7
p.remove(editor);
p.remove(close);
p.revalidate();
extension.setChanged();
TableCreatePanel.this.extension.setChanged();
}
});
c.gridy++;
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableModifyInfoPanel.java
176,7 → 176,7
private void addField(final TableDescritor desc, final JPanel p, GridBagConstraints c, final FieldDescriptor field) {
c.weightx = 1;
c.gridx = 0;
final FieldDescriptorEditor editor = new FieldDescriptorEditor(extension, field);
final FieldDescriptorEditor editor = new FieldDescriptorEditor(this.extension, field);
p.add(editor, c);
 
c.gridx++;
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableCreateMainPanel.java
12,11 → 12,11
}
 
public void select(TableDescritor tableDescriptor) {
((TableListPanel) leftComponent).selectItem(tableDescriptor);
((TableListPanel) this.leftComponent).selectItem(tableDescriptor);
}
 
@Override
public JComponent createLeftComponent() {
return new TableListPanel(extension, this);
return new TableListPanel(this.extension, this);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableListPanel.java
23,7 → 23,7
 
@Override
public void addNewItem() {
((CreateTableListModel) dataModel).addNewTable();
((CreateTableListModel) this.dataModel).addNewTable();
}
 
@Override
30,7 → 30,7
public void renameItem(Object item) {
final TableDescritor e = (TableDescritor) item;
final Window w = SwingUtilities.windowForComponent(this);
final String s = (String) JOptionPane.showInputDialog(w, "Nouveau nom", "Renommer la liste", JOptionPane.PLAIN_MESSAGE, null, null, e.getName());
final String s = (String) JOptionPane.showInputDialog(w, "Nouveau nom", "Renommer la table", JOptionPane.PLAIN_MESSAGE, null, null, e.getName());
if ((s != null) && (s.length() > 0)) {
e.setName(s);
}
38,8 → 38,8
 
@Override
public void removeItem(Object item) {
((CreateTableListModel) dataModel).removeElement(item);
extension.removeCreateTable((TableDescritor) item);
((CreateTableListModel) this.dataModel).removeElement(item);
this.extension.removeCreateTable((TableDescritor) item);
}
 
@Override
47,10 → 47,10
if (item != null) {
TableDescritor n = (TableDescritor) item;
System.out.println("TableListPanel..valueChanged():" + n);
final TableCreatePanel p = new TableCreatePanel(n, extension);
tableInfoPanel.setRightPanel(new JScrollPane(p));
final TableCreatePanel p = new TableCreatePanel(n, this.extension);
this.tableInfoPanel.setRightPanel(new JScrollPane(p));
} else {
tableInfoPanel.setRightPanel(new JPanel());
this.tableInfoPanel.setRightPanel(new JPanel());
}
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/ModifiedTableListModel.java
32,7 → 32,7
@Override
public void stateChanged(ChangeEvent e) {
this.clear();
addContent(extension);
addContent(this.extension);
this.fireContentsChanged(this, 0, this.getSize());
}
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableDescritor.java
36,9 → 36,9
// Create elements
ComptaPropsConfiguration conf = ComptaPropsConfiguration.getInstanceCompta();
DBRoot root = conf.getRootSociete();
if (conf.getDirectory().getElement(name) == null) {
final SQLTable table = root.getTable(name);
final SQLElement e = new SQLElement("ext." + name, "ext." + name, table) {
if (conf.getDirectory().getElement(this.name) == null) {
final SQLTable table = root.getTable(this.name);
final SQLElement e = new SQLElement("ext." + this.name, "ext." + this.name, table) {
 
@Override
protected List<String> getListFields() {
60,6 → 60,7
l.add("NOM");
} else {
ListDescriptor listDesc = null;
l.clear();
for (ListDescriptor listDescriptor : ext.getCreateListList()) {
if (listDescriptor.getMainTable().equals(getTable().getName())) {
listDesc = listDescriptor;
66,6 → 67,7
break;
}
}
if (listDesc != null) {
for (ColumnDescriptor string : listDesc.getColumns()) {
if (!string.getFieldsPaths().contains(".")) {
l.add(string.getFieldsPaths());
73,6 → 75,12
}
}
}
if (l.isEmpty()) {
if (!getTable().getContentFields().isEmpty()) {
l.add(new ArrayList<>(getTable().getContentFields()).get(0).getName());
}
}
}
return l;
}
 
101,7 → 109,7
return new ExtensionGroupSQLComponent(this, cDescriptor.getGroup());
}
}
JOptionPane.showMessageDialog(new JFrame(), "Unable to create default creation component for table " + name);
JOptionPane.showMessageDialog(new JFrame(), "Unable to create default creation component for table " + TableDescritor.this.name);
return null;
}
};
111,7 → 119,7
}
 
public String getName() {
return name;
return this.name;
}
 
public void setName(String name) {
119,22 → 127,22
}
 
public List<FieldDescriptor> getFields() {
return fields;
return this.fields;
}
 
public void add(FieldDescriptor f) {
fields.add(f);
this.fields.add(f);
 
}
 
public void remove(FieldDescriptor field) {
fields.remove(field);
this.fields.remove(field);
 
}
 
@Override
public String toString() {
return name;
return this.name;
}
 
public void sortFields() {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableMainPanel.java
14,14 → 14,14
public TableMainPanel(Extension extension) {
this.setLayout(new GridLayout(1, 1));
JTabbedPane tab = new JTabbedPane();
component = new TableCreateMainPanel(extension);
tab.addTab("Tables créées par l'extension", component);
this.component = new TableCreateMainPanel(extension);
tab.addTab("Tables créées par l'extension", this.component);
tab.addTab("Tables modifiées", new TableModifyMainPanel(extension));
this.add(tab);
}
 
public void select(TableDescritor tableDescriptor) {
component.select(tableDescriptor);
this.component.select(tableDescriptor);
 
}
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableModifyPanel.java
88,7 → 88,7
private void addField(final TableDescritor desc, final JPanel p, GridBagConstraints c, final FieldDescriptor field) {
c.weightx = 1;
c.gridx = 0;
final FieldDescriptorEditor editor = new FieldDescriptorEditor(extension, field);
final FieldDescriptorEditor editor = new FieldDescriptorEditor(this.extension, field);
p.add(editor, c);
 
c.gridx++;
104,7 → 104,7
p.remove(editor);
p.remove(close);
p.revalidate();
extension.setChanged();
TableModifyPanel.this.extension.setChanged();
}
});
c.gridy++;
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/FieldDescriptor.java
39,14 → 39,14
@Override
public String toString() {
String string = this.table + " " + this.name + " type:" + this.type + " default:" + this.defaultValue + " l:" + this.length + " t:" + this.foreignTable;
if (link != null) {
string += " => " + link.toString();
if (this.link != null) {
string += " => " + this.link.toString();
}
return string;
}
 
public String getName() {
return name;
return this.name;
}
 
public void setName(String name) {
54,7 → 54,7
}
 
public String getType() {
return type;
return this.type;
}
 
public void setType(String type) {
62,7 → 62,7
}
 
public String getDefaultValue() {
return defaultValue;
return this.defaultValue;
}
 
public void setDefaultValue(String defaultValue) {
70,7 → 70,7
}
 
public String getLength() {
return length;
return this.length;
}
 
public void setLength(String length) {
78,7 → 78,7
}
 
public String getTable() {
return table;
return this.table;
}
 
public void setLink(FieldDescriptor fieldDescriptor) {
86,7 → 86,7
}
 
public FieldDescriptor getLink() {
return link;
return this.link;
}
 
public void setForeignTable(String foreignTable) {
94,7 → 94,7
}
 
public String getForeignTable() {
return foreignTable;
return this.foreignTable;
}
 
public String getExtendedLabel() {
111,8 → 111,8
public boolean equals(Object obj) {
if (obj instanceof FieldDescriptor) {
FieldDescriptor f = (FieldDescriptor) obj;
if (getTable().equals(f.getTable()) && getName().equals(f.getTable())) {
return getLink() != null && getLink().equals(f.getLink());
if (getTable().equals(f.getTable()) && getName().equals(f.getName())) {
return (getLink() == null && f.getLink() == null) || (getLink() != null && getLink().equals(f.getLink()));
} else {
return false;
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableModifyMainPanel.java
14,13 → 14,13
public TableModifyMainPanel(Extension extension) {
this.setLayout(new GridLayout(1, 1));
final TableModifyLeftPanel newLeftComponent = new TableModifyLeftPanel(extension, this);
split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, newLeftComponent, new JPanel());
this.add(split);
this.split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, newLeftComponent, new JPanel());
this.add(this.split);
}
 
public void setRightPanel(JComponent p) {
this.invalidate();
split.setRightComponent(p);
this.split.setRightComponent(p);
this.revalidate();
this.repaint();
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionInfoPanel.java
113,16 → 113,16
final JButton startButton = new JButton("Démarrer");
 
panel.add(startButton);
startButton.setEnabled(!extension.isStarted());
startButton.setEnabled(!this.extension.isStarted());
final JButton stopButton = new JButton("Arrêter");
panel.add(stopButton);
stopButton.setEnabled(extension.isStarted());
stopButton.setEnabled(this.extension.isStarted());
final JButton saveButton = new JButton("Enregister");
saveButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
extension.save();
ExtensionInfoPanel.this.extension.save();
 
}
});
137,10 → 137,10
 
@Override
public void actionPerformed(ActionEvent e) {
String xml = extension.toXML();
String xml = ExtensionInfoPanel.this.extension.toXML();
System.out.println(xml);
FileDialog fDialog = new FileDialog(new JFrame(), "Export", FileDialog.SAVE);
fDialog.setFile(extension.getName() + ".ocext");
fDialog.setFile(ExtensionInfoPanel.this.extension.getName() + ".ocext");
fDialog.setVisible(true);
String fileName = fDialog.getFile();
if (fileName != null) {
225,17 → 225,17
 
}
// Create extension from XML
extension.stop();
ExtensionInfoPanel.this.extension.stop();
if (!xml.isEmpty()) {
if (!extension.isEmpty()) {
if (!ExtensionInfoPanel.this.extension.isEmpty()) {
int result = JOptionPane.showConfirmDialog(ExtensionInfoPanel.this, "Attention l'extension actuelle sera écrasée.\nContinuer l'importation?");
if (result != JOptionPane.YES_OPTION) {
return;
}
}
extension.clearAll();
extension.importFromXML(xml);
extension.setChanged();
ExtensionInfoPanel.this.extension.clearAll();
ExtensionInfoPanel.this.extension.importFromXML(xml);
ExtensionInfoPanel.this.extension.setChanged();
}
 
}
251,11 → 251,25
public void run() {
final DBRoot root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
try {
extension.start(root, false);
} catch (SQLException e1) {
e1.printStackTrace();
ExtensionInfoPanel.this.extension.start(root, false);
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
reload.setMode(ReloadPanel.MODE_EMPTY);
}
});
} catch (SQLException e) {
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
reload.setMode(ReloadPanel.MODE_BLINK);
}
});
ExceptionHandler.handle("Start error", e);
}
}
}).start();
}
});
267,8 → 281,27
new Thread(new Runnable() {
@Override
public void run() {
extension.stop();
try {
ExtensionInfoPanel.this.extension.stop();
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
reload.setMode(ReloadPanel.MODE_EMPTY);
}
});
} catch (Exception e) {
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
reload.setMode(ReloadPanel.MODE_BLINK);
}
});
ExceptionHandler.handle("Stop error", e);
}
 
}
}).start();
}
});
334,7 → 367,7
// --------- UI
panel.add(new JLabelBold("Interfaces de saisie"), c);
c.gridy++;
List<ComponentDescritor> createComponentList = extension.getCreateComponentList();
List<ComponentDescritor> createComponentList = this.extension.getCreateComponentList();
if (createComponentList.size() > 0) {
String components = "";
for (int i = 0; i < createComponentList.size(); i++) {
363,7 → 396,7
// --------- LIST
panel.add(new JLabelBold("Listes"), c);
c.gridy++;
List<ListDescriptor> createListList = extension.getCreateListList();
List<ListDescriptor> createListList = this.extension.getCreateListList();
if (createListList.size() > 0) {
String components = "";
for (int i = 0; i < createListList.size(); i++) {
391,9 → 424,9
// --------- MENUS
panel.add(new JLabelBold("Menus et actions"), c);
c.gridy++;
final int actionCount = extension.getActionDescriptors().size();
final int menuCount = extension.getCreateMenuList().size();
final int menuCount2 = extension.getRemoveMenuList().size();
final int actionCount = this.extension.getActionDescriptors().size();
final int menuCount = this.extension.getCreateMenuList().size();
final int menuCount2 = this.extension.getRemoveMenuList().size();
if (actionCount > 0) {
if (actionCount > 1)
panel.add(new JLabel(actionCount + " actions"), c);
427,9 → 460,9
panel.add(new JLabelBold("Traductions et renommage de labels"), c);
c.gridy++;
 
int actionTranslationCount = extension.getActionTranslations().size();
int menuTranslationCount = extension.getMenuTranslations().size();
int fieldTranslationCount = extension.getFieldTranslations().size();
int actionTranslationCount = this.extension.getActionTranslations().size();
int menuTranslationCount = this.extension.getMenuTranslations().size();
int fieldTranslationCount = this.extension.getFieldTranslations().size();
if (fieldTranslationCount > 0) {
if (fieldTranslationCount > 1)
panel.add(new JLabel(fieldTranslationCount + " traductions de champs"), c);
504,32 → 537,32
}
 
private void openTableEditor() {
final TableMainPanel contentPane = new TableMainPanel(extension);
openEditor(frameTableEditor, contentPane, "Tables dans la base de données");
final TableMainPanel contentPane = new TableMainPanel(this.extension);
openEditor(this.frameTableEditor, contentPane, "Tables dans la base de données");
 
}
 
private void openListEditor() {
final ListCreateMainPanel contentPane = new ListCreateMainPanel(extension);
openEditor(frameListEditor, contentPane, "Listes personnalisées");
final ListCreateMainPanel contentPane = new ListCreateMainPanel(this.extension);
openEditor(this.frameListEditor, contentPane, "Listes personnalisées");
 
}
 
protected void openComponentEditor() {
final ComponentCreateMainPanel contentPane = new ComponentCreateMainPanel(extension);
openEditor(frameListEditor, contentPane, "Interfaces personnalisées");
final ComponentCreateMainPanel contentPane = new ComponentCreateMainPanel(this.extension);
openEditor(this.frameListEditor, contentPane, "Interfaces personnalisées");
 
}
 
protected void openMenuEditor() {
final MenuMainPanel contentPane = new MenuMainPanel(extension);
openEditor(frameMenuEditor, contentPane, "Menus et actions");
final MenuMainPanel contentPane = new MenuMainPanel(this.extension);
openEditor(this.frameMenuEditor, contentPane, "Menus et actions");
 
}
 
protected void openTranslationEditor() {
final TranslationMainPanel contentPane = new TranslationMainPanel(extension);
openEditor(frameTranslationEditor, contentPane, "Traductions");
final TranslationMainPanel contentPane = new TranslationMainPanel(this.extension);
openEditor(this.frameTranslationEditor, contentPane, "Traductions");
 
}
 
536,7 → 569,7
private void openEditor(JFrame frame, JPanel mainPanel, String title) {
if (frame == null) {
frame = new JFrame();
frame.setTitle(extension.getName() + " - " + title);
frame.setTitle(this.extension.getName() + " - " + title);
frame.setContentPane(mainPanel);
frame.setMinimumSize(new Dimension(796, 560));
frame.pack();
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ClickableLabel.java
25,7 → 25,7
 
public void paint(Graphics g) {
super.paint(g);
if (mouseOver) {
if (this.mouseOver) {
Rectangle r = g.getClipBounds();
final int y1 = r.height - getFontMetrics(getFont()).getDescent() + 1;
g.drawLine(0, y1, getFontMetrics(getFont()).stringWidth(getText()), y1);
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/Extension.java
91,22 → 91,22
public class Extension {
 
// Descriptors of the extension
private List<ElementDescriptor> elementList = new ArrayList<ElementDescriptor>();
private List<TableDescritor> createTableList = new ArrayList<TableDescritor>();
private List<TableDescritor> modifyTableList = new ArrayList<TableDescritor>();
private List<ListDescriptor> createListList = new ArrayList<ListDescriptor>();
private List<TableTranslation> tableTranslations = new ArrayList<TableTranslation>();
private List<FieldTranslation> fieldTranslations = new ArrayList<FieldTranslation>();
private List<MenuTranslation> menuTranslations = new ArrayList<MenuTranslation>();
private List<ActionTranslation> actionTranslations = new ArrayList<ActionTranslation>();
private List<ComponentDescritor> createComponentList = new ArrayList<ComponentDescritor>();
private List<ComponentDescritor> modifyComponentList = new ArrayList<ComponentDescritor>();
private List<MenuDescriptor> createMenuList = new ArrayList<MenuDescriptor>();
private List<MenuDescriptor> removeMenuList = new ArrayList<MenuDescriptor>();
private List<ActionDescriptor> createActionList = new ArrayList<ActionDescriptor>();
private List<ElementDescriptor> elementList = new ArrayList<>();
private List<TableDescritor> createTableList = new ArrayList<>();
private List<TableDescritor> modifyTableList = new ArrayList<>();
private List<ListDescriptor> createListList = new ArrayList<>();
private List<TableTranslation> tableTranslations = new ArrayList<>();
private List<FieldTranslation> fieldTranslations = new ArrayList<>();
private List<MenuTranslation> menuTranslations = new ArrayList<>();
private List<ActionTranslation> actionTranslations = new ArrayList<>();
private List<ComponentDescritor> createComponentList = new ArrayList<>();
private List<ComponentDescritor> modifyComponentList = new ArrayList<>();
private List<MenuDescriptor> createMenuList = new ArrayList<>();
private List<MenuDescriptor> removeMenuList = new ArrayList<>();
private List<ActionDescriptor> createActionList = new ArrayList<>();
 
// Listeners
private List<ChangeListener> listeners = new ArrayList<ChangeListener>();
private List<ChangeListener> listeners = new ArrayList<>();
 
private String name;
private boolean notSaved;
119,24 → 119,24
}
 
public void clearAll() {
elementList.clear();
createTableList.clear();
modifyTableList.clear();
createListList.clear();
tableTranslations.clear();
fieldTranslations.clear();
menuTranslations.clear();
actionTranslations.clear();
createComponentList.clear();
modifyComponentList.clear();
createMenuList.clear();
removeMenuList.clear();
createActionList.clear();
listeners.clear();
this.elementList.clear();
this.createTableList.clear();
this.modifyTableList.clear();
this.createListList.clear();
this.tableTranslations.clear();
this.fieldTranslations.clear();
this.menuTranslations.clear();
this.actionTranslations.clear();
this.createComponentList.clear();
this.modifyComponentList.clear();
this.createMenuList.clear();
this.removeMenuList.clear();
this.createActionList.clear();
this.listeners.clear();
 
notSaved = true;
autoStart = false;
isStarted = false;
this.notSaved = true;
this.autoStart = false;
this.isStarted = false;
 
}
 
145,7 → 145,7
}
 
public boolean isAutoStart() {
return autoStart;
return this.autoStart;
}
 
public void start(DBRoot root, boolean inModuleStart) throws SQLException {
156,14 → 156,13
Log.get().severe("Extension " + this.getName() + " not started due to database error");
return;
}
// Register translations
registerTranslations(root);
// Create menus
if (!inModuleStart) {
final MenuAndActions copy = MenuManager.getInstance().copyMenuAndActions();
registerMenuActions(copy);
// Register translations before setting menu
registerTranslations(root);
MenuManager.getInstance().setMenuAndActions(copy);
}
 
Log.get().info("Extension " + this.getName() + " started");
this.isStarted = true;
this.autoStart = true;
282,21 → 281,14
}
}, menuDescriptor.getId(), true);
}
} else if (menuDescriptor.getType().equals(MenuDescriptor.LIST)) {
// No action to register
} else if (menuDescriptor.getType().equals(MenuDescriptor.GROUP)) {
// TODO
} else {
Log.get().warning("unknown type " + menuDescriptor.getType());
}
}
 
// System.err.println("****" + MenuManager.getInstance().getActionForId("test1"));
//
// final MenuAndActions copy = MenuManager.getInstance().copyMenuAndActions();
// // create group
// final Group group = copy.getGroup();
initMenuGroup(menuAndActions.getGroup());
// MenuManager.getInstance().setMenuAndActions(copy);
// System.err.println("*******" + MenuManager.getInstance().getActionForId("test1"));
}
 
public SQLTableModelSourceOnline createSource(SQLElement element, ListSQLRequest req, ListDescriptor listDesc) {
305,7 → 297,7
for (ColumnDescriptor cDesc : listDesc.getColumns()) {
final String fieldspath = cDesc.getFieldsPaths();
final String[] paths = fieldspath.split(",");
final Set<FieldPath> fps = new LinkedHashSet<FieldPath>();
final Set<FieldPath> fps = new LinkedHashSet<>();
for (int i = 0; i < paths.length; i++) {
// LOCAL, id_batiment.id_site.nom
final SQLName name = SQLName.parse(paths[i].trim());
417,13 → 409,13
}
 
private boolean setupDatabase(DBRoot root) throws SQLException {
List<ChangeTable<?>> changesToApply = new ArrayList<ChangeTable<?>>();
List<SQLCreateTable> createToApply = new ArrayList<SQLCreateTable>();
List<ChangeTable<?>> changesToApply = new ArrayList<>();
List<SQLCreateTable> createToApply = new ArrayList<>();
// Create fields and tables if needed
final List<TableDescritor> t = new ArrayList<TableDescritor>();
final List<TableDescritor> t = new ArrayList<>();
t.addAll(this.createTableList);
t.addAll(this.modifyTableList);
Set<String> tableNames = new HashSet<String>();
Set<String> tableNames = new HashSet<>();
for (TableDescritor tDesc : t) {
String tableName = tDesc.getName();
tableNames.add(tableName);
483,7 → 475,6
createTable.addDateAndTimeColumn(fieldName);
} else if (type.equals(FieldDescriptor.TYPE_REF)) {
// created later
mustAdd = false;
}
mustAdd = true;
} else {
520,6 → 511,11
final SQLField f = (table == null) ? null : table.getFieldRaw(fDesc.getName());
if (f == null && fDesc.getType().equals(FieldDescriptor.TYPE_REF)) {
final String fTableName = fDesc.getForeignTable();
if (fTableName == null || fTableName.isEmpty()) {
JOptionPane.showMessageDialog(new JFrame(),
"L'extension ne peut pas s'installer car le champs référence " + fDesc.getName() + " de la table " + tDesc.getName() + " ne définit pas de table étrangère");
return false;
} else {
final SQLTable fTable = root.getTable(fTableName);
if (fTable != null) {
final AlterTable mTable = new AlterTable(table);
532,6 → 528,7
}
}
}
}
// Create foreign keys
if (!changesToApply.isEmpty()) {
for (String change : ChangeTable.cat(changesToApply)) {
558,7 → 555,7
}
 
public String getName() {
return name;
return this.name;
}
 
@SuppressWarnings("unchecked")
593,7 → 590,7
FieldDescriptor f = createFieldDescriptorFrom(name, field);
tDesc.add(f);
}
if (tDesc.getFields().size() > 0) {
if (!tDesc.getFields().isEmpty()) {
if (type.equals("create")) {
this.createTableList.add(tDesc);
} else if (type.equals("modify")) {
657,7 → 654,7
listDesc.setMainTable(mainTable);
final List<Element> columns = eList.getChildren("column");
for (Element field : columns) {
ColumnDescriptor f = createColumnDescriptorFrom(mainTable, field);
ColumnDescriptor f = createColumnDescriptorFrom(field);
listDesc.add(f);
}
if (listDesc.getColumnCount() > 0) {
756,7 → 753,7
e.printStackTrace();
}
}
notSaved = false;
this.notSaved = false;
 
fireChanged();
}
824,20 → 821,20
rootElement.addContent(eTable);
}
// Translations
final HashSet<String> locales = new HashSet<String>();
for (Translation tr : tableTranslations) {
final HashSet<String> locales = new HashSet<>();
for (Translation tr : this.tableTranslations) {
locales.add(tr.getLocale());
}
for (Translation tr : fieldTranslations) {
for (Translation tr : this.fieldTranslations) {
locales.add(tr.getLocale());
}
for (Translation tr : menuTranslations) {
for (Translation tr : this.menuTranslations) {
locales.add(tr.getLocale());
}
for (Translation tr : actionTranslations) {
for (Translation tr : this.actionTranslations) {
locales.add(tr.getLocale());
}
final List<String> lLocales = new ArrayList<String>(locales);
final List<String> lLocales = new ArrayList<>(locales);
Collections.sort(lLocales);
for (String locale : lLocales) {
final Element eTranslation = new Element("translation");
844,7 → 841,7
eTranslation.setAttribute("locale", locale);
rootElement.addContent(eTranslation);
// Tables
for (TableTranslation tTranslation : tableTranslations) {
for (TableTranslation tTranslation : this.tableTranslations) {
if (tTranslation.getLocale().equals(locale)) {
final Element eTable = new Element("element");
eTable.setAttribute("refid", tTranslation.getTableName());
856,7 → 853,7
if (plural != null && !plural.isEmpty()) {
eTable.setAttribute("plural", plural);
}
for (FieldTranslation fTranslation : fieldTranslations) {
for (FieldTranslation fTranslation : this.fieldTranslations) {
// Fields
if (fTranslation.getLocale().equals(locale) && fTranslation.getTableName().equals(tTranslation.getTableName())) {
final Element eField = new Element("item");
873,7 → 870,7
}
}
// Menus
for (MenuTranslation tMenu : menuTranslations) {
for (MenuTranslation tMenu : this.menuTranslations) {
if (tMenu.getLocale().equals(locale)) {
final Element eMenu = new Element("menu");
eMenu.setAttribute("refid", tMenu.getId());
883,7 → 880,7
}
 
// Actions
for (ActionTranslation tAction : actionTranslations) {
for (ActionTranslation tAction : this.actionTranslations) {
if (tAction.getLocale().equals(locale)) {
final Element eMenu = new Element("action");
eMenu.setAttribute("refid", tAction.getId());
1076,7 → 1073,7
return f;
}
 
private ColumnDescriptor createColumnDescriptorFrom(String table, Element field) {
private ColumnDescriptor createColumnDescriptorFrom(Element field) {
final ColumnDescriptor f = new ColumnDescriptor(field.getAttributeValue("id"));
f.setFieldsPaths(field.getAttributeValue("fields"));
f.setStyle(field.getAttributeValue("style"));
1084,7 → 1081,7
}
 
private void fireChanged() {
for (ChangeListener listener : listeners) {
for (ChangeListener listener : this.listeners) {
listener.stateChanged(new ChangeEvent(this));
}
 
1091,7 → 1088,7
}
 
public List<TableDescritor> getCreateTableList() {
return createTableList;
return this.createTableList;
}
 
public void addCreateTable(TableDescritor value) {
1105,11 → 1102,11
}
 
public List<TableDescritor> getModifyTableList() {
return modifyTableList;
return this.modifyTableList;
}
 
public List<ListDescriptor> getCreateListList() {
return createListList;
return this.createListList;
}
 
public ListDescriptor getCreateListFromId(String id) {
1154,8 → 1151,7
 
public SQLTable getSQLTable(TableDescritor tableDesc) {
try {
SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(tableDesc.getName());
return t;
return ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(tableDesc.getName());
} catch (Exception e) {
return null;
}
1207,8 → 1203,8
}
 
public List<String> getAllKnownTableNames() {
final List<String> l = new ArrayList<String>();
final Set<String> s = new HashSet<String>();
final List<String> l = new ArrayList<>();
final Set<String> s = new HashSet<>();
for (SQLTable t : AllTableListModel.getAllDatabaseTables()) {
s.add(t.getName());
}
1240,7 → 1236,7
}
 
public List<String> getTranslatedFieldOfTable(String tableName) {
final List<String> l = new ArrayList<String>();
final List<String> l = new ArrayList<>();
for (FieldTranslation tr : this.fieldTranslations) {
if (tr.getTableName().equals(tableName)) {
l.add(tr.getFieldName());
1281,7 → 1277,7
}
 
public List<MenuDescriptor> getCreateMenuList() {
return createMenuList;
return this.createMenuList;
}
 
public void addCreateMenu(MenuDescriptor desc) {
1298,7 → 1294,7
}
 
public List<MenuDescriptor> getRemoveMenuList() {
return removeMenuList;
return this.removeMenuList;
}
 
public void addRemoveMenu(MenuDescriptor desc) {
1307,7 → 1303,7
}
 
public List<String> getAllKnownFieldName(String tableName) {
final Set<String> l = new HashSet<String>();
final Set<String> l = new HashSet<>();
// fields created in the extension
 
final List<TableDescritor> desc = getCreateTableList();
1332,11 → 1328,11
}
}
 
return new ArrayList<String>(l);
return new ArrayList<>(l);
}
 
public List<String> getAllKnownActionNames() {
ArrayList<String> s = new ArrayList<String>();
final Set<String> s = new HashSet<>();
Collection<SQLElement> elements = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElements();
for (SQLElement element : elements) {
Collection<IListeAction> actions = element.getRowActions();
1349,12 → 1345,13
}
}
}
Collections.sort(s);
return s;
final List<String> list = new ArrayList<>(s);
Collections.sort(list);
return list;
}
 
public List<String> getActionNames() {
ArrayList<String> s = new ArrayList<String>();
ArrayList<String> s = new ArrayList<>();
for (ActionDescriptor action : this.createActionList) {
s.add(action.getId());
}
1373,9 → 1370,20
return this.createActionList;
}
 
public void addCreateAction(ActionDescriptor obj) {
this.createActionList.add(obj);
setChanged();
}
 
public void removeCreateAction(ActionDescriptor obj) {
this.createActionList.remove(obj);
setChanged();
}
 
public boolean isEmpty() {
return createTableList.isEmpty() && modifyTableList.isEmpty() && createListList.isEmpty() && tableTranslations.isEmpty() && fieldTranslations.isEmpty() && menuTranslations.isEmpty()
&& actionTranslations.isEmpty() && createComponentList.isEmpty() && modifyComponentList.isEmpty() && createMenuList.isEmpty() && removeMenuList.isEmpty() && createActionList.isEmpty();
return this.createTableList.isEmpty() && this.modifyTableList.isEmpty() && this.createListList.isEmpty() && this.tableTranslations.isEmpty() && this.fieldTranslations.isEmpty()
&& this.menuTranslations.isEmpty() && this.actionTranslations.isEmpty() && this.createComponentList.isEmpty() && this.modifyComponentList.isEmpty() && this.createMenuList.isEmpty()
&& this.removeMenuList.isEmpty() && this.createActionList.isEmpty();
}
 
public String getTableNameForElementId(String id) {
1397,15 → 1405,24
}
 
public List<MenuTranslation> getMenuTranslations() {
return menuTranslations;
return this.menuTranslations;
}
 
public MenuTranslation getMenuTranslation(String menuId, String locale) {
for (MenuTranslation tr : this.menuTranslations) {
if (tr.getId().equals(menuId) && tr.getLocale().equals(locale)) {
return tr;
}
}
return null;
}
 
public List<ActionTranslation> getActionTranslations() {
return actionTranslations;
return this.actionTranslations;
}
 
public List<FieldTranslation> getFieldTranslations() {
return fieldTranslations;
return this.fieldTranslations;
}
 
public void removeChangeListener(ChangeListener listener) {
1429,10 → 1446,10
}
 
public void removeRemoveMenuForId(String id) {
for (int i = removeMenuList.size() - 1; i >= 0; i--) {
final MenuDescriptor m = removeMenuList.get(i);
for (int i = this.removeMenuList.size() - 1; i >= 0; i--) {
final MenuDescriptor m = this.removeMenuList.get(i);
if (m.getId().equals(id)) {
removeMenuList.remove(i);
this.removeMenuList.remove(i);
}
}
 
1439,10 → 1456,10
}
 
public void removeCreateMenuForId(String id) {
for (int i = createMenuList.size() - 1; i >= 0; i--) {
final MenuDescriptor m = createMenuList.get(i);
for (int i = this.createMenuList.size() - 1; i >= 0; i--) {
final MenuDescriptor m = this.createMenuList.get(i);
if (m.getId().equals(id)) {
createMenuList.remove(i);
this.createMenuList.remove(i);
}
}
 
1449,7 → 1466,7
}
 
public MenuDescriptor getRemoveMenuItemFromId(String itemId) {
for (MenuDescriptor m : removeMenuList) {
for (MenuDescriptor m : this.removeMenuList) {
if (m.getId().equals(itemId)) {
return m;
}
1459,9 → 1476,9
 
public void renameMenuItem(String previousId, String newId) {
if (!previousId.equals(newId)) {
final List<MenuDescriptor> descs = new ArrayList<MenuDescriptor>(createMenuList.size() + removeMenuList.size());
descs.addAll(createMenuList);
descs.addAll(removeMenuList);
final List<MenuDescriptor> descs = new ArrayList<>(this.createMenuList.size() + this.removeMenuList.size());
descs.addAll(this.createMenuList);
descs.addAll(this.removeMenuList);
for (MenuDescriptor m : descs) {
if (m.getId().equals(previousId)) {
m.setId(newId);
1473,7 → 1490,7
}
 
public void moveMenuItem(String itemId, String parentId) {
for (MenuDescriptor m : createMenuList) {
for (MenuDescriptor m : this.createMenuList) {
if (m.getId().equals(itemId)) {
m.setInsertInMenu(parentId);
}
1540,4 → 1557,5
fTranslation.setLabel(text);
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/action/ActionListPanel.java
36,9 → 36,9
@Override
public void itemSelected(Object item) {
if (item != null) {
tableTranslationPanel.setRightPanel(new JScrollPane(new MenuTranslationItemEditor(new Item(item.toString()), extension)));
this.tableTranslationPanel.setRightPanel(new JScrollPane(new MenuTranslationItemEditor(new Item(item.toString()), this.extension)));
} else {
tableTranslationPanel.setRightPanel(new JPanel());
this.tableTranslationPanel.setRightPanel(new JPanel());
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/action/ActionTranslation.java
13,11 → 13,11
}
 
public String getId() {
return id;
return this.id;
}
 
public String getLabel() {
return label;
return this.label;
}
 
public void setLabel(String label) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/action/ActionTranslationPanel.java
13,6 → 13,6
 
@Override
public JComponent createLeftComponent() {
return new ActionListPanel(extension, this);
return new ActionListPanel(this.extension, this);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/LocaleSelector.java
36,10 → 36,10
}
 
Collections.sort(langs);
comboLang = new JComboBox(langs);
this.add(comboLang);
comboCountry = new JComboBox();
this.add(comboCountry);
this.comboLang = new JComboBox(langs);
this.add(this.comboLang);
this.comboCountry = new JComboBox();
this.add(this.comboCountry);
 
try {
this.setLocale(Locale.getDefault());
46,36 → 46,36
} catch (Exception e) {
System.err.println("LocaleSelector warning: unable to set current language");
}
comboLang.addActionListener(new ActionListener() {
this.comboLang.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
if (interactive) {
lang = comboLang.getSelectedItem().toString();
if (LocaleSelector.this.interactive) {
LocaleSelector.this.lang = LocaleSelector.this.comboLang.getSelectedItem().toString();
updateCountryFromLang();
country = comboCountry.getSelectedItem().toString();
LocaleSelector.this.country = LocaleSelector.this.comboCountry.getSelectedItem().toString();
fireActionPerformed();
}
}
 
});
comboCountry.addActionListener(new ActionListener() {
this.comboCountry.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
if (interactive) {
country = comboCountry.getSelectedItem().toString();
if (LocaleSelector.this.interactive) {
LocaleSelector.this.country = LocaleSelector.this.comboCountry.getSelectedItem().toString();
fireActionPerformed();
}
}
 
});
final int minWidth = comboLang.getPreferredSize().width * 2;
final int minHeight = comboLang.getPreferredSize().height;
comboLang.setMinimumSize(new Dimension(minWidth, minHeight));
comboLang.setPreferredSize(new Dimension(minWidth, minHeight));
comboCountry.setMinimumSize(new Dimension(minWidth, minHeight));
comboCountry.setPreferredSize(new Dimension(minWidth, minHeight));
final int minWidth = this.comboLang.getPreferredSize().width * 2;
final int minHeight = this.comboLang.getPreferredSize().height;
this.comboLang.setMinimumSize(new Dimension(minWidth, minHeight));
this.comboLang.setPreferredSize(new Dimension(minWidth, minHeight));
this.comboCountry.setMinimumSize(new Dimension(minWidth, minHeight));
this.comboCountry.setPreferredSize(new Dimension(minWidth, minHeight));
}
 
private void updateCountryFromLang() {
84,7 → 84,7
Locale[] l = Locale.getAvailableLocales();
for (int i = 0; i < l.length; i++) {
Locale lo = (Locale) l[i];
if (lo.getLanguage().equals(lang)) {
if (lo.getLanguage().equals(this.lang)) {
countries.add(lo.getCountry());
}
}
92,16 → 92,16
if (countries.isEmpty()) {
countries.add("");
}
comboCountry.setModel(new DefaultComboBoxModel(countries));
this.comboCountry.setModel(new DefaultComboBoxModel(countries));
}
 
public Locale getLocale() {
Locale[] l = Locale.getAvailableLocales();
if (country != null) {
if (this.country != null) {
 
for (int i = 0; i < l.length; i++) {
Locale lo = (Locale) l[i];
if (lo.getLanguage().equals(lang) && lo.getCountry().equals(country)) {
if (lo.getLanguage().equals(this.lang) && lo.getCountry().equals(this.country)) {
return lo;
}
}
108,7 → 108,7
}
for (int i = 0; i < l.length; i++) {
Locale lo = (Locale) l[i];
if (lo.getLanguage().equals(lang)) {
if (lo.getLanguage().equals(this.lang)) {
return lo;
}
}
126,9 → 126,9
this.lang = l.getLanguage();
this.country = l.getCountry();
System.err.println("LocaleSelector.setLocale() " + this.lang + " " + this.country);
this.comboLang.setSelectedItem(lang);
this.comboLang.setSelectedItem(this.lang);
updateCountryFromLang();
this.comboCountry.setSelectedItem(country);
this.comboCountry.setSelectedItem(this.country);
this.interactive = true;
}
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/AllTableListPanel.java
32,9 → 32,9
@Override
public void itemSelected(Object item) {
if (item != null) {
tableTranslationPanel.setRightPanel(new JScrollPane(new TableTranslationEditorPanel(extension, (String) item)));
this.tableTranslationPanel.setRightPanel(new JScrollPane(new TableTranslationEditorPanel(this.extension, (String) item)));
} else {
tableTranslationPanel.setRightPanel(new JPanel());
this.tableTranslationPanel.setRightPanel(new JPanel());
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/TableTranslationEditorPanel.java
64,13 → 64,13
c.fill = GridBagConstraints.BOTH;
final JSeparator sep = new JSeparator(JSeparator.VERTICAL);
this.add(sep, c);
hideableComponents.add(sep);
this.hideableComponents.add(sep);
c.gridheight = 1;
c.weightx = 1;
c.gridx++;
c.fill = GridBagConstraints.NONE;
final LocaleSelector comboLang2 = new LocaleSelector();
hideableComponents.add(comboLang2);
this.hideableComponents.add(comboLang2);
comboLang2.setLocale(Locale.ENGLISH);
this.add(comboLang2, c);
// Singular
81,10 → 81,10
this.add(new JLabel("Singulier", SwingConstants.RIGHT), c);
c.gridx++;
 
this.add(textSingular1, c);
this.add(this.textSingular1, c);
c.gridx += 2;
hideableComponents.add(textSingular2);
this.add(textSingular2, c);
this.hideableComponents.add(this.textSingular2);
this.add(this.textSingular2, c);
 
// Plural
c.gridx = 0;
92,10 → 92,10
c.weightx = 0;
this.add(new JLabel("Pluriel", SwingConstants.RIGHT), c);
c.gridx++;
this.add(textPlural1, c);
this.add(this.textPlural1, c);
c.gridx += 2;
hideableComponents.add(textPlural2);
this.add(textPlural2, c);
this.hideableComponents.add(this.textPlural2);
this.add(this.textPlural2, c);
 
// Fields
c.gridx = 0;
111,7 → 111,7
c.gridx = 2;
c.fill = GridBagConstraints.BOTH;
final JSeparator sep2 = new JSeparator(JSeparator.VERTICAL);
hideableComponents.add(sep2);
this.hideableComponents.add(sep2);
this.add(sep2, c);
 
c.fill = GridBagConstraints.HORIZONTAL;
122,14 → 122,14
this.add(new JLabel(fName, SwingConstants.RIGHT), c);
c.gridx++;
final JTextField t1 = new JTextField();
map1.put(fName, t1);
fieldsMap.put(t1, fName);
this.map1.put(fName, t1);
this.fieldsMap.put(t1, fName);
this.add(t1, c);
c.gridx += 2;
final JTextField t2 = new JTextField();
hideableComponents.add(t2);
fieldsMap.put(t2, fName);
map2.put(fName, t2);
this.hideableComponents.add(t2);
this.fieldsMap.put(t2, fName);
this.map2.put(fName, t2);
this.add(t2, c);
c.gridy++;
}
189,22 → 189,22
}
 
});
for (final JTextField textField : map1.values()) {
for (final JTextField textField : this.map1.values()) {
textField.getDocument().addDocumentListener(new SimpleDocumentListener() {
 
@Override
public void changedUpdate(DocumentEvent e, String text) {
extension.setFieldTranslation(tableName, fieldsMap.get(textField), comboLang1.getLocale(), text);
extension.setFieldTranslation(tableName, TableTranslationEditorPanel.this.fieldsMap.get(textField), comboLang1.getLocale(), text);
}
 
});
}
for (final JTextField textField : map2.values()) {
for (final JTextField textField : this.map2.values()) {
textField.getDocument().addDocumentListener(new SimpleDocumentListener() {
 
@Override
public void changedUpdate(DocumentEvent e, String text) {
extension.setFieldTranslation(tableName, fieldsMap.get(textField), comboLang2.getLocale(), text);
extension.setFieldTranslation(tableName, TableTranslationEditorPanel.this.fieldsMap.get(textField), comboLang2.getLocale(), text);
}
 
});
215,11 → 215,11
private void updateUIFrom(Extension extension, String tableName, Object l1, Object l2) {
if (l1 != null) {
final String lang = l1.toString();
updateUI(extension, tableName, lang, textSingular1, textPlural1, map1);
updateUI(extension, tableName, lang, this.textSingular1, this.textPlural1, this.map1);
}
if (l2 != null) {
final String lang = l2.toString();
updateUI(extension, tableName, lang, textSingular2, textPlural2, map2);
updateUI(extension, tableName, lang, this.textSingular2, this.textPlural2, this.map2);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/FieldTranslation.java
21,19 → 21,19
}
 
public String getTableName() {
return tableName;
return this.tableName;
}
 
public String getFieldName() {
return fieldName;
return this.fieldName;
}
 
public String getLabel() {
return label;
return this.label;
}
 
public String getDocumentation() {
return documentation;
return this.documentation;
}
 
public void setDocumentation(String documentation) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/TableTranslation.java
14,7 → 14,7
}
 
public String getTableName() {
return tableName;
return this.tableName;
}
 
public void setSingular(String singular) {
22,7 → 22,7
}
 
public String getSingular() {
return singular;
return this.singular;
}
 
public void setPlural(String plural) {
30,6 → 30,6
}
 
public String getPlural() {
return plural;
return this.plural;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/TableTranslationPanel.java
10,20 → 10,20
 
public TableTranslationPanel(Extension extension) {
super(extension);
split.setDividerLocation(250);
this.split.setDividerLocation(250);
}
 
public void setRightPanel(JComponent p) {
super.setRightPanel(p);
split.setDividerLocation(250);
this.split.setDividerLocation(250);
}
 
@Override
public JComponent createLeftComponent() {
return new AllTableListPanel(extension, this);
return new AllTableListPanel(this.extension, this);
}
 
public void select(TableDescritor tableDescriptor) {
((AllTableListPanel) leftComponent).selectItem(tableDescriptor);
((AllTableListPanel) this.leftComponent).selectItem(tableDescriptor);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/menu/MenuTranslation.java
13,7 → 13,7
}
 
public String getId() {
return id;
return this.id;
}
 
public void setLabel(String label) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/menu/MenuTranslationPanel.java
36,9 → 36,9
}
 
public void fillModel() {
newModel.fillFromDescriptor(extension);
tree.setModel(newModel);
tree.expandRow(0);
this.newModel.fillFromDescriptor(this.extension);
this.tree.setModel(this.newModel);
this.tree.expandRow(0);
}
 
@Override
54,8 → 54,8
c.insets = new Insets(2, 2, 2, 0);
 
panel.add(new JLabel("Menus"), c);
newModel = new MenuItemTreeModel();
tree = new JTree() {
this.newModel = new MenuItemTreeModel();
this.tree = new JTree() {
@Override
public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
69,10 → 69,10
return userObject.toString();
}
};
tree.setModel(newModel);
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
tree.expandRow(0);
this.tree.setModel(this.newModel);
this.tree.setRootVisible(false);
this.tree.setShowsRootHandles(true);
this.tree.expandRow(0);
final DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer() {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
85,13 → 85,16
if (tr.getUserObject() instanceof Item) {
r.setText(((Item) tr.getUserObject()).getId());
}
if (sel) {
r.setForeground(Color.WHITE);
}
return r;
}
};
 
treeRenderer.setLeafIcon(null);
tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(tree);
this.tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(this.tree);
comp2.setMinimumSize(new Dimension(250, 150));
comp2.setPreferredSize(new Dimension(250, 150));
c.weighty = 1;
101,16 → 104,16
 
// init
 
tree.addMouseListener(new MouseAdapter() {
this.tree.addMouseListener(new MouseAdapter() {
 
@Override
public void mousePressed(MouseEvent e) {
final TreePath selectionPath = tree.getSelectionPath();
final TreePath selectionPath = MenuTranslationPanel.this.tree.getSelectionPath();
if (selectionPath == null) {
setRightPanel(new JPanel());
} else {
Item i = (Item) ((DefaultMutableTreeNode) selectionPath.getLastPathComponent()).getUserObject();
setRightPanel(new MenuTranslationItemEditor(i, extension));
setRightPanel(new MenuTranslationItemEditor(i, MenuTranslationPanel.this.extension));
}
}
});
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/menu/MenuTranslationItemEditor.java
2,6 → 2,8
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Locale;
 
import javax.swing.JLabel;
24,6 → 26,8
private JTextField textId;
private JTextField textTranslation1;
private JTextField textTranslation2;
final LocaleSelector comboLang1;
final LocaleSelector comboLang2;
 
public MenuTranslationItemEditor(final Item item, final Extension extension) {
this.extension = extension;
37,8 → 41,8
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridwidth = 3;
textId = new JTextField();
this.add(textId, c);
this.textId = new JTextField();
this.add(this.textId, c);
 
// Language selector
c.gridx = 0;
50,7 → 54,7
final String[] isoLanguages = Locale.getISOLanguages();
System.out.println(isoLanguages.length);
 
final LocaleSelector comboLang1 = new LocaleSelector();
comboLang1 = new LocaleSelector();
 
c.weightx = 1;
c.gridx++;
67,7 → 71,7
c.weightx = 1;
c.gridx++;
c.fill = GridBagConstraints.NONE;
final LocaleSelector comboLang2 = new LocaleSelector();
comboLang2 = new LocaleSelector();
 
comboLang2.setLocale(Locale.ENGLISH);
this.add(comboLang2, c);
84,16 → 88,16
 
c.weightx = 1;
 
textTranslation1 = new JTextField(20);
this.textTranslation1 = new JTextField(20);
 
this.add(textTranslation1, c);
this.add(this.textTranslation1, c);
 
c.gridx += 2;
c.fill = GridBagConstraints.HORIZONTAL;
 
c.weightx = 1;
textTranslation2 = new JTextField(20);
this.add(textTranslation2, c);
this.textTranslation2 = new JTextField(20);
this.add(this.textTranslation2, c);
 
c.gridy++;
c.weighty = 1;
101,7 → 105,7
 
initUIFrom(item);
 
textTranslation1.getDocument().addDocumentListener(new DocumentListener() {
this.textTranslation1.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
116,11 → 120,11
 
@Override
public void changedUpdate(DocumentEvent e) {
extension.setMenuTranslation(item.getId(), textTranslation1.getText(), comboLang1.getLocale());
extension.setMenuTranslation(item.getId(), MenuTranslationItemEditor.this.textTranslation1.getText(), comboLang1.getLocale());
extension.setChanged();
}
});
textTranslation2.getDocument().addDocumentListener(new DocumentListener() {
this.textTranslation2.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
135,21 → 139,56
 
@Override
public void changedUpdate(DocumentEvent e) {
extension.setMenuTranslation(item.getId(), textTranslation2.getText(), comboLang2.getLocale());
extension.setMenuTranslation(item.getId(), MenuTranslationItemEditor.this.textTranslation2.getText(), comboLang2.getLocale());
extension.setChanged();
}
});
comboLang1.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
MenuTranslation t = extension.getMenuTranslation(textId.getText(), comboLang1.getLocale().toString());
if (t != null) {
textTranslation1.setText(t.getLabel());
} else {
textTranslation1.setText("");
}
}
});
comboLang2.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
MenuTranslation t = extension.getMenuTranslation(textId.getText(), comboLang2.getLocale().toString());
if (t != null) {
textTranslation2.setText(t.getLabel());
} else {
textTranslation2.setText("");
}
}
});
 
}
 
private void initUIFrom(Item item) {
 
final LayoutHints localHint = item.getLocalHint();
System.out.println("ItemEditor.initUIFrom:" + item + " " + localHint);
textId.setEnabled(false);
if (textId != null) {
textId.setText(item.getId());
this.textId.setEnabled(false);
if (this.textId != null) {
this.textId.setText(item.getId());
}
 
MenuTranslation t = extension.getMenuTranslation(textId.getText(), comboLang1.getLocale().toString());
if (t != null) {
textTranslation1.setText(t.getLabel());
} else {
textTranslation1.setText("");
}
t = extension.getMenuTranslation(textId.getText(), comboLang2.getLocale().toString());
if (t != null) {
textTranslation2.setText(t.getLabel());
} else {
textTranslation2.setText("");
}
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/GroupTreeModel.java
19,7 → 19,7
}
 
public void setShowAll(boolean b) {
if (b != showAll) {
if (b != this.showAll) {
this.showAll = b;
System.err.println("GroupTreeModel.setShowAll()" + b);
reload();
68,7 → 68,7
final ActivableMutableTreeNode newChild = new ActivableMutableTreeNode(item);
 
newChild.setActive(n.containsGroupId(item.getId()));
if (showAll || newChild.isActive()) {
if (this.showAll || newChild.isActive()) {
node.add(newChild);
}
if (item instanceof Group) {
102,7 → 102,7
this.componentDescriptor.removeGroup(item);
}
reload(n);
componentDescriptor.fireGroupChanged();
this.componentDescriptor.fireGroupChanged();
}
 
@Override
109,7 → 109,7
protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) {
// To update preview while reordering
super.fireTreeNodesInserted(source, path, childIndices, children);
componentDescriptor.fireGroupChanged();
this.componentDescriptor.fireGroupChanged();
}
 
@Override
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ComponentListPanel.java
22,7 → 22,7
 
@Override
public void addNewItem() {
((CreateComponentListModel) dataModel).addComponentList();
((CreateComponentListModel) this.dataModel).addComponentList();
}
 
@Override
39,8 → 39,8
 
@Override
public void removeItem(Object item) {
((CreateComponentListModel) dataModel).removeElement(item);
extension.removeCreateComponent((ComponentDescritor) item);
((CreateComponentListModel) this.dataModel).removeElement(item);
this.extension.removeCreateComponent((ComponentDescritor) item);
}
 
@Override
47,10 → 47,10
public void itemSelected(Object item) {
if (item != null) {
ComponentDescritor n = (ComponentDescritor) item;
final ComponentCreatePanel p = new ComponentCreatePanel(n, extension);
tableInfoPanel.setRightPanel(p);
final ComponentCreatePanel p = new ComponentCreatePanel(n, this.extension);
this.tableInfoPanel.setRightPanel(p);
} else {
tableInfoPanel.setRightPanel(new JPanel());
this.tableInfoPanel.setRightPanel(new JPanel());
}
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ComponentDescritor.java
16,7 → 16,7
}
 
public String getTable() {
return table;
return this.table;
}
 
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/CreateComponentListModel.java
22,13 → 22,13
@Override
public void stateChanged(ChangeEvent e) {
this.clear();
addContent(extension);
addContent(this.extension);
}
 
public void addComponentList() {
final ComponentDescritor l = new ComponentDescritor("Interface de saisie " + (this.getSize() + 1));
this.addElement(l);
extension.addCreateComponent(l);
this.extension.addCreateComponent(l);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/GroupEditor.java
61,8 → 61,8
c.insets = new Insets(2, 2, 2, 0);
 
panel.add(new JLabelBold("Champs et groupes"), c);
newModel = new ItemTreeModel();
tree = new ReorderableJTree() {
this.newModel = new ItemTreeModel();
this.tree = new ReorderableJTree() {
@Override
public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
76,10 → 76,10
return userObject.toString();
}
};
tree.setModel(newModel);
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
tree.expandRow(0);
this.tree.setModel(this.newModel);
this.tree.setRootVisible(false);
this.tree.setShowsRootHandles(true);
this.tree.expandRow(0);
final DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer() {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
97,8 → 97,8
};
 
treeRenderer.setLeafIcon(null);
tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(tree);
this.tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(this.tree);
comp2.setMinimumSize(new Dimension(250, 150));
comp2.setPreferredSize(new Dimension(250, 150));
c.weighty = 1;
139,7 → 139,7
showHideButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
newModel.toggleActive(tree.getSelectionPath());
GroupEditor.this.newModel.toggleActive(GroupEditor.this.tree.getSelectionPath());
}
});
 
147,36 → 147,36
 
@Override
public void actionPerformed(ActionEvent e) {
newModel.setShowAll(hideCheckbox.isSelected());
setMainTable(n.getTable());
GroupEditor.this.newModel.setShowAll(hideCheckbox.isSelected());
setMainTable(GroupEditor.this.n.getTable());
setRightPanel(new JPanel());
}
});
 
tree.addTreeSelectionListener(new TreeSelectionListener() {
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
 
@Override
public void valueChanged(TreeSelectionEvent e) {
final Object selectedValue = tree.getSelectionPath();
final Object selectedValue = GroupEditor.this.tree.getSelectionPath();
showHideButton.setEnabled((selectedValue != null));
}
});
tree.addMouseListener(new MouseAdapter() {
this.tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
newModel.toggleActive(tree.getSelectionPath());
GroupEditor.this.newModel.toggleActive(GroupEditor.this.tree.getSelectionPath());
}
}
 
@Override
public void mousePressed(MouseEvent e) {
final TreePath selectionPath = tree.getSelectionPath();
final TreePath selectionPath = GroupEditor.this.tree.getSelectionPath();
if (selectionPath == null) {
setRightPanel(new JPanel());
} else {
Item i = (Item) ((DefaultMutableTreeNode) selectionPath.getLastPathComponent()).getUserObject();
setRightPanel(new ItemEditor(i, n));
setRightPanel(new ItemEditor(i, GroupEditor.this.n));
}
}
});
184,31 → 184,31
}
 
protected void addNewGroup() {
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (tree.getModel().getRoot())).getFirstChild();
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (this.tree.getModel().getRoot())).getFirstChild();
DefaultMutableTreeNode node = root;
if (node.getChildCount() > 0) {
node = (DefaultMutableTreeNode) node.getFirstChild();
}
if (tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
if (this.tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) this.tree.getLastSelectedPathComponent();
}
if (node != root) {
DefaultMutableTreeNode newNode = new ActivableMutableTreeNode(new Group("group" + node.getParent().getChildCount() + 1));
final DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
parent.insert(newNode, parent.getIndex(node));
newModel.reload();
tree.setSelectionPath(new TreePath(newModel.getPathToRoot(newNode)));
this.newModel.reload();
this.tree.setSelectionPath(new TreePath(this.newModel.getPathToRoot(newNode)));
}
 
}
 
public void setMainTable(String table) {
n.setTable(table);
this.n.setTable(table);
 
initGroupFromTable(extension.getAllKnownFieldName(table));
newModel.fillFromGroup(n, this.tableGroup);
initGroupFromTable(this.extension.getAllKnownFieldName(table));
this.newModel.fillFromGroup(this.n, this.tableGroup);
 
tree.expandRow(0);
this.tree.expandRow(0);
}
 
public void initGroupFromTable(List<String> fields) {
215,9 → 215,9
System.out.println("GroupEditor.initGroupFromTable()");
System.out.println("GroupEditor.initGroupFromTable Component group");
 
this.tableGroup = new Group(n.getId());
this.tableGroup = new Group(this.n.getId());
for (String field : fields) {
Item i = n.getItemFromId(field);
Item i = this.n.getItemFromId(field);
Item newItem = new Item(field);
 
if (i != null) {
232,11 → 232,11
 
public Group getFilteredGroup() {
// Parcours du Tree
Group filteredGroup = new Group(n.getId());
if (n.getTable() == null) {
throw new IllegalStateException("Not table defined for " + n);
Group filteredGroup = new Group(this.n.getId());
if (this.n.getTable() == null) {
throw new IllegalStateException("Not table defined for " + this.n);
}
walk(newModel, filteredGroup, newModel.getRoot());
walk(this.newModel, filteredGroup, this.newModel.getRoot());
filteredGroup = (Group) filteredGroup.getItem(0);
 
return filteredGroup;
256,7 → 256,7
} else {
final Item item = new Item(userObject.getId());
item.setLocalHint(new LayoutHints(userObject.getLocalHint()));
final SQLTable table = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(n.getTable());
final SQLTable table = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(this.n.getTable());
if (table.contains(userObject.getId())) {
SQLField field = table.getField(userObject.getId());
if (!field.isPrimaryKey() && !field.getName().endsWith("ORDRE") && !field.getName().endsWith("ARCHIVE")) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ItemEditor.java
47,8 → 47,8
c.gridx++;
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
textId = new JTextField(30);
this.add(textId, c);
this.textId = new JTextField(30);
this.add(this.textId, c);
c.gridy++;
} else {
// Label du champs
77,8 → 77,8
c.gridx++;
c.fill = GridBagConstraints.NONE;
c.weightx = 1;
comboType = new JComboBox(new String[] { "normal", "large", "très large" });
this.add(comboType, c);
this.comboType = new JComboBox(new String[] { "normal", "large", "très large" });
this.add(this.comboType, c);
c.gridy++;
}
c.gridx = 0;
92,9 → 92,9
this.add(labelSep, c);
c.gridx++;
c.fill = GridBagConstraints.NONE;
checkSeparated = new JCheckBox();
this.checkSeparated = new JCheckBox();
c.weightx = 1;
this.add(checkSeparated, c);
this.add(this.checkSeparated, c);
c.gridx = 0;
c.gridy++;
if (!this.isEditingGroup) {
104,9 → 104,9
c.gridx++;
c.weightx = 1;
c.fill = GridBagConstraints.NONE;
checkLabel = new JCheckBox();
this.checkLabel = new JCheckBox();
 
this.add(checkLabel, c);
this.add(this.checkLabel, c);
 
c.gridy++;
 
117,8 → 117,8
c.gridx++;
c.fill = GridBagConstraints.NONE;
c.weightx = 1;
checkFillH = new JCheckBox();
this.add(checkFillH, c);
this.checkFillH = new JCheckBox();
this.add(this.checkFillH, c);
c.gridy++;
}
 
129,8 → 129,8
initUIFrom(item);
 
// Listeners
if (isEditingGroup) {
textId.getDocument().addDocumentListener(new DocumentListener() {
if (this.isEditingGroup) {
this.textId.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
146,44 → 146,44
 
@Override
public void changedUpdate(DocumentEvent e) {
item.setId(textId.getText());
item.setId(ItemEditor.this.textId.getText());
component.fireGroupChanged();
 
}
});
}
checkSeparated.addActionListener(new ActionListener() {
this.checkSeparated.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
item.setLocalHint(item.getLocalHint().getBuilder().setSeparated(checkSeparated.isSelected()).build());
item.setLocalHint(item.getLocalHint().getBuilder().setSeparated(ItemEditor.this.checkSeparated.isSelected()).build());
component.fireGroupChanged();
}
});
 
if (!isEditingGroup) {
checkLabel.addActionListener(new ActionListener() {
if (!this.isEditingGroup) {
this.checkLabel.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
item.setLocalHint(item.getLocalHint().getBuilder().setShowLabel(checkLabel.isSelected()).build());
item.setLocalHint(item.getLocalHint().getBuilder().setShowLabel(ItemEditor.this.checkLabel.isSelected()).build());
component.fireGroupChanged();
}
});
checkFillH.addActionListener(new ActionListener() {
this.checkFillH.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
item.setLocalHint(item.getLocalHint().getBuilder().setFillHeight(checkFillH.isSelected()).build());
item.setLocalHint(item.getLocalHint().getBuilder().setFillHeight(ItemEditor.this.checkFillH.isSelected()).build());
component.fireGroupChanged();
}
});
 
comboType.addActionListener(new ActionListener() {
this.comboType.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
int i = comboType.getSelectedIndex();
int i = ItemEditor.this.comboType.getSelectedIndex();
final LayoutHintsBuilder h = item.getLocalHint().getBuilder();
if (i == 0) {
h.setFillWidth(false);
208,20 → 208,20
 
final LayoutHints localHint = item.getLocalHint();
 
checkSeparated.setSelected(localHint.isSeparated());
this.checkSeparated.setSelected(localHint.isSeparated());
 
if (!isEditingGroup) {
if (!this.isEditingGroup) {
if (localHint.fillWidth() && localHint.largeWidth()) {
comboType.setSelectedIndex(2);
this.comboType.setSelectedIndex(2);
} else if (localHint.fillWidth()) {
comboType.setSelectedIndex(1);
this.comboType.setSelectedIndex(1);
} else {
comboType.setSelectedIndex(0);
this.comboType.setSelectedIndex(0);
}
checkFillH.setSelected(localHint.fillHeight());
checkLabel.setSelected(localHint.showLabel());
this.checkFillH.setSelected(localHint.fillHeight());
this.checkLabel.setSelected(localHint.showLabel());
} else {
textId.setText(item.getId());
this.textId.setText(item.getId());
 
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ComponentCreatePanel.java
58,16 → 58,16
c.gridwidth = 2;
c.fill = GridBagConstraints.BOTH;
 
panel = new GroupEditor(n, extension);
this.panel = new GroupEditor(n, extension);
final String mainTable = n.getTable();
if (mainTable == null && comboTable.getModel().getSize() > 0) {
comboTable.setSelectedIndex(0);
panel.setMainTable((String) comboTable.getModel().getElementAt(0));
this.panel.setMainTable((String) comboTable.getModel().getElementAt(0));
} else {
comboTable.setSelectedItem(mainTable);
panel.setMainTable(mainTable);
this.panel.setMainTable(mainTable);
}
this.add(panel, c);
this.add(this.panel, c);
 
final JButton previewButton = new JButton("Prévisualiser");
c.gridy++;
82,7 → 82,7
 
@Override
public void actionPerformed(ActionEvent e) {
panel.setMainTable((String) comboTable.getSelectedItem());
ComponentCreatePanel.this.panel.setMainTable((String) comboTable.getSelectedItem());
 
}
});
96,7 → 96,7
JOptionPane.showMessageDialog(ComponentCreatePanel.this, "La table doit être créée avant de pouvoir prévisualiser.");
return;
}
final Group group = panel.getFilteredGroup();
final Group group = ComponentCreatePanel.this.panel.getFilteredGroup();
 
final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
if (element == null) {
103,17 → 103,17
Log.get().warning("No element for table: " + t.getName());
}
final GroupSQLComponent gComponent = new ExtensionGroupSQLComponent(element, group);
oldGroup = group;
if (previewFrame == null || !previewFrame.isVisible()) {
previewFrame = new JFrame();
previewFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
previewFrame.setTitle("Preview: " + group.getId());
ComponentCreatePanel.this.oldGroup = group;
if (ComponentCreatePanel.this.previewFrame == null || !ComponentCreatePanel.this.previewFrame.isVisible()) {
ComponentCreatePanel.this.previewFrame = new JFrame();
ComponentCreatePanel.this.previewFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
ComponentCreatePanel.this.previewFrame.setTitle("Preview: " + group.getId());
}
final EditPanel panel = new EditPanel(gComponent, EditMode.CREATION);
previewFrame.setContentPane(panel);
previewFrame.pack();
if (!previewFrame.isVisible()) {
FrameUtil.show(previewFrame);
ComponentCreatePanel.this.previewFrame.setContentPane(panel);
ComponentCreatePanel.this.previewFrame.pack();
if (!ComponentCreatePanel.this.previewFrame.isVisible()) {
FrameUtil.show(ComponentCreatePanel.this.previewFrame);
}
 
};
123,15 → 123,15
 
@Override
public void stateChanged(ChangeEvent e) {
if (previewFrame == null || !previewFrame.isVisible()) {
if (ComponentCreatePanel.this.previewFrame == null || !ComponentCreatePanel.this.previewFrame.isVisible()) {
return;
}
final Group group = panel.getFilteredGroup();
if (group.equalsDesc(oldGroup)) {
final Group group = ComponentCreatePanel.this.panel.getFilteredGroup();
if (group.equalsDesc(ComponentCreatePanel.this.oldGroup)) {
// Avoid refresh when group doesn't change
return;
}
oldGroup = group;
ComponentCreatePanel.this.oldGroup = group;
final SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(n.getTable());
if (t == null) {
return;
138,10 → 138,10
}
final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
final GroupSQLComponent gComponent = new ExtensionGroupSQLComponent(element, group);
previewFrame.setContentPane(new EditPanel(gComponent, EditMode.CREATION));
previewFrame.pack();
if (!previewFrame.isVisible()) {
FrameUtil.show(previewFrame);
ComponentCreatePanel.this.previewFrame.setContentPane(new EditPanel(gComponent, EditMode.CREATION));
ComponentCreatePanel.this.previewFrame.pack();
if (!ComponentCreatePanel.this.previewFrame.isVisible()) {
FrameUtil.show(ComponentCreatePanel.this.previewFrame);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ActivableMutableTreeNode.java
14,7 → 14,7
}
 
public boolean isActive() {
return active;
return this.active;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ComponentCreateMainPanel.java
9,12 → 9,12
 
public ComponentCreateMainPanel(Extension extension) {
super(extension);
split.setDividerLocation(0.5D);
this.split.setDividerLocation(0.5D);
}
 
@Override
public JComponent createLeftComponent() {
return new ComponentListPanel(extension, this);
return new ComponentListPanel(this.extension, this);
}
 
public void select(ComponentDescritor listDescriptor) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/GroupDescritor.java
23,7 → 23,7
}
 
public String getId() {
return id;
return this.id;
}
 
public void setId(String id) {
31,7 → 31,7
}
 
public Group getGroup() {
return group;
return this.group;
}
 
@Override
40,7 → 40,7
}
 
public boolean containsGroupId(String gId) {
return containsGroup(group, gId);
return containsGroup(this.group, gId);
}
 
private boolean containsGroup(Item item, String gId) {
61,7 → 61,7
}
 
public Item getItemFromId(String id) {
return getItemFromId(group, id);
return getItemFromId(this.group, id);
}
 
private Item getItemFromId(Item item, String gId) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/MenuMainPanel.java
7,7 → 7,6
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.menu.mainmenu.MainMenuPanel;
import org.openconcerto.modules.extensionbuilder.meu.actions.ActionMainPanel;
 
public class MenuMainPanel extends JPanel {
final MainMenuPanel mainMenuPanel;
15,9 → 14,10
public MenuMainPanel(Extension extension) {
this.setLayout(new GridLayout(1, 1));
JTabbedPane tab = new JTabbedPane();
mainMenuPanel = new MainMenuPanel(extension);
tab.addTab("Menu principal", mainMenuPanel);
tab.addTab("Actions contextuelles", new ActionMainPanel(extension));
this.mainMenuPanel = new MainMenuPanel(extension);
tab.addTab("Menu principal", this.mainMenuPanel);
// TODO : terminer la gestion des actions
// tab.addTab("Actions contextuelles", new ActionMainPanel(extension));
this.add(tab);
}
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/mainmenu/MenuItemEditor.java
59,9 → 59,9
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridwidth = 2;
textId = new JTextField();
this.textId = new JTextField();
 
this.add(textId, c);
this.add(this.textId, c);
c.gridy++;
 
c.gridwidth = 1;
72,13 → 72,13
c.gridx++;
 
c.fill = GridBagConstraints.HORIZONTAL;
comboActionType = new JComboBox();
this.comboActionType = new JComboBox();
 
this.add(comboActionType, c);
this.add(this.comboActionType, c);
c.gridx++;
c.weightx = 1;
comboActionChoice = new JComboBox();
this.add(comboActionChoice, c);
this.comboActionChoice = new JComboBox();
this.add(this.comboActionChoice, c);
 
c.gridy++;
}
87,9 → 87,9
c.gridx = 1;
c.weightx = 0;
c.fill = GridBagConstraints.NONE;
shownInMenu = new JCheckBox("Afficher dans le menu");
this.shownInMenu = new JCheckBox("Afficher dans le menu");
 
this.add(shownInMenu, c);
this.add(this.shownInMenu, c);
 
JPanel spacer = new JPanel();
c.gridx = 1;
100,9 → 100,9
initUIFrom(item.getId());
 
// Listeners
if (!isEditingGroup) {
if (!this.isEditingGroup) {
// comboActionType
comboActionType.addActionListener(new ActionListener() {
this.comboActionType.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
110,14 → 110,14
int type = cb.getSelectedIndex();
if (type == 0) {
// Saisie
comboActionChoice.setModel(new DefaultComboBoxModel(componentIds));
MenuItemEditor.this.comboActionChoice.setModel(new DefaultComboBoxModel(MenuItemEditor.this.componentIds));
 
MenuDescriptor desc = extension.getCreateMenuItemFromId(item.getId());
desc.setType(MenuDescriptor.CREATE);
desc.setListId(null);
if (componentIds.size() > 0) {
comboActionChoice.setSelectedIndex(0);
desc.setComponentId(comboActionChoice.getSelectedItem().toString());
if (MenuItemEditor.this.componentIds.size() > 0) {
MenuItemEditor.this.comboActionChoice.setSelectedIndex(0);
desc.setComponentId(MenuItemEditor.this.comboActionChoice.getSelectedItem().toString());
} else {
desc.setComponentId(null);
}
124,12 → 124,12
extension.setChanged();
} else {
// Liste
comboActionChoice.setModel(new DefaultComboBoxModel(listIds));
MenuItemEditor.this.comboActionChoice.setModel(new DefaultComboBoxModel(MenuItemEditor.this.listIds));
MenuDescriptor desc = extension.getCreateMenuItemFromId(item.getId());
desc.setType(MenuDescriptor.LIST);
if (listIds.size() > 0) {
comboActionChoice.setSelectedIndex(0);
desc.setListId(comboActionChoice.getSelectedItem().toString());
if (MenuItemEditor.this.listIds.size() > 0) {
MenuItemEditor.this.comboActionChoice.setSelectedIndex(0);
desc.setListId(MenuItemEditor.this.comboActionChoice.getSelectedItem().toString());
} else {
desc.setListId(null);
}
139,15 → 139,15
 
}
});
comboActionChoice.addActionListener(new ActionListener() {
this.comboActionChoice.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
MenuDescriptor desc = extension.getCreateMenuItemFromId(item.getId());
if (desc.getType().equals(MenuDescriptor.CREATE)) {
desc.setComponentId(comboActionChoice.getSelectedItem().toString());
desc.setComponentId(MenuItemEditor.this.comboActionChoice.getSelectedItem().toString());
} else if (desc.getType().equals(MenuDescriptor.LIST)) {
desc.setListId(comboActionChoice.getSelectedItem().toString());
desc.setListId(MenuItemEditor.this.comboActionChoice.getSelectedItem().toString());
} else {
desc.setComponentId(null);
desc.setListId(null);
156,13 → 156,13
});
 
}
shownInMenu.addActionListener(new ActionListener() {
this.shownInMenu.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
final boolean selected = shownInMenu.isSelected();
final boolean selected = MenuItemEditor.this.shownInMenu.isSelected();
 
treeModel.setActive(selected, item.getId());
MenuItemEditor.this.treeModel.setActive(selected, item.getId());
}
});
 
169,11 → 169,11
}
 
private void initUIFrom(String itemId) {
boolean hasCreated = extension.getCreateMenuItemFromId(itemId) != null;
textId.setEnabled(hasCreated);
previousId = itemId;
boolean hasCreated = this.extension.getCreateMenuItemFromId(itemId) != null;
this.textId.setEnabled(hasCreated);
this.previousId = itemId;
if (hasCreated) {
textId.getDocument().addDocumentListener(new DocumentListener() {
this.textId.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
187,12 → 187,12
 
@Override
public void changedUpdate(DocumentEvent e) {
String t = textId.getText();
String t = MenuItemEditor.this.textId.getText();
System.err.println("MenuItemEditor.initUIFrom(...).new DocumentListener() {...}.changedUpdate()" + t);
 
if (!previousId.equals(t)) {
treeModel.renameMenuItem(previousId, t);
previousId = t;
if (!MenuItemEditor.this.previousId.equals(t)) {
MenuItemEditor.this.treeModel.renameMenuItem(MenuItemEditor.this.previousId, t);
MenuItemEditor.this.previousId = t;
 
}
}
199,59 → 199,59
});
}
 
shownInMenu.setSelected(extension.getRemoveMenuItemFromId(itemId) == null);
if (textId != null) {
textId.setText(itemId);
this.shownInMenu.setSelected(this.extension.getRemoveMenuItemFromId(itemId) == null);
if (this.textId != null) {
this.textId.setText(itemId);
}
if (!isEditingGroup) {
comboActionType.setEnabled(true);
comboActionChoice.setEnabled(true);
if (!this.isEditingGroup) {
this.comboActionType.setEnabled(true);
this.comboActionChoice.setEnabled(true);
final Action actionForId = MenuManager.getInstance().getActionForId(itemId);
if (hasCreated) {
MenuDescriptor desc = extension.getCreateMenuItemFromId(itemId);
comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Saisie", "Liste" }));
MenuDescriptor desc = this.extension.getCreateMenuItemFromId(itemId);
this.comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Saisie", "Liste" }));
//
final List<ComponentDescritor> compDescList = extension.getCreateComponentList();
componentIds = new Vector<String>(compDescList.size());
final List<ComponentDescritor> compDescList = this.extension.getCreateComponentList();
this.componentIds = new Vector<String>(compDescList.size());
for (ComponentDescritor componentDescritor : compDescList) {
final String id = componentDescritor.getId();
if (id != null) {
componentIds.add(id);
this.componentIds.add(id);
}
}
 
Collections.sort(componentIds);
Collections.sort(this.componentIds);
 
final List<ListDescriptor> listDescList = extension.getCreateListList();
listIds = new Vector<>(listDescList.size());
final List<ListDescriptor> listDescList = this.extension.getCreateListList();
this.listIds = new Vector<>(listDescList.size());
for (ListDescriptor listDescritor : listDescList) {
final String id = listDescritor.getId();
if (id != null) {
listIds.add(id);
this.listIds.add(id);
}
}
 
Collections.sort(listIds);
Collections.sort(this.listIds);
//
 
String type = desc.getType();
if (type.equals(MenuDescriptor.CREATE)) {
final String componentId = desc.getComponentId();
if (!componentIds.contains(componentId) && componentId != null) {
componentIds.add(componentId);
if (!this.componentIds.contains(componentId) && componentId != null) {
this.componentIds.add(componentId);
}
comboActionType.setSelectedIndex(0);
comboActionChoice.setModel(new DefaultComboBoxModel(componentIds));
comboActionChoice.setSelectedItem(componentId);
this.comboActionType.setSelectedIndex(0);
this.comboActionChoice.setModel(new DefaultComboBoxModel(this.componentIds));
this.comboActionChoice.setSelectedItem(componentId);
 
} else if (type.equals(MenuDescriptor.LIST)) {
final String listId = desc.getListId();
if (!listIds.contains(listId) && listId != null) {
listIds.add(listId);
if (!this.listIds.contains(listId) && listId != null) {
this.listIds.add(listId);
}
comboActionType.setSelectedIndex(1);
comboActionChoice.setModel(new DefaultComboBoxModel(listIds));
comboActionChoice.setSelectedItem(listId);
this.comboActionType.setSelectedIndex(1);
this.comboActionChoice.setModel(new DefaultComboBoxModel(this.listIds));
this.comboActionChoice.setSelectedItem(listId);
 
} else {
throw new IllegalArgumentException("Unknown type " + type);
263,14 → 263,14
JFrame frame = a.createFrame();
if (frame != null) {
if (frame instanceof EditFrame) {
comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Saisie" }));
this.comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Saisie" }));
} else if (frame instanceof IListFrame) {
comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Liste" }));
this.comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Liste" }));
} else {
comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Autre" }));
this.comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Autre" }));
}
 
comboActionChoice.setModel(new DefaultComboBoxModel(new String[] { frame.getTitle() }));
this.comboActionChoice.setModel(new DefaultComboBoxModel(new String[] { frame.getTitle() }));
} else {
comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Autre" }));
comboActionChoice.setModel(new DefaultComboBoxModel(new String[] { actionForId.getClass().getName() }));
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/mainmenu/MainMenuGroupEditor.java
49,20 → 49,20
}
 
public void fillModel() {
newModel.fillFromDescriptor(extension);
tree.setModel(newModel);
this.newModel.fillFromDescriptor(this.extension);
this.tree.setModel(this.newModel);
expand();
 
}
 
private void expand() {
tree.expandRow(0);
this.tree.expandRow(0);
 
final List<MenuDescriptor> m = new ArrayList<MenuDescriptor>();
m.addAll(extension.getCreateMenuList());
m.addAll(extension.getRemoveMenuList());
m.addAll(this.extension.getCreateMenuList());
m.addAll(this.extension.getRemoveMenuList());
for (MenuDescriptor menuDescriptor : m) {
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.tree.getModel().getRoot();
@SuppressWarnings("unchecked")
final Enumeration<DefaultMutableTreeNode> e = root.depthFirstEnumeration();
while (e.hasMoreElements()) {
72,7 → 72,7
final String nodeLabel = ((Item) userObject).getId();
if (nodeLabel != null && nodeLabel.equals(menuDescriptor.getId())) {
final TreePath path = new TreePath(((DefaultMutableTreeNode) node.getParent()).getPath());
tree.expandPath(path);
this.tree.expandPath(path);
}
}
}
92,11 → 92,11
c.insets = new Insets(2, 2, 2, 0);
 
panel.add(new JLabel("Menus"), c);
newModel = new MenuItemTreeModel();
tree = new ReorderableJTree();
tree.setModel(newModel);
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
this.newModel = new MenuItemTreeModel();
this.tree = new ReorderableJTree();
this.tree.setModel(this.newModel);
this.tree.setRootVisible(false);
this.tree.setShowsRootHandles(true);
 
final DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer() {
@Override
109,7 → 109,7
final JLabel r = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (tr.getUserObject() instanceof Item) {
final String id = ((Item) tr.getUserObject()).getId();
if (extension.getCreateMenuItemFromId(id) != null) {
if (MainMenuGroupEditor.this.extension.getCreateMenuItemFromId(id) != null) {
r.setForeground(new Color(50, 80, 150));
}
}
116,13 → 116,16
if (!tr.isActive()) {
r.setForeground(Color.LIGHT_GRAY);
}
if (sel) {
r.setForeground(Color.WHITE);
}
return r;
}
};
 
treeRenderer.setLeafIcon(null);
tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(tree);
this.tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(this.tree);
comp2.setMinimumSize(new Dimension(250, 150));
comp2.setPreferredSize(new Dimension(250, 150));
c.weighty = 1;
170,13 → 173,13
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final TreePath selectionPath = tree.getSelectionPath();
final TreePath selectionPath = MainMenuGroupEditor.this.tree.getSelectionPath();
if (selectionPath != null) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath.getLastPathComponent();
if (node.getUserObject() != null) {
String idToDelete = ((Item) node.getUserObject()).getId();
extension.removeCreateMenuForId(idToDelete);
extension.setChanged();
MainMenuGroupEditor.this.extension.removeCreateMenuForId(idToDelete);
MainMenuGroupEditor.this.extension.setChanged();
fillModel();
}
 
187,21 → 190,21
 
@Override
public void actionPerformed(ActionEvent e) {
newModel.setShowAll(hideCheckbox.isSelected());
newModel.fillFromDescriptor(extension);
MainMenuGroupEditor.this.newModel.setShowAll(hideCheckbox.isSelected());
MainMenuGroupEditor.this.newModel.fillFromDescriptor(MainMenuGroupEditor.this.extension);
}
 
});
tree.addTreeSelectionListener(new TreeSelectionListener() {
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
 
@Override
public void valueChanged(TreeSelectionEvent e) {
final TreePath selectionPath = tree.getSelectionPath();
final TreePath selectionPath = MainMenuGroupEditor.this.tree.getSelectionPath();
if (selectionPath != null) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath.getLastPathComponent();
if (node.getUserObject() != null) {
String selectedId = ((Item) node.getUserObject()).getId();
removeButton.setEnabled(extension.getCreateMenuItemFromId(selectedId) != null);
removeButton.setEnabled(MainMenuGroupEditor.this.extension.getCreateMenuItemFromId(selectedId) != null);
}
} else {
removeButton.setEnabled(false);
209,26 → 212,26
 
}
});
tree.addMouseListener(new MouseAdapter() {
this.tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
newModel.toggleActive(tree.getSelectionPath());
MainMenuGroupEditor.this.newModel.toggleActive(MainMenuGroupEditor.this.tree.getSelectionPath());
}
}
 
@Override
public void mousePressed(MouseEvent e) {
final TreePath selectionPath = tree.getSelectionPath();
final TreePath selectionPath = MainMenuGroupEditor.this.tree.getSelectionPath();
if (selectionPath == null) {
setRightPanel(new JPanel());
} else {
Item i = (Item) ((DefaultMutableTreeNode) selectionPath.getLastPathComponent()).getUserObject();
setRightPanel(new MenuItemEditor(newModel, i, extension));
setRightPanel(new MenuItemEditor(MainMenuGroupEditor.this.newModel, i, MainMenuGroupEditor.this.extension));
}
}
});
tree.getModel().addTreeModelListener(new TreeModelListener() {
this.tree.getModel().addTreeModelListener(new TreeModelListener() {
 
@Override
public void treeStructureChanged(TreeModelEvent e) {
257,13 → 260,13
}
 
protected void addNewGroup() {
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (tree.getModel().getRoot())).getFirstChild();
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (this.tree.getModel().getRoot())).getFirstChild();
DefaultMutableTreeNode node = root;
if (node.getChildCount() > 0) {
node = (DefaultMutableTreeNode) node.getFirstChild();
}
if (tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
if (this.tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) this.tree.getLastSelectedPathComponent();
}
if (node != root) {
final String newGroupId = "group" + node.getParent().getChildCount() + 1;
274,23 → 277,23
final MenuDescriptor desc = new MenuDescriptor(newGroupId);
desc.setType(MenuDescriptor.GROUP);
desc.setInsertInMenu(((Item) parent.getUserObject()).getId());
extension.addCreateMenu(desc);
extension.setChanged();
this.extension.addCreateMenu(desc);
this.extension.setChanged();
 
newModel.reload();
tree.setSelectionPath(new TreePath(newModel.getPathToRoot(newNode)));
this.newModel.reload();
this.tree.setSelectionPath(new TreePath(this.newModel.getPathToRoot(newNode)));
}
extension.setChanged();
this.extension.setChanged();
}
 
protected void addNewItem() {
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (tree.getModel().getRoot())).getFirstChild();
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (this.tree.getModel().getRoot())).getFirstChild();
DefaultMutableTreeNode node = root;
if (node.getChildCount() > 0) {
node = (DefaultMutableTreeNode) node.getFirstChild();
}
if (tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
if (this.tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) this.tree.getLastSelectedPathComponent();
}
if (node != root) {
final String newActionId = "action" + node.getParent().getChildCount() + 1;
300,10 → 303,10
final MenuDescriptor desc = new MenuDescriptor(newActionId);
desc.setType(MenuDescriptor.CREATE);
desc.setInsertInMenu(((Item) parent.getUserObject()).getId());
extension.addCreateMenu(desc);
extension.setChanged();
newModel.reload();
tree.setSelectionPath(new TreePath(newModel.getPathToRoot(newNode)));
this.extension.addCreateMenu(desc);
this.extension.setChanged();
this.newModel.reload();
this.tree.setSelectionPath(new TreePath(this.newModel.getPathToRoot(newNode)));
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/mainmenu/MenuDescriptor.java
16,7 → 16,7
}
 
public String getId() {
return id;
return this.id;
}
 
public void setId(String id) {
24,7 → 24,7
}
 
public String getListId() {
return listId;
return this.listId;
}
 
public void setListId(String listId) {
32,7 → 32,7
}
 
public String getComponentId() {
return componentId;
return this.componentId;
}
 
public void setComponentId(String componentId) {
44,7 → 44,7
* @return "list" or "create"
* */
public String getType() {
return type;
return this.type;
}
 
public void setType(String type) {
52,7 → 52,7
}
 
public String getInsertInMenu() {
return insertInMenu;
return this.insertInMenu;
}
 
public void setInsertInMenu(String insertInMenu) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/mainmenu/MenuItemTreeModel.java
64,7 → 64,7
depth++;
final ActivableMutableTreeNode newChild = new ActivableMutableTreeNode(item);
newChild.setActive(isActive(item.getId()));
if (showAll || newChild.isActive()) {
if (this.showAll || newChild.isActive()) {
node.add(newChild);
}
if (item instanceof Group) {
81,7 → 81,7
}
 
private boolean isActive(String id) {
List<MenuDescriptor> l = extension.getRemoveMenuList();
List<MenuDescriptor> l = this.extension.getRemoveMenuList();
for (MenuDescriptor menuDescriptor : l) {
if (menuDescriptor.getId().equals(id)) {
return false;
108,11 → 108,11
 
public void setActive(boolean active, String id) {
if (active) {
extension.removeRemoveMenuForId(id);
this.extension.removeRemoveMenuForId(id);
} else {
extension.addRemoveMenu(new MenuDescriptor(id));
this.extension.addRemoveMenu(new MenuDescriptor(id));
}
extension.setChanged();
this.extension.setChanged();
 
DefaultMutableTreeNode n = getNode(id);
if (n != null) {
137,9 → 137,9
public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent, int index) {
Item it = (Item) ((DefaultMutableTreeNode) newChild).getUserObject();
Group g = (Group) ((DefaultMutableTreeNode) parent).getUserObject();
extension.moveMenuItem(it.getId(), g.getId());
this.extension.moveMenuItem(it.getId(), g.getId());
super.insertNodeInto(newChild, parent, index);
extension.setChanged();
this.extension.setChanged();
}
 
@SuppressWarnings("rawtypes")
158,8 → 158,8
}
}
 
extension.renameMenuItem(previousId, newId);
extension.setChanged();
this.extension.renameMenuItem(previousId, newId);
this.extension.setChanged();
 
}
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/MenuCreateMainPanel.java
9,12 → 9,12
 
public MenuCreateMainPanel(Extension extension) {
super(extension);
split.setDividerLocation(0.5D);
this.split.setDividerLocation(0.5D);
}
 
@Override
public JComponent createLeftComponent() {
return new MenuListPanel(extension, this);
return new MenuListPanel(this.extension, this);
}
 
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionListPanel.java
18,10 → 18,10
}
this.extensionBuilderModule = extensionBuilderModule;
this.setLayout(new GridLayout(1, 1));
newLeftComponent = new ExtensionMainListPanel(this);
this.split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, newLeftComponent, rPanel);
this.newLeftComponent = new ExtensionMainListPanel(this);
this.split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this.newLeftComponent, this.rPanel);
this.add(this.split);
newLeftComponent.fill();
this.newLeftComponent.fill();
}
 
public void setRightPanel(JComponent p) {
32,11 → 32,11
}
 
public ExtensionBuilderModule getExtensionBuilderModule() {
return extensionBuilderModule;
return this.extensionBuilderModule;
}
 
public void modelChanged() {
newLeftComponent.modelChanged();
this.newLeftComponent.modelChanged();
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionBuilderModule.java
89,7 → 89,7
}
Log.get().info("setupMenu");
// Start previously started extensions
for (Extension extension : extensions) {
for (Extension extension : this.extensions) {
if (extension.isAutoStart()) {
try {
extension.setupMenu(ctxt);
108,7 → 108,7
final DBRoot root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
 
// Start previously started extensions
for (Extension extension : extensions) {
for (Extension extension : this.extensions) {
if (extension.isAutoStart()) {
try {
extension.start(root, true);
124,7 → 124,7
 
@Override
protected void stop() {
for (Extension extension : extensions) {
for (Extension extension : this.extensions) {
extension.stop();
}
this.extensions.clear();
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionListModel.java
17,7 → 17,7
}
 
public void fill(final EditableListPanel list) {
addAll(moduleListPanel.getExtensionBuilderModule().getExtensions());
addAll(this.moduleListPanel.getExtensionBuilderModule().getExtensions());
final int size = this.getSize();
if (size > 0) {
final Object firstElement = firstElement();
39,7 → 39,7
@Override
public void addElement(Object obj) {
final Extension e = (Extension) obj;
moduleListPanel.getExtensionBuilderModule().add(e);
this.moduleListPanel.getExtensionBuilderModule().add(e);
e.addChangeListener(this);
super.addElement(obj);
}
49,7 → 49,7
final Extension extenstion = (Extension) obj;
final int answer = JOptionPane.showConfirmDialog(new JFrame(), "Voulez vous vraiment supprimer l'extension " + extenstion.getName() + " ?", "Suppression", JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.OK_OPTION) {
moduleListPanel.getExtensionBuilderModule().remove(extenstion);
this.moduleListPanel.getExtensionBuilderModule().remove(extenstion);
extenstion.removeChangeListener(this);
return super.removeElement(obj);
}
58,7 → 58,7
 
@Override
public void stateChanged(ChangeEvent e) {
moduleListPanel.modelChanged();
this.moduleListPanel.modelChanged();
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/FieldDescSelector.java
9,6 → 9,7
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
 
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
46,8 → 47,8
// Col 0
c.gridx = 0;
c.gridy++;
treeModel = new FieldTreeModel(extension);
this.tree = new JTree(treeModel) {
this.treeModel = new FieldTreeModel(extension);
this.tree = new JTree(this.treeModel) {
@Override
public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
61,19 → 62,19
return " " + d.getName();
}
};
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
this.tree.setRootVisible(false);
this.tree.setShowsRootHandles(true);
final DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer();
 
treeRenderer.setLeafIcon(null);
treeRenderer.setOpenIcon(new ImageIcon(this.getClass().getResource("ref.png")));
treeRenderer.setClosedIcon(new ImageIcon(this.getClass().getResource("ref.png")));
tree.setCellRenderer(treeRenderer);
this.tree.setCellRenderer(treeRenderer);
c.gridheight = 2;
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
this.add(new JScrollPane(tree), c);
this.add(new JScrollPane(this.tree), c);
// Col 1
c.gridx = 1;
c.gridheight = 1;
93,7 → 94,7
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
listModel = new DefaultListModel() {
this.listModel = new DefaultListModel() {
@Override
public void addElement(Object obj) {
if (!(obj instanceof ColumnDescriptor)) {
103,9 → 104,9
}
 
};
list = new ReorderableJList();
list.setModel(listModel);
list.setCellRenderer(new DefaultListCellRenderer() {
this.list = new ReorderableJList();
this.list.setModel(this.listModel);
this.list.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
ColumnDescriptor f = (ColumnDescriptor) value;
113,9 → 114,9
return super.getListCellRendererComponent(list, label, index, isSelected, cellHasFocus);
}
});
this.add(new JScrollPane(list), c);
this.add(new JScrollPane(this.list), c);
// Listeners
tree.addMouseListener(new MouseAdapter() {
this.tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
140,7 → 141,7
 
}
});
list.addKeyListener(new KeyAdapter() {
this.list.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
154,8 → 155,8
 
public void setMainTable(String table) {
this.listDescriptor.setMainTable(table);
treeModel.fillFromTable(table);
listModel.removeAllElements();
this.treeModel.fillFromTable(table);
this.listModel.removeAllElements();
for (ColumnDescriptor d : this.listDescriptor.getColumns()) {
this.listModel.addElement(d);
}
162,18 → 163,24
}
 
private void deleteSelectedInList() {
Object[] vals = list.getSelectedValues();
if (vals == null)
List<Object> vals = this.list.getSelectedValuesList();
if (vals.isEmpty())
return;
for (int i = 0; i < vals.length; i++) {
Object object = vals[i];
this.listModel.removeElement(object);
for (Object object : vals) {
boolean b = this.listModel.removeElement(object);
if (!b) {
throw new IllegalStateException("cannot remove " + object + " from list model " + this.listModel);
}
list.clearSelection();
if (object instanceof ColumnDescriptor) {
ColumnDescriptor c = (ColumnDescriptor) object;
this.listDescriptor.remove(c);
}
}
this.list.clearSelection();
}
 
private void addTreeSelectionToList() {
final TreePath[] paths = tree.getSelectionPaths();
final TreePath[] paths = this.tree.getSelectionPaths();
if (paths == null)
return;
for (int i = 0; i < paths.length; i++) {
203,10 → 210,10
if (d != null && root != null) {
boolean add = true;
final String extendedLabel = root.getPath();
final int size = listModel.getSize();
final int size = this.listModel.getSize();
// Check if already in the list
for (int j = 0; j < size; j++) {
if (((ColumnDescriptor) listModel.getElementAt(j)).getFieldsPaths().contains(extendedLabel)) {
if (((ColumnDescriptor) this.listModel.getElementAt(j)).getFieldsPaths().contains(extendedLabel)) {
add = false;
break;
}
214,12 → 221,12
if (add) {
final ColumnDescriptor colDesc = new ColumnDescriptor(root.getPath());
colDesc.setFieldsPaths(root.getPath());
listModel.addElement(colDesc);
listDescriptor.add(colDesc);
this.listModel.addElement(colDesc);
this.listDescriptor.add(colDesc);
}
}
}
tree.clearSelection();
this.tree.clearSelection();
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/FieldTreeModel.java
80,7 → 80,7
newChild.setAllowsChildren(false);
}
}
this.setRoot(root);
this.setRoot(this.root);
}
}
 
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ListCreateMainPanel.java
13,7 → 13,7
 
@Override
public JComponent createLeftComponent() {
return new ListListPanel(extension, this);
return new ListListPanel(this.extension, this);
}
 
public void select(ListDescriptor listDescriptor) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/EditableListPanel.java
43,9 → 43,9
if (title != null) {
this.add(new JLabel(title), c);
}
list = new JList(dataModel);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane comp2 = new JScrollPane(list);
this.list = new JList(dataModel);
this.list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane comp2 = new JScrollPane(this.list);
comp2.setMinimumSize(new Dimension(150, 150));
comp2.setPreferredSize(new Dimension(150, 150));
c.weighty = 1;
64,15 → 64,15
this.add(addButton, c);
c.gridy++;
if (canRename) {
renameButton = new JButton("Renommer");
this.add(renameButton, c);
renameButton.setEnabled(false);
renameButton.addActionListener(new ActionListener() {
this.renameButton = new JButton("Renommer");
this.add(this.renameButton, c);
this.renameButton.setEnabled(false);
this.renameButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
if (list.getSelectedValue() != null) {
renameItem(list.getSelectedValue());
if (EditableListPanel.this.list.getSelectedValue() != null) {
renameItem(EditableListPanel.this.list.getSelectedValue());
}
}
 
80,9 → 80,9
c.gridy++;
}
 
removeButton = new JButton("Supprimer");
removeButton.setEnabled(false);
this.add(removeButton, c);
this.removeButton = new JButton("Supprimer");
this.removeButton.setEnabled(false);
this.add(this.removeButton, c);
 
// init
 
98,25 → 98,25
 
});
 
removeButton.addActionListener(new ActionListener() {
this.removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (list.getSelectedValue() != null) {
removeItem(list.getSelectedValue());
if (EditableListPanel.this.list.getSelectedValue() != null) {
removeItem(EditableListPanel.this.list.getSelectedValue());
}
}
});
}
list.addListSelectionListener(new ListSelectionListener() {
this.list.addListSelectionListener(new ListSelectionListener() {
 
@Override
public void valueChanged(ListSelectionEvent e) {
final Object selectedValue = list.getSelectedValue();
if (removeButton != null) {
removeButton.setEnabled(selectedValue != null);
final Object selectedValue = EditableListPanel.this.list.getSelectedValue();
if (EditableListPanel.this.removeButton != null) {
EditableListPanel.this.removeButton.setEnabled(selectedValue != null);
}
if (renameButton != null) {
renameButton.setEnabled(selectedValue != null);
if (EditableListPanel.this.renameButton != null) {
EditableListPanel.this.renameButton.setEnabled(selectedValue != null);
}
if (!e.getValueIsAdjusting() && selectedValue != null) {
 
136,7 → 136,7
* Select an item in the list
* */
public void selectItem(Object item) {
list.setSelectedValue(item, true);
this.list.setSelectedValue(item, true);
}
 
/**
162,7 → 162,7
public abstract void itemSelected(Object item);
 
public void reload() {
list.invalidate();
list.repaint();
this.list.invalidate();
this.list.repaint();
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ListListPanel.java
21,7 → 21,7
 
@Override
public void addNewItem() {
((CreateListListModel) dataModel).addNewList();
((CreateListListModel) this.dataModel).addNewList();
}
 
@Override
36,8 → 36,8
 
@Override
public void removeItem(Object item) {
((CreateListListModel) dataModel).removeElement(item);
extension.removeCreateList((ListDescriptor) item);
((CreateListListModel) this.dataModel).removeElement(item);
this.extension.removeCreateList((ListDescriptor) item);
}
 
@Override
44,10 → 44,10
public void itemSelected(Object item) {
if (item != null) {
ListDescriptor n = (ListDescriptor) item;
final ListCreatePanel p = new ListCreatePanel(n, extension);
tableInfoPanel.setRightPanel(p);
final ListCreatePanel p = new ListCreatePanel(n, this.extension);
this.tableInfoPanel.setRightPanel(p);
} else {
tableInfoPanel.setRightPanel(new JPanel());
this.tableInfoPanel.setRightPanel(new JPanel());
}
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ListDescriptor.java
15,7 → 15,7
}
 
public String getId() {
return id;
return this.id;
}
 
public void setId(String id) {
27,11 → 27,11
}
 
public String getMainTable() {
return mainTable;
return this.mainTable;
}
 
public List<ColumnDescriptor> getColumns() {
return columns;
return this.columns;
}
 
@Override
51,4 → 51,8
public void removeAllColumns() {
this.columns.clear();
}
 
public void remove(ColumnDescriptor c) {
this.columns.remove(c);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ColumnDescriptor.java
15,14 → 15,14
}
 
public String getId() {
return id;
return this.id;
}
 
public String getFieldsPaths() {
String r = "";
final int size = fieldPaths.size();
final int size = this.fieldPaths.size();
for (int i = 0; i < size; i++) {
String fieldPath = fieldPaths.get(i);
String fieldPath = this.fieldPaths.get(i);
if (i != 0) {
r += ",";
}
33,14 → 33,14
 
public void setFieldsPaths(String paths) {
final List<String> l = StringUtils.fastSplit(paths, ',');
fieldPaths.clear();
this.fieldPaths.clear();
for (String string : l) {
fieldPaths.add(string.trim());
this.fieldPaths.add(string.trim());
}
}
 
public String getStyle() {
return style;
return this.style;
}
 
public void setStyle(String style) {
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/CreateListListModel.java
17,7 → 17,7
}
 
private void addContent() {
this.addAll(extension.getCreateListList());
this.addAll(this.extension.getCreateListList());
}
 
@Override
28,11 → 28,11
 
public void addNewList() {
final ListDescriptor l = new ListDescriptor("liste " + (this.getSize() + 1));
final List<String> allKnownTableNames = extension.getAllKnownTableNames();
final List<String> allKnownTableNames = this.extension.getAllKnownTableNames();
final String mainTable = allKnownTableNames.get(0);
l.setMainTable(mainTable);
this.addElement(l);
extension.addCreateList(l);
this.extension.addCreateList(l);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ListCreatePanel.java
38,16 → 38,16
c.weighty = 1;
c.gridwidth = 2;
c.fill = GridBagConstraints.BOTH;
panel = new FieldDescSelector(n, extension);
this.panel = new FieldDescSelector(n, extension);
final String mainTable = n.getMainTable();
if (mainTable == null && comboTable.getModel().getSize() > 0) {
comboTable.setSelectedIndex(0);
panel.setMainTable((String) comboTable.getModel().getElementAt(0));
this.panel.setMainTable((String) comboTable.getModel().getElementAt(0));
} else {
comboTable.setSelectedItem(mainTable);
panel.setMainTable(mainTable);
this.panel.setMainTable(mainTable);
}
this.add(panel, c);
this.add(this.panel, c);
 
comboTable.addActionListener(new ActionListener() {
 
54,7 → 54,7
@Override
public void actionPerformed(ActionEvent e) {
n.removeAllColumns();
panel.setMainTable((String) comboTable.getSelectedItem());
ListCreatePanel.this.panel.setMainTable((String) comboTable.getSelectedItem());
extension.setChanged();
}
});
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/AbstractSplittedPanel.java
15,14 → 15,14
this.extension = extension;
this.setLayout(new GridLayout(1, 1));
this.setOpaque(false);
leftComponent = createLeftComponent();
split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftComponent, new JPanel());
this.add(split);
this.leftComponent = createLeftComponent();
this.split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this.leftComponent, new JPanel());
this.add(this.split);
}
 
public void setRightPanel(JComponent p) {
this.invalidate();
split.setRightComponent(p);
this.split.setRightComponent(p);
this.revalidate();
this.repaint();
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionMainListPanel.java
22,6 → 22,7
this.moduleListPanel = moduleListPanel;
this.list.setFixedCellHeight(new JLabel("A").getPreferredSize().height + 8);
this.list.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
final JLabel listCellRendererComponent = (JLabel) super.getListCellRendererComponent(list, ((Extension) value).getName(), index, isSelected, cellHasFocus);
Extension e = (Extension) value;
35,13 → 36,13
}
 
public void fill() {
((ExtensionListModel) dataModel).fill(this);
((ExtensionListModel) this.dataModel).fill(this);
 
}
 
@Override
public void addNewItem() {
((ExtensionListModel) dataModel).addNewModule();
((ExtensionListModel) this.dataModel).addNewModule();
}
 
@Override
56,22 → 57,22
 
@Override
public void removeItem(Object item) {
((ExtensionListModel) dataModel).removeElement(item);
((ExtensionListModel) this.dataModel).removeElement(item);
}
 
@Override
public void itemSelected(Object item) {
if (item != null) {
final ExtensionInfoPanel p = new ExtensionInfoPanel((Extension) item, moduleListPanel);
moduleListPanel.setRightPanel(p);
final ExtensionInfoPanel p = new ExtensionInfoPanel((Extension) item, this.moduleListPanel);
this.moduleListPanel.setRightPanel(p);
} else {
moduleListPanel.setRightPanel(new JPanel());
this.moduleListPanel.setRightPanel(new JPanel());
}
 
}
 
public void modelChanged() {
list.invalidate();
list.repaint();
this.list.invalidate();
this.list.repaint();
}
}
/trunk/Modules/Module Subscription/src/org/openconcerto/modules/subscription/panel/DevisAboPanel.java
8,8 → 8,8
import java.util.Date;
 
import org.openconcerto.erp.core.common.element.NumerotationAutoSQLElement;
import org.openconcerto.erp.core.sales.quote.element.DevisSQLElement;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
21,18 → 21,19
}
 
private SQLTable tableNum = Configuration.getInstance().getRoot().findTable("NUMEROTATION_AUTO");
private SQLElement eltDev = Configuration.getInstance().getDirectory().getElement("DEVIS");
 
@Override
protected void injectRow(SQLRow row, SQLRowValues rowVals, Date dateNew, SQLRow rowAbonnement) {
super.injectRow(row, rowVals, dateNew, rowAbonnement);
String nextNumero = NumerotationAutoSQLElement.getNextNumero(DevisSQLElement.class);
String nextNumero = NumerotationAutoSQLElement.getNextNumero(this.eltDev.getClass());
rowVals.put("NUMERO", nextNumero);
 
// incrémentation du numéro auto
final SQLRowValues rowValsNum = new SQLRowValues(this.tableNum);
int val = this.tableNum.getRow(2).getInt(NumerotationAutoSQLElement.getLabelNumberFor(DevisSQLElement.class));
int val = this.tableNum.getRow(2).getInt(NumerotationAutoSQLElement.getLabelNumberFor(this.eltDev.getClass()));
val++;
rowValsNum.put(NumerotationAutoSQLElement.getLabelNumberFor(DevisSQLElement.class), new Integer(val));
rowValsNum.put(NumerotationAutoSQLElement.getLabelNumberFor(this.eltDev.getClass()), new Integer(val));
try {
rowValsNum.update(2);
} catch (final SQLException e) {
/trunk/Modules/Module Subscription/src/org/openconcerto/modules/subscription/panel/FacturesAboPanel.java
11,11 → 11,11
 
import org.openconcerto.erp.core.common.element.NumerotationAutoSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.EcritureSQLElement;
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement;
import org.openconcerto.erp.core.sales.invoice.report.VenteFactureXmlSheet;
import org.openconcerto.erp.generationEcritures.GenerationMvtSaisieVenteFacture;
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.IResultSetHandler;
import org.openconcerto.sql.model.SQLDataSource;
import org.openconcerto.sql.model.SQLRow;
33,18 → 33,19
}
 
private final SQLTable tableNum = Configuration.getInstance().getRoot().findTable("NUMEROTATION_AUTO");
private SQLElement eltFact = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
 
@Override
protected void validItem(SQLRowAccessor sqlRowAccessor) {
// Affectation d'un numero
SQLRowValues rowVals = sqlRowAccessor.createEmptyUpdateRow();
String nextNumero = NumerotationAutoSQLElement.getNextNumero(SaisieVenteFactureSQLElement.class);
String nextNumero = NumerotationAutoSQLElement.getNextNumero(this.eltFact.getClass());
rowVals.put("DATE", new Date());
rowVals.put("NUMERO", nextNumero);
 
SQLRowValues rowValsNum = new SQLRowValues(tableNum);
 
String labelNumberFor = NumerotationAutoSQLElement.getLabelNumberFor(SaisieVenteFactureSQLElement.class);
String labelNumberFor = NumerotationAutoSQLElement.getLabelNumberFor(this.eltFact.getClass());
int val = tableNum.getRow(2).getInt(labelNumberFor);
val++;
rowValsNum.put(labelNumberFor, Integer.valueOf(val));
109,7 → 110,7
@Override
protected void injectRow(SQLRow row, SQLRowValues rowVals, Date dateNew, SQLRow rowAbonnement) {
super.injectRow(row, rowVals, dateNew, rowAbonnement);
rowVals.put("NUMERO", "ABO--" + NumerotationAutoSQLElement.getNextNumero(SaisieVenteFactureSQLElement.class));
rowVals.put("NUMERO", "ABO--" + NumerotationAutoSQLElement.getNextNumero(this.eltFact.getClass()));
rowVals.put("ID_ADRESSE", row.getObject("ID_ADRESSE"));
rowVals.put("ID_COMPTE_PCE_SERVICE", row.getObject("ID_COMPTE_PCE_SERVICE"));
rowVals.put("PORT_HT", row.getObject("PORT_HT"));
/trunk/Modules/Module Subscription/src/org/openconcerto/modules/subscription/panel/AboPanel.java
120,11 → 120,11
* @param type
*/
private void createUI(final SQLElement elt, final SQLElement itemsElement, final String type) {
final SQLTableModelSourceOnline tableCmd = elt.getTableSource(true);
final SwingWorker<SQLTableModelSourceOnline, Object> worker = new SwingWorker<SQLTableModelSourceOnline, Object>() {
 
@Override
protected SQLTableModelSourceOnline doInBackground() throws Exception {
final SQLTableModelSourceOnline tableCmd = elt.getTableSource(true);
Where wD = new Where(elt.getTable().getField("CREATION_AUTO_VALIDER"), "=", Boolean.FALSE);
wD = wD.and(new Where(elt.getTable().getField("ID_ABONNEMENT"), "IS NOT", (Object) null));
tableCmd.getReq().setWhere(wD);
/trunk/Modules/Module Subscription/src/org/openconcerto/modules/subscription/panel/BonCommandeAboPanel.java
8,10 → 8,10
import java.util.List;
 
import org.openconcerto.erp.core.common.element.NumerotationAutoSQLElement;
import org.openconcerto.erp.core.sales.order.element.CommandeClientSQLElement;
import org.openconcerto.erp.core.sales.order.report.CommandeClientXmlSheet;
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
26,17 → 26,18
}
 
private SQLTable tableNum = Configuration.getInstance().getRoot().findTable("NUMEROTATION_AUTO");
private SQLElement eltCmd = Configuration.getInstance().getDirectory().getElement("COMMANDE_CLIENT");
 
@Override
protected void injectRow(SQLRow row, SQLRowValues rowVals, Date dateNew, SQLRow rowAbonnement) {
// TODO Raccord de méthode auto-généré
super.injectRow(row, rowVals, dateNew, rowAbonnement);
rowVals.put("NUMERO", NumerotationAutoSQLElement.getNextNumero(CommandeClientSQLElement.class));
rowVals.put("NUMERO", NumerotationAutoSQLElement.getNextNumero(this.eltCmd.getClass()));
// incrémentation du numéro auto
final SQLRowValues rowValsNum = new SQLRowValues(this.tableNum);
int val = this.tableNum.getRow(2).getInt(NumerotationAutoSQLElement.getLabelNumberFor(CommandeClientSQLElement.class));
int val = this.tableNum.getRow(2).getInt(NumerotationAutoSQLElement.getLabelNumberFor(this.eltCmd.getClass()));
val++;
rowValsNum.put(NumerotationAutoSQLElement.getLabelNumberFor(CommandeClientSQLElement.class), new Integer(val));
rowValsNum.put(NumerotationAutoSQLElement.getLabelNumberFor(this.eltCmd.getClass()), new Integer(val));
try {
rowValsNum.update(2);
} catch (final SQLException e) {
/trunk/Modules/Module Subscription/src/org/openconcerto/modules/subscription/Module.java
40,7 → 40,6
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
import org.openconcerto.utils.i18n.TranslationManager;
 
public final class Module extends AbstractModule {
 
110,7 → 109,6
@Override
protected void setupElements(final SQLElementDirectory dir) {
super.setupElements(dir);
TranslationManager.getInstance().addTranslationStreamFromClass(this.getClass());
dir.addSQLElement(SubscriptionSQLElement.class);
NumerotationAutoSQLElement.addClass(SubscriptionSQLElement.class, "ABONNEMENT");
((SaisieVenteFactureSQLElement) dir.getElement("SAISIE_VENTE_FACTURE")).putSpecialAction("subscription.autocreate", new DoWithRow() {
/trunk/Modules/Module Google Docs/src/org/openconcerto/modules/google/docs/GoogleDocsPreferencePanel.java
101,8 → 101,10
ll.uploadFile(f, "OpenConcerto/Devis/2010", "Test Google Docs", true);
JOptionPane.showMessageDialog(GoogleDocsPreferencePanel.this, "Connexion réussie");
} catch (AuthenticationException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(GoogleDocsPreferencePanel.this, "Identifiant ou mot de passe invalide");
} catch (Throwable e1) {
e1.printStackTrace();
JOptionPane.showMessageDialog(GoogleDocsPreferencePanel.this, e1.getMessage());
}
}
/trunk/Modules/Module Customer Support/src/org/openconcerto/modules/customersupport/labels_fr.xml
1,7 → 1,7
<?xml version="1.0" encoding="UTF-8" ?>
<ROOT>
<element refid="customersupport.ticket" nameClass="masculine" name="ticket de support">
<FIELD name="STATUS" label="Status" />
<FIELD name="STATUS" label="Statut" />
<FIELD name="LABEL" label="Libellé" />
<FIELD name="ID_CLIENT" label="Client" />
<FIELD name="NUMBER" label="Numéro" />
10,7 → 10,7
<FIELD name="RATING" label="Priorité" />
<FIELD name="TYPE" label="Type" />
<FIELD name="REMIND_DATE" label="Prochain rappel le" />
<FIELD name="DATE" label="Date" />
<FIELD name="DATE" label="Date ticket" />
<FIELD name="CLOSED_AND_ARCHIVED" label="Archivé" />
</element>
<element refid="customersupport.ticket.history" nameClass="feminine" name="Intervention sur ticket">
17,6 → 17,6
<FIELD name="ID_CUSTOMER_SUPPORT_TICKET" label="Ticket" />
<FIELD name="ID_USER_COMMON" label="Utilisateur en charge" />
<FIELD name="INFORMATION" label="Détails de l'intervention" />
<FIELD name="DATE" label="Date" />
<FIELD name="DATE" label="Date inter." />
</element>
</ROOT>
/trunk/Modules/Module Customer Support/src/org/openconcerto/modules/customersupport/Module.java
1,6 → 1,5
package org.openconcerto.modules.customersupport;
 
import java.io.File;
import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
9,7 → 8,6
import java.util.List;
import java.util.Set;
 
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.erp.config.MainFrame;
import org.openconcerto.erp.modules.AbstractModule;
import org.openconcerto.erp.modules.ComponentsContext;
16,20 → 14,15
import org.openconcerto.erp.modules.DBContext;
import org.openconcerto.erp.modules.MenuContext;
import org.openconcerto.erp.modules.ModuleFactory;
import org.openconcerto.erp.modules.ModuleManager;
import org.openconcerto.erp.modules.ModulePackager;
import org.openconcerto.erp.modules.RuntimeModuleFactory;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.GlobalMapper;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.FieldPath;
import org.openconcerto.sql.model.SQLRequestLog;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.model.graph.Path;
import org.openconcerto.sql.ui.ConnexionPanel;
import org.openconcerto.sql.utils.SQLCreateTable;
import org.openconcerto.sql.view.ListeAddPanel;
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn;
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/JCalendarItemDB.java
25,7 → 25,13
assert r.isFrozen();
this.item = r;
this.group = dir.getElement(this.item.getTable()).getContainer(this.item);
if (this.group == null) {
throw new IllegalArgumentException("no group found for row " + r);
}
this.operationElem = dir.getElement(OperationSQLElement.class);
if (this.operationElem == null) {
throw new IllegalStateException("no element found " + OperationSQLElement.class);
}
this.operation = CollectionUtils.getSole(this.group.getReferentRows(this.operationElem.getTable()));
}
 
84,7 → 90,7
}
 
public String getStatus() {
return status;
return this.status;
}
 
public void setOperationType(String type) {
92,7 → 98,7
}
 
public String getType() {
return type;
return this.type;
}
 
public String getFlagsString() {
109,7 → 115,7
}
 
public String getPlannerXML() {
return plannerXML;
return this.plannerXML;
}
 
public void setPlannerXML(String string) {
117,7 → 123,7
}
 
public String getPlannerUID() {
return plannerUID;
return this.plannerUID;
}
 
public void setPlannerUID(String plannerUID) {
125,7 → 131,7
}
 
public String getSiteName() {
return siteName;
return this.siteName;
}
 
public void setSiteName(String siteName) {
133,7 → 139,7
}
 
public String getSiteComment() {
return siteComment;
return this.siteComment;
}
 
public void setSiteComment(String siteComment) {
145,7 → 151,7
}
 
public Number getSiteId() {
return siteId;
return this.siteId;
}
 
public int getId() {
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationCalendarItemPrinter.java
11,9 → 11,11
 
public class OperationCalendarItemPrinter extends CalendarItemPrinter {
public static final Font FONT_LINE = new Font("Arial", Font.PLAIN, 9);
private List<JCalendarItem> itemsToWork;
 
public OperationCalendarItemPrinter(String title, List<JCalendarItem> items, PageFormat pf) {
public OperationCalendarItemPrinter(String title, List<JCalendarItem> items, PageFormat pf, List<JCalendarItem> itemsToWork) {
super(title, items, pf);
this.itemsToWork = itemsToWork;
}
 
@Override
38,7 → 40,7
 
@Override
public String getTitle() {
final List<JCalendarItem> items = this.getItems();
final List<JCalendarItem> items = this.itemsToWork;
int totalMinutes = 0;
for (JCalendarItem jCalendarItem : items) {
long t2 = jCalendarItem.getDtEnd().getTimeInMillis();
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationHistoryPanel.java
72,6 → 72,7
public void propertyChange(PropertyChangeEvent evt) {
final List<SQLRowValues> selectedRows = list.getSelectedRows();
final IListPanel listePanel = listHistoriquePanel.getListePanel(0);
// Activation/Desactivation des boutons Mofifier/Supprimer
if (selectedRows != null && !selectedRows.isEmpty()) {
final Set<Long> idsCalendarItemGroup = new HashSet<>();
for (SQLRowValues sqlRowValues : selectedRows) {
142,24 → 143,25
cal.set(Calendar.YEAR, selectedYear + 1);
Date dEnd = cal.getTime();
 
final SQLTable groupT = comboRequest.getPrimaryTable().getTable("CALENDAR_ITEM_GROUP");
final SQLTable calItemT = comboRequest.getPrimaryTable().getTable("CALENDAR_ITEM");
final SQLTable itemGroupTable = comboRequest.getPrimaryTable().getTable("CALENDAR_ITEM_GROUP");
final SQLTable itemTable = comboRequest.getPrimaryTable().getTable("CALENDAR_ITEM");
final SQLTable operationTable = comboRequest.getPrimaryTable().getTable("OPERATION");
final List<?> dateGroupIDs;
{
final SQLSelect copy = new SQLSelect(input);
copy.clearSelect();
copy.addSelect(copy.getAlias(groupT.getKey()));
copy.setWhere(copy.getAlias(comboRequest.getPrimaryTable().getTable("OPERATION").getField("ID_SITE")), "=", panel.getSelectedRow().getID());
final List<?> allGroupIDs = calItemT.getDBSystemRoot().getDataSource().executeCol(copy.asString());
 
copy.addSelect(copy.getAlias(itemGroupTable.getKey()));
copy.setWhere(copy.getAlias(operationTable.getField("ID_SITE")), "=", panel.getSelectedRow().getID());
final List<?> allGroupIDs = itemTable.getDBSystemRoot().getDataSource().executeCol(copy.asString());
final SQLSelect selIDGroup = new SQLSelect();
selIDGroup.addSelect(calItemT.getField("ID_CALENDAR_ITEM_GROUP"));
final Where where = new Where(calItemT.getField("START"), dStart, true, dEnd, true);
selIDGroup.setWhere(where).andWhere(new Where(calItemT.getField("ID_CALENDAR_ITEM_GROUP"), allGroupIDs));
dateGroupIDs = calItemT.getDBSystemRoot().getDataSource().executeCol(selIDGroup.asString());
selIDGroup.addSelect(itemTable.getField("ID_CALENDAR_ITEM_GROUP"));
final Where where = new Where(itemTable.getField("START"), dStart, true, dEnd, true);
selIDGroup.setWhere(where).andWhere(new Where(itemTable.getField("ID_CALENDAR_ITEM_GROUP"), allGroupIDs));
dateGroupIDs = itemTable.getDBSystemRoot().getDataSource().executeCol(selIDGroup.asString());
}
 
input.setWhere(new Where(input.getAlias(groupT.getKey()), dateGroupIDs));
Where w = new Where(input.getAlias(itemGroupTable.getKey()), dateGroupIDs);
input.setWhere(w);
} catch (Throwable e) {
e.printStackTrace();
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/ModuleOperation.java
62,8 → 62,6
// SQLRequestLog.showFrame();
TemplateManager.getInstance().register(OPERATIONS_REPORT_TEMPLATE_ID);
TemplateManager.getInstance().register(OPERATIONS_REPORT_TEMPLATE2_ID);
// Translation loading
TranslationManager.getInstance().addTranslationStreamFromClass(this.getClass());
}
 
@Override
148,6 → 146,10
createTableOperation.addVarCharColumn("DESCRIPTION", 10000);
createTableOperation.addVarCharColumn("PLANNER_UID", 2048);
createTableOperation.addVarCharColumn("PLANNER_XML", 2048);
 
ctxt.executeSQL();
// SQLTable.setUndefID(ctxt.getRoot().getSchema(), TABLE_SITE, null);
// SQLTable.setUndefID(ctxt.getRoot().getSchema(), TABLE_OPERATION, null);
}
}
 
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/CalendarPrintPanel.java
43,6 → 43,8
private static final double POINTS_PER_INCH = 72.0;
 
public CalendarPrintPanel(final OperationCalendarManager manager, final int week, final int year, final List<User> selectedUsers, final List<String> selectedStates) {
 
System.err.println("CalendarPrintPanel.CalendarPrintPanel()" + selectedUsers);
preview.setSelected(true);
//
this.setLayout(new GridBagLayout());
109,8 → 111,15
});
final PageFormat pf = new PageFormat();
pf.setPaper(new A4());
final CalendarItemPrinter printable = new OperationCalendarItemPrinter(user.getFullName(), itemInWeek, pf);
List<JCalendarItem> itemsToWork = new ArrayList<>();
for (JCalendarItem item : itemInWeek) {
if (!item.hasFlag(ModuleOperation.FREE_TIME_FLAG)) {
itemsToWork.add(item);
}
}
 
final CalendarItemPrinter printable = new OperationCalendarItemPrinter(user.getFullName(), itemInWeek, pf, itemsToWork);
 
p.add(printable);
}
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationCalendarPanel.java
117,12 → 117,11
this.beginStateSaving(conf.getConfDir(), w);
}
 
public static Map<Integer, Long> getDurations(List<List<JCalendarItem>> list, final Flag requiredFlag) {
public static Map<Integer, Long> getDurations(List<List<JCalendarItem>> list, final Flag requiredFlag, final Flag excludedFlag) {
final Map<Integer, Long> res = new HashMap<>();
final Flag freeTimeFlag = ModuleOperation.FREE_TIME_FLAG;
for (List<JCalendarItem> items : list) {
for (JCalendarItem item : items) {
if (!item.hasFlag(freeTimeFlag) && (requiredFlag == null || item.hasFlag(requiredFlag)) && item.getCookie() instanceof SQLRowValues) {
if (!item.hasFlag(excludedFlag) && (requiredFlag == null || item.hasFlag(requiredFlag)) && item.getCookie() instanceof SQLRowValues) {
final SQLRowValues user = (SQLRowValues) item.getCookie();
final long toAddMinutes = (item.getDtEnd().getTimeInMillis() - item.getDtStart().getTimeInMillis()) / (60 * 1000);
final Integer key = user.getID();
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/UserOperationListModel.java
140,7 → 140,7
return this.usersAndWeeklyMinutes;
}
}
final Map<User, Integer> uInfo = new LinkedHashMap<User, Integer>();
final Map<User, Integer> uInfo = new LinkedHashMap<>();
final SQLRowValues v = new SQLRowValues(this.salarieElem.getTable());
v.putNulls("NOM", "PRENOM");
v.putRowValues("ID_INFOS_SALARIE_PAYE").putNulls("DUREE_HEBDO");
152,10 → 152,14
for (int i = 0; i < size; i++) {
final User u = users.get(i);
final String name = u.getName().trim();
final String firstName = u.getFirstName();
final String firstName = u.getFirstName().trim();
Integer minutes = null;
for (SQLRowValues row : rows) {
if (row.getString("NOM").trim().equalsIgnoreCase(name) && row.getString("PRENOM").trim().equalsIgnoreCase(firstName)) {
// Matching Utilisateur <-> Salarié
// Nom et prénom identique
final String sName = row.getString("NOM").trim();
final String sFirstName = row.getString("PRENOM").trim();
if (sName.equalsIgnoreCase(name) && sFirstName.equalsIgnoreCase(firstName)) {
minutes = (int) row.getForeign("ID_INFOS_SALARIE_PAYE").getFloat("DUREE_HEBDO") * 60;
break;
}
169,8 → 173,8
}
 
private void setDurations(final List<List<JCalendarItem>> viewItems) {
final Map<Integer, Long> all = OperationCalendarPanel.getDurations(viewItems, null);
final Map<Integer, Long> locked = OperationCalendarPanel.getDurations(viewItems, Flag.getFlag("locked"));
final Map<Integer, Long> all = OperationCalendarPanel.getDurations(viewItems, null, ModuleOperation.FREE_TIME_FLAG);
final Map<Integer, Long> locked = OperationCalendarPanel.getDurations(viewItems, Flag.getFlag("locked"), ModuleOperation.FREE_TIME_FLAG);
synchronized (this) {
this.allDurations = Collections.unmodifiableMap(all);
this.lockedDurations = Collections.unmodifiableMap(locked);
217,10 → 221,10
// not a SALARIE
suffix = "";
} else {
// Durée verrouillée
final int d2 = getDuration(locked, u.getId());
// Durée planifiée
final int d = getDuration(all, u.getId());
// Durée verrouillée
final int d2 = getDuration(locked, u.getId());
suffix = " [" + formatDuration(d2) + " / " + formatDuration(d) + " / " + formatDuration(weeklyMinutes) + "]";
}
res.add(createItem(u, (u.getFullName() + suffix).trim()));
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/UserColor.java
18,12 → 18,16
final int size = users.size();
for (int i = 0; i < size; i++) {
final User u = users.get(i);
map.put(u.getId(), Color.decode(COLORS[i % COLORS.length]));
if (u.getColor() == null) {
this.map.put(u.getId(), Color.decode(COLORS[i % COLORS.length]));
} else {
this.map.put(u.getId(), u.getColor());
}
}
}
 
public synchronized Color getColor(int id) {
return map.get(id);
return this.map.get(id);
}
 
public static final synchronized UserColor getInstance() {
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationExportPanel.java
74,13 → 74,13
public class OperationExportPanel extends JPanel {
 
@GuardedBy("EDT")
static private final DateFormat DF = new SimpleDateFormat("yyyyMMdd");
private static final DateFormat DF = new SimpleDateFormat("yyyyMMdd");
 
final JCheckBox lockedCheckBox = new JCheckBox("verrouillées uniquement");
final JButton bPrint = new JButton("Exporter");
 
public OperationExportPanel(final OperationCalendarManager manager, final List<SQLRowValues> rowsSite) {
lockedCheckBox.setSelected(true);
this.lockedCheckBox.setSelected(true);
//
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
141,8 → 141,8
//
final JPanel p = new JPanel();
p.setLayout(new FlowLayout(FlowLayout.RIGHT));
p.add(lockedCheckBox);
p.add(bPrint);
p.add(this.lockedCheckBox);
p.add(this.bPrint);
c.gridwidth = 2;
c.gridx = 0;
c.gridy++;
151,7 → 151,7
this.add(p, c);
//
 
bPrint.addActionListener(new ActionListener() {
this.bPrint.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
160,9 → 160,9
}
final String statusVal = statusCombo.getValue();
final List<String> states = StringUtils.isEmpty(statusVal, true) ? null : Collections.singletonList(statusVal);
final List<JCalendarItem> items = manager.getItemIn(d1.getDate(), d2.getDate(), null, states);
final List<JCalendarItemDB> itemsToExport = new ArrayList<JCalendarItemDB>(items.size());
if (lockedCheckBox.isSelected()) {
final List<JCalendarItem> items = manager.getItemIn(d1.getDate(), d2.getDate(), manager.getAllUsers(), states);
final List<JCalendarItemDB> itemsToExport = new ArrayList<>(items.size());
if (OperationExportPanel.this.lockedCheckBox.isSelected()) {
for (JCalendarItem jCalendarItem : items) {
JCalendarItemDB i = (JCalendarItemDB) jCalendarItem;
if (i.getFlagsString().contains("locked")) {
176,12 → 176,12
}
}
if (rowsSite != null && !rowsSite.isEmpty()) {
final Set<String> allowedSites = new HashSet<String>();
final Set<String> allowedSites = new HashSet<>();
for (SQLRowValues r : rowsSite) {
String siteName = r.getString("NAME");
allowedSites.add(siteName);
}
final List<JCalendarItemDB> filtered = new ArrayList<JCalendarItemDB>(itemsToExport.size());
final List<JCalendarItemDB> filtered = new ArrayList<>(itemsToExport.size());
for (JCalendarItemDB i : itemsToExport) {
if (allowedSites.contains(i.getSiteName())) {
filtered.add(i);
218,9 → 218,9
});
}
 
static private final class Planner implements Comparable<Planner> {
private static final class Planner implements Comparable<Planner> {
 
static private final BigDecimal MS_PER_HOUR = BigDecimal.valueOf(1000 * 3600);
private static final BigDecimal MS_PER_HOUR = BigDecimal.valueOf(1000 * 3600);
 
private final String uid;
private final String xml;
256,7 → 256,7
 
final Element scheduleElem = doc.getRootElement().getChild("schedule");
this.startTime = new Date(Long.valueOf(scheduleElem.getAttributeValue("start")));
final long endTime = Long.valueOf(scheduleElem.getAttributeValue("end"));
final long endTime = Long.parseLong(scheduleElem.getAttributeValue("end"));
this.hours = DecimalUtils.round(BigDecimal.valueOf(endTime - this.startTime.getTime()).divide(MS_PER_HOUR, DecimalUtils.HIGH_PRECISION), 5);
} catch (Exception e) {
throw new IllegalStateException("couldn't get start for " + this.xml, e);
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationCalendarManager.java
62,6 → 62,10
this.userMngr = userMngr;
}
 
public UserManager getUserMngr() {
return userMngr;
}
 
public final SQLElementDirectory getDirectory() {
return this.dir;
}
389,4 → 393,15
}
return l.get(0);
}
 
/**
* Enabled or disabled users
*/
public List<User> getAllUsers() {
final List<User> result = new ArrayList<>();
for (User user : this.userMngr.getUsers().values()) {
result.add(user);
}
return result;
}
}
/trunk/Modules/Module Badge/src/org/openconcerto/modules/badge/Module.java
31,7 → 31,7
import org.openconcerto.erp.core.common.element.AdresseSQLElement;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.common.ui.ListeViewPanel;
import org.openconcerto.erp.core.customerrelationship.customer.element.ContactSQLElement;
import org.openconcerto.erp.core.customerrelationship.customer.element.ComptaContactSQLElement;
import org.openconcerto.erp.core.customerrelationship.customer.element.CustomerSQLElement;
import org.openconcerto.erp.modules.AbstractModule;
import org.openconcerto.erp.modules.ComponentsContext;
166,6 → 166,7
 
createTable.addForeignColumn("ID_ADRESSE", addrElem.getTable());
createTable.addForeignColumn("ID_PLAGE_HORAIRE", new SQLName("PLAGE_HORAIRE"), SQLSyntax.ID_NAME, null);
ctxt.executeSQL();
}
// at least v1.0
 
240,7 → 241,7
vals.put("CODE", code);
newClient = vals.insert();
}
final SQLRowValues contactVals = new SQLRowValues(ctxt.getElementDirectory().getElement(ContactSQLElement.class).getTable());
final SQLRowValues contactVals = new SQLRowValues(ctxt.getElementDirectory().getElement(ComptaContactSQLElement.class).getTable());
contactVals.putForeignID("ID_CLIENT", newClient);
contactVals.load(adhR.asRow(), Arrays.asList("NOM", "DATE_NAISSANCE"));
contactVals.put("PRENOM", firstName);
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/LeadSQLElement.java
4,6 → 4,7
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;
54,6 → 55,38
super(module, Module.TABLE_LEAD);
 
// Call
final RowAction.PredicateRowAction addDuplicateAction = new RowAction.PredicateRowAction(new AbstractAction("Créer à partir de") {
 
@Override
public void actionPerformed(ActionEvent e) {
SQLRow sRow = IListe.get(e).getSelectedRow().asRow();
final SQLTable table = LeadSQLElement.this.getTable().getTable(Module.TABLE_LEAD);
final SQLElement leadElt = LeadSQLElement.this.getDirectory().getElement(table);
EditFrame editFrame = new EditFrame(leadElt);
final SQLRowValues sqlRowValues = new SQLRowValues(table);
sqlRowValues.put("COMPANY", sRow.getObject("COMPANY"));
sqlRowValues.put("PHONE", sRow.getObject("PHONE"));
sqlRowValues.put("FAX", sRow.getObject("FAX"));
sqlRowValues.put("WEBSITE", sRow.getObject("WEBSITE"));
sqlRowValues.put("DATE", new Date());
SQLRowValues adr = new SQLRowValues(sRow.getForeign("ID_ADRESSE").asRowValues());
sqlRowValues.put("ID_ADRESSE", adr);
sqlRowValues.put("INDUSTRY", sRow.getObject("INDUSTRY"));
sqlRowValues.put("REVENUE", sRow.getObject("REVENUE"));
sqlRowValues.put("EMPLOYEES", sRow.getObject("EMPLOYEES"));
sqlRowValues.put("LOCALISATION", sRow.getObject("LOCALISATION"));
sqlRowValues.put("SIRET", sRow.getObject("SIRET"));
sqlRowValues.put("APE", sRow.getObject("APE"));
 
editFrame.getSQLComponent().select(sqlRowValues);
FrameUtil.show(editFrame);
}
}, true) {
};
addDuplicateAction.setPredicate(IListeEvent.getSingleSelectionPredicate());
getRowActions().add(addDuplicateAction);
 
// Call
final RowAction.PredicateRowAction addCallAction = new RowAction.PredicateRowAction(new AbstractAction("Appeler") {
 
@Override
121,6 → 154,79
}
}
 
if (getTable().contains("MODIFICATION_DATE")) {
BaseSQLTableModelColumn dateM = new BaseSQLTableModelColumn("Date de modification", Date.class) {
 
@Override
protected Object show_(SQLRowAccessor r) {
return r.getObject("MODIFICATION_DATE");
}
 
@Override
public Set<FieldPath> getPaths() {
Path p = new Path(getTable());
return CollectionUtils.createSet(new FieldPath(p, "MODIFICATION_DATE"));
}
};
source.getColumns().add(1, dateM);
}
 
BaseSQLTableModelColumn dateV = new BaseSQLTableModelColumn("Visite", Date.class) {
 
@Override
protected Object show_(SQLRowAccessor r) {
Date d = null;
Collection<? extends SQLRowAccessor> l = r.getReferentRows(r.getTable().getTable("LEAD_VISIT"));
for (SQLRowAccessor sqlRowAccessor : l) {
if (d != null && sqlRowAccessor.getObject("DATE") != null && d.before(sqlRowAccessor.getDate("DATE").getTime())) {
d = sqlRowAccessor.getDate("DATE").getTime();
} else {
if (d == null && sqlRowAccessor.getObject("DATE") != null) {
d = sqlRowAccessor.getDate("DATE").getTime();
}
}
 
}
return d;
}
 
@Override
public Set<FieldPath> getPaths() {
Path p = new Path(getTable());
p = p.add(p.getLast().getTable("LEAD_VISIT"));
return CollectionUtils.createSet(new FieldPath(p, "DATE"));
}
};
source.getColumns().add(1, dateV);
 
BaseSQLTableModelColumn dateA = new BaseSQLTableModelColumn("Appel", Date.class) {
 
@Override
protected Object show_(SQLRowAccessor r) {
Date d = null;
Collection<? extends SQLRowAccessor> l = r.getReferentRows(r.getTable().getTable("LEAD_CALL"));
for (SQLRowAccessor sqlRowAccessor : l) {
if (d != null && sqlRowAccessor.getObject("DATE") != null && d.before(sqlRowAccessor.getDate("DATE").getTime())) {
d = sqlRowAccessor.getDate("DATE").getTime();
} else {
if (d == null && sqlRowAccessor.getObject("DATE") != null) {
d = sqlRowAccessor.getDate("DATE").getTime();
}
}
 
}
return d;
}
 
@Override
public Set<FieldPath> getPaths() {
Path p = new Path(getTable());
p = p.add(p.getLast().getTable("LEAD_CALL"));
return CollectionUtils.createSet(new FieldPath(p, "DATE"));
}
};
source.getColumns().add(1, dateA);
 
BaseSQLTableModelColumn adresse = new BaseSQLTableModelColumn("Adresse", String.class) {
 
@Override
189,6 → 295,32
};
source.getColumns().add(ville);
 
BaseSQLTableModelColumn dpt = new BaseSQLTableModelColumn("Département", String.class) {
 
@Override
protected Object show_(SQLRowAccessor r) {
 
String s = r.getForeign("ID_ADRESSE").getString("CODE_POSTAL");
if (s != null && s.length() >= 2) {
return s.substring(0, 2);
} else {
return s;
}
 
}
 
@Override
public Set<FieldPath> getPaths() {
Path p = new Path(getTable());
final SQLTable clientT = getTable().getForeignTable("ID_CLIENT");
p = p.add(clientT);
p = p.add(clientT.getField("ID_ADRESSE"));
return CollectionUtils.createSet(new FieldPath(p, "VILLE"), new FieldPath(p, "CODE_POSTAL"));
}
};
 
source.getColumns().add(dpt);
 
if (getTable().contains("REMIND_DATE")) {
BaseSQLTableModelColumn dateRemind = new BaseSQLTableModelColumn("Date de rappel", Date.class) {
 
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/translation_fr.xml
New file
0,0 → 1,4
<translation lang="fr">
<item id="customerrelationship.lead.items.call.tab" label="Appels" />
<item id="customerrelationship.lead.items.visit.tab" label="Visites" />
</translation>
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/LeadCustomerSQLInjector.java
3,6 → 3,8
*/
package org.openconcerto.modules.customerrelationship.lead;
 
import java.util.Date;
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRowAccessor;
26,6 → 28,8
map(leadTable.getField("MOBILE"), customerTable.getField("TEL_P"));
// map(leadTable.getField("INFORMATION"), customerTable.getField("INFOS"));
map(getSource().getField("INFOS"), getDestination().getField("INFOS"));
remove(leadTable.getField("DATE"), customerTable.getField("DATE"));
mapDefaultValues(customerTable.getField("DATE"), new Date());
remove(leadTable.getField("ID_ADRESSE"), customerTable.getField("ID_ADRESSE"));
}
 
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/labels_fr.xml
38,6 → 38,7
name="rapport d'appel prospect" namePlural="rapports d'appel prospect">
<FIELD name="DATE" label="Date de l'appel" />
<FIELD name="ID_LEAD" label="Entreprise" />
<FIELD name="ID_COMMERCIAL" label="Commercial" />
<FIELD name="INFORMATION" label="Résumé de l'appel" />
<FIELD name="NEXTCONTACT_DATE" label="Date de prochain contact" />
<FIELD name="NEXTCONTACT_INFO" label="Motif de prochain contact" />
47,6 → 48,7
</element>
<element refid="org.openconcerto.modules.customerrelationship.lead/CUSTOMER_CALL" nameClass="masculine"
name="rapport d'appel client" namePlural="rapports d'appel client">
<FIELD name="ID_COMMERCIAL" label="Commercial" />
<FIELD name="DATE" label="Date de l'appel" />
<FIELD name="ID_CLIENT" label="Client" />
<FIELD name="INFORMATION" label="Résumé de l'appel" />
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/LeadSQLComponent.java
5,13 → 5,17
 
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
 
import org.openconcerto.modules.customerrelationship.lead.visit.LeadActionItemTable;
import org.openconcerto.sql.element.GroupSQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLBackgroundTableCache;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.SQLSearchableTextCombo;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.ui.JDate;
21,8 → 25,12
import org.openconcerto.ui.group.Group;
 
public class LeadSQLComponent extends GroupSQLComponent {
 
private LeadActionItemTable tableCall, tableVisit;
 
public LeadSQLComponent(SQLElement element, Group group) {
super(element, group);
startTabGroupAfter("customerrelationship.lead.state");
}
 
@Override
37,10 → 45,26
public JComponent getLabel(String id) {
if (id.equals("customerrelationship.lead.person")) {
return new JLabelBold("Contact");
}
if (id.equals("customerrelationship.lead.items.visit.tab")) {
return new JLabelBold("Visites");
}
if (id.equals("customerrelationship.lead.items.visit")) {
return new JLabelBold("");
}
if (id.equals("customerrelationship.lead.items.call.tab")) {
return new JLabelBold("Appels");
}
if (id.equals("customerrelationship.lead.items.call")) {
return new JLabelBold("");
} else if (id.equals("customerrelationship.lead.contact")) {
return new JLabel();
} else if (id.equals("customerrelationship.lead.address")) {
return new JLabelBold("Adresse");
} else if (id.equals("customerrelationship.lead.info")) {
return new JLabelBold("Infos");
} else if (id.equals("customerrelationship.lead.state")) {
return new JLabelBold("Statut");
} else {
return super.getLabel(id);
}
48,20 → 72,61
 
@Override
public JComponent createEditor(String id) {
 
if (id.equals("INFORMATION") || id.equals("INFOS")) {
final ITextArea jTextArea = new ITextArea();
final ITextArea jTextArea = new ITextArea(3,3);
jTextArea.setFont(new JLabel().getFont());
return jTextArea;
} else if (id.equals("ID_COMMERCIAL") || id.equals("ID_TITRE_PERSONNEL")) {
ElementComboBox comp = new ElementComboBox(false, 1);
((ElementComboBox) comp).init(getElement().getForeignElement(id));
return comp;
} else if (id.equals("customerrelationship.lead.items.call")) {
tableCall = new LeadActionItemTable(getElement().getDirectory().getElement(Module.TABLE_LEAD_CALL));
return tableCall;
} else if (id.equals("customerrelationship.lead.items.visit")) {
tableVisit = new LeadActionItemTable(getElement().getDirectory().getElement(Module.TABLE_LEAD_VISIT));
return tableVisit;
} else if (id.equals("INDUSTRY") || id.equals("STATUS") || id.equals("RATING") || id.equals("SOURCE") || id.equals("DISPO")) {
return new SQLSearchableTextCombo(ComboLockedMode.UNLOCKED, 1, 20, false);
return new SQLSearchableTextCombo(ComboLockedMode.UNLOCKED, 1, 1, false);
} else if (id.equals("DATE")) {
return new JDate(true);
}
return super.createEditor(id);
JComponent comp = super.createEditor(id);
if(comp.getClass() == JTextField.class) {
JTextField jtxt = new JTextField(10);
comp = jtxt;
}
 
return comp;
}
 
@Override
public int insert(SQLRow order) {
int id = super.insert(order);
this.tableCall.updateField("ID_LEAD", id);
this.tableVisit.updateField("ID_LEAD", id);
return id;
}
 
@Override
public void select(SQLRowAccessor r) {
super.select(r);
if (r != null) {
this.tableCall.insertFrom("ID_LEAD", r.getID());
this.tableVisit.insertFrom("ID_LEAD", r.getID());
}
}
 
@Override
public void update() {
super.update();
this.tableCall.updateField("ID_LEAD", getSelectedID());
this.tableVisit.updateField("ID_LEAD", getSelectedID());
}
 
@Override
protected SQLRowValues createDefaults() {
SQLRowValues rowVals = new SQLRowValues(getTable());
rowVals.put("STATUS", "Nouveau");
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/visit/LeadVisitSQLElement.java
28,6 → 28,11
final List<String> l = new ArrayList<String>();
l.add("DATE");
l.add("ID_LEAD");
l.add("INFORMATION");
if (getTable().contains("ID_COMMERCIAL")) {
l.add("ID_COMMERCIAL");
}
 
l.add("NEXTCONTACT_DATE");
return l;
}
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/visit/CustomerVisitSQLElement.java
28,6 → 28,10
final List<String> l = new ArrayList<String>();
l.add("DATE");
l.add("ID_CLIENT");
l.add("INFORMATION");
if (getTable().contains("ID_COMMERCIAL")) {
l.add("ID_COMMERCIAL");
}
l.add("NEXTCONTACT_DATE");
return l;
}
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/visit/LeadActionItemTable.java
New file
0,0 → 1,106
package org.openconcerto.modules.customerrelationship.lead.visit;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.io.File;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Vector;
 
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ToolTipManager;
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLBackgroundTableCache;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.view.list.RowValuesTable;
import org.openconcerto.sql.view.list.RowValuesTableControlPanel;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.RowValuesTableRenderer;
import org.openconcerto.sql.view.list.SQLTableElement;
import org.openconcerto.ui.table.TimestampTableCellEditor;
 
public class LeadActionItemTable extends JPanel {
 
private RowValuesTable table;
final RowValuesTableControlPanel comp;
 
public LeadActionItemTable(SQLElement elt) {
this.setOpaque(false);
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = 1;
c.gridheight = 1;
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.weighty = 0;
 
List<SQLTableElement> list = new Vector<SQLTableElement>();
 
SQLTableElement tableElementDateL = new SQLTableElement(elt.getTable().getField("DATE"), Timestamp.class, new TimestampTableCellEditor());
list.add(tableElementDateL);
 
SQLTableElement tableElementTps = new SQLTableElement(elt.getTable().getField("INFORMATION"));
list.add(tableElementTps);
 
if (elt.getTable().contains("ID_COMMERCIAL")) {
SQLTableElement tableElementCom = new SQLTableElement(elt.getTable().getField("ID_COMMERCIAL"));
list.add(tableElementCom);
}
 
SQLRowValues rowValsDefault = new SQLRowValues(elt.getTable());
rowValsDefault.put("DATE", new Date());
if (elt.getTable().contains("ID_COMMERCIAL")) {
final int idUser = UserManager.getInstance().getCurrentUser().getId();
final SQLElement eltComm = elt.getForeignElement("ID_COMMERCIAL");
SQLRow rowsComm = SQLBackgroundTableCache.getInstance().getCacheForTable(eltComm.getTable()).getFirstRowContains(idUser, eltComm.getTable().getField("ID_USER_COMMON"));
 
if (rowsComm != null) {
rowValsDefault.put("ID_COMMERCIAL", rowsComm.getID());
}
}
final RowValuesTableModel model = new RowValuesTableModel(elt, list, elt.getTable().getField("DATE"), false, rowValsDefault);
 
this.table = new RowValuesTable(model, new File(Configuration.getInstance().getConfDir(), "Table" + File.separator + "Table_LeadActionItemTable.xml"));
ToolTipManager.sharedInstance().unregisterComponent(this.table);
ToolTipManager.sharedInstance().unregisterComponent(this.table.getTableHeader());
this.comp = new RowValuesTableControlPanel(this.table);
this.add(this.comp, c);
 
c.gridy++;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
this.add(new JScrollPane(this.table), c);
this.table.setDefaultRenderer(Long.class, new RowValuesTableRenderer());
}
 
public void updateField(String field, int id) {
this.table.updateField(field, id);
}
 
public void insertFrom(String field, SQLRowValues row) {
this.table.insertFrom(field, row);
}
 
public void insertFrom(String field, int id) {
this.table.insertFrom(field, id);
}
 
public RowValuesTableModel getModel() {
return this.table.getRowValuesTableModel();
}
 
public void setEditable(boolean b) {
this.comp.setEditable(b);
this.table.setEditable(b);
}
 
}
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/importer/LeadImporter.java
19,10 → 19,15
import org.openconcerto.openoffice.spreadsheet.Sheet;
import org.openconcerto.openoffice.spreadsheet.SpreadSheet;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesCluster;
import org.openconcerto.sql.model.SQLRowValuesCluster.StoreMode;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLRowValuesCluster.StoreMode;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.utils.cc.IdentityHashSet;
import org.openconcerto.utils.text.CSVReader;
import org.openconcerto.utils.text.CharsetHelper;
76,6 → 81,82
public abstract T convert(String[] line);
}
 
public Map<Object, LeadCSV> exportLeads(SQLTable tableLead, File dir2save, File sheetFile) throws Exception {
List<String[]> adresse = new ArrayList<String[]>();
List<String[]> leadList = new ArrayList<String[]>();
 
Map<Object, LeadCSV> leadMap = new HashMap<Object, LeadCSV>();
 
SQLSelect sel = new SQLSelect();
sel.addSelectStar(tableLead);
List<SQLRow> leads = SQLRowListRSH.execute(sel);
int i = 1;
for (SQLRow lead : leads) {
 
int idAdr = adresse.size();
AdresseCSV adr = createAdresse(i, lead.getForeign("ID_ADRESSE"));
adresse.add(adr.toCSVLine());
LeadCSV leadCsv = createLeadFromRow(i, lead, Integer.valueOf(adr.getId().toString()));
leadList.add(leadCsv.toCSVLine());
leadMap.put(leadCsv.getId(), leadCsv);
i++;
}
 
DataImporter importer = new DataImporter(tableLead);
final File csvFile = new File(dir2save, "Lead.csv");
csvFile.createNewFile();
importer.exportModelToCSV(csvFile, leadList);
DataImporter importerAdr = new DataImporter(tableLead.getForeignTable("ID_ADRESSE"));
final File csvFile2 = new File(dir2save, "Address.csv");
csvFile2.createNewFile();
importerAdr.exportModelToCSV(csvFile2, adresse);
 
return leadMap;
}
 
public AdresseCSV createAdresse(int i, SQLRow rowAdr) {
 
String street = rowAdr.getString("RUE");
final String ville = rowAdr.getString("VILLE");
final String cp = rowAdr.getString("CODE_POSTAL");
 
AdresseCSV adrLine = new AdresseCSV(i, street, ville, cp);
 
return adrLine;
}
 
public LeadCSV createLeadFromRow(int i, SQLRowAccessor row, int idAdr) {
 
LeadCSV leadLine = new LeadCSV(i, row.getString("COMPANY"), "");
 
leadLine.setIdAdr(idAdr);
 
leadLine.setPhone(row.getString("PHONE"));
leadLine.setMail(row.getString("EMAIL"));
leadLine.setCell(row.getString("MOBILE"));
leadLine.setFax(row.getString("FAX"));
leadLine.setContact(row.getString("NAME"));
leadLine.setLocalisation(row.getString("LOCALISATION"));
leadLine.setSecteur(row.getString("INDUSTRY"));
leadLine.setEffectif(String.valueOf(row.getInt("EMPLOYEES")));
leadLine.setOrigine(row.getString("SOURCE"));
 
leadLine.setSiret(row.getString("SIRET"));
leadLine.setApe(row.getString("APE"));
 
leadLine.setNom(row.getString("NAME"));
leadLine.setPrenom(row.getString("FIRSTNAME"));
leadLine.setDesc(row.getString("INFORMATION"));
// rowVals.put("REVENUE", (getBudget().trim().length()==0?0:Integer);
leadLine.setDispo(row.getString("DISPO"));
leadLine.setTypeT(row.getString("INDUSTRY"));
leadLine.setStatut(row.getString("STATUS"));
leadLine.setInfos(row.getString("INFOS"));
 
return leadLine;
 
}
 
public LeadCSV createLead(int i, Sheet sheet, int idAdr, int id) {
final Cell<SpreadSheet> cell0 = sheet.getImmutableCellAt(0, i);
final String societeName = cell0.getValue().toString().trim();
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/LeadGroup.java
1,6 → 1,5
package org.openconcerto.modules.customerrelationship.lead;
 
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.users.rights.UserRights;
import org.openconcerto.sql.users.rights.UserRightsManager;
import org.openconcerto.ui.group.Group;
11,52 → 10,59
public LeadGroup() {
super("customerrelationship.lead.default");
final Group g = new Group("customerrelationship.lead.identifier");
g.addItem("NUMBER");
g.addItem("DATE");
g.addItem("NUMBER", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
g.addItem("DATE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
g.addItem("COMPANY", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
this.add(g);
 
final Group gContact = new Group("customerrelationship.lead.person", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gContact.addItem("NAME");
gContact.addItem("FIRSTNAME");
gContact.addItem("ID_TITRE_PERSONNEL");
gContact.addItem("ID_TITRE_PERSONNEL", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gContact.addItem("NAME", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gContact.addItem("FIRSTNAME", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
this.add(gContact);
 
final Group gCustomer = new Group("customerrelationship.lead.contact", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gCustomer.addItem("ROLE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gCustomer.addItem("PHONE");
gCustomer.addItem("MOBILE");
gCustomer.addItem("FAX");
gCustomer.addItem("PHONE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gCustomer.addItem("MOBILE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gCustomer.addItem("FAX", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gCustomer.addItem("EMAIL", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gCustomer.addItem("WEBSITE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
this.add(gCustomer);
 
final Group gAddress = new Group("customerrelationship.lead.address", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gAddress.addItem("ID_ADRESSE");
gAddress.addItem("ID_ADRESSE", LayoutHints.DEFAULT_VERY_LARGE_FIELD_HINTS);
this.add(gAddress);
 
final Group gInfos = new Group("customerrelationship.lead.info");
gInfos.addItem("INFORMATION", new LayoutHints(true, true, true, true, true, true));
gInfos.addItem("INDUSTRY");
gInfos.addItem("REVENUE");
gInfos.addItem("EMPLOYEES");
gInfos.addItem("INFOS", new LayoutHints(true, true, true, true, true, true));
final Group gInfos = new Group("customerrelationship.lead.info", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gInfos.addItem("INFORMATION", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gInfos.addItem("INDUSTRY", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gInfos.addItem("REVENUE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gInfos.addItem("EMPLOYEES", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gInfos.addItem("INFOS", new LayoutHints(true, true, true, true, true, true, true, true));
this.add(gInfos);
 
final Group gState = new Group("customerrelationship.lead.state");
gState.addItem("RATING");
gState.addItem("SOURCE");
gState.addItem("STATUS");
gState.addItem("ID_COMMERCIAL");
gState.addItem("REMIND_DATE");
final Group gState = new Group("customerrelationship.lead.state", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gState.addItem("RATING", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gState.addItem("SOURCE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gState.addItem("STATUS", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gState.addItem("ID_COMMERCIAL", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gState.addItem("REMIND_DATE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
UserRights rights = UserRightsManager.getCurrentUserRights();
if (rights.haveRight("CLIENT_PROSPECT")) {
gState.addItem("ID_CLIENT");
gState.addItem("ID_CLIENT", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
}
gState.addItem("DISPO");
 
gState.addItem("DISPO", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
this.add(gState);
 
final Group gItems = new Group("customerrelationship.lead.items.call.tab");
gItems.addItem("customerrelationship.lead.items.call", LayoutHints.DEFAULT_VERY_LARGE_TEXT_HINTS);
this.add(gItems);
 
final Group gItems2 = new Group("customerrelationship.lead.items.visit.tab");
gItems2.addItem("customerrelationship.lead.items.visit", LayoutHints.DEFAULT_VERY_LARGE_TEXT_HINTS);
this.add(gItems2);
 
}
 
public static void main(String[] args) {
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/call/CustomerCallSQLElement.java
15,6 → 15,7
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.component.ITextArea;
 
public class CustomerCallSQLElement extends ModuleElement {
 
27,6 → 28,11
final List<String> l = new ArrayList<String>();
l.add("DATE");
l.add("ID_CLIENT");
l.add("INFORMATION");
if (getTable().contains("ID_COMMERCIAL")) {
l.add("ID_COMMERCIAL");
}
return l;
}
 
54,10 → 60,8
@Override
public JComponent createEditor(String id) {
if (id.equals("INFORMATION")) {
final JTextArea jTextArea = new JTextArea();
jTextArea.setFont(new JLabel().getFont());
jTextArea.setMinimumSize(new Dimension(200, 150));
jTextArea.setPreferredSize(new Dimension(200, 150));
final ITextArea jTextArea = new ITextArea();
jTextArea.setRows(20);
return new JScrollPane(jTextArea);
} else if (id.equals("DATE")) {
return new JDate(true);
/trunk/Modules/Module Lead/src/org/openconcerto/modules/customerrelationship/lead/call/LeadCallSQLElement.java
7,7 → 7,6
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
 
import org.openconcerto.erp.modules.AbstractModule;
import org.openconcerto.erp.modules.ModuleElement;
15,6 → 14,7
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.component.ITextArea;
 
public class LeadCallSQLElement extends ModuleElement {
 
27,6 → 27,11
final List<String> l = new ArrayList<String>();
l.add("DATE");
l.add("ID_LEAD");
l.add("INFORMATION");
if (getTable().contains("ID_COMMERCIAL")) {
l.add("ID_COMMERCIAL");
}
 
return l;
}
 
54,10 → 59,8
@Override
public JComponent createEditor(String id) {
if (id.equals("INFORMATION")) {
final JTextArea jTextArea = new JTextArea();
jTextArea.setFont(new JLabel().getFont());
jTextArea.setMinimumSize(new Dimension(200, 150));
jTextArea.setPreferredSize(new Dimension(200, 150));
final ITextArea jTextArea = new ITextArea();
jTextArea.setRows(20);
return new JScrollPane(jTextArea);
} else if (id.equals("DATE")) {
return new JDate(true);
/trunk/Modules/Module Project/src/org/openconcerto/modules/project/Module.java
94,7 → 94,6
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.cc.IExnClosure;
import org.openconcerto.utils.cc.ITransformer;
import org.openconcerto.utils.i18n.TranslationManager;
 
public final class Module extends AbstractModule {
 
191,7 → 190,6
@Override
protected void setupElements(final SQLElementDirectory dir) {
super.setupElements(dir);
TranslationManager.getInstance().addTranslationStreamFromClass(this.getClass());
dir.addSQLElement(ProjectSQLElement.class);
dir.addSQLElement(ProjectStateSQLElement.class);
dir.addSQLElement(ProjectTypeSQLElement.class);
607,7 → 605,7
protected void setupComponents(final ComponentsContext ctxt) {
 
DBRoot root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
List<String> table2check = Arrays.asList("BON_RECEPTION", "DEMANDE_PRIX", "DEMANDE_ACHAT_ELEMENT");
List<String> table2check = Arrays.asList("BON_RECEPTION", "DEMANDE_PRIX", "DEMANDE_ACHAT_ELEMENT", "FACTURE_FOURNISSEUR");
for (String table : table2check) {
if (root.contains(table)) {
SQLTable tableCR = root.getTable(table);
/trunk/Modules/Module Expense/src/org/openconcerto/modules/humanresources/travel/expense/labels_fr.xml
1,7 → 1,7
<?xml version="1.0" encoding="UTF-8" ?>
<ROOT>
<TABLE name="EXPENSE_STATE">
<FIELD name="NAME" label="Nom" />
<FIELD name="NAME" label="Statut" />
</TABLE>
<TABLE name="EXPENSE">
<FIELD name="NAME" label="Nom" />
12,9 → 12,9
<FIELD name="TRAVEL_RATE" label="Tarif kilométrique" />
<FIELD name="TRAVEL_AMOUNT" label="Montant des frais kilométriques" />
<FIELD name="MISC_AMOUNT" label="Montant des frais annexes" />
<FIELD name="ID_EXPENSE_STATE" label="Status" />
<FIELD name="ID_EXPENSE_STATE" label="Statut" />
<FIELD name="ID_USER_COMMON" label="Employé" />
<FIELD name="ID_EXPENSE_STATE" label="Status" />
<FIELD name="ID_EXPENSE_STATE" label="Statut" />
</TABLE>
 
</ROOT>
/trunk/Modules/Module Expense/src/org/openconcerto/modules/humanresources/travel/expense/ExpenseSQLComponent.java
7,6 → 7,7
import java.util.Set;
 
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.text.AbstractDocument;
import javax.swing.text.JTextComponent;
 
13,9 → 14,10
import org.openconcerto.erp.core.common.ui.DeviseField;
import org.openconcerto.sql.element.GroupSQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.itemview.VWRowItemView;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.component.ITextArea;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.component.text.TextComponentUtils;
import org.openconcerto.ui.group.Group;
import org.openconcerto.utils.text.DocumentFilterList;
41,11 → 43,13
}
};
 
final AbstractDocument comp1 = (AbstractDocument) TextComponentUtils.getDocument(getView("TRAVEL_DISTANCE").getComp());
final AbstractDocument comp1 = (AbstractDocument) TextComponentUtils
.getDocument(getView("TRAVEL_DISTANCE").getComp());
DocumentFilterList.add(comp1, new LimitedSizeDocumentFilter(5), FilterType.SIMPLE_FILTER);
getView("TRAVEL_DISTANCE").addValueListener(listener);
 
final AbstractDocument comp2 = (AbstractDocument) TextComponentUtils.getDocument(getView("TRAVEL_RATE").getComp());
final AbstractDocument comp2 = (AbstractDocument) TextComponentUtils
.getDocument(getView("TRAVEL_RATE").getComp());
DocumentFilterList.add(comp2, new LimitedSizeDocumentFilter(5), FilterType.SIMPLE_FILTER);
 
getView("TRAVEL_RATE").addValueListener(listener);
62,17 → 66,33
}
 
@Override
public JComponent getEditor(String id) {
if (id.equals("DESCRIPTION")) {
return new ITextArea();
} else if (id.equals("DATE")) {
public JComponent createEditor(String id) {
if(id.equals("ID_USER_COMMON") || id.equals("ID_EXPENSE_STATE")) {
ElementComboBox comp = new ElementComboBox(false, 15);
((ElementComboBox) comp).init(getElement().getForeignElement(id));
return comp;
}
else if (id.equals("DATE")) {
return new JDate(true);
} else if (id.endsWith("AMOUNT")) {
return new DeviseField();
}
return super.getEditor(id);
return super.createEditor(id);
}
 
@Override
public JLabel getLabel(String id) {
if (id.equals("humanresources.travel.expense.travel")) {
return new JLabelBold("Frais kilometriques");
} else if (id.equals("humanresources.travel.expense.default")) {
return new JLabelBold("Descriptif");
} else if (id.equals("humanresources.travel.expense.misc")) {
return new JLabelBold("Frais annexes");
} else {
return (JLabel) super.getLabel(id);
}
}
 
private void updateAmount() {
float v1 = getFloat("TRAVEL_DISTANCE");
float v2 = getFloat("TRAVEL_RATE");
/trunk/Modules/Module Expense/src/org/openconcerto/modules/humanresources/travel/expense/ExpenseGroup.java
7,32 → 7,31
public class ExpenseGroup extends Group {
 
public ExpenseGroup() {
super(ExpenseSQLElement.ELEMENT_CODE + ".default");
super(ExpenseSQLElement.ELEMENT_CODE + ".default", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
final Group g = new Group(ExpenseSQLElement.ELEMENT_CODE + ".identifier");
g.addItem("DATE");
g.addItem("ID_USER_COMMON");
g.addItem("DATE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
g.addItem("ID_USER_COMMON", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
 
this.add(g);
 
final Group gDescription = new Group(ExpenseSQLElement.ELEMENT_CODE + ".description");
gDescription.add(new Item("DESCRIPTION", new LayoutHints(true, true, true, true, true, true)));
gDescription.addItem("DESCRIPTION", new LayoutHints(true, true, true, true, true, true, true, true));
gDescription.addItem("ID_EXPENSE_STATE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
this.add(gDescription);
 
final Group gTravel = new Group(ExpenseSQLElement.ELEMENT_CODE + ".travel", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gTravel.addItem("TRAVEL_DISTANCE");
gTravel.addItem("TRAVEL_RATE");
gTravel.addItem("TRAVEL_AMOUNT");
final Group gTravel = new Group(ExpenseSQLElement.ELEMENT_CODE + ".travel",
LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gTravel.addItem("TRAVEL_DISTANCE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gTravel.addItem("TRAVEL_RATE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
gTravel.addItem("TRAVEL_AMOUNT", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
this.add(gTravel);
 
final Group gAddress = new Group(ExpenseSQLElement.ELEMENT_CODE + ".misc", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gAddress.addItem("MISC_AMOUNT");
final Group gAddress = new Group(ExpenseSQLElement.ELEMENT_CODE + ".misc",
LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS);
gAddress.addItem("MISC_AMOUNT", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
// gAddress.addItem("ID_EXPENSE_STATE", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
this.add(gAddress);
 
final Group gState = new Group(ExpenseSQLElement.ELEMENT_CODE + ".state");
gState.addItem("ID_EXPENSE_STATE");
 
this.add(gState);
 
}
 
}
/trunk/Modules/Module Expense/src/org/openconcerto/modules/humanresources/travel/expense/translation_fr.xml
New file
0,0 → 1,5
<translation lang="fr">
<item id="humanresources.travel.expense.travel" label="Frais kilometriques" />
<item id="humanresources.travel.expense.misc" label="Frais annexes" />
<item id="humanresources.travel.expense.default" label="Description" />
</translation>
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/BooleanProcessor.java
13,13 → 13,13
import org.openconcerto.ui.VFlowLayout;
 
public class BooleanProcessor extends JPanel implements BatchProcessor {
private final SQLField field;
private final BatchField field;
 
private JRadioButton bTrue;
private JRadioButton bFalse;
private JRadioButton bInvert;
 
public BooleanProcessor(SQLField field) {
public BooleanProcessor(BatchField field) {
this.field = field;
this.setLayout(new VFlowLayout());
bTrue = new JRadioButton("forcer à vrai");
41,7 → 41,7
if (bTrue.isSelected()) {
for (SQLRowAccessor sqlRowAccessor : r) {
final SQLRowValues rowValues = sqlRowAccessor.createEmptyUpdateRow();
rowValues.put(field.getName(), Boolean.TRUE);
rowValues.put(field.getField().getName(), Boolean.TRUE);
processBeforeUpdate(sqlRowAccessor, rowValues);
rowValues.update();
}
48,7 → 48,7
} else if (bFalse.isSelected()) {
for (SQLRowAccessor sqlRowAccessor : r) {
final SQLRowValues rowValues = sqlRowAccessor.createEmptyUpdateRow();
rowValues.put(field.getName(), Boolean.FALSE);
rowValues.put(field.getField().getName(), Boolean.FALSE);
processBeforeUpdate(sqlRowAccessor, rowValues);
rowValues.update();
}
55,9 → 55,9
} else if (bInvert.isSelected()) {
for (SQLRowAccessor sqlRowAccessor : r) {
final SQLRowValues rowValues = sqlRowAccessor.createEmptyUpdateRow();
final Boolean boolean1 = sqlRowAccessor.asRow().getBoolean(field.getName());
final Boolean boolean1 = sqlRowAccessor.asRow().getBoolean(field.getField().getName());
if (boolean1 != null) {
rowValues.put(field.getName(), boolean1.equals(Boolean.FALSE));
rowValues.put(field.getField().getName(), boolean1.equals(Boolean.FALSE));
processBeforeUpdate(sqlRowAccessor, rowValues);
rowValues.update();
}
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/BatchDetailPanel.java
22,46 → 22,47
this.setLayout(new VFlowLayout());
}
 
public void setField(SQLField field) {
public void setField(BatchField batchField) {
this.removeAll();
 
SQLField field = batchField.getField();
final SQLType type = field.getType();
final Class<?> javaType = type.getJavaType();
final String fName = field.getName();
if (fName.equals("PV_TTC")) {
final NumberProcessor p = new TTCProcessor(field);
final NumberProcessor p = new TTCProcessor(batchField);
this.add(p);
this.processor = p;
} else if (fName.equals("PV_HT")) {
final NumberProcessor p = new HTProcessor(field);
final NumberProcessor p = new HTProcessor(batchField);
this.add(p);
this.processor = p;
} else if (fName.equals("ID_TAXE")) {
final ReferenceProcessor p = new TVAProcessor(field);
final ReferenceProcessor p = new TVAProcessor(batchField);
this.add(p);
this.processor = p;
} else if (fName.equals("PA_HT")) {
final NumberProcessor p = new PurchaseProcessor(field);
final NumberProcessor p = new PurchaseProcessor(batchField);
this.add(p);
this.processor = p;
} else if (javaType.equals(Boolean.class)) {
final BooleanProcessor p = new BooleanProcessor(field);
final BooleanProcessor p = new BooleanProcessor(batchField);
this.add(p);
this.processor = p;
} else if (field.isKey()) {
final ReferenceProcessor p = new ReferenceProcessor(field);
final ReferenceProcessor p = new ReferenceProcessor(batchField);
this.add(p);
this.processor = p;
} else if (javaType.equals(String.class)) {
final StringProcessor p = new StringProcessor(field);
final StringProcessor p = new StringProcessor(batchField);
this.add(p);
this.processor = p;
} else if (javaType.equals(Date.class)) {
final DateProcessor p = new DateProcessor(field);
final DateProcessor p = new DateProcessor(batchField);
this.add(p);
this.processor = p;
} else if (javaType.equals(BigDecimal.class) || javaType.equals(Float.class) || javaType.equals(Double.class) || javaType.equals(Integer.class) || javaType.equals(Long.class)) {
final NumberProcessor p = new NumberProcessor(field);
final NumberProcessor p = new NumberProcessor(batchField);
this.add(p);
this.processor = p;
}
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/BatchField.java
New file
0,0 → 1,58
package org.openconcerto.modules.common.batchprocessing;
 
import java.util.List;
 
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.SQLFieldTranslator;
 
public class BatchField {
 
private final SQLField field;
private final SQLRowAccessor foreignLinkRow;
private final SQLFieldTranslator translator;
private final SQLElement elementLink;
 
public BatchField(SQLElementDirectory dir, SQLField field, SQLRowAccessor foreignLinkRow) {
this.field = field;
this.foreignLinkRow = foreignLinkRow;
 
this.translator = dir.getTranslator();
if (foreignLinkRow == null) {
this.elementLink = null;
} else {
this.elementLink = dir.getElement(foreignLinkRow.getTable());
}
}
 
public SQLField getField() {
return field;
}
 
public SQLRowAccessor getForeignLinkRow() {
return foreignLinkRow;
}
 
public String getComboName() {
if (this.foreignLinkRow == null) {
return this.translator.getLabelFor(this.field);
} else {
return this.elementLink.getPluralName() + " " + this.foreignLinkRow.getString("NOM") + " " + this.translator.getLabelFor(this.field);
}
}
 
public List<SQLRow> getReferentRows(SQLRowAccessor rowOrigin) {
SQLSelect sel = new SQLSelect();
sel.addSelectStar(this.field.getTable());
final Where w = new Where(this.field.getTable().getField("ID_" + rowOrigin.getTable().getName()), "=", rowOrigin.getID());
sel.setWhere(w.and(new Where(this.field.getTable().getField("ID_" + foreignLinkRow.getTable().getName()), "=", foreignLinkRow.getID())));
return SQLRowListRSH.execute(sel);
}
 
}
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/Module.java
2,7 → 2,6
 
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
 
9,18 → 8,12
import javax.swing.AbstractAction;
import javax.swing.JFrame;
 
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.erp.modules.AbstractModule;
import org.openconcerto.erp.modules.ComponentsContext;
import org.openconcerto.erp.modules.ModuleFactory;
import org.openconcerto.erp.modules.ModuleManager;
import org.openconcerto.erp.modules.ModulePackager;
import org.openconcerto.erp.modules.RuntimeModuleFactory;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRequestLog;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.ui.ConnexionPanel;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
import org.openconcerto.sql.view.list.RowAction;
33,7 → 26,7
}
 
@Override
protected void setupComponents(ComponentsContext ctxt) {
protected void setupComponents(final ComponentsContext ctxt) {
 
super.setupComponents(ctxt);
final SQLElement element = ctxt.getElement("ARTICLE");
60,7 → 53,7
 
};
 
f.setContentPane(new BatchEditorPanel(rows, filter));
f.setContentPane(new BatchEditorPanel(ctxt.getElement("ARTICLE").getDirectory(), rows, filter));
f.pack();
f.setMinimumSize(new Dimension(400, 300));
f.setLocationRelativeTo(IListe.get(e));
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/NumberProcessor.java
13,7 → 13,7
import javax.swing.JRadioButton;
import javax.swing.JTextField;
 
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.ui.DefaultGridBagConstraints;
20,7 → 20,7
 
public class NumberProcessor extends JPanel implements BatchProcessor {
 
private final SQLField field;
private final BatchField batchfield;
// Editors
final JTextField tReplace = new JTextField();
private JRadioButton bReplace;
30,8 → 30,8
final JTextField tRemove = new JTextField();
private JRadioButton bRemove;
 
public NumberProcessor(SQLField field) {
this.field = field;
public NumberProcessor(BatchField field) {
this.batchfield = field;
 
this.setLayout(new GridBagLayout());
bReplace = new JRadioButton("remplacer par");
110,11 → 110,23
if (bReplace.isSelected()) {
BigDecimal v = new BigDecimal(this.tReplace.getText().trim());
for (SQLRowAccessor sqlRowAccessor : r) {
 
if (batchfield.getForeignLinkRow() != null) {
 
final List<SQLRow> referentRow = batchfield.getReferentRows(sqlRowAccessor);
for (SQLRow sqlRowT : referentRow) {
SQLRowValues rowValues = sqlRowT.createEmptyUpdateRow();
rowValues.put(batchfield.getField().getName(), decimalToFieldType(v));
processBeforeUpdate(sqlRowT, rowValues);
rowValues.update();
}
} else {
final SQLRowValues rowValues = sqlRowAccessor.createEmptyUpdateRow();
rowValues.put(field.getName(), decimalToFieldType(v));
rowValues.put(batchfield.getField().getName(), decimalToFieldType(v));
processBeforeUpdate(sqlRowAccessor, rowValues);
rowValues.update();
}
}
} else if (bAdd.isSelected()) {
 
String t = this.tAdd.getText().trim();
127,18 → 139,44
BigDecimal v = new BigDecimal(t);
 
for (SQLRowAccessor sqlRowAccessor : r) {
final SQLRowValues rowValues = sqlRowAccessor.createEmptyUpdateRow();
final BigDecimal value = sqlRowAccessor.asRow().getBigDecimal(field.getName());
 
if (batchfield.getForeignLinkRow() != null) {
 
final List<SQLRow> referentRow = batchfield.getReferentRows(sqlRowAccessor);
for (SQLRow sqlRowT : referentRow) {
 
SQLRowValues rowValues = sqlRowT.createEmptyUpdateRow();
BigDecimal value = sqlRowT.asRow().getBigDecimal(batchfield.getField().getName());
 
if (value != null) {
if (isPercent) {
rowValues.put(field.getName(), decimalToFieldType(value.multiply(v.divide(new BigDecimal(100)).add(BigDecimal.ONE))));
rowValues.put(batchfield.getField().getName(), decimalToFieldType(value.multiply(v.divide(new BigDecimal(100)).add(BigDecimal.ONE))));
} else {
rowValues.put(field.getName(), decimalToFieldType(value.add(v)));
rowValues.put(batchfield.getField().getName(), decimalToFieldType(value.add(v)));
}
processBeforeUpdate(sqlRowT, rowValues);
rowValues.update();
}
}
} else {
 
final SQLRowValues rowValues;
final BigDecimal value;
 
rowValues = sqlRowAccessor.createEmptyUpdateRow();
value = sqlRowAccessor.asRow().getBigDecimal(batchfield.getField().getName());
 
if (value != null) {
if (isPercent) {
rowValues.put(batchfield.getField().getName(), decimalToFieldType(value.multiply(v.divide(new BigDecimal(100)).add(BigDecimal.ONE))));
} else {
rowValues.put(batchfield.getField().getName(), decimalToFieldType(value.add(v)));
}
processBeforeUpdate(sqlRowAccessor, rowValues);
rowValues.update();
}
}
}
} else if (bRemove.isSelected()) {
String t = this.tRemove.getText().trim();
boolean isPercent = false;
149,15 → 187,35
 
BigDecimal v = new BigDecimal(t);
for (SQLRowAccessor sqlRowAccessor : r) {
final SQLRowValues rowValues = sqlRowAccessor.createEmptyUpdateRow();
if (batchfield.getForeignLinkRow() != null) {
final List<SQLRow> referentRow = batchfield.getReferentRows(sqlRowAccessor);
if (referentRow != null && !referentRow.isEmpty()) {
for (SQLRow sqlRowT : referentRow) {
 
final BigDecimal value = sqlRowAccessor.asRow().getBigDecimal(field.getName());
SQLRowValues rowValues = sqlRowT.createEmptyUpdateRow();
final BigDecimal value = sqlRowT.getBigDecimal(batchfield.getField().getName());
if (value != null) {
if (isPercent) {
rowValues.put(field.getName(), decimalToFieldType(value.multiply(v.divide(new BigDecimal(-100)).add(BigDecimal.ONE))));
rowValues.put(batchfield.getField().getName(), decimalToFieldType(value.multiply(v.divide(new BigDecimal(-100)).add(BigDecimal.ONE))));
} else {
rowValues.put(field.getName(), decimalToFieldType(value.add(v)));
rowValues.put(batchfield.getField().getName(), decimalToFieldType(value.add(v)));
}
processBeforeUpdate(sqlRowT, rowValues);
rowValues.update();
}
}
}
} else {
 
SQLRowValues rowValues = sqlRowAccessor.createEmptyUpdateRow();
final BigDecimal value = sqlRowAccessor.asRow().getBigDecimal(batchfield.getField().getName());
 
if (value != null) {
if (isPercent) {
rowValues.put(batchfield.getField().getName(), decimalToFieldType(value.multiply(v.divide(new BigDecimal(-100)).add(BigDecimal.ONE))));
} else {
rowValues.put(batchfield.getField().getName(), decimalToFieldType(value.add(v)));
}
processBeforeUpdate(sqlRowAccessor, rowValues);
rowValues.update();
}
164,9 → 222,10
}
}
}
}
 
private Object decimalToFieldType(BigDecimal v) {
final Class<?> javaType = field.getType().getJavaType();
final Class<?> javaType = batchfield.getField().getType().getJavaType();
if (javaType.equals(BigDecimal.class)) {
return v;
} else if (javaType.equals(Float.class)) {
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/ReferenceProcessor.java
18,18 → 18,18
 
public class ReferenceProcessor extends JPanel implements BatchProcessor {
 
private final SQLField field;
private final BatchField field;
final SQLElement element;
private ElementComboBox combo;
 
public ReferenceProcessor(SQLField field) {
public ReferenceProcessor(BatchField field) {
this.field = field;
this.element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(field.getForeignTable());
this.element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(field.getField().getForeignTable());
 
if (element != null) {
this.setLayout(new BorderLayout());
this.add(new JLabel("remplacer par "), BorderLayout.WEST);
combo = new ElementComboBox(true, 200);
combo = new ElementComboBox(true, 10);
combo.setMinimal();
combo.setAddIconVisible(false);
combo.init(element);
36,7 → 36,7
this.add(combo, BorderLayout.CENTER);
} else {
this.setLayout(new FlowLayout());
this.add(new JLabelWarning("No element for table " + field.getTable().getName()));
this.add(new JLabelWarning("No element for table " + field.getField().getTable().getName()));
}
}
 
45,7 → 45,7
 
for (SQLRowAccessor sqlRowAccessor : r) {
final SQLRowValues rowValues = sqlRowAccessor.createEmptyUpdateRow();
rowValues.put(field.getName(), combo.getSelectedId());
rowValues.put(field.getField().getName(), combo.getSelectedId());
processBeforeUpdate(sqlRowAccessor, rowValues);
rowValues.update();
}
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/product/HTProcessor.java
4,8 → 4,8
 
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.utils.ConvertDevise;
import org.openconcerto.modules.common.batchprocessing.BatchField;
import org.openconcerto.modules.common.batchprocessing.NumberProcessor;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
12,7 → 12,7
 
public class HTProcessor extends NumberProcessor {
 
public HTProcessor(SQLField field) {
public HTProcessor(BatchField field) {
super(field);
}
 
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/product/PurchaseProcessor.java
2,14 → 2,14
 
import java.math.BigDecimal;
 
import org.openconcerto.modules.common.batchprocessing.BatchField;
import org.openconcerto.modules.common.batchprocessing.NumberProcessor;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
 
public class PurchaseProcessor extends NumberProcessor {
 
public PurchaseProcessor(SQLField field) {
public PurchaseProcessor(BatchField field) {
super(field);
}
 
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/product/TTCProcessor.java
4,8 → 4,8
 
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.utils.ConvertDevise;
import org.openconcerto.modules.common.batchprocessing.BatchField;
import org.openconcerto.modules.common.batchprocessing.NumberProcessor;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
12,7 → 12,7
 
public class TTCProcessor extends NumberProcessor {
 
public TTCProcessor(SQLField field) {
public TTCProcessor(BatchField field) {
super(field);
}
 
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/product/TVAProcessor.java
4,8 → 4,8
 
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.utils.ConvertDevise;
import org.openconcerto.modules.common.batchprocessing.BatchField;
import org.openconcerto.modules.common.batchprocessing.ReferenceProcessor;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
12,7 → 12,7
 
public class TVAProcessor extends ReferenceProcessor {
 
public TVAProcessor(SQLField field) {
public TVAProcessor(BatchField field) {
super(field);
}
 
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/StringProcessor.java
29,8 → 29,8
private JRadioButton bLower;
private JRadioButton bUpper;
 
public StringProcessor(SQLField field) {
this.field = field;
public StringProcessor(BatchField field) {
this.field = field.getField();
 
this.setLayout(new GridBagLayout());
bReplace = new JRadioButton("remplacer par");
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/BatchEditorPanel.java
24,10 → 24,13
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.PropsConfiguration;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.request.SQLFieldTranslator;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
36,24 → 39,34
 
public class BatchEditorPanel extends JPanel {
 
public BatchEditorPanel(final List<SQLRowValues> rows, FieldFilter filter) {
Configuration conf = PropsConfiguration.getInstance();
final SQLFieldTranslator translator = conf.getTranslator();
public BatchEditorPanel(final SQLElementDirectory dir, final List<SQLRowValues> rows, FieldFilter filter) {
SQLFieldTranslator translator = dir.getTranslator();
Set<SQLField> fields = rows.get(0).getTable().getFields();
List<SQLField> f = new ArrayList<SQLField>();
List<BatchField> f = new ArrayList<BatchField>();
for (SQLField sqlField : fields) {
if (ForbiddenFieldName.isAllowed(sqlField.getName()) && translator.getLabelFor(sqlField) != null) {
if (filter == null || !filter.isFiltered(sqlField)) {
f.add(sqlField);
f.add(new BatchField(dir, sqlField, null));
}
}
}
SQLTable tableTarif = rows.get(0).getTable().getTable("TARIF");
SQLTable tableArticleTarif = rows.get(0).getTable().getTable("ARTICLE_TARIF");
SQLSelect sel = new SQLSelect();
sel.addSelectStar(tableTarif);
List<SQLRow> rowTarif = SQLRowListRSH.execute(sel);
for (SQLRow sqlRow : rowTarif) {
f.add(new BatchField(dir, tableArticleTarif.getField("PV_HT"), sqlRow));
if (tableArticleTarif.contains("POURCENT_REMISE")) {
f.add(new BatchField(dir, tableArticleTarif.getField("POURCENT_REMISE"), sqlRow));
}
}
 
Collections.sort(f, new Comparator<SQLField>() {
Collections.sort(f, new Comparator<BatchField>() {
 
@Override
public int compare(SQLField o1, SQLField o2) {
return translator.getLabelFor(o1).compareToIgnoreCase(translator.getLabelFor(o2));
public int compare(BatchField o1, BatchField o2) {
return o1.getComboName().compareToIgnoreCase(o2.getComboName());
}
});
this.setLayout(new GridBagLayout());
60,11 → 73,11
GridBagConstraints c = new DefaultGridBagConstraints();
this.add(new JLabel("Champ"), c);
 
final JComboBox<SQLField> combo = new JComboBox<SQLField>(f.toArray(new SQLField[1]));
final JComboBox<BatchField> combo = new JComboBox<BatchField>(f.toArray(new BatchField[1]));
combo.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
String label = translator.getLabelFor(((SQLField) value));
String label = ((BatchField) value).getComboName();
return super.getListCellRendererComponent(list, label, index, isSelected, cellHasFocus);
}
});
86,7 → 99,7
c.gridy++;
c.anchor = GridBagConstraints.NORTHWEST;
final BatchDetailPanel comp = new BatchDetailPanel();
comp.setField((SQLField) combo.getSelectedItem());
comp.setField((BatchField) combo.getSelectedItem());
this.add(comp, c);
 
JPanel actions = new JPanel();
108,7 → 121,7
 
@Override
public void itemStateChanged(ItemEvent e) {
comp.setField((SQLField) combo.getSelectedItem());
comp.setField((BatchField) combo.getSelectedItem());
 
}
});
/trunk/Modules/Module Batch Processing/src/org/openconcerto/modules/common/batchprocessing/DateProcessor.java
17,8 → 17,8
private final JDate d = new JDate(true);
private final SQLField field;
 
public DateProcessor(SQLField field) {
this.field = field;
public DateProcessor(BatchField field) {
this.field = field.getField();
this.setLayout(new FlowLayout());
this.add(new JLabel("forcer la date au "));
this.add(d);
/trunk/Modules/Module Label/lib/barcode4j-2.1.0.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/Modules/Module Label/lib/barcode4j-2.1.0.jar
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/Modules/Module Label/lib/jbarcode-0.2.8.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/Modules/Module Label/lib/jbarcode-0.2.8.jar
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/Modules/Module Label/src/uk/org/okapibarcode/util/Gs1.java
New file
0,0 → 1,596
/*
* Copyright 2018 Robin Stuart, Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.util;
 
import uk.org.okapibarcode.backend.OkapiException;
 
/**
* GS1 utility class.
*/
public final class Gs1 {
 
private Gs1() {
// utility class
}
 
/**
* Verifies that the specified data is in good GS1 format <tt>"[AI]data"</tt> pairs, and returns
* a reduced version of the input string containing FNC1 escape sequences instead of AI
* brackets. With a few small exceptions, this code matches the Zint GS1 validation code as
* closely as possible, in order to make it easier to keep in sync.
*
* @param s the data string to verify
* @param fnc1 the string to use to represent FNC1 in the output
* @return the input data, verified and with FNC1 strings added at the appropriate positions
* @see <a href="https://sourceforge.net/p/zint/code/ci/master/tree/backend/gs1.c">Corresponding
* Zint code</a>
* @see <a href="http://www.gs1.org/docs/gsmp/barcodes/GS1_General_Specifications.pdf">GS1
* specification</a>
*/
public static String verify(final String s, final String fnc1) {
 
// Enforce compliance with GS1 General Specification
// http://www.gs1.org/docs/gsmp/barcodes/GS1_General_Specifications.pdf
 
final char[] source = s.toCharArray();
final StringBuilder reduced = new StringBuilder(source.length);
final int[] ai_value = new int[100];
final int[] ai_location = new int[100];
final int[] data_location = new int[100];
final int[] data_length = new int[100];
int error_latch;
 
/* Detect extended ASCII characters */
for (int i = 0; i < source.length; i++) {
if (source[i] >= 128) {
throw new OkapiException("Extended ASCII characters are not supported by GS1");
}
if (source[i] < 32) {
throw new OkapiException("Control characters are not supported by GS1");
}
}
 
/* Make sure we start with an AI */
if (source[0] != '[') {
throw new OkapiException("Data does not start with an AI");
}
 
/* Check the position of the brackets */
int bracket_level = 0;
int max_bracket_level = 0;
int ai_length = 0;
int max_ai_length = 0;
int min_ai_length = 5;
int j = 0;
boolean ai_latch = false;
for (int i = 0; i < source.length; i++) {
ai_length += j;
if (j == 1 && source[i] != ']' && (source[i] < '0' || source[i] > '9')) {
ai_latch = true;
}
if (source[i] == '[') {
bracket_level++;
j = 1;
}
if (source[i] == ']') {
bracket_level--;
if (ai_length < min_ai_length) {
min_ai_length = ai_length;
}
j = 0;
ai_length = 0;
}
if (bracket_level > max_bracket_level) {
max_bracket_level = bracket_level;
}
if (ai_length > max_ai_length) {
max_ai_length = ai_length;
}
}
min_ai_length--;
 
if (bracket_level != 0) {
/* Not all brackets are closed */
throw new OkapiException("Malformed AI in input data (brackets don't match)");
}
 
if (max_bracket_level > 1) {
/* Nested brackets */
throw new OkapiException("Found nested brackets in input data");
}
 
if (max_ai_length > 4) {
/* AI is too long */
throw new OkapiException("Invalid AI in input data (AI too long)");
}
 
if (min_ai_length <= 1) {
/* AI is too short */
throw new OkapiException("Invalid AI in input data (AI too short)");
}
 
if (ai_latch) {
/* Non-numeric data in AI */
throw new OkapiException("Invalid AI in input data (non-numeric characters in AI)");
}
 
int ai_count = 0;
for (int i = 1; i < source.length; i++) {
if (source[i - 1] == '[') {
ai_location[ai_count] = i;
ai_value[ai_count] = 0;
for (j = 0; source[i + j] != ']'; j++) {
ai_value[ai_count] *= 10;
ai_value[ai_count] += Character.getNumericValue(source[i + j]);
}
ai_count++;
}
}
 
for (int i = 0; i < ai_count; i++) {
data_location[i] = ai_location[i] + 3;
if (ai_value[i] >= 100) {
data_location[i]++;
}
if (ai_value[i] >= 1000) {
data_location[i]++;
}
data_length[i] = source.length - data_location[i];
for (j = source.length - 1; j >= data_location[i]; j--) {
if (source[j] == '[') {
data_length[i] = j - data_location[i];
}
}
}
 
for (int i = 0; i < ai_count; i++) {
if (data_length[i] == 0) {
/* No data for given AI */
throw new OkapiException("Empty data field in input data");
}
}
 
// Check for valid AI values and data lengths according to GS1 General
// Specification Release 18, January 2018
for (int i = 0; i < ai_count; i++) {
 
error_latch = 2;
switch (ai_value[i]) {
// Length 2 Fixed
case 20: // VARIANT
if (data_length[i] != 2) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 3 Fixed
case 422: // ORIGIN
case 424: // COUNTRY PROCESS
case 426: // COUNTRY FULL PROCESS
if (data_length[i] != 3) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 4 Fixed
case 8111: // POINTS
if (data_length[i] != 4) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 6 Fixed
case 11: // PROD DATE
case 12: // DUE DATE
case 13: // PACK DATE
case 15: // BEST BY
case 16: // SELL BY
case 17: // USE BY
case 7006: // FIRST FREEZE DATE
case 8005: // PRICE PER UNIT
if (data_length[i] != 6) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 10 Fixed
case 7003: // EXPIRY TIME
if (data_length[i] != 10) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 13 Fixed
case 410: // SHIP TO LOC
case 411: // BILL TO
case 412: // PURCHASE FROM
case 413: // SHIP FOR LOC
case 414: // LOC NO
case 415: // PAY TO
case 416: // PROD/SERV LOC
case 7001: // NSN
if (data_length[i] != 13) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 14 Fixed
case 1: // GTIN
case 2: // CONTENT
case 8001: // DIMENSIONS
if (data_length[i] != 14) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 17 Fixed
case 402: // GSIN
if (data_length[i] != 17) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 18 Fixed
case 0: // SSCC
case 8006: // ITIP
case 8017: // GSRN PROVIDER
case 8018: // GSRN RECIPIENT
if (data_length[i] != 18) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 2 Max
case 7010: // PROD METHOD
if (data_length[i] > 2) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 3 Max
case 427: // ORIGIN SUBDIVISION
case 7008: // AQUATIC SPECIES
if (data_length[i] > 3) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 4 Max
case 7004: // ACTIVE POTENCY
if (data_length[i] > 4) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 6 Max
case 242: // MTO VARIANT
if (data_length[i] > 6) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 8 Max
case 30: // VAR COUNT
case 37: // COUNT
if (data_length[i] > 8) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 10 Max
case 7009: // FISHING GEAR TYPE
case 8019: // SRIN
if (data_length[i] > 10) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 12 Max
case 7005: // CATCH AREA
case 8011: // CPID SERIAL
if (data_length[i] > 12) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 20 Max
case 10: // BATCH/LOT
case 21: // SERIAL
case 22: // CPV
case 243: // PCN
case 254: // GLN EXTENSION COMPONENT
case 420: // SHIP TO POST
case 7020: // REFURB LOT
case 7021: // FUNC STAT
case 7022: // REV STAT
case 710: // NHRN PZN
case 711: // NHRN CIP
case 712: // NHRN CN
case 713: // NHRN DRN
case 714: // NHRN AIM
case 8002: // CMT NO
case 8012: // VERSION
if (data_length[i] > 20) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 25 Max
case 8020: // REF NO
if (data_length[i] > 25) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 30 Max
case 240: // ADDITIONAL ID
case 241: // CUST PART NO
case 250: // SECONDARY SERIAL
case 251: // REF TO SOURCE
case 400: // ORDER NUMBER
case 401: // GINC
case 403: // ROUTE
case 7002: // MEAT CUT
case 7023: // GIAI ASSEMBLY
case 8004: // GIAI
case 8010: // CPID
case 8013: // BUDI-DI
case 90: // INTERNAL
if (data_length[i] > 30) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 34 Max
case 8007: // IBAN
if (data_length[i] > 34) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
// Length 70 Max
case 8110: // Coupon code
case 8112: // Paperless coupon code
case 8200: // PRODUCT URL
if (data_length[i] > 70) {
error_latch = 1;
} else {
error_latch = 0;
}
break;
 
}
 
if (ai_value[i] == 253) { // GDTI
if (data_length[i] < 14 || data_length[i] > 30) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] == 255) { // GCN
if (data_length[i] < 14 || data_length[i] > 25) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3100 && ai_value[i] <= 3169) {
if (data_length[i] != 6) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3200 && ai_value[i] <= 3379) {
if (data_length[i] != 6) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3400 && ai_value[i] <= 3579) {
if (data_length[i] != 6) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3600 && ai_value[i] <= 3699) {
if (data_length[i] != 6) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3900 && ai_value[i] <= 3909) { // AMOUNT
if (data_length[i] > 15) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3910 && ai_value[i] <= 3919) { // AMOUNT
if (data_length[i] < 4 || data_length[i] > 18) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3920 && ai_value[i] <= 3929) { // PRICE
if (data_length[i] > 15) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3930 && ai_value[i] <= 3939) { // PRICE
if (data_length[i] < 4 || data_length[i] > 18) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 3940 && ai_value[i] <= 3949) { // PRCNT OFF
if (data_length[i] != 4) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] == 421) { // SHIP TO POST
if (data_length[i] < 3 || data_length[i] > 12) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] == 423 || ai_value[i] == 425) {
// COUNTRY INITIAL PROCESS || COUNTRY DISASSEMBLY
if (data_length[i] < 3 || data_length[i] > 15) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] == 7007) { // HARVEST DATE
if (data_length[i] < 6 || data_length[i] > 12) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 7030 && ai_value[i] <= 7039) { // PROCESSOR #
if (data_length[i] < 4 || data_length[i] > 30) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] == 8003) { // GRAI
if (data_length[i] < 15 || data_length[i] > 30) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] == 8008) { // PROD TIME
if (data_length[i] < 9 || data_length[i] > 12) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (ai_value[i] >= 91 && ai_value[i] <= 99) { // INTERNAL
if (data_length[i] > 90) {
error_latch = 1;
} else {
error_latch = 0;
}
}
 
if (error_latch == 1) {
throw new OkapiException("Invalid data length for AI");
}
 
if (error_latch == 2) {
throw new OkapiException("Invalid AI value");
}
}
 
/* Resolve AI data - put resulting string in 'reduced' */
int last_ai = 0;
boolean fixedLengthAI = true;
for (int i = 0; i < source.length; i++) {
if (source[i] != '[' && source[i] != ']') {
reduced.append(source[i]);
}
if (source[i] == '[') {
/* Start of an AI string */
if (!fixedLengthAI) {
reduced.append(fnc1);
}
last_ai = 10 * Character.getNumericValue(source[i + 1]) + Character.getNumericValue(source[i + 2]);
/*
* The following values from
* "GS-1 General Specification version 8.0 issue 2, May 2008" figure 5.4.8.2.1 - 1
* "Element Strings with Pre-Defined Length Using Application Identifiers"
*/
fixedLengthAI = last_ai >= 0 && last_ai <= 4 || last_ai >= 11 && last_ai <= 20 || last_ai == 23
|| /* legacy support - see 5.3.8.2.2 */
last_ai >= 31 && last_ai <= 36 || last_ai == 41;
}
}
 
return reduced.toString();
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/util/Doubles.java
New file
0,0 → 1,39
/*
* Copyright 2015 Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.util;
 
/**
* Double utility class.
*
* @author Daniel Gredler
*/
public final class Doubles {
 
private Doubles() {
// utility class
}
 
/**
* It's usually not a good idea to check floating point numbers for exact equality. This method
* allows us to check for approximate equality.
*
* @param d1 the first double
* @param d2 the second double
* @return whether or not the two doubles are approximately equal (to within 0.0001)
*/
public static boolean roughlyEqual(final double d1, final double d2) {
return Math.abs(d1 - d2) < 0.0001;
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/util/Arrays.java
New file
0,0 → 1,112
/*
* Copyright 2018 Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.util;
 
import uk.org.okapibarcode.backend.OkapiException;
 
/**
* Array utility class.
*
* @author Daniel Gredler
*/
public final class Arrays {
 
private Arrays() {
// utility class
}
 
/**
* Returns the position of the specified value in the specified array.
*
* @param value the value to search for
* @param array the array to search in
* @return the position of the specified value in the specified array
*/
public static int positionOf(final char value, final char[] array) {
for (int i = 0; i < array.length; i++) {
if (value == array[i]) {
return i;
}
}
throw new OkapiException("Unable to find character '" + value + "' in character array.");
}
 
/**
* Returns the position of the specified value in the specified array.
*
* @param value the value to search for
* @param array the array to search in
* @return the position of the specified value in the specified array
*/
public static int positionOf(final int value, final int[] array) {
for (int i = 0; i < array.length; i++) {
if (value == array[i]) {
return i;
}
}
throw new OkapiException("Unable to find integer '" + value + "' in integer array.");
}
 
/**
* Returns <code>true</code> if the specified array contains the specified value.
*
* @param array the array to check in
* @param value the value to check for
* @return true if the specified array contains the specified value
*/
public static boolean contains(final int[] array, final int value) {
for (int i = 0; i < array.length; i++) {
if (array[i] == value) {
return true;
}
}
return false;
}
 
/**
* Returns <code>true</code> if the specified array contains the specified sub-array at the
* specified index.
*
* @param array the array to search in
* @param searchFor the sub-array to search for
* @param index the index at which to search
* @return whether or not the specified array contains the specified sub-array at the specified
* index
*/
public static boolean containsAt(final byte[] array, final byte[] searchFor, final int index) {
for (int i = 0; i < searchFor.length; i++) {
if (index + i >= array.length || array[index + i] != searchFor[i]) {
return false;
}
}
return true;
}
 
/**
* Inserts the specified array into the specified original array at the specified index.
*
* @param original the original array into which we want to insert another array
* @param index the index at which we want to insert the array
* @param inserted the array that we want to insert
* @return the combined array
*/
public static int[] insertArray(final int[] original, final int index, final int[] inserted) {
final int[] modified = new int[original.length + inserted.length];
System.arraycopy(original, 0, modified, 0, index);
System.arraycopy(inserted, 0, modified, index, inserted.length);
System.arraycopy(original, index, modified, index + inserted.length, modified.length - index - inserted.length);
return modified;
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/util/EciMode.java
New file
0,0 → 1,67
/*
* Copyright 2018 Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.util;
 
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
 
public class EciMode {
 
public static final EciMode NONE = new EciMode(-1, null);
 
public final int mode;
public final Charset charset;
 
private EciMode(final int mode, final Charset charset) {
this.mode = mode;
this.charset = charset;
}
 
public static EciMode of(final String data, final String charsetName, final int mode) {
try {
final Charset charset = Charset.forName(charsetName);
if (charset.canEncode() && charset.newEncoder().canEncode(data)) {
return new EciMode(mode, charset);
} else {
return NONE;
}
} catch (final UnsupportedCharsetException e) {
return NONE;
}
}
 
public EciMode or(final String data, final String charsetName, final int mode) {
if (!equals(NONE)) {
return this;
} else {
return of(data, charsetName, mode);
}
}
 
@Override
public boolean equals(final Object other) {
return other instanceof EciMode && ((EciMode) other).mode == this.mode;
}
 
@Override
public int hashCode() {
return Integer.valueOf(this.mode).hashCode();
}
 
@Override
public String toString() {
return "EciMode[mode=" + this.mode + ", charset=" + this.charset + "]";
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/util/Strings.java
New file
0,0 → 1,226
/*
* Copyright 2018 Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.util;
 
import static java.nio.charset.StandardCharsets.ISO_8859_1;
 
import java.nio.charset.StandardCharsets;
 
import uk.org.okapibarcode.backend.OkapiException;
 
/**
* String utility class.
*
* @author Daniel Gredler
*/
public final class Strings {
 
private Strings() {
// utility class
}
 
/**
* Replaces raw values with special placeholders, where applicable.
*
* @param s the string to add placeholders to
* @return the specified string, with placeholders added
* @see <a href="http://www.zint.org.uk/Manual.aspx?type=p&page=4">Zint placeholders</a>
* @see #unescape(String, boolean)
*/
public static String escape(final String s) {
final StringBuilder sb = new StringBuilder(s.length() + 10);
for (int i = 0; i < s.length(); i++) {
final char c = s.charAt(i);
switch (c) {
case '\u0000':
sb.append("\\0"); // null
break;
case '\u0004':
sb.append("\\E"); // end of transmission
break;
case '\u0007':
sb.append("\\a"); // bell
break;
case '\u0008':
sb.append("\\b"); // backspace
break;
case '\u0009':
sb.append("\\t"); // horizontal tab
break;
case '\n':
sb.append("\\n"); // line feed
break;
case '\u000b':
sb.append("\\v"); // vertical tab
break;
case '\u000c':
sb.append("\\f"); // form feed
break;
case '\r':
sb.append("\\r"); // carriage return
break;
case '\u001b':
sb.append("\\e"); // escape
break;
case '\u001d':
sb.append("\\G"); // group separator
break;
case '\u001e':
sb.append("\\R"); // record separator
break;
case '\\':
sb.append("\\\\"); // escape the escape character
break;
default:
if (c >= 32 && c <= 126) {
sb.append(c); // printable ASCII
} else {
final byte[] bytes = String.valueOf(c).getBytes(ISO_8859_1);
final String hex = String.format("%02X", bytes[0] & 0xFF);
sb.append("\\x").append(hex);
}
break;
}
}
return sb.toString();
}
 
/**
* Replaces any special placeholders with their raw values (not including FNC values).
*
* @param s the string to check for placeholders
* @param lenient whether or not to be lenient with unrecognized escape sequences
* @return the specified string, with placeholders replaced
* @see <a href="http://www.zint.org.uk/Manual.aspx?type=p&page=4">Zint placeholders</a>
* @see #escape(String)
*/
public static String unescape(final String s, final boolean lenient) {
final StringBuilder sb = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
final char c = s.charAt(i);
if (c != '\\') {
sb.append(c);
} else {
if (i + 1 >= s.length()) {
final String msg = "Error processing escape sequences: expected escape character, found end of string";
throw new OkapiException(msg);
} else {
final char c2 = s.charAt(i + 1);
switch (c2) {
case '0':
sb.append('\u0000'); // null
i++;
break;
case 'E':
sb.append('\u0004'); // end of transmission
i++;
break;
case 'a':
sb.append('\u0007'); // bell
i++;
break;
case 'b':
sb.append('\u0008'); // backspace
i++;
break;
case 't':
sb.append('\u0009'); // horizontal tab
i++;
break;
case 'n':
sb.append('\n'); // line feed
i++;
break;
case 'v':
sb.append('\u000b'); // vertical tab
i++;
break;
case 'f':
sb.append('\u000c'); // form feed
i++;
break;
case 'r':
sb.append('\r'); // carriage return
i++;
break;
case 'e':
sb.append('\u001b'); // escape
i++;
break;
case 'G':
sb.append('\u001d'); // group separator
i++;
break;
case 'R':
sb.append('\u001e'); // record separator
i++;
break;
case '\\':
sb.append('\\'); // escape the escape character
i++;
break;
case 'x':
if (i + 3 >= s.length()) {
final String msg = "Error processing escape sequences: expected hex sequence, found end of string";
throw new OkapiException(msg);
} else {
final char c3 = s.charAt(i + 2);
final char c4 = s.charAt(i + 3);
if (isHex(c3) && isHex(c4)) {
final byte b = (byte) Integer.parseInt("" + c3 + c4, 16);
sb.append(new String(new byte[] { b }, StandardCharsets.ISO_8859_1));
i += 3;
} else {
final String msg = "Error processing escape sequences: expected hex sequence, found '" + c3 + c4 + "'";
throw new OkapiException(msg);
}
}
break;
default:
if (lenient) {
sb.append(c);
} else {
throw new OkapiException("Error processing escape sequences: expected valid escape character, found '" + c2 + "'");
}
}
}
}
}
return sb.toString();
}
 
private static boolean isHex(final char c) {
return c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f';
}
 
/**
* Appends the specific integer to the specified string, in binary format, padded to the
* specified number of digits.
*
* @param s the string to append to
* @param value the value to append, in binary format
* @param digits the number of digits to pad to
*/
public static void binaryAppend(final StringBuilder s, final int value, final int digits) {
final int start = 0x01 << digits - 1;
for (int i = 0; i < digits; i++) {
if ((value & start >> i) == 0) {
s.append('0');
} else {
s.append('1');
}
}
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/output/SvgRenderer.java
New file
0,0 → 1,225
/*
* Copyright 2014-2015 Robin Stuart, Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.output;
 
import static uk.org.okapibarcode.backend.HumanReadableAlignment.CENTER;
import static uk.org.okapibarcode.backend.HumanReadableAlignment.JUSTIFY;
 
import java.awt.Color;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
 
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
import org.w3c.dom.Document;
import org.w3c.dom.Text;
 
import uk.org.okapibarcode.backend.Hexagon;
import uk.org.okapibarcode.backend.HumanReadableAlignment;
import uk.org.okapibarcode.backend.Symbol;
import uk.org.okapibarcode.backend.TextBox;
 
/**
* Renders symbologies to SVG (Scalable Vector Graphics).
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
* @author Daniel Gredler
*/
public class SvgRenderer implements SymbolRenderer {
 
/** The output stream to render to. */
private final OutputStream out;
 
/** The magnification factor to apply. */
private final double magnification;
 
/** The paper (background) color. */
private final Color paper;
 
/** The ink (foreground) color. */
private final Color ink;
 
/** Whether or not to include the XML prolog in the output. */
private final boolean xmlProlog;
 
/**
* Creates a new SVG renderer.
*
* @param out the output stream to render to
* @param magnification the magnification factor to apply
* @param paper the paper (background) color
* @param ink the ink (foreground) color
* @param xmlProlog whether or not to include the XML prolog in the output (usually {@code true}
* for standalone SVG documents, {@code false} for SVG content embedded directly in HTML
* documents)
*/
public SvgRenderer(final OutputStream out, final double magnification, final Color paper, final Color ink, final boolean xmlProlog) {
this.out = out;
this.magnification = magnification;
this.paper = paper;
this.ink = ink;
this.xmlProlog = xmlProlog;
}
 
/** {@inheritDoc} */
@Override
public void render(final Symbol symbol) throws IOException {
 
final String content = symbol.getContent();
final int width = (int) (symbol.getWidth() * this.magnification);
final int height = (int) (symbol.getHeight() * this.magnification);
final int marginX = (int) (symbol.getQuietZoneHorizontal() * this.magnification);
final int marginY = (int) (symbol.getQuietZoneVertical() * this.magnification);
 
String title;
if (content == null || content.isEmpty()) {
title = "OkapiBarcode Generated Symbol";
} else {
title = content;
}
 
final String fgColour = String.format("%02X", this.ink.getRed()) + String.format("%02X", this.ink.getGreen()) + String.format("%02X", this.ink.getBlue());
 
final String bgColour = String.format("%02X", this.paper.getRed()) + String.format("%02X", this.paper.getGreen()) + String.format("%02X", this.paper.getBlue());
 
try (ExtendedOutputStreamWriter writer = new ExtendedOutputStreamWriter(this.out, "%.2f")) {
 
// XML Prolog
if (this.xmlProlog) {
writer.append("<?xml version=\"1.0\" standalone=\"no\"?>\n");
writer.append("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
writer.append(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
}
 
// Header
writer.append("<svg width=\"").appendInt(width).append("\" height=\"").appendInt(height).append("\" version=\"1.1").append("\" xmlns=\"http://www.w3.org/2000/svg\">\n");
writer.append(" <desc>").append(clean(title)).append("</desc>\n");
writer.append(" <g id=\"barcode\" fill=\"#").append(fgColour).append("\">\n");
writer.append(" <rect x=\"0\" y=\"0\" width=\"").appendInt(width).append("\" height=\"").appendInt(height).append("\" fill=\"#").append(bgColour).append("\" />\n");
 
// Rectangles
for (int i = 0; i < symbol.getRectangles().size(); i++) {
final Rectangle2D.Double rect = symbol.getRectangles().get(i);
writer.append(" <rect x=\"").append(rect.x * this.magnification + marginX).append("\" y=\"").append(rect.y * this.magnification + marginY).append("\" width=\"")
.append(rect.width * this.magnification).append("\" height=\"").append(rect.height * this.magnification).append("\" />\n");
}
 
// Text
for (int i = 0; i < symbol.getTexts().size(); i++) {
final TextBox text = symbol.getTexts().get(i);
final HumanReadableAlignment alignment = text.alignment == JUSTIFY && text.text.length() == 1 ? CENTER : text.alignment;
double x;
String anchor;
switch (alignment) {
case LEFT:
case JUSTIFY:
x = this.magnification * text.x + marginX;
anchor = "start";
break;
case RIGHT:
x = this.magnification * text.x + this.magnification * text.width + marginX;
anchor = "end";
break;
case CENTER:
x = this.magnification * text.x + this.magnification * text.width / 2 + marginX;
anchor = "middle";
break;
default:
throw new IllegalStateException("Unknown alignment: " + alignment);
}
writer.append(" <text x=\"").append(x).append("\" y=\"").append(text.y * this.magnification + marginY).append("\" text-anchor=\"").append(anchor).append("\"\n");
if (alignment == JUSTIFY) {
writer.append(" textLength=\"").append(text.width * this.magnification).append("\" lengthAdjust=\"spacing\"\n");
}
writer.append(" font-family=\"").append(clean(symbol.getFontName())).append("\" font-size=\"").append(symbol.getFontSize() * this.magnification).append("\" fill=\"#")
.append(fgColour).append("\">\n");
writer.append(" ").append(clean(text.text)).append("\n");
writer.append(" </text>\n");
}
 
// Circles
for (int i = 0; i < symbol.getTarget().size(); i++) {
final Ellipse2D.Double ellipse = symbol.getTarget().get(i);
String color;
if ((i & 1) == 0) {
color = fgColour;
} else {
color = bgColour;
}
writer.append(" <circle cx=\"").append((ellipse.x + ellipse.width / 2) * this.magnification + marginX).append("\" cy=\"")
.append((ellipse.y + ellipse.width / 2) * this.magnification + marginY).append("\" r=\"").append(ellipse.width / 2 * this.magnification).append("\" fill=\"#").append(color)
.append("\" />\n");
}
 
// Hexagons
for (int i = 0; i < symbol.getHexagons().size(); i++) {
final Hexagon hexagon = symbol.getHexagons().get(i);
writer.append(" <path d=\"");
for (int j = 0; j < 6; j++) {
if (j == 0) {
writer.append("M ");
} else {
writer.append("L ");
}
writer.append(hexagon.pointX[j] * this.magnification + marginX).append(" ").append(hexagon.pointY[j] * this.magnification + marginY).append(" ");
}
writer.append("Z\" />\n");
}
 
// Footer
writer.append(" </g>\n");
writer.append("</svg>\n");
}
}
 
/**
* Cleans / sanitizes the specified string for inclusion in XML. A bit convoluted, but we're
* trying to do it without adding an external dependency just for this...
*
* @param s the string to be cleaned / sanitized
* @return the cleaned / sanitized string
*/
protected String clean(String s) {
 
// remove control characters
s = s.replaceAll("[\u0000-\u001f]", "");
 
// escape XML characters
try {
final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
final Text text = document.createTextNode(s);
final Transformer transformer = TransformerFactory.newInstance().newTransformer();
final DOMSource source = new DOMSource(text);
final StringWriter writer = new StringWriter();
final StreamResult result = new StreamResult(writer);
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(source, result);
return writer.toString();
} catch (ParserConfigurationException | TransformerException | TransformerFactoryConfigurationError e) {
return s;
}
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/output/ExtendedOutputStreamWriter.java
New file
0,0 → 1,80
/*
* Copyright 2015 Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.output;
 
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
 
/**
* {@link OutputStreamWriter} extension which provides some convenience methods for writing numbers.
*/
class ExtendedOutputStreamWriter extends OutputStreamWriter {
 
/** Format to use when writing doubles to the stream. */
private final String doubleFormat;
 
/**
* Creates a new extended output stream writer, using the UTF-8 charset.
*
* @param out the stream to write to
* @param doubleFormat the format to use when writing doubles to the stream
*/
public ExtendedOutputStreamWriter(final OutputStream out, final String doubleFormat) {
super(out, StandardCharsets.UTF_8);
this.doubleFormat = doubleFormat;
}
 
/** {@inheritDoc} */
@Override
public ExtendedOutputStreamWriter append(final CharSequence cs) throws IOException {
super.append(cs);
return this;
}
 
/** {@inheritDoc} */
@Override
public ExtendedOutputStreamWriter append(final CharSequence cs, final int start, final int end) throws IOException {
super.append(cs, start, end);
return this;
}
 
/**
* Writes the specified double to the stream, formatted according to the format specified in the
* constructor.
*
* @param d the double to write to the stream
* @return this writer
* @throws IOException if an I/O error occurs
*/
public ExtendedOutputStreamWriter append(final double d) throws IOException {
super.append(String.format(Locale.ROOT, this.doubleFormat, d));
return this;
}
 
/**
* Writes the specified integer to the stream.
*
* @param i the integer to write to the stream
* @return this writer
* @throws IOException if an I/O error occurs
*/
public ExtendedOutputStreamWriter appendInt(final int i) throws IOException {
super.append(String.valueOf(i));
return this;
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/output/SymbolRenderer.java
New file
0,0 → 1,34
/*
* Copyright 2015 Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.output;
 
import java.io.IOException;
 
import uk.org.okapibarcode.backend.Symbol;
 
/**
* Renders symbols to some output format.
*/
public interface SymbolRenderer {
 
/**
* Renders the specified symbology.
*
* @param symbol the symbology to render
* @throws IOException if there is an I/O error
*/
void render(Symbol symbol) throws IOException;
 
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/output/Java2DRenderer.java
New file
0,0 → 1,169
/*
* Copyright 2014-2015 Robin Stuart, Robert Elliott, Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.output;
 
import static uk.org.okapibarcode.backend.HumanReadableAlignment.CENTER;
import static uk.org.okapibarcode.backend.HumanReadableAlignment.JUSTIFY;
 
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.Collections;
import java.util.List;
 
import uk.org.okapibarcode.backend.Hexagon;
import uk.org.okapibarcode.backend.HumanReadableAlignment;
import uk.org.okapibarcode.backend.Symbol;
import uk.org.okapibarcode.backend.TextBox;
 
/**
* Renders symbologies using the Java 2D API.
*/
public class Java2DRenderer implements SymbolRenderer {
 
/** The graphics to render to. */
private final Graphics2D g2d;
 
/** The magnification factor to apply. */
private final double magnification;
 
/** The paper (background) color. */
private final Color paper;
 
/** The ink (foreground) color. */
private final Color ink;
 
/**
* Creates a new Java 2D renderer. If the specified paper color is <tt>null</tt>, the symbol is
* drawn without clearing the existing <tt>g2d</tt> background.
*
* @param g2d the graphics to render to
* @param magnification the magnification factor to apply
* @param paper the paper (background) color (may be <tt>null</tt>)
* @param ink the ink (foreground) color
*/
public Java2DRenderer(final Graphics2D g2d, final double magnification, final Color paper, final Color ink) {
this.g2d = g2d;
this.magnification = magnification;
this.paper = paper;
this.ink = ink;
}
 
/** {@inheritDoc} */
@Override
public void render(final Symbol symbol) {
 
final int marginX = (int) (symbol.getQuietZoneHorizontal() * this.magnification);
final int marginY = (int) (symbol.getQuietZoneVertical() * this.magnification);
 
Font f = symbol.getFont();
if (f != null) {
f = f.deriveFont((float) (f.getSize2D() * this.magnification));
} else {
f = new Font(symbol.getFontName(), Font.PLAIN, (int) (symbol.getFontSize() * this.magnification));
f = f.deriveFont(Collections.singletonMap(TextAttribute.TRACKING, 0));
}
 
final Font oldFont = this.g2d.getFont();
final Color oldColor = this.g2d.getColor();
 
if (this.paper != null) {
final int w = (int) (symbol.getWidth() * this.magnification);
final int h = (int) (symbol.getHeight() * this.magnification);
this.g2d.setColor(this.paper);
this.g2d.fillRect(0, 0, w, h);
}
 
this.g2d.setColor(this.ink);
 
for (final Rectangle2D.Double rect : symbol.getRectangles()) {
final double x = rect.x * this.magnification + marginX;
final double y = rect.y * this.magnification + marginY;
final double w = rect.width * this.magnification;
final double h = rect.height * this.magnification;
this.g2d.fillRect((int) x, (int) y, (int) w, (int) h);
}
 
for (final TextBox text : symbol.getTexts()) {
final HumanReadableAlignment alignment = text.alignment == JUSTIFY && text.text.length() == 1 ? CENTER : text.alignment;
final Font font = alignment != JUSTIFY ? f : addTracking(f, text.width * this.magnification, text.text, this.g2d);
this.g2d.setFont(font);
final FontMetrics fm = this.g2d.getFontMetrics();
final Rectangle2D bounds = fm.getStringBounds(text.text, this.g2d);
final float y = (float) (text.y * this.magnification) + marginY;
float x;
switch (alignment) {
case LEFT:
case JUSTIFY:
x = (float) (this.magnification * text.x + marginX);
break;
case RIGHT:
x = (float) (this.magnification * text.x + this.magnification * text.width - bounds.getWidth() + marginX);
break;
case CENTER:
x = (float) (this.magnification * text.x + this.magnification * text.width / 2 - bounds.getWidth() / 2 + marginX);
break;
default:
throw new IllegalStateException("Unknown alignment: " + alignment);
}
this.g2d.drawString(text.text, x, y);
}
 
for (final Hexagon hexagon : symbol.getHexagons()) {
final Polygon polygon = new Polygon();
for (int j = 0; j < 6; j++) {
polygon.addPoint((int) (hexagon.pointX[j] * this.magnification + marginX), (int) (hexagon.pointY[j] * this.magnification + marginY));
}
this.g2d.fill(polygon);
}
 
final List<Ellipse2D.Double> target = symbol.getTarget();
for (int i = 0; i + 1 < target.size(); i += 2) {
final Ellipse2D.Double outer = adjust(target.get(i), this.magnification, marginX, marginY);
final Ellipse2D.Double inner = adjust(target.get(i + 1), this.magnification, marginX, marginY);
final Area area = new Area(outer);
area.subtract(new Area(inner));
this.g2d.fill(area);
}
 
this.g2d.setFont(oldFont);
this.g2d.setColor(oldColor);
}
 
private static Ellipse2D.Double adjust(final Ellipse2D.Double ellipse, final double magnification, final int marginX, final int marginY) {
final double x = ellipse.x * magnification + marginX;
final double y = ellipse.y * magnification + marginY;
final double w = ellipse.width * magnification + marginX;
final double h = ellipse.height * magnification + marginY;
return new Ellipse2D.Double(x, y, w, h);
}
 
private static Font addTracking(final Font baseFont, final double maxTextWidth, final String text, final Graphics2D g2d) {
final FontRenderContext frc = g2d.getFontRenderContext();
final double originalWidth = baseFont.getStringBounds(text, frc).getWidth();
final double extraSpace = maxTextWidth - originalWidth;
final double extraSpacePerGap = extraSpace / (text.length() - 1);
final double scaleX = baseFont.isTransformed() ? baseFont.getTransform().getScaleX() : 1;
final double tracking = extraSpacePerGap / (baseFont.getSize2D() * scaleX);
return baseFont.deriveFont(Collections.singletonMap(TextAttribute.TRACKING, tracking));
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/output/PostScriptRenderer.java
New file
0,0 → 1,211
/*
* Copyright 2015 Robin Stuart, Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.output;
 
import static uk.org.okapibarcode.backend.HumanReadableAlignment.CENTER;
import static uk.org.okapibarcode.backend.HumanReadableAlignment.JUSTIFY;
import static uk.org.okapibarcode.util.Doubles.roughlyEqual;
 
import java.awt.Color;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.OutputStream;
 
import uk.org.okapibarcode.backend.Hexagon;
import uk.org.okapibarcode.backend.HumanReadableAlignment;
import uk.org.okapibarcode.backend.Symbol;
import uk.org.okapibarcode.backend.TextBox;
 
/**
* Renders symbologies to EPS (Encapsulated PostScript).
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
* @author Daniel Gredler
*/
public class PostScriptRenderer implements SymbolRenderer {
 
/** The output stream to render to. */
private final OutputStream out;
 
/** The magnification factor to apply. */
private final double magnification;
 
/** The paper (background) color. */
private final Color paper;
 
/** The ink (foreground) color. */
private final Color ink;
 
/**
* Creates a new PostScript renderer.
*
* @param out the output stream to render to
* @param magnification the magnification factor to apply
* @param paper the paper (background) color
* @param ink the ink (foreground) color
*/
public PostScriptRenderer(final OutputStream out, final double magnification, final Color paper, final Color ink) {
this.out = out;
this.magnification = magnification;
this.paper = paper;
this.ink = ink;
}
 
/** {@inheritDoc} */
@Override
public void render(final Symbol symbol) throws IOException {
 
// All y dimensions are reversed because EPS origin (0,0) is at the bottom left, not top
// left
 
final String content = symbol.getContent();
final int width = (int) (symbol.getWidth() * this.magnification);
final int height = (int) (symbol.getHeight() * this.magnification);
final int marginX = (int) (symbol.getQuietZoneHorizontal() * this.magnification);
final int marginY = (int) (symbol.getQuietZoneVertical() * this.magnification);
 
String title;
if (content == null || content.isEmpty()) {
title = "OkapiBarcode Generated Symbol";
} else {
title = content;
}
 
try (ExtendedOutputStreamWriter writer = new ExtendedOutputStreamWriter(this.out, "%.2f")) {
 
// Header
writer.append("%!PS-Adobe-3.0 EPSF-3.0\n");
writer.append("%%Creator: OkapiBarcode\n");
writer.append("%%Title: ").append(title).append('\n');
writer.append("%%Pages: 0\n");
writer.append("%%BoundingBox: 0 0 ").appendInt(width).append(" ").appendInt(height).append("\n");
writer.append("%%EndComments\n");
 
// Definitions
writer.append("/TL { setlinewidth moveto lineto stroke } bind def\n");
writer.append("/TC { moveto 0 360 arc 360 0 arcn fill } bind def\n");
writer.append("/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def\n");
writer.append("/TB { 2 copy } bind def\n");
writer.append("/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def\n");
writer.append("/TE { pop pop } bind def\n");
 
// Background
writer.append("newpath\n");
writer.append(this.ink.getRed() / 255.0).append(" ").append(this.ink.getGreen() / 255.0).append(" ").append(this.ink.getBlue() / 255.0).append(" setrgbcolor\n");
writer.append(this.paper.getRed() / 255.0).append(" ").append(this.paper.getGreen() / 255.0).append(" ").append(this.paper.getBlue() / 255.0).append(" setrgbcolor\n");
writer.append(height).append(" 0.00 TB 0.00 ").append(width).append(" TR\n");
 
// Rectangles
for (int i = 0; i < symbol.getRectangles().size(); i++) {
final Rectangle2D.Double rect = symbol.getRectangles().get(i);
if (i == 0) {
writer.append("TE\n");
writer.append(this.ink.getRed() / 255.0).append(" ").append(this.ink.getGreen() / 255.0).append(" ").append(this.ink.getBlue() / 255.0).append(" setrgbcolor\n");
writer.append(rect.height * this.magnification).append(" ").append(height - (rect.y + rect.height) * this.magnification - marginY).append(" TB ")
.append(rect.x * this.magnification + marginX).append(" ").append(rect.width * this.magnification).append(" TR\n");
} else {
final Rectangle2D.Double prev = symbol.getRectangles().get(i - 1);
if (!roughlyEqual(rect.height, prev.height) || !roughlyEqual(rect.y, prev.y)) {
writer.append("TE\n");
writer.append(this.ink.getRed() / 255.0).append(" ").append(this.ink.getGreen() / 255.0).append(" ").append(this.ink.getBlue() / 255.0).append(" setrgbcolor\n");
writer.append(rect.height * this.magnification).append(" ").append(height - (rect.y + rect.height) * this.magnification - marginY).append(" ");
}
writer.append("TB ").append(rect.x * this.magnification + marginX).append(" ").append(rect.width * this.magnification).append(" TR\n");
}
}
 
// Text
for (int i = 0; i < symbol.getTexts().size(); i++) {
final TextBox text = symbol.getTexts().get(i);
final HumanReadableAlignment alignment = text.alignment == JUSTIFY && text.text.length() == 1 ? CENTER : text.alignment;
if (i == 0) {
writer.append("TE\n");
;
writer.append(this.ink.getRed() / 255.0).append(" ").append(this.ink.getGreen() / 255.0).append(" ").append(this.ink.getBlue() / 255.0).append(" setrgbcolor\n");
}
writer.append("matrix currentmatrix\n");
writer.append("/").append(symbol.getFontName()).append(" findfont\n");
writer.append(symbol.getFontSize() * this.magnification).append(" scalefont setfont\n");
final double y = height - text.y * this.magnification - marginY;
switch (alignment) {
case LEFT:
final double leftX = this.magnification * text.x + marginX;
writer.append(" 0 0 moveto ").append(leftX).append(" ").append(y).append(" translate 0.00 rotate 0 0 moveto\n");
writer.append(" (").append(text.text).append(") show\n");
break;
case JUSTIFY:
final double textX = this.magnification * text.x + marginX;
final double textW = this.magnification * text.width;
writer.append(" 0 0 moveto ").append(textX).append(" ").append(y).append(" translate 0.00 rotate 0 0 moveto\n");
writer.append(" (").append(text.text).append(") dup stringwidth pop ").append(textW).append(" sub neg 1 index length 1 sub div 0").append(" 3 -1 roll ashow\n");
break;
case RIGHT:
final double rightX = this.magnification * text.x + this.magnification * text.width + marginX;
writer.append(" 0 0 moveto ").append(rightX).append(" ").append(y).append(" translate 0.00 rotate 0 0 moveto\n");
writer.append(" (").append(text.text).append(") stringwidth\n");
writer.append("pop\n");
writer.append("-1 mul 0 rmoveto\n");
writer.append(" (").append(text.text).append(") show\n");
break;
case CENTER:
final double centerX = this.magnification * text.x + this.magnification * text.width / 2 + marginX;
writer.append(" 0 0 moveto ").append(centerX).append(" ").append(y).append(" translate 0.00 rotate 0 0 moveto\n");
writer.append(" (").append(text.text).append(") stringwidth\n");
writer.append("pop\n");
writer.append("-2 div 0 rmoveto\n");
writer.append(" (").append(text.text).append(") show\n");
break;
default:
throw new IllegalStateException("Unknown alignment: " + alignment);
}
writer.append("setmatrix\n");
}
 
// Circles
// Because MaxiCode size is fixed, this ignores magnification
for (int i = 0; i < symbol.getTarget().size(); i += 2) {
final Ellipse2D.Double ellipse1 = symbol.getTarget().get(i);
final Ellipse2D.Double ellipse2 = symbol.getTarget().get(i + 1);
if (i == 0) {
writer.append("TE\n");
writer.append(this.ink.getRed() / 255.0).append(" ").append(this.ink.getGreen() / 255.0).append(" ").append(this.ink.getBlue() / 255.0).append(" setrgbcolor\n");
writer.append(this.ink.getRed() / 255.0).append(" ").append(this.ink.getGreen() / 255.0).append(" ").append(this.ink.getBlue() / 255.0).append(" setrgbcolor\n");
}
final double x1 = ellipse1.x + ellipse1.width / 2;
final double x2 = ellipse2.x + ellipse2.width / 2;
final double y1 = height - ellipse1.y - ellipse1.width / 2;
final double y2 = height - ellipse2.y - ellipse2.width / 2;
final double r1 = ellipse1.width / 2;
final double r2 = ellipse2.width / 2;
writer.append(x1 + marginX).append(" ").append(y1 - marginY).append(" ").append(r1).append(" ").append(x2 + marginX).append(" ").append(y2 - marginY).append(" ").append(r2).append(" ")
.append(x2 + r2 + marginX).append(" ").append(y2 - marginY).append(" TC\n");
}
 
// Hexagons
// Because MaxiCode size is fixed, this ignores magnification
for (int i = 0; i < symbol.getHexagons().size(); i++) {
final Hexagon hexagon = symbol.getHexagons().get(i);
for (int j = 0; j < 6; j++) {
writer.append(hexagon.pointX[j] + marginX).append(" ").append(height - hexagon.pointY[j] - marginY).append(" ");
}
writer.append(" TH\n");
}
 
// Footer
writer.append("\nshowpage\n");
}
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/Code32.java
New file
0,0 → 1,107
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
/**
* <p>
* Implements Code 32, also known as Italian Pharmacode, A variation of Code 39 used by the Italian
* Ministry of Health ("Ministero della Sanità")
*
* <p>
* Requires a numeric input up to 8 digits in length. Check digit is calculated.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class Code32 extends Symbol {
 
private static final char[] TABLE = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z' };
 
@Override
protected void encode() {
int i, checksum, checkpart, checkdigit;
int pharmacode, remainder, devisor;
String localstr, risultante;
final int[] codeword = new int[6];
final Code3Of9 c39 = new Code3Of9();
 
if (this.content.length() > 8) {
throw new OkapiException("Input too long");
}
 
if (!this.content.matches("[0-9]+")) {
throw new OkapiException("Invalid characters in input");
}
 
/* Add leading zeros as required */
localstr = "";
for (i = this.content.length(); i < 8; i++) {
localstr += "0";
}
localstr += this.content;
 
/* Calculate the check digit */
checksum = 0;
checkpart = 0;
for (i = 0; i < 4; i++) {
checkpart = Character.getNumericValue(localstr.charAt(i * 2));
checksum += checkpart;
checkpart = 2 * Character.getNumericValue(localstr.charAt(i * 2 + 1));
if (checkpart >= 10) {
checksum += checkpart - 10 + 1;
} else {
checksum += checkpart;
}
}
 
/* Add check digit to data string */
checkdigit = checksum % 10;
final char check = (char) (checkdigit + '0');
localstr += check;
infoLine("Check Digit: " + check);
 
/* Convert string into an integer value */
pharmacode = 0;
for (i = 0; i < localstr.length(); i++) {
pharmacode *= 10;
pharmacode += Character.getNumericValue(localstr.charAt(i));
}
 
/* Convert from decimal to base-32 */
devisor = 33554432;
for (i = 5; i >= 0; i--) {
codeword[i] = pharmacode / devisor;
remainder = pharmacode % devisor;
pharmacode = remainder;
devisor /= 32;
}
 
/* Look up values in 'Tabella di conversione' */
risultante = "";
for (i = 5; i >= 0; i--) {
risultante += TABLE[codeword[i]];
}
 
/* Plot the barcode using Code 39 */
 
this.readable = "A" + localstr;
this.pattern = new String[1];
this.row_count = 1;
this.row_height = new int[] { -1 };
infoLine("Code 39 Equivalent: " + risultante);
 
c39.setContent(risultante);
this.pattern[0] = c39.pattern[0];
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/HumanReadableLocation.java
New file
0,0 → 1,30
/*
* Copyright 2015 Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.backend;
 
/**
* The location of a bar code's human-readable text.
*/
public enum HumanReadableLocation {
 
/** Display the human-readable text below the bar code. */
BOTTOM,
 
/** Display the human-readable text above the bar code. */
TOP,
 
/** Do not display the human-readable text. */
NONE
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/EanUpcAddOn.java
New file
0,0 → 1,112
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.backend;
 
/**
* <p>
* Implements EAN/UPC add-on bar code symbology according to BS EN 797:1996.
*
* @see Ean
* @see Upc
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class EanUpcAddOn extends Symbol {
 
private static final String[] EAN_SET_A = { "3211", "2221", "2122", "1411", "1132", "1231", "1114", "1312", "1213", "3112" };
 
private static final String[] EAN_SET_B = { "1123", "1222", "2212", "1141", "2311", "1321", "4111", "2131", "3121", "2113" };
 
private static final String[] EAN2_PARITY = { "AA", "AB", "BA", "BB" };
 
private static final String[] EAN5_PARITY = { "BBAAA", "BABAA", "BAABA", "BAAAB", "ABBAA", "AABBA", "AAABB", "ABABA", "ABAAB", "AABAB" };
 
@Override
protected void encode() {
 
if (!this.content.matches("[0-9]+")) {
throw new OkapiException("Invalid characters in input");
}
 
if (this.content.length() > 5) {
throw new OkapiException("Input data too long");
}
 
final int targetLength = this.content.length() > 2 ? 5 : 2;
 
if (this.content.length() < targetLength) {
for (int i = this.content.length(); i < targetLength; i++) {
this.content = '0' + this.content;
}
}
 
final String bars = targetLength == 2 ? ean2(this.content) : ean5(this.content);
 
this.readable = this.content;
this.pattern = new String[] { bars };
this.row_count = 1;
this.row_height = new int[] { -1 };
}
 
private static String ean2(final String content) {
 
final int sum = (content.charAt(0) - '0') * 10 + content.charAt(1) - '0';
final String parity = EAN2_PARITY[sum % 4];
 
final StringBuilder sb = new StringBuilder();
sb.append("112"); /* Start */
for (int i = 0; i < 2; i++) {
final int val = content.charAt(i) - '0';
if (parity.charAt(i) == 'B') {
sb.append(EAN_SET_B[val]);
} else {
sb.append(EAN_SET_A[val]);
}
if (i != 1) { /* Glyph separator */
sb.append("11");
}
}
 
return sb.toString();
}
 
private static String ean5(final String content) {
 
int sum = 0;
for (int i = 0; i < 5; i++) {
if (i % 2 == 0) {
sum += 3 * (content.charAt(i) - '0');
} else {
sum += 9 * (content.charAt(i) - '0');
}
}
final String parity = EAN5_PARITY[sum % 10];
 
final StringBuilder sb = new StringBuilder();
sb.append("112"); /* Start */
for (int i = 0; i < 5; i++) {
final int val = content.charAt(i) - '0';
if (parity.charAt(i) == 'B') {
sb.append(EAN_SET_B[val]);
} else {
sb.append(EAN_SET_A[val]);
}
if (i != 4) { /* Glyph separator */
sb.append("11");
}
}
 
return sb.toString();
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/OkapiException.java
New file
0,0 → 1,36
/*
* Copyright 2015 Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.backend;
 
/**
* An Okapi Barcode exception.
*
* @author Daniel Gredler
*/
public class OkapiException extends RuntimeException {
 
/** Serial version UID. */
private static final long serialVersionUID = -630504124631140642L;
 
/**
* Creates a new instance.
*
* @param message the error message
*/
public OkapiException(final String message) {
super(message);
}
 
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/KixCode.java
New file
0,0 → 1,107
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
import static uk.org.okapibarcode.util.Arrays.positionOf;
 
import java.awt.geom.Rectangle2D;
import java.util.Locale;
 
/**
* <p>
* Implements Dutch Post KIX Code as used by Royal Dutch TPG Post (Netherlands).
*
* <p>
* The input data can consist of digits 0-9 and characters A-Z, and should be 11 characters in
* length. No check digit is added.
*
* <p>
* KIX Code is the same as RM4SCC, but without the check digit.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
* @see <a href="http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx">KIX
* Code Specification</a>
*/
public class KixCode extends Symbol {
 
private static final String[] ROYAL_TABLE = { "TTFF", "TDAF", "TDFA", "DTAF", "DTFA", "DDAA", "TADF", "TFTF", "TFDA", "DATF", "DADA", "DFTA", "TAFD", "TFAD", "TFFT", "DAAD", "DAFT", "DFAT",
"ATDF", "ADTF", "ADDA", "FTTF", "FTDA", "FDTA", "ATFD", "ADAD", "ADFT", "FTAD", "FTFT", "FDAT", "AADD", "AFTD", "AFDT", "FATD", "FADT", "FFTT" };
 
private static final char[] KR_SET = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z' };
 
@Override
protected void encode() {
 
this.content = this.content.toUpperCase(Locale.ENGLISH);
 
if (!this.content.matches("[0-9A-Z]+")) {
throw new OkapiException("Invalid characters in data");
}
 
final StringBuilder sb = new StringBuilder(this.content.length());
for (int i = 0; i < this.content.length(); i++) {
final int j = positionOf(this.content.charAt(i), KR_SET);
sb.append(ROYAL_TABLE[j]);
}
 
final String dest = sb.toString();
infoLine("Encoding: " + dest);
 
this.readable = "";
this.pattern = new String[] { dest };
this.row_count = 1;
this.row_height = new int[] { -1 };
}
 
@Override
protected void plotSymbol() {
int xBlock;
int x, y, w, h;
 
this.rectangles.clear();
x = 0;
w = 1;
y = 0;
h = 0;
for (xBlock = 0; xBlock < this.pattern[0].length(); xBlock++) {
final char c = this.pattern[0].charAt(xBlock);
switch (c) {
case 'A':
y = 0;
h = 5;
break;
case 'D':
y = 3;
h = 5;
break;
case 'F':
y = 0;
h = 8;
break;
case 'T':
y = 3;
h = 2;
break;
default:
throw new IllegalStateException("Unknown pattern character: " + c);
}
this.rectangles.add(new Rectangle2D.Double(x, y, w, h));
x += 2;
}
this.symbol_width = (this.pattern[0].length() - 1) * 2 + 1; // final bar doesn't need extra
// whitespace
this.symbol_height = 8;
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/ReedSolomon.java
New file
0,0 → 1,103
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
/**
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class ReedSolomon {
private int logmod;
private int rlen;
 
private int[] logt;
private int[] alog;
private int[] rspoly;
public int[] res;
 
public int getResult(final int count) {
return this.res[count];
}
 
public void init_gf(final int poly) {
int m, b, p, v;
 
// Find the top bit, and hence the symbol size
for (b = 1, m = 0; b <= poly; b <<= 1) {
m++;
}
b >>= 1;
m--;
 
// Calculate the log/alog tables
this.logmod = (1 << m) - 1;
this.logt = new int[this.logmod + 1];
this.alog = new int[this.logmod];
 
for (p = 1, v = 0; v < this.logmod; v++) {
this.alog[v] = p;
this.logt[p] = v;
p <<= 1;
if ((p & b) != 0) {
p ^= poly;
}
}
}
 
public void init_code(final int nsym, int index) {
int i, k;
 
this.rspoly = new int[nsym + 1];
 
this.rlen = nsym;
 
this.rspoly[0] = 1;
for (i = 1; i <= nsym; i++) {
this.rspoly[i] = 1;
for (k = i - 1; k > 0; k--) {
if (this.rspoly[k] != 0) {
this.rspoly[k] = this.alog[(this.logt[this.rspoly[k]] + index) % this.logmod];
}
this.rspoly[k] ^= this.rspoly[k - 1];
}
this.rspoly[0] = this.alog[(this.logt[this.rspoly[0]] + index) % this.logmod];
index++;
}
}
 
public void encode(final int len, final int[] data) {
int i, k, m;
 
this.res = new int[this.rlen];
for (i = 0; i < this.rlen; i++) {
this.res[i] = 0;
}
 
for (i = 0; i < len; i++) {
m = this.res[this.rlen - 1] ^ data[i];
for (k = this.rlen - 1; k > 0; k--) {
if (m != 0 && this.rspoly[k] != 0) {
this.res[k] = this.res[k - 1] ^ this.alog[(this.logt[m] + this.logt[this.rspoly[k]]) % this.logmod];
} else {
this.res[k] = this.res[k - 1];
}
}
if (m != 0 && this.rspoly[0] != 0) {
this.res[0] = this.alog[(this.logt[m] + this.logt[this.rspoly[0]]) % this.logmod];
} else {
this.res[0] = 0;
}
}
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/CodablockF.java
New file
0,0 → 1,869
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
import java.awt.geom.Rectangle2D;
import java.nio.charset.StandardCharsets;
 
/**
* <p>
* Implements Codablock-F according to AIM Europe "Uniform Symbology Specification - Codablock F",
* 1995.
*
* <p>
* Codablock-F is a multi-row symbology using Code 128 encoding. It can encode any 8-bit ISO 8859-1
* (Latin-1) data up to approximately 1000 alpha-numeric characters or 2000 numeric digits in
* length.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class CodablockF extends Symbol {
 
private enum Mode {
SHIFTA, LATCHA, SHIFTB, LATCHB, SHIFTC, LATCHC, AORB, ABORC, CANDB, CANDBB
}
 
private enum CfMode {
MODEA, MODEB, MODEC
}
 
/* Annex A Table A.1 */
private static final String[] C_128_TABLE = { "212222", "222122", "222221", "121223", "121322", "131222", "122213", "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231",
"113222", "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121",
"111323", "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131",
"213113", "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221",
"112214", "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212",
"421112", "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214",
"211232", "2331112" };
 
private final int[][] blockmatrix = new int[44][62];
private int columns_needed;
private int rows_needed;
private CfMode final_mode;
private final CfMode[] subset_selector = new CfMode[44];
 
/**
* TODO: It doesn't appear that this symbol should support GS1 (it's not in the GS1 spec and
* Zint doesn't support GS1 with this type of symbology). However, the code below does contain
* GS1 checks, so we'll mark it as supported for now. It's very possible that the code below
* which supports GS1 only does so because it was originally copied from the Code 128 source
* code (just a suspicion, though).
*/
@Override
protected boolean gs1Supported() {
return true;
}
 
@Override
protected void encode() {
 
int input_length, i, j, k;
int min_module_height;
Mode last_mode, this_mode;
double estimate_codelength;
String row_pattern;
final int[] row_indicator = new int[44];
final int[] row_check = new int[44];
int k1_sum, k2_sum;
int k1_check, k2_check;
 
this.final_mode = CfMode.MODEA;
 
if (!this.content.matches("[\u0000-\u00FF]+")) {
throw new OkapiException("Invalid characters in input data");
}
 
this.inputData = toBytes(this.content, StandardCharsets.ISO_8859_1, 0x00);
input_length = this.inputData.length - 1;
 
if (input_length > 5450) {
throw new OkapiException("Input data too long");
}
 
/* Make a guess at how many characters will be needed to encode the data */
estimate_codelength = 0.0;
last_mode = Mode.AORB; /* Codablock always starts with Code A */
for (i = 0; i < input_length; i++) {
this_mode = findSubset(this.inputData[i]);
if (this_mode != last_mode) {
estimate_codelength += 1.0;
}
if (this_mode != Mode.ABORC) {
estimate_codelength += 1.0;
} else {
estimate_codelength += 0.5;
}
if (this.inputData[i] > 127) {
estimate_codelength += 1.0;
}
last_mode = this_mode;
}
 
/* Decide symbol size based on the above guess */
this.rows_needed = (int) (0.5 + Math.sqrt((estimate_codelength + 2) / 1.45));
if (this.rows_needed < 2) {
this.rows_needed = 2;
}
if (this.rows_needed > 44) {
this.rows_needed = 44;
}
this.columns_needed = (int) (estimate_codelength + 2) / this.rows_needed;
if (this.columns_needed < 4) {
this.columns_needed = 4;
}
if (this.columns_needed > 62) {
throw new OkapiException("Input data too long");
}
 
/* Encode the data */
data_encode_blockf();
 
/* Add check digits - Annex F */
k1_sum = 0;
k2_sum = 0;
for (i = 0; i < input_length; i++) {
if (this.inputData[i] == FNC1) {
k1_sum += (i + 1) * 29; /* GS */
k2_sum += i * 29;
} else {
k1_sum += (i + 1) * this.inputData[i];
k2_sum += i * this.inputData[i];
}
}
k1_check = k1_sum % 86;
k2_check = k2_sum % 86;
if (this.final_mode == CfMode.MODEA || this.final_mode == CfMode.MODEB) {
k1_check = k1_check + 64;
if (k1_check > 95) {
k1_check -= 96;
}
k2_check = k2_check + 64;
if (k2_check > 95) {
k2_check -= 96;
}
}
this.blockmatrix[this.rows_needed - 1][this.columns_needed - 2] = k1_check;
this.blockmatrix[this.rows_needed - 1][this.columns_needed - 1] = k2_check;
 
/* Calculate row height (4.6.1.a) */
min_module_height = (int) (0.55 * (this.columns_needed + 3)) + 3;
if (min_module_height < 8) {
min_module_height = 8;
}
 
/* Encode the Row Indicator in the First Row of the Symbol - Table D2 */
if (this.subset_selector[0] == CfMode.MODEC) {
/* Code C */
row_indicator[0] = this.rows_needed - 2;
} else {
/* Code A or B */
row_indicator[0] = this.rows_needed + 62;
 
if (row_indicator[0] > 95) {
row_indicator[0] -= 95;
}
}
 
/* Encode the Row Indicator in the Second and Subsequent Rows of the Symbol - Table D3 */
for (i = 1; i < this.rows_needed; i++) {
/* Note that the second row is row number 1 because counting starts from 0 */
if (this.subset_selector[i] == CfMode.MODEC) {
/* Code C */
row_indicator[i] = i + 42;
} else {
/* Code A or B */
if (i < 6) {
row_indicator[i] = i + 10;
} else {
row_indicator[i] = i + 20;
}
}
}
 
/* Calculate row check digits - Annex E */
for (i = 0; i < this.rows_needed; i++) {
k = 103;
switch (this.subset_selector[i]) {
case MODEA:
k += 98;
break;
case MODEB:
k += 100;
break;
case MODEC:
k += 99;
break;
}
k += 2 * row_indicator[i];
for (j = 0; j < this.columns_needed; j++) {
k += (j + 3) * this.blockmatrix[i][j];
}
row_check[i] = k % 103;
}
 
this.readable = "";
this.row_count = this.rows_needed;
this.pattern = new String[this.row_count];
this.row_height = new int[this.row_count];
 
infoLine("Grid Size: " + this.columns_needed + " X " + this.rows_needed);
infoLine("K1 Check Digit: " + k1_check);
infoLine("K2 Check Digit: " + k2_check);
 
/* Resolve the data into patterns and place in symbol structure */
info("Encoding: ");
for (i = 0; i < this.rows_needed; i++) {
 
row_pattern = "";
/* Start character */
row_pattern += C_128_TABLE[103]; /* Always Start A */
 
switch (this.subset_selector[i]) {
case MODEA:
row_pattern += C_128_TABLE[98];
info("MODEA ");
break;
case MODEB:
row_pattern += C_128_TABLE[100];
info("MODEB ");
break;
case MODEC:
row_pattern += C_128_TABLE[99];
info("MODEC ");
break;
}
row_pattern += C_128_TABLE[row_indicator[i]];
infoSpace(row_indicator[i]);
 
for (j = 0; j < this.columns_needed; j++) {
row_pattern += C_128_TABLE[this.blockmatrix[i][j]];
infoSpace(this.blockmatrix[i][j]);
}
 
row_pattern += C_128_TABLE[row_check[i]];
info("(" + row_check[i] + ") ");
 
/* Stop character */
row_pattern += C_128_TABLE[106];
 
/* Write the information into the symbol */
this.pattern[i] = row_pattern;
this.row_height[i] = 15;
}
infoLine();
 
this.symbol_height = this.rows_needed * 15;
}
 
private Mode findSubset(final int letter) {
Mode mode;
 
if (letter == FNC1) {
mode = Mode.AORB;
} else if (letter <= 31) {
mode = Mode.SHIFTA;
} else if (letter >= 48 && letter <= 57) {
mode = Mode.ABORC;
} else if (letter <= 95) {
mode = Mode.AORB;
} else if (letter <= 127) {
mode = Mode.SHIFTB;
} else if (letter <= 159) {
mode = Mode.SHIFTA;
} else if (letter <= 223) {
mode = Mode.AORB;
} else {
mode = Mode.SHIFTB;
}
 
return mode;
}
 
private void data_encode_blockf() {
 
int i, j, input_position, current_row;
int column_position, c;
CfMode current_mode;
boolean done, exit_status;
final int input_length = this.inputData.length - 1;
 
exit_status = false;
current_row = 0;
current_mode = CfMode.MODEA;
column_position = 0;
input_position = 0;
c = 0;
 
do {
done = false;
/*
* 'done' ensures that the instructions are followed in the correct order for each input
* character
*/
 
if (column_position == 0) {
/* The Beginning of a row */
c = this.columns_needed;
current_mode = character_subset_select(input_position);
this.subset_selector[current_row] = current_mode;
if (current_row == 0 && this.inputDataType == DataType.GS1) {
/* Section 4.4.7.1 */
this.blockmatrix[current_row][column_position] = 102; /* FNC1 */
column_position++;
c--;
}
}
 
if (this.inputData[input_position] == FNC1) {
this.blockmatrix[current_row][column_position] = 102; /* FNC1 */
column_position++;
c--;
input_position++;
done = true;
}
 
if (!done) {
if (c <= 2) {
/* Annex B section 1 rule 1 */
/*
* Ensure that there is sufficient encodation capacity to continue (using the
* rules of Annex B.2).
*/
switch (current_mode) {
case MODEA: /* Table B1 applies */
if (findSubset(this.inputData[input_position]) == Mode.ABORC) {
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
done = true;
}
 
if (findSubset(this.inputData[input_position]) == Mode.SHIFTB && c == 1) {
/* Needs two symbols */
this.blockmatrix[current_row][column_position] = 100; /* Code B */
column_position++;
c--;
done = true;
}
 
if (this.inputData[input_position] >= 244 && !done) {
/* Needs three symbols */
this.blockmatrix[current_row][column_position] = 100; /* Code B */
column_position++;
c--;
if (c == 1) {
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
}
done = true;
}
 
if (this.inputData[input_position] >= 128 && !done && c == 1) {
/* Needs two symbols */
this.blockmatrix[current_row][column_position] = 100; /* Code B */
column_position++;
c--;
done = true;
}
break;
case MODEB: /* Table B2 applies */
if (findSubset(this.inputData[input_position]) == Mode.ABORC) {
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
done = true;
}
 
if (findSubset(this.inputData[input_position]) == Mode.SHIFTA && c == 1) {
/* Needs two symbols */
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
done = true;
}
 
if (this.inputData[input_position] >= 128 && this.inputData[input_position] <= 159 && !done) {
/* Needs three symbols */
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
if (c == 1) {
this.blockmatrix[current_row][column_position] = 100; /* Code B */
column_position++;
c--;
}
done = true;
}
 
if (this.inputData[input_position] >= 160 && !done && c == 1) {
/* Needs two symbols */
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
done = true;
}
break;
case MODEC: /* Table B3 applies */
if (findSubset(this.inputData[input_position]) != Mode.ABORC && c == 1) {
/* Needs two symbols */
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
done = true;
}
 
if (findSubset(this.inputData[input_position]) == Mode.ABORC && findSubset(this.inputData[input_position + 1]) != Mode.ABORC && c == 1) {
/* Needs two symbols */
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
done = true;
}
 
if (this.inputData[input_position] >= 128) {
/* Needs three symbols */
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
if (c == 1) {
this.blockmatrix[current_row][column_position] = 100; /* Code B */
column_position++;
c--;
}
}
break;
}
}
}
 
if (!done) {
if ((findSubset(this.inputData[input_position]) == Mode.AORB || findSubset(this.inputData[input_position]) == Mode.SHIFTA) && current_mode == CfMode.MODEA) {
/* Annex B section 1 rule 2 */
/*
* If in Code Subset A and the next data character can be encoded in Subset A
* encode the next character.
*/
if (this.inputData[input_position] >= 128) {
/* Extended ASCII character */
this.blockmatrix[current_row][column_position] = 101; /* FNC4 */
column_position++;
c--;
}
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
done = true;
}
}
 
if (!done) {
if ((findSubset(this.inputData[input_position]) == Mode.AORB || findSubset(this.inputData[input_position]) == Mode.SHIFTB) && current_mode == CfMode.MODEB) {
/* Annex B section 1 rule 3 */
/*
* If in Code Subset B and the next data character can be encoded in subset B,
* encode the next character.
*/
if (this.inputData[input_position] >= 128) {
/* Extended ASCII character */
this.blockmatrix[current_row][column_position] = 100; /* FNC4 */
column_position++;
c--;
}
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
done = true;
}
}
 
if (!done) {
if (findSubset(this.inputData[input_position]) == Mode.ABORC && findSubset(this.inputData[input_position + 1]) == Mode.ABORC && current_mode == CfMode.MODEC) {
/* Annex B section 1 rule 4 */
/* If in Code Subset C and the next data are 2 digits, encode them. */
this.blockmatrix[current_row][column_position] = (this.inputData[input_position] - '0') * 10 + this.inputData[input_position + 1] - '0';
column_position++;
c--;
input_position += 2;
done = true;
}
}
 
if (!done) {
if ((current_mode == CfMode.MODEA || current_mode == CfMode.MODEB) && (findSubset(this.inputData[input_position]) == Mode.ABORC || this.inputData[input_position] == FNC1)) {
// Count the number of numeric digits
// If 4 or more numeric data characters occur together when in subsets A or B:
// a. If there is an even number of numeric data characters, insert a Code C
// character before the
// first numeric digit to change to subset C.
// b. If there is an odd number of numeric data characters, insert a Code Set C
// character immediately
// after the first numeric digit to change to subset C.
i = 0;
j = 0;
do {
i++;
if (this.inputData[input_position + j] == FNC1) {
i++;
}
j++;
} while (findSubset(this.inputData[input_position + j]) == Mode.ABORC || this.inputData[input_position + j] == FNC1);
i--;
 
if (i >= 4) {
/* Annex B section 1 rule 5 */
if (i % 2 == 1) {
/* Annex B section 1 rule 5a */
this.blockmatrix[current_row][column_position] = 99; /* Code C */
column_position++;
c--;
this.blockmatrix[current_row][column_position] = (this.inputData[input_position] - '0') * 10 + this.inputData[input_position + 1] - '0';
column_position++;
c--;
input_position += 2;
current_mode = CfMode.MODEC;
} else {
/* Annex B section 1 rule 5b */
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
}
done = true;
} else {
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
done = true;
}
}
}
 
if (!done) {
if (current_mode == CfMode.MODEB && findSubset(this.inputData[input_position]) == Mode.SHIFTA) {
/* Annex B section 1 rule 6 */
/*
* When in subset B and an ASCII control character occurs in the data: a. If
* there is a lower case character immediately following the control character,
* insert a Shift character before the control character. b. Otherwise, insert a
* Code A character before the control character to change to subset A.
*/
if (this.inputData[input_position + 1] >= 96 && this.inputData[input_position + 1] <= 127) {
/* Annex B section 1 rule 6a */
this.blockmatrix[current_row][column_position] = 98; /* Shift */
column_position++;
c--;
if (this.inputData[input_position] >= 128) {
/* Extended ASCII character */
this.blockmatrix[current_row][column_position] = 100; /* FNC4 */
column_position++;
c--;
}
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
} else {
/* Annex B section 1 rule 6b */
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
if (this.inputData[input_position] >= 128) {
/* Extended ASCII character */
this.blockmatrix[current_row][column_position] = 100; /* FNC4 */
column_position++;
c--;
}
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
current_mode = CfMode.MODEA;
}
done = true;
}
}
 
if (!done) {
if (current_mode == CfMode.MODEA && findSubset(this.inputData[input_position]) == Mode.SHIFTB) {
/* Annex B section 1 rule 7 */
/*
* When in subset A and a lower case character occurs in the data: a. If
* following that character, a control character occurs in the data before the
* occurrence of another lower case character, insert a Shift character before
* the lower case character. b. Otherwise, insert a Code B character before the
* lower case character to change to subset B.
*/
if (findSubset(this.inputData[input_position + 1]) == Mode.SHIFTA && findSubset(this.inputData[input_position + 2]) == Mode.SHIFTB) {
/* Annex B section 1 rule 7a */
this.blockmatrix[current_row][column_position] = 98; /* Shift */
column_position++;
c--;
if (this.inputData[input_position] >= 128) {
/* Extended ASCII character */
this.blockmatrix[current_row][column_position] = 101; /* FNC4 */
column_position++;
c--;
}
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
} else {
/* Annex B section 1 rule 7b */
this.blockmatrix[current_row][column_position] = 100; /* Code B */
column_position++;
c--;
if (this.inputData[input_position] >= 128) {
/* Extended ASCII character */
this.blockmatrix[current_row][column_position] = 101; /* FNC4 */
column_position++;
c--;
}
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
current_mode = CfMode.MODEB;
}
done = true;
}
}
 
if (!done) {
if (current_mode == CfMode.MODEC && (findSubset(this.inputData[input_position]) != Mode.ABORC || findSubset(this.inputData[input_position + 1]) != Mode.ABORC)) {
/* Annex B section 1 rule 8 */
/*
* When in subset C and a non-numeric character (or a single digit) occurs in
* the data, insert a Code A or Code B character before that character,
* following rules 8a and 8b to determine between code subsets A and B. a. If an
* ASCII control character (eg NUL) occurs in the data before any lower case
* character, use Code A. b. Otherwise use Code B.
*/
if (findSubset(this.inputData[input_position]) == Mode.SHIFTA) {
/* Annex B section 1 rule 8a */
this.blockmatrix[current_row][column_position] = 101; /* Code A */
column_position++;
c--;
if (this.inputData[input_position] >= 128) {
/* Extended ASCII character */
this.blockmatrix[current_row][column_position] = 101; /* FNC4 */
column_position++;
c--;
}
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
current_mode = CfMode.MODEA;
} else {
/* Annex B section 1 rule 8b */
this.blockmatrix[current_row][column_position] = 100; /* Code B */
column_position++;
c--;
if (this.inputData[input_position] >= 128) {
/* Extended ASCII character */
this.blockmatrix[current_row][column_position] = 100; /* FNC4 */
column_position++;
c--;
}
this.blockmatrix[current_row][column_position] = a3_convert(this.inputData[input_position]);
column_position++;
c--;
input_position++;
current_mode = CfMode.MODEB;
}
done = true;
}
}
 
if (input_position == input_length) {
/* End of data - Annex B rule 5a */
if (c == 1) {
if (current_mode == CfMode.MODEA) {
this.blockmatrix[current_row][column_position] = 100; /* Code B */
current_mode = CfMode.MODEB;
} else {
this.blockmatrix[current_row][column_position] = 101; /* Code A */
current_mode = CfMode.MODEA;
}
column_position++;
c--;
}
 
if (c == 0) {
/* Another row is needed */
column_position = 0;
c = this.columns_needed;
current_row++;
this.subset_selector[current_row] = CfMode.MODEA;
current_mode = CfMode.MODEA;
}
 
if (c > 2) {
/* Fill up the last row */
do {
if (current_mode == CfMode.MODEA) {
this.blockmatrix[current_row][column_position] = 100; /* Code B */
current_mode = CfMode.MODEB;
} else {
this.blockmatrix[current_row][column_position] = 101; /* Code A */
current_mode = CfMode.MODEA;
}
column_position++;
c--;
} while (c > 2);
}
 
/* If (c == 2) { do nothing } */
 
exit_status = true;
this.final_mode = current_mode;
} else {
if (c <= 0) {
/* Start new row - Annex B rule 5b */
column_position = 0;
current_row++;
if (current_row > 43) {
throw new OkapiException("Too many rows.");
}
}
}
 
} while (!exit_status);
 
if (current_row == 0) {
/* fill up the first row */
for (c = column_position; c <= this.columns_needed; c++) {
if (current_mode == CfMode.MODEA) {
this.blockmatrix[current_row][c] = 100; /* Code B */
current_mode = CfMode.MODEB;
} else {
this.blockmatrix[current_row][c] = 101; /* Code A */
current_mode = CfMode.MODEA;
}
}
current_row++;
/* add a second row */
this.subset_selector[current_row] = CfMode.MODEA;
current_mode = CfMode.MODEA;
for (c = 0; c <= this.columns_needed - 2; c++) {
if (current_mode == CfMode.MODEA) {
this.blockmatrix[current_row][c] = 100; /* Code B */
current_mode = CfMode.MODEB;
} else {
this.blockmatrix[current_row][c] = 101; /* Code A */
current_mode = CfMode.MODEA;
}
}
}
 
this.rows_needed = current_row + 1;
}
 
private CfMode character_subset_select(final int input_position) {
 
/* Section 4.5.2 - Determining the Character Subset Selector in a Row */
 
if (this.inputData[input_position] >= '0' && this.inputData[input_position] <= '9') {
/* Rule 1 */
return CfMode.MODEC;
}
 
if (this.inputData[input_position] >= 128 && this.inputData[input_position] <= 160) {
/* Rule 2 (i) */
return CfMode.MODEA;
}
 
if (this.inputData[input_position] >= 0 && this.inputData[input_position] <= 31) {
/* Rule 3 */
return CfMode.MODEA;
}
 
/* Rule 4 */
return CfMode.MODEB;
}
 
private int a3_convert(final int source) {
/* Annex A section 3 */
if (source < 32) {
return source + 64;
}
if (source >= 32 && source <= 127) {
return source - 32;
}
if (source >= 128 && source <= 159) {
return source - 128 + 64;
}
/* if source >= 160 */
return source - 128 - 32;
}
 
@Override
protected void plotSymbol() {
int xBlock, yBlock;
int x, y, w, h;
boolean black;
 
this.rectangles.clear();
y = 1;
h = 1;
for (yBlock = 0; yBlock < this.row_count; yBlock++) {
black = true;
x = 0;
for (xBlock = 0; xBlock < this.pattern[yBlock].length(); xBlock++) {
if (black) {
black = false;
w = this.pattern[yBlock].charAt(xBlock) - '0';
if (this.row_height[yBlock] == -1) {
h = this.default_height;
} else {
h = this.row_height[yBlock];
}
if (w != 0 && h != 0) {
final Rectangle2D.Double rect = new Rectangle2D.Double(x, y, w, h);
this.rectangles.add(rect);
}
if (x + w > this.symbol_width) {
this.symbol_width = x + w;
}
} else {
black = true;
}
x += this.pattern[yBlock].charAt(xBlock) - '0';
}
y += h;
if (y > this.symbol_height) {
this.symbol_height = y;
}
/* Add bars between rows */
if (yBlock != this.row_count - 1) {
final Rectangle2D.Double rect = new Rectangle2D.Double(11, y - 1, this.symbol_width - 24, 2);
this.rectangles.add(rect);
}
}
 
/* Add top and bottom binding bars */
final Rectangle2D.Double top = new Rectangle2D.Double(0, 0, this.symbol_width, 2);
this.rectangles.add(top);
final Rectangle2D.Double bottom = new Rectangle2D.Double(0, y - 1, this.symbol_width, 2);
this.rectangles.add(bottom);
this.symbol_height += 1;
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/AustraliaPost.java
New file
0,0 → 1,481
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.backend;
 
import static uk.org.okapibarcode.util.Arrays.positionOf;
 
import java.awt.geom.Rectangle2D;
 
/**
* Implements the <a href=
* "http://auspost.com.au/media/documents/a-guide-to-printing-the-4state-barcode-v31-mar2012.pdf">Australia
* Post 4-State barcode</a>.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class AustraliaPost extends Symbol {
 
private static final char[] CHARACTER_SET = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ' ', '#' };
 
private static final String[] N_ENCODING_TABLE = { "00", "01", "02", "10", "11", "12", "20", "21", "22", "30" };
 
private static final String[] C_ENCODING_TABLE = { "222", "300", "301", "302", "310", "311", "312", "320", "321", "322", "000", "001", "002", "010", "011", "012", "020", "021", "022", "100",
"101", "102", "110", "111", "112", "120", "121", "122", "200", "201", "202", "210", "211", "212", "220", "221", "023", "030", "031", "032", "033", "103", "113", "123", "130", "131", "132",
"133", "203", "213", "223", "230", "231", "232", "233", "303", "313", "323", "330", "331", "332", "333", "003", "013" };
 
private static final String[] BAR_VALUE_TABLE = { "000", "001", "002", "003", "010", "011", "012", "013", "020", "021", "022", "023", "030", "031", "032", "033", "100", "101", "102", "103", "110",
"111", "112", "113", "120", "121", "122", "123", "130", "131", "132", "133", "200", "201", "202", "203", "210", "211", "212", "213", "220", "221", "222", "223", "230", "231", "232", "233",
"300", "301", "302", "303", "310", "311", "312", "313", "320", "321", "322", "323", "330", "331", "332", "333" };
 
private enum ausMode {
AUSPOST, AUSREPLY, AUSROUTE, AUSREDIRECT
}
 
private ausMode mode;
 
public AustraliaPost() {
this.mode = ausMode.AUSPOST;
}
 
/**
* Specify encoding of Australia Post Standard Customer Barcode, Customer Barcode 2 or Customer
* Barcode 3 (37-bar, 52-bar and 67-bar symbols) depending on input data length. Valid data
* characters are 0-9, A-Z, a-z, space and hash (#). A Format Control Code (FCC) is added and
* should not be included in the input data.
* <p>
* Input data should include a 8-digit Deliver Point ID (DPID) optionally followed by customer
* information as shown below.
* <table summary="Permitted Australia Post input data">
* <tbody>
* <tr>
* <th>
* <p>
* Input Length
* </p>
* </th>
* <th>
* <p>
* Required Input Format
* </p>
* </th>
* <th>
* <p>
* Symbol Length
* </p>
* </th>
* <th>
* <p>
* FCC
* </p>
* </th>
* <th>
* <p>
* Encoding Table
* </p>
* </th>
* </tr>
* <tr>
* <td>
* <p>
* 8
* </p>
* </td>
* <td>
* <p>
* 99999999
* </p>
* </td>
* <td>
* <p>
* 37-bar
* </p>
* </td>
* <td>
* <p>
* 11
* </p>
* </td>
* <td>
* <p>
* None
* </p>
* </td>
* </tr>
* <tr>
* <td>
* <p>
* 13
* </p>
* </td>
* <td>
* <p>
* 99999999AAAAA
* </p>
* </td>
* <td>
* <p>
* 52-bar
* </p>
* </td>
* <td>
* <p>
* 59
* </p>
* </td>
* <td>
* <p>
* C
* </p>
* </td>
* </tr>
* <tr>
* <td>
* <p>
* 16
* </p>
* </td>
* <td>
* <p>
* 9999999999999999
* </p>
* </td>
* <td>
* <p>
* 52-bar
* </p>
* </td>
* <td>
* <p>
* 59
* </p>
* </td>
* <td>
* <p>
* N
* </p>
* </td>
* </tr>
* <tr>
* <td>
* <p>
* 18
* </p>
* </td>
* <td>
* <p>
* 99999999AAAAAAAAAA
* </p>
* </td>
* <td>
* <p>
* 67-bar
* </p>
* </td>
* <td>
* <p>
* 62
* </p>
* </td>
* <td>
* <p>
* C
* </p>
* </td>
* </tr>
* <tr>
* <td>
* <p>
* 23
* </p>
* </td>
* <td>
* <p>
* 99999999999999999999999
* </p>
* </td>
* <td>
* <p>
* 67-bar
* </p>
* </td>
* <td>
* <p>
* 62
* </p>
* </td>
* <td>
* <p>
* N
* </p>
* </td>
* </tr>
* </tbody>
* </table>
*/
public void setPostMode() {
this.mode = ausMode.AUSPOST;
}
 
/**
* Specify encoding of a Reply Paid version of the Australia Post 4-State Barcode (FCC 45) which
* requires an 8-digit DPID input.
*/
public void setReplyMode() {
this.mode = ausMode.AUSREPLY;
}
 
/**
* Specify encoding of a Routing version of the Australia Post 4-State Barcode (FCC 87) which
* requires an 8-digit DPID input.
*/
public void setRouteMode() {
this.mode = ausMode.AUSROUTE;
}
 
/**
* Specify encoding of a Redirection version of the Australia Post 4-State Barcode (FCC 92)
* which requires an 8-digit DPID input.
*/
public void setRedirectMode() {
this.mode = ausMode.AUSREDIRECT;
}
 
/** {@inheritDoc} */
@Override
protected void encode() {
String formatControlCode = "00";
String deliveryPointId;
String barStateValues;
String zeroPaddedInput = "";
int i;
 
switch (this.mode) {
case AUSPOST:
switch (this.content.length()) {
case 8:
formatControlCode = "11";
break;
case 13:
formatControlCode = "59";
break;
case 16:
formatControlCode = "59";
if (!this.content.matches("[0-9]+")) {
throw new OkapiException("Invalid characters in data");
}
break;
case 18:
formatControlCode = "62";
break;
case 23:
formatControlCode = "62";
if (!this.content.matches("[0-9]+")) {
throw new OkapiException("Invalid characters in data");
}
break;
default:
throw new OkapiException("Auspost input is wrong length");
}
break;
case AUSREPLY:
if (this.content.length() > 8) {
throw new OkapiException("Auspost input is too long");
} else {
formatControlCode = "45";
}
break;
case AUSROUTE:
if (this.content.length() > 8) {
throw new OkapiException("Auspost input is too long");
} else {
formatControlCode = "87";
}
break;
case AUSREDIRECT:
if (this.content.length() > 8) {
throw new OkapiException("Auspost input is too long");
} else {
formatControlCode = "92";
}
break;
}
 
infoLine("FCC: " + formatControlCode);
 
if (this.mode != ausMode.AUSPOST) {
for (i = this.content.length(); i < 8; i++) {
zeroPaddedInput += "0";
}
}
zeroPaddedInput += this.content;
 
if (!this.content.matches("[0-9A-Za-z #]+")) {
throw new OkapiException("Invalid characters in data");
}
 
/* Verify that the first 8 characters are numbers */
deliveryPointId = zeroPaddedInput.substring(0, 8);
 
if (!deliveryPointId.matches("[0-9]+")) {
throw new OkapiException("Invalid characters in DPID");
}
 
infoLine("DPID: " + deliveryPointId);
 
/* Start */
barStateValues = "13";
 
/* Encode the FCC */
for (i = 0; i < 2; i++) {
barStateValues += N_ENCODING_TABLE[formatControlCode.charAt(i) - '0'];
}
 
/* Delivery Point Identifier (DPID) */
for (i = 0; i < 8; i++) {
barStateValues += N_ENCODING_TABLE[deliveryPointId.charAt(i) - '0'];
}
 
/* Customer Information */
switch (zeroPaddedInput.length()) {
case 13:
case 18:
for (i = 8; i < zeroPaddedInput.length(); i++) {
barStateValues += C_ENCODING_TABLE[positionOf(zeroPaddedInput.charAt(i), CHARACTER_SET)];
}
break;
case 16:
case 23:
for (i = 8; i < zeroPaddedInput.length(); i++) {
barStateValues += N_ENCODING_TABLE[positionOf(zeroPaddedInput.charAt(i), CHARACTER_SET)];
}
break;
}
 
/* Filler bar */
switch (barStateValues.length()) {
case 22:
case 37:
case 52:
barStateValues += "3";
break;
}
 
/* Reed Solomon error correction */
barStateValues += calcReedSolomon(barStateValues);
 
/* Stop character */
barStateValues += "13";
 
infoLine("Total Length: " + barStateValues.length());
info("Encoding: ");
for (i = 0; i < barStateValues.length(); i++) {
switch (barStateValues.charAt(i)) {
case '1':
info("A");
break;
case '2':
info("D");
break;
case '0':
info("F");
break;
case '3':
info("T");
break;
}
}
infoLine();
 
this.readable = "";
this.pattern = new String[1];
this.pattern[0] = barStateValues;
this.row_count = 1;
this.row_height = new int[1];
this.row_height[0] = -1;
}
 
private String calcReedSolomon(final String oldBarStateValues) {
final ReedSolomon rs = new ReedSolomon();
String newBarStateValues = "";
 
/* Adds Reed-Solomon error correction to auspost */
 
int barStateCount;
int tripleValueCount = 0;
final int[] tripleValue = new int[31];
 
for (barStateCount = 2; barStateCount < oldBarStateValues.length(); barStateCount += 3, tripleValueCount++) {
tripleValue[tripleValueCount] = barStateToDecimal(oldBarStateValues.charAt(barStateCount), 4) + barStateToDecimal(oldBarStateValues.charAt(barStateCount + 1), 2)
+ barStateToDecimal(oldBarStateValues.charAt(barStateCount + 2), 0);
}
 
rs.init_gf(0x43);
rs.init_code(4, 1);
rs.encode(tripleValueCount, tripleValue);
 
for (barStateCount = 4; barStateCount > 0; barStateCount--) {
newBarStateValues += BAR_VALUE_TABLE[rs.getResult(barStateCount - 1)];
}
 
return newBarStateValues;
}
 
private int barStateToDecimal(final char oldBarStateValues, final int shift) {
return oldBarStateValues - '0' << shift;
}
 
/** {@inheritDoc} */
@Override
protected void plotSymbol() {
int xBlock;
int x, y, w, h;
 
this.rectangles.clear();
x = 0;
w = 1;
y = 0;
h = 0;
for (xBlock = 0; xBlock < this.pattern[0].length(); xBlock++) {
switch (this.pattern[0].charAt(xBlock)) {
case '1':
y = 0;
h = 5;
break;
case '2':
y = 3;
h = 5;
break;
case '0':
y = 0;
h = 8;
break;
case '3':
y = 3;
h = 2;
break;
}
 
final Rectangle2D.Double rect = new Rectangle2D.Double(x, y, w, h);
this.rectangles.add(rect);
 
x += 2;
}
 
this.symbol_width = (this.pattern[0].length() - 1) * 2 + 1; // no whitespace needed after
// the final bar
this.symbol_height = 8;
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/Codabar.java
New file
0,0 → 1,95
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
import static uk.org.okapibarcode.util.Arrays.positionOf;
 
/**
* <p>
* Implements Codabar barcode symbology according to BS EN 798:1996.
*
* <p>
* Also known as NW-7, Monarch, ABC Codabar, USD-4, Ames Code and Code 27. Codabar can encode any
* length string starting and ending with the letters A-D and containing between these letters the
* numbers 0-9, dash (-), dollar ($), colon (:), slash (/), full stop (.) or plus (+). No check
* digit is generated.
*
* @author <a href="mailto:jakel2006@me.com">Robert Elliott</a>
*/
public class Codabar extends Symbol {
 
private static final String[] CODABAR_TABLE = { "11111221", "11112211", "11121121", "22111111", "11211211", "21111211", "12111121", "12112111", "12211111", "21121111", "11122111", "11221111",
"21112121", "21211121", "21212111", "11212121", "11221211", "12121121", "11121221", "11122211" };
 
private static final char[] CHARACTER_SET = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '$', ':', '/', '.', '+', 'A', 'B', 'C', 'D' };
 
/** Ratio of wide bar width to narrow bar width. */
private double moduleWidthRatio = 2;
 
/**
* Sets the ratio of wide bar width to narrow bar width. Valid values are usually between
* {@code 2} and {@code 3}. The default value is {@code 2}.
*
* @param moduleWidthRatio the ratio of wide bar width to narrow bar width
*/
public void setModuleWidthRatio(final double moduleWidthRatio) {
this.moduleWidthRatio = moduleWidthRatio;
}
 
/**
* Returns the ratio of wide bar width to narrow bar width.
*
* @return the ratio of wide bar width to narrow bar width
*/
public double getModuleWidthRatio() {
return this.moduleWidthRatio;
}
 
/** {@inheritDoc} */
@Override
protected void encode() {
 
if (!this.content.matches("[A-D]{1}[0-9:/\\$\\.\\+\u002D]+[A-D]{1}")) {
throw new OkapiException("Invalid characters in input");
}
 
String horizontalSpacing = "";
 
final int l = this.content.length();
for (int i = 0; i < l; i++) {
horizontalSpacing += CODABAR_TABLE[positionOf(this.content.charAt(i), CHARACTER_SET)];
}
 
this.readable = this.content;
this.pattern = new String[] { horizontalSpacing };
this.row_count = 1;
this.row_height = new int[] { -1 };
}
 
/** {@inheritDoc} */
@Override
protected double getModuleWidth(final int originalWidth) {
if (originalWidth == 1) {
return 1;
} else {
return this.moduleWidthRatio;
}
}
 
/** {@inheritDoc} */
@Override
protected int[] getCodewords() {
return getPatternAsCodewords(8);
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/Code3Of9Extended.java
New file
0,0 → 1,78
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
/**
* <p>
* Implements Code 3 of 9 Extended, also known as Code 39e and Code39+.
*
* <p>
* Supports encoding of all characters in the 7-bit ASCII table. A modulo-43 check digit can be
* added if required.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class Code3Of9Extended extends Symbol {
 
private static final String[] E_CODE_39 = { "%U", "$A", "$B", "$C", "$D", "$E", "$F", "$G", "$H", "$I", "$J", "$K", "$L", "$M", "$N", "$O", "$P", "$Q", "$R", "$S", "$T", "$U", "$V", "$W", "$X",
"$Y", "$Z", "%A", "%B", "%C", "%D", "%E", " ", "/A", "/B", "/C", "/D", "/E", "/F", "/G", "/H", "/I", "/J", "/K", "/L", "-", ".", "/O", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"/Z", "%F", "%G", "%H", "%I", "%J", "%V", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "%K", "%L",
"%M", "%N", "%O", "%W", "+A", "+B", "+C", "+D", "+E", "+F", "+G", "+H", "+I", "+J", "+K", "+L", "+M", "+N", "+O", "+P", "+Q", "+R", "+S", "+T", "+U", "+V", "+W", "+X", "+Y", "+Z", "%P",
"%Q", "%R", "%S", "%T" };
 
public enum CheckDigit {
NONE, MOD43
}
 
private CheckDigit checkOption = CheckDigit.NONE;
 
/**
* Select addition of optional Modulo-43 check digit or encoding without check digit.
*
* @param checkMode check digit option
*/
public void setCheckDigit(final CheckDigit checkMode) {
this.checkOption = checkMode;
}
 
@Override
protected void encode() {
String buffer = "";
final int l = this.content.length();
int asciicode;
final Code3Of9 c = new Code3Of9();
 
if (this.checkOption == CheckDigit.MOD43) {
c.setCheckDigit(Code3Of9.CheckDigit.MOD43);
}
 
if (!this.content.matches("[\u0000-\u007F]+")) {
throw new OkapiException("Invalid characters in input data");
}
 
for (int i = 0; i < l; i++) {
asciicode = this.content.charAt(i);
buffer += E_CODE_39[asciicode];
}
 
c.setContent(buffer);
 
this.readable = this.content;
this.pattern = new String[1];
this.pattern[0] = c.pattern[0];
this.row_count = 1;
this.row_height = new int[1];
this.row_height[0] = -1;
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/Postnet.java
New file
0,0 → 1,156
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.backend;
 
import static uk.org.okapibarcode.backend.HumanReadableLocation.NONE;
import static uk.org.okapibarcode.backend.HumanReadableLocation.TOP;
 
import java.awt.geom.Rectangle2D;
 
/**
* <p>
* Implements <a href="http://en.wikipedia.org/wiki/POSTNET">POSTNET</a> and
* <a href="http://en.wikipedia.org/wiki/Postal_Alpha_Numeric_Encoding_Technique">PLANET</a> bar
* code symbologies.
*
* <p>
* POSTNET and PLANET both use numerical input data and include a modulo-10 check digit.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class Postnet extends Symbol {
 
public static enum Mode {
PLANET, POSTNET
};
 
private static final String[] PN_TABLE = { "LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", "SLSLS", "SLLSS", "LSSSL", "LSSLS", "LSLSS" };
 
private static final String[] PL_TABLE = { "SSLLL", "LLLSS", "LLSLS", "LLSSL", "LSLLS", "LSLSL", "LSSLL", "SLLLS", "SLLSL", "SLSLL" };
 
private Mode mode;
 
public Postnet() {
this.mode = Mode.POSTNET;
this.default_height = 12;
this.humanReadableLocation = HumanReadableLocation.NONE;
}
 
/**
* Sets the barcode mode (PLANET or POSTNET). The default mode is POSTNET.
*
* @param mode the barcode mode (PLANET or POSTNET)
*/
public void setMode(final Mode mode) {
this.mode = mode;
}
 
/**
* Returns the barcode mode (PLANET or POSTNET). The default mode is POSTNET.
*
* @return the barcode mode (PLANET or POSTNET)
*/
public Mode getMode() {
return this.mode;
}
 
@Override
protected void encode() {
final String[] table = this.mode == Mode.POSTNET ? PN_TABLE : PL_TABLE;
encode(table);
}
 
private void encode(final String[] table) {
int i, sum, check_digit;
String dest;
 
if (this.content.length() > 38) {
throw new OkapiException("Input too long");
}
 
if (!this.content.matches("[0-9]+")) {
throw new OkapiException("Invalid characters in data");
}
 
sum = 0;
dest = "L";
 
for (i = 0; i < this.content.length(); i++) {
dest += table[this.content.charAt(i) - '0'];
sum += this.content.charAt(i) - '0';
}
 
check_digit = (10 - sum % 10) % 10;
infoLine("Check Digit: " + check_digit);
 
dest += table[check_digit];
dest += "L";
 
infoLine("Encoding: " + dest);
this.readable = this.content;
this.pattern = new String[] { dest };
this.row_count = 1;
this.row_height = new int[] { -1 };
}
 
@Override
protected void plotSymbol() {
int xBlock, shortHeight;
double x, y, w, h;
 
this.rectangles.clear();
this.texts.clear();
 
int baseY;
if (this.humanReadableLocation == TOP) {
baseY = getTheoreticalHumanReadableHeight();
} else {
baseY = 0;
}
 
x = 0;
w = this.moduleWidth;
shortHeight = (int) (0.4 * this.default_height);
for (xBlock = 0; xBlock < this.pattern[0].length(); xBlock++) {
if (this.pattern[0].charAt(xBlock) == 'L') {
y = baseY;
h = this.default_height;
} else {
y = baseY + this.default_height - shortHeight;
h = shortHeight;
}
this.rectangles.add(new Rectangle2D.Double(x, y, w, h));
x += 2.5 * w;
}
 
this.symbol_width = (int) Math.ceil((this.pattern[0].length() - 1) * 2.5 * w + w); // final
// bar
// doesn't
// need
// extra
// whitespace
this.symbol_height = this.default_height;
 
if (this.humanReadableLocation != NONE && !this.readable.isEmpty()) {
double baseline;
if (this.humanReadableLocation == TOP) {
baseline = this.fontSize;
} else {
baseline = this.symbol_height + this.fontSize;
}
this.texts.add(new TextBox(0, baseline, this.symbol_width, this.readable, this.humanReadableAlignment));
}
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/Telepen.java
New file
0,0 → 1,166
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
/**
* <p>
* Implements Telepen (also known as Telepen Alpha).
*
* <p>
* Telepen can encode ASCII text input and includes a modulo-127 check digit. Telepen Numeric allows
* compression of numeric data into a Telepen symbol. Data can consist of pairs of numbers or pairs
* consisting of a numerical digit followed by an X character. Telepen Numeric also includes a
* modulo-127 check digit.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class Telepen extends Symbol {
 
public static enum Mode {
NORMAL, NUMERIC
}
 
private static final String[] TELE_TABLE = { "1111111111111111", "1131313111", "33313111", "1111313131", "3111313111", "11333131", "13133131", "111111313111", "31333111", "1131113131", "33113131",
"1111333111", "3111113131", "1113133111", "1311133111", "111111113131", "3131113111", "11313331", "333331", "111131113111", "31113331", "1133113111", "1313113111", "1111113331",
"31131331", "113111113111", "3311113111", "1111131331", "311111113111", "1113111331", "1311111331", "11111111113111", "31313311", "1131311131", "33311131", "1111313311", "3111311131",
"11333311", "13133311", "111111311131", "31331131", "1131113311", "33113311", "1111331131", "3111113311", "1113131131", "1311131131", "111111113311", "3131111131", "1131131311",
"33131311", "111131111131", "3111131311", "1133111131", "1313111131", "111111131311", "3113111311", "113111111131", "3311111131", "111113111311", "311111111131", "111311111311",
"131111111311", "11111111111131", "3131311111", "11313133", "333133", "111131311111", "31113133", "1133311111", "1313311111", "1111113133", "313333", "113111311111", "3311311111",
"11113333", "311111311111", "11131333", "13111333", "11111111311111", "31311133", "1131331111", "33331111", "1111311133", "3111331111", "11331133", "13131133", "111111331111",
"3113131111", "1131111133", "33111133", "111113131111", "3111111133", "111311131111", "131111131111", "111111111133", "31311313", "113131111111", "3331111111", "1111311313",
"311131111111", "11331313", "13131313", "11111131111111", "3133111111", "1131111313", "33111313", "111133111111", "3111111313", "111313111111", "131113111111", "111111111313",
"313111111111", "1131131113", "33131113", "11113111111111", "3111131113", "113311111111", "131311111111", "111111131113", "3113111113", "11311111111111", "331111111111", "111113111113",
"31111111111111", "111311111113", "131111111113" };
 
private Mode mode = Mode.NORMAL;
 
public void setMode(final Mode mode) {
this.mode = mode;
}
 
public Mode getMode() {
return this.mode;
}
 
@Override
protected void encode() {
if (this.mode == Mode.NORMAL) {
normal_mode();
} else {
numeric_mode();
}
}
 
private void normal_mode() {
int count = 0, asciicode, check_digit;
String p = "";
String dest;
 
final int l = this.content.length();
 
if (!this.content.matches("[\u0000-\u007F]+")) {
throw new OkapiException("Invalid characters in input data");
}
 
dest = TELE_TABLE['_']; // Start
for (int i = 0; i < l; i++) {
asciicode = this.content.charAt(i);
p += TELE_TABLE[asciicode];
count += asciicode;
}
 
check_digit = 127 - count % 127;
if (check_digit == 127) {
check_digit = 0;
}
 
p += TELE_TABLE[check_digit];
 
infoLine("Check Digit: " + check_digit);
 
dest += p;
dest += TELE_TABLE['z']; // Stop
 
this.readable = this.content;
this.pattern = new String[1];
this.pattern[0] = dest;
this.row_count = 1;
this.row_height = new int[1];
this.row_height[0] = -1;
}
 
private void numeric_mode() {
int count = 0, check_digit;
String p = "";
String t;
String dest;
final int l = this.content.length();
int tl, glyph;
char c1, c2;
 
// FIXME: Ensure no extended ASCII or Unicode characters are entered
if (!this.content.matches("[0-9X]+")) {
throw new OkapiException("Invalid characters in input");
}
 
/* If input is an odd length, add a leading zero */
if ((l & 1) == 1) {
t = "0" + this.content;
tl = l + 1;
} else {
t = this.content;
tl = l;
}
 
dest = TELE_TABLE['_']; // Start
for (int i = 0; i < tl; i += 2) {
 
c1 = t.charAt(i);
c2 = t.charAt(i + 1);
 
/* Input nX is allowed, but Xn is not */
if (c1 == 'X') {
throw new OkapiException("Invalid position of X in data");
}
 
if (c2 == 'X') {
glyph = c1 - '0' + 17;
count += glyph;
} else {
glyph = 10 * (c1 - '0') + c2 - '0' + 27;
count += glyph;
}
 
p += TELE_TABLE[glyph];
}
 
check_digit = 127 - count % 127;
if (check_digit == 127) {
check_digit = 0;
}
 
p += TELE_TABLE[check_digit];
 
infoLine("Check Digit: " + check_digit);
 
dest += p;
dest += TELE_TABLE['z']; // Stop
this.readable = this.content;
this.pattern = new String[1];
this.pattern[0] = dest;
this.row_count = 1;
this.row_height = new int[1];
this.row_height[0] = -1;
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/TextBox.java
New file
0,0 → 1,62
/*
* Copyright 2014-2018 Robin Stuart, Daniel Gredler
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
 
package uk.org.okapibarcode.backend;
 
/**
* A simple text item class.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
* @author Daniel Gredler
*/
public class TextBox {
 
/** The X position of the text's left boundary. */
public final double x;
 
/** The Y position of the text baseline. */
public final double y;
 
/** The width of the text box. */
public final double width;
 
/** The text value. */
public final String text;
 
/** The text alignment. */
public final HumanReadableAlignment alignment;
 
/**
* Creates a new instance.
*
* @param x the X position of the text's left boundary
* @param y the Y position of the text baseline
* @param width the width of the text box
* @param text the text value
* @param alignment the text alignment
*/
public TextBox(final double x, final double y, final double width, final String text, final HumanReadableAlignment alignment) {
this.x = x;
this.y = y;
this.width = width;
this.text = text;
this.alignment = alignment;
}
 
/** {@inheritDoc} */
@Override
public String toString() {
return "TextBox[x=" + this.x + ", y=" + this.y + ", width=" + this.width + ", text=" + this.text + ", alignment=" + this.alignment + "]";
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/AztecRune.java
New file
0,0 → 1,160
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
/**
* <p>
* Implements the Aztec Runes bar code symbology according to ISO/IEC 24778:2008 Annex A.
*
* <p>
* Aztec Runes is a fixed-size matrix symbology which can encode whole integer values between 0 and
* 255.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class AztecRune extends Symbol {
 
private static final int[] BIT_PLACEMENT_MAP = { 1, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 1, 0, 0, 0, 0, 0, 0, 0, 1, 9, 28, 1, 0, 1, 1, 1, 1, 1, 0, 1, 10, 27, 1, 0, 1,
0, 0, 0, 1, 0, 1, 11, 26, 1, 0, 1, 0, 1, 0, 1, 0, 1, 12, 25, 1, 0, 1, 0, 0, 0, 1, 0, 1, 13, 24, 1, 0, 1, 1, 1, 1, 1, 0, 1, 14, 23, 1, 0, 0, 0, 0, 0, 0, 0, 1, 15, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 0, 22, 21, 20, 19, 18, 17, 16, 0, 0 };
 
@Override
protected void encode() {
 
if (!this.content.matches("[0-9]+")) {
throw new OkapiException("Invalid input data");
}
 
int decimalValue = 0;
switch (this.content.length()) {
case 1:
decimalValue = this.content.charAt(0) - '0';
break;
case 2:
decimalValue = 10 * (this.content.charAt(0) - '0');
decimalValue += this.content.charAt(1) - '0';
break;
case 3:
decimalValue = 100 * (this.content.charAt(0) - '0');
decimalValue += 10 * (this.content.charAt(1) - '0');
decimalValue += this.content.charAt(2) - '0';
break;
default:
throw new OkapiException("Input too large");
}
 
if (decimalValue > 255) {
throw new OkapiException("Input too large");
}
 
final StringBuilder binaryDataStream = new StringBuilder(28);
for (int i = 0x80; i > 0; i = i >> 1) {
if ((decimalValue & i) != 0) {
binaryDataStream.append('1');
} else {
binaryDataStream.append('0');
}
}
 
final int[] dataCodeword = new int[3];
dataCodeword[0] = 0;
dataCodeword[1] = 0;
 
for (int i = 0; i < 2; i++) {
if (binaryDataStream.charAt(i * 4) == '1') {
dataCodeword[i] += 8;
}
if (binaryDataStream.charAt(i * 4 + 1) == '1') {
dataCodeword[i] += 4;
}
if (binaryDataStream.charAt(i * 4 + 2) == '1') {
dataCodeword[i] += 2;
}
if (binaryDataStream.charAt(i * 4 + 3) == '1') {
dataCodeword[i] += 1;
}
}
 
final int[] errorCorrectionCodeword = new int[6];
 
final ReedSolomon rs = new ReedSolomon();
rs.init_gf(0x13);
rs.init_code(5, 1);
rs.encode(2, dataCodeword);
 
for (int i = 0; i < 5; i++) {
errorCorrectionCodeword[i] = rs.getResult(i);
}
 
for (int i = 0; i < 5; i++) {
if ((errorCorrectionCodeword[4 - i] & 0x08) != 0) {
binaryDataStream.append('1');
} else {
binaryDataStream.append('0');
}
if ((errorCorrectionCodeword[4 - i] & 0x04) != 0) {
binaryDataStream.append('1');
} else {
binaryDataStream.append('0');
}
if ((errorCorrectionCodeword[4 - i] & 0x02) != 0) {
binaryDataStream.append('1');
} else {
binaryDataStream.append('0');
}
if ((errorCorrectionCodeword[4 - i] & 0x01) != 0) {
binaryDataStream.append('1');
} else {
binaryDataStream.append('0');
}
}
 
final StringBuilder reversedBinaryDataStream = new StringBuilder(28);
for (int i = 0; i < binaryDataStream.length(); i++) {
if ((i & 1) == 0) {
if (binaryDataStream.charAt(i) == '0') {
reversedBinaryDataStream.append('1');
} else {
reversedBinaryDataStream.append('0');
}
} else {
reversedBinaryDataStream.append(binaryDataStream.charAt(i));
}
}
 
infoLine("Binary: " + reversedBinaryDataStream);
 
this.readable = "";
this.pattern = new String[11];
this.row_count = 11;
this.row_height = new int[11];
 
for (int row = 0; row < 11; row++) {
final StringBuilder rowBinary = new StringBuilder(11);
for (int column = 0; column < 11; column++) {
if (BIT_PLACEMENT_MAP[row * 11 + column] == 1) {
rowBinary.append('1');
}
if (BIT_PLACEMENT_MAP[row * 11 + column] == 0) {
rowBinary.append('0');
}
if (BIT_PLACEMENT_MAP[row * 11 + column] >= 2) {
rowBinary.append(reversedBinaryDataStream.charAt(BIT_PLACEMENT_MAP[row * 11 + column] - 2));
}
}
this.pattern[row] = bin2pat(rowBinary);
this.row_height[row] = 1;
}
}
}
/trunk/Modules/Module Label/src/uk/org/okapibarcode/backend/Composite.java
New file
0,0 → 1,2769
/*
* Copyright 2014 Robin Stuart
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package uk.org.okapibarcode.backend;
 
import static uk.org.okapibarcode.util.Arrays.positionOf;
 
import java.awt.geom.Rectangle2D;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
 
import uk.org.okapibarcode.backend.DataBar14.Mode;
 
/**
* <p>
* Implements GS1 Composite symbology according to ISO/IEC 24723:2010.
*
* <p>
* Composite symbols comprise a 2D element which encodes GS1 data and a "linear" element which can
* be UPC, EAN, Code 128 or GS1 DataBar symbol.
*
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
*/
public class Composite extends Symbol {
 
/** The linear component choices available. */
public static enum LinearEncoding {
UPCA, UPCE, EAN, CODE_128, DATABAR_14, DATABAR_14_STACK, DATABAR_14_STACK_OMNI, DATABAR_LIMITED, DATABAR_EXPANDED, DATABAR_EXPANDED_STACK
}
 
/** The 2D component choices available. */
public static enum CompositeMode {
/**
* Indicates that the composite symbol uses a MicroPDF417 variant as the 2D component. Of
* the 2D component choices, this one holds the least amount of data.
*/
CC_A,
/**
* Indicates that the composite symbol uses a MicroPDF417 symbol as the 2D component,
* starting with a codeword of 920.
*/
CC_B,
/**
* Indicates that the composite symbol uses a PDF417 symbol as the 2D component, starting
* with a codeword of 920. Of the 2D component choices, this one holds the most amount of
* data. May only be used if the linear component is {@link LinearEncoding#CODE_128 Code
* 128}.
*/
CC_C
}
 
private static enum GeneralFieldMode {
NUMERIC, ALPHA, ISOIEC, INVALID_CHAR, ANY_ENC, ALPHA_OR_ISO
}
 
/* CC-A component coefficients from ISO/IEC 24728:2006 Annex F */
private static final int[] CCA_COEFFS = {
/* k = 4 */
522, 568, 723, 809,
/* k = 5 */
427, 919, 460, 155, 566,
/* k = 6 */
861, 285, 19, 803, 17, 766,
/* k = 7 */
76, 925, 537, 597, 784, 691, 437,
/* k = 8 */
237, 308, 436, 284, 646, 653, 428, 379 };
 
private static final int[] COEFRS = {
/* k = 2 */
27, 917,
/* k = 4 */
522, 568, 723, 809,
/* k = 8 */
237, 308, 436, 284, 646, 653, 428, 379,
/* k = 16 */
274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65,
/* k = 32 */
361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410,
/* k = 64 */
539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, 440, 35, 519, 31, 460, 594,
225, 535, 517, 352, 605, 158, 651, 201, 488, 502, 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543,
/* k = 128 */
521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, 516, 258, 457, 907, 594, 723,
674, 292, 272, 96, 684, 432, 686, 606, 860, 569, 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48,
228, 821, 808, 898, 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, 211, 330,
539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539,
/* k = 256 */
524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, 710, 814, 919, 89, 68, 569, 11,
204, 796, 605, 540, 913, 801, 700, 799, 137, 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334,
376, 849, 521, 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, 2, 290, 743, 199,
655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, 722, 384, 177, 752, 607, 640, 455, 193, 689, 707,
805, 641, 48, 60, 732, 621, 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73,
914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, 167, 29, 872, 449,
83, 402, 41, 656, 505, 579, 481, 173, 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10,
/* k = 512 */
352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, 846, 75, 327, 520, 435, 543,
203, 666, 249, 346, 781, 621, 640, 268, 794, 534, 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107,
784, 860, 658, 741, 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, 240, 518,
794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, 40, 708, 575, 162, 864, 229, 65, 861,
841, 512, 164, 477, 221, 92, 358, 785, 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533,
820, 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, 283, 711, 472, 420, 245,
288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109,
608, 563, 365, 181, 772, 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, 787,
680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, 242, 797, 838, 837, 720, 224, 307,
631, 61, 87, 560, 310, 756, 665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281,
73, 469, 791, 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, 37, 357, 720,
742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, 447, 171, 616, 464, 190, 531, 297, 321, 762,
752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849,
647, 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 };
 
/* rows, error codewords, k-offset of valid CC-A sizes from ISO/IEC 24723:2006 Table 9 */
private static final int[] CCA_VARIANTS = { 5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, 4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8, 0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9,
15, 22 };
 
/*
* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24723:2006 tables
* 10 and 11
*/
private static final int[] A_RAP_TABLE = { 39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29, 0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 26, 14, 9, 19, 33, 12, 40, 46, 23, 52,
23, 13, 17, 27, 33, 52, 3, 6, 46, 41, 6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3 };
 
private static final String[] CODAGEMC = { "urA", "xfs", "ypy", "unk", "xdw", "yoz", "pDA", "uls", "pBk", "eBA", "pAs", "eAk", "prA", "uvs", "xhy", "pnk", "utw", "xgz", "fDA", "pls", "fBk", "frA",
"pvs", "uxy", "fnk", "ptw", "uwz", "fls", "psy", "fvs", "pxy", "ftw", "pwz", "fxy", "yrx", "ufk", "xFw", "ymz", "onA", "uds", "xEy", "olk", "ucw", "dBA", "oks", "uci", "dAk", "okg", "dAc",
"ovk", "uhw", "xaz", "dnA", "ots", "ugy", "dlk", "osw", "ugj", "dks", "osi", "dvk", "oxw", "uiz", "dts", "owy", "dsw", "owj", "dxw", "oyz", "dwy", "dwj", "ofA", "uFs", "xCy", "odk", "uEw",
"xCj", "clA", "ocs", "uEi", "ckk", "ocg", "ckc", "ckE", "cvA", "ohs", "uay", "ctk", "ogw", "uaj", "css", "ogi", "csg", "csa", "cxs", "oiy", "cww", "oij", "cwi", "cyy", "oFk", "uCw", "xBj",
"cdA", "oEs", "uCi", "cck", "oEg", "uCb", "ccc", "oEa", "ccE", "oED", "chk", "oaw", "uDj", "cgs", "oai", "cgg", "oab", "cga", "cgD", "obj", "cib", "cFA", "oCs", "uBi", "cEk", "oCg", "uBb",
"cEc", "oCa", "cEE", "oCD", "cEC", "cas", "cag", "caa", "cCk", "uAr", "oBa", "oBD", "cCB", "tfk", "wpw", "yez", "mnA", "tds", "woy", "mlk", "tcw", "woj", "FBA", "mks", "FAk", "mvk", "thw",
"wqz", "FnA", "mts", "tgy", "Flk", "msw", "Fks", "Fkg", "Fvk", "mxw", "tiz", "Fts", "mwy", "Fsw", "Fsi", "Fxw", "myz", "Fwy", "Fyz", "vfA", "xps", "yuy", "vdk", "xow", "yuj", "qlA", "vcs",
"xoi", "qkk", "vcg", "xob", "qkc", "vca", "mfA", "tFs", "wmy", "qvA", "mdk", "tEw", "wmj", "qtk", "vgw", "xqj", "hlA", "Ekk", "mcg", "tEb", "hkk", "qsg", "hkc", "EvA", "mhs", "tay", "hvA",
"Etk", "mgw", "taj", "htk", "qww", "vij", "hss", "Esg", "hsg", "Exs", "miy", "hxs", "Eww", "mij", "hww", "qyj", "hwi", "Eyy", "hyy", "Eyj", "hyj", "vFk", "xmw", "ytj", "qdA", "vEs", "xmi",
"qck", "vEg", "xmb", "qcc", "vEa", "qcE", "qcC", "mFk", "tCw", "wlj", "qhk", "mEs", "tCi", "gtA", "Eck", "vai", "tCb", "gsk", "Ecc", "mEa", "gsc", "qga", "mED", "EcC", "Ehk", "maw", "tDj",
"gxk", "Egs", "mai", "gws", "qii", "mab", "gwg", "Ega", "EgD", "Eiw", "mbj", "gyw", "Eii", "gyi", "Eib", "gyb", "gzj", "qFA", "vCs", "xli", "qEk", "vCg", "xlb", "qEc", "vCa", "qEE", "vCD",
"qEC", "qEB", "EFA", "mCs", "tBi", "ghA", "EEk", "mCg", "tBb", "ggk", "qag", "vDb", "ggc", "EEE", "mCD", "ggE", "qaD", "ggC", "Eas", "mDi", "gis", "Eag", "mDb", "gig", "qbb", "gia", "EaD",
"giD", "gji", "gjb", "qCk", "vBg", "xkr", "qCc", "vBa", "qCE", "vBD", "qCC", "qCB", "ECk", "mBg", "tAr", "gak", "ECc", "mBa", "gac", "qDa", "mBD", "gaE", "ECC", "gaC", "ECB", "EDg", "gbg",
"gba", "gbD", "vAq", "vAn", "qBB", "mAq", "EBE", "gDE", "gDC", "gDB", "lfA", "sps", "wey", "ldk", "sow", "ClA", "lcs", "soi", "Ckk", "lcg", "Ckc", "CkE", "CvA", "lhs", "sqy", "Ctk", "lgw",
"sqj", "Css", "lgi", "Csg", "Csa", "Cxs", "liy", "Cww", "lij", "Cwi", "Cyy", "Cyj", "tpk", "wuw", "yhj", "ndA", "tos", "wui", "nck", "tog", "wub", "ncc", "toa", "ncE", "toD", "lFk", "smw",
"wdj", "nhk", "lEs", "smi", "atA", "Cck", "tqi", "smb", "ask", "ngg", "lEa", "asc", "CcE", "asE", "Chk", "law", "snj", "axk", "Cgs", "trj", "aws", "nii", "lab", "awg", "Cga", "awa", "Ciw",
"lbj", "ayw", "Cii", "ayi", "Cib", "Cjj", "azj", "vpA", "xus", "yxi", "vok", "xug", "yxb", "voc", "xua", "voE", "xuD", "voC", "nFA", "tms", "wti", "rhA", "nEk", "xvi", "wtb", "rgk", "vqg",
"xvb", "rgc", "nEE", "tmD", "rgE", "vqD", "nEB", "CFA", "lCs", "sli", "ahA", "CEk", "lCg", "slb", "ixA", "agk", "nag", "tnb", "iwk", "rig", "vrb", "lCD", "iwc", "agE", "naD", "iwE", "CEB",
"Cas", "lDi", "ais", "Cag", "lDb", "iys", "aig", "nbb", "iyg", "rjb", "CaD", "aiD", "Cbi", "aji", "Cbb", "izi", "ajb", "vmk", "xtg", "ywr", "vmc", "xta", "vmE", "xtD", "vmC", "vmB", "nCk",
"tlg", "wsr", "rak", "nCc", "xtr", "rac", "vna", "tlD", "raE", "nCC", "raC", "nCB", "raB", "CCk", "lBg", "skr", "aak", "CCc", "lBa", "iik", "aac", "nDa", "lBD", "iic", "rba", "CCC", "iiE",
"aaC", "CCB", "aaB", "CDg", "lBr", "abg", "CDa", "ijg", "aba", "CDD", "ija", "abD", "CDr", "ijr", "vlc", "xsq", "vlE", "xsn", "vlC", "vlB", "nBc", "tkq", "rDc", "nBE", "tkn", "rDE", "vln",
"rDC", "nBB", "rDB", "CBc", "lAq", "aDc", "CBE", "lAn", "ibc", "aDE", "nBn", "ibE", "rDn", "CBB", "ibC", "aDB", "ibB", "aDq", "ibq", "ibn", "xsf", "vkl", "tkf", "nAm", "nAl", "CAo", "aBo",
"iDo", "CAl", "aBl", "kpk", "BdA", "kos", "Bck", "kog", "seb", "Bcc", "koa", "BcE", "koD", "Bhk", "kqw", "sfj", "Bgs", "kqi", "Bgg", "kqb", "Bga", "BgD", "Biw", "krj", "Bii", "Bib", "Bjj",
"lpA", "sus", "whi", "lok", "sug", "loc", "sua", "loE", "suD", "loC", "BFA", "kms", "sdi", "DhA", "BEk", "svi", "sdb", "Dgk", "lqg", "svb", "Dgc", "BEE", "kmD", "DgE", "lqD", "BEB", "Bas",
"kni", "Dis", "Bag", "knb", "Dig", "lrb", "Dia", "BaD", "Bbi", "Dji", "Bbb", "Djb", "tuk", "wxg", "yir", "tuc", "wxa", "tuE", "wxD", "tuC", "tuB", "lmk", "stg", "nqk", "lmc", "sta", "nqc",
"tva", "stD", "nqE", "lmC", "nqC", "lmB", "nqB", "BCk", "klg", "Dak", "BCc", "str", "bik", "Dac", "lna", "klD", "bic", "nra", "BCC", "biE", "DaC", "BCB", "DaB", "BDg", "klr", "Dbg", "BDa",
"bjg", "Dba", "BDD", "bja", "DbD", "BDr", "Dbr", "bjr", "xxc", "yyq", "xxE", "yyn", "xxC", "xxB", "ttc", "wwq", "vvc", "xxq", "wwn", "vvE", "xxn", "vvC", "ttB", "vvB", "llc", "ssq", "nnc",
"llE", "ssn", "rrc", "nnE", "ttn", "rrE", "vvn", "llB", "rrC", "nnB", "rrB", "BBc", "kkq", "DDc", "BBE", "kkn", "bbc", "DDE", "lln", "jjc", "bbE", "nnn", "BBB", "jjE", "rrn", "DDB", "jjC",
"BBq", "DDq", "BBn", "bbq", "DDn", "jjq", "bbn", "jjn", "xwo", "yyf", "xwm", "xwl", "tso", "wwf", "vto", "xwv", "vtm", "tsl", "vtl", "lko", "ssf", "nlo", "lkm", "rno", "nlm", "lkl", "rnm",
"nll", "rnl", "BAo", "kkf", "DBo", "lkv", "bDo", "DBm", "BAl", "jbo", "bDm", "DBl", "jbm", "bDl", "jbl", "DBv", "jbv", "xwd", "vsu", "vst", "nku", "rlu", "rlt", "DAu", "bBu", "jDu", "jDt",
"ApA", "Aok", "keg", "Aoc", "AoE", "AoC", "Aqs", "Aqg", "Aqa", "AqD", "Ari", "Arb", "kuk", "kuc", "sha", "kuE", "shD", "kuC", "kuB", "Amk", "kdg", "Bqk", "kvg", "kda", "Bqc", "kva", "BqE",
"kvD", "BqC", "AmB", "BqB", "Ang", "kdr", "Brg", "kvr", "Bra", "AnD", "BrD", "Anr", "Brr", "sxc", "sxE", "sxC", "sxB", "ktc", "lvc", "sxq", "sgn", "lvE", "sxn", "lvC", "ktB", "lvB", "Alc",
"Bnc", "AlE", "kcn", "Drc", "BnE", "AlC", "DrE", "BnC", "AlB", "DrC", "BnB", "Alq", "Bnq", "Aln", "Drq", "Bnn", "Drn", "wyo", "wym", "wyl", "swo", "txo", "wyv", "txm", "swl", "txl", "kso",
"sgf", "lto", "swv", "nvo", "ltm", "ksl", "nvm", "ltl", "nvl", "Ako", "kcf", "Blo", "ksv", "Dno", "Blm", "Akl", "bro", "Dnm", "Bll", "brm", "Dnl", "Akv", "Blv", "Dnv", "brv", "yze", "yzd",
"wye", "xyu", "wyd", "xyt", "swe", "twu", "swd", "vxu", "twt", "vxt", "kse", "lsu", "ksd", "ntu", "lst", "rvu", "ypk", "zew", "xdA", "yos", "zei", "xck", "yog", "zeb", "xcc", "yoa", "xcE",
"yoD", "xcC", "xhk", "yqw", "zfj", "utA", "xgs", "yqi", "usk", "xgg", "yqb", "usc", "xga", "usE", "xgD", "usC", "uxk", "xiw", "yrj", "ptA", "uws", "xii", "psk", "uwg", "xib", "psc", "uwa",
"psE", "uwD", "psC", "pxk", "uyw", "xjj", "ftA", "pws", "uyi", "fsk", "pwg", "uyb", "fsc", "pwa", "fsE", "pwD", "fxk", "pyw", "uzj", "fws", "pyi", "fwg", "pyb", "fwa", "fyw", "pzj", "fyi",
"fyb", "xFA", "yms", "zdi", "xEk", "ymg", "zdb", "xEc", "yma", "xEE", "ymD", "xEC", "xEB", "uhA", "xas", "yni", "ugk", "xag", "ynb", "ugc", "xaa", "ugE", "xaD", "ugC", "ugB", "oxA", "uis",
"xbi", "owk", "uig", "xbb", "owc", "uia", "owE", "uiD", "owC", "owB", "dxA", "oys", "uji", "dwk", "oyg", "ujb", "dwc", "oya", "dwE", "oyD", "dwC", "dys", "ozi", "dyg", "ozb", "dya", "dyD",
"dzi", "dzb", "xCk", "ylg", "zcr", "xCc", "yla", "xCE", "ylD", "xCC", "xCB", "uak", "xDg", "ylr", "uac", "xDa", "uaE", "xDD", "uaC", "uaB", "oik", "ubg", "xDr", "oic", "uba", "oiE", "ubD",
"oiC", "oiB", "cyk", "ojg", "ubr", "cyc", "oja", "cyE", "ojD", "cyC", "cyB", "czg", "ojr", "cza", "czD", "czr", "xBc", "ykq", "xBE", "ykn", "xBC", "xBB", "uDc", "xBq", "uDE", "xBn", "uDC",
"uDB", "obc", "uDq", "obE", "uDn", "obC", "obB", "cjc", "obq", "cjE", "obn", "cjC", "cjB", "cjq", "cjn", "xAo", "ykf", "xAm", "xAl", "uBo", "xAv", "uBm", "uBl", "oDo", "uBv", "oDm", "oDl",
"cbo", "oDv", "cbm", "cbl", "xAe", "xAd", "uAu", "uAt", "oBu", "oBt", "wpA", "yes", "zFi", "wok", "yeg", "zFb", "woc", "yea", "woE", "yeD", "woC", "woB", "thA", "wqs", "yfi", "tgk", "wqg",
"yfb", "tgc", "wqa", "tgE", "wqD", "tgC", "tgB", "mxA", "tis", "wri", "mwk", "tig", "wrb", "mwc", "tia", "mwE", "tiD", "mwC", "mwB", "FxA", "mys", "tji", "Fwk", "myg", "tjb", "Fwc", "mya",
"FwE", "myD", "FwC", "Fys", "mzi", "Fyg", "mzb", "Fya", "FyD", "Fzi", "Fzb", "yuk", "zhg", "hjs", "yuc", "zha", "hbw", "yuE", "zhD", "hDy", "yuC", "yuB", "wmk", "ydg", "zEr", "xqk", "wmc",
"zhr", "xqc", "yva", "ydD", "xqE", "wmC", "xqC", "wmB", "xqB", "tak", "wng", "ydr", "vik", "tac", "wna", "vic", "xra", "wnD", "viE", "taC", "viC", "taB", "viB", "mik", "tbg", "wnr", "qyk",
"mic", "tba", "qyc", "vja", "tbD", "qyE", "miC", "qyC", "miB", "qyB", "Eyk", "mjg", "tbr", "hyk", "Eyc", "mja", "hyc", "qza", "mjD", "hyE", "EyC", "hyC", "EyB", "Ezg", "mjr", "hzg", "Eza",
"hza", "EzD", "hzD", "Ezr", "ytc", "zgq", "grw", "ytE", "zgn", "gny", "ytC", "glz", "ytB", "wlc", "ycq", "xnc", "wlE", "ycn", "xnE", "ytn", "xnC", "wlB", "xnB", "tDc", "wlq", "vbc", "tDE",
"wln", "vbE", "xnn", "vbC", "tDB", "vbB", "mbc", "tDq", "qjc", "mbE", "tDn", "qjE", "vbn", "qjC", "mbB", "qjB", "Ejc", "mbq", "gzc", "EjE", "mbn", "gzE", "qjn", "gzC", "EjB", "gzB", "Ejq",
"gzq", "Ejn", "gzn", "yso", "zgf", "gfy", "ysm", "gdz", "ysl", "wko", "ycf", "xlo", "ysv", "xlm", "wkl", "xll", "tBo", "wkv", "vDo", "tBm", "vDm", "tBl", "vDl", "mDo", "tBv", "qbo", "vDv",
"qbm", "mDl", "qbl", "Ebo", "mDv", "gjo", "Ebm", "gjm", "Ebl", "gjl", "Ebv", "gjv", "yse", "gFz", "ysd", "wke", "xku", "wkd", "xkt", "tAu", "vBu", "tAt", "vBt", "mBu", "qDu", "mBt", "qDt",
"EDu", "gbu", "EDt", "gbt", "ysF", "wkF", "xkh", "tAh", "vAx", "mAx", "qBx", "wek", "yFg", "zCr", "wec", "yFa", "weE", "yFD", "weC", "weB", "sqk", "wfg", "yFr", "sqc", "wfa", "sqE", "wfD",
"sqC", "sqB", "lik", "srg", "wfr", "lic", "sra", "liE", "srD", "liC", "liB", "Cyk", "ljg", "srr", "Cyc", "lja", "CyE", "ljD", "CyC", "CyB", "Czg", "ljr", "Cza", "CzD", "Czr", "yhc", "zaq",
"arw", "yhE", "zan", "any", "yhC", "alz", "yhB", "wdc", "yEq", "wvc", "wdE", "yEn", "wvE", "yhn", "wvC", "wdB", "wvB", "snc", "wdq", "trc", "snE", "wdn", "trE", "wvn", "trC", "snB", "trB",
"lbc", "snq", "njc", "lbE", "snn", "njE", "trn", "njC", "lbB", "njB", "Cjc", "lbq", "azc", "CjE", "lbn", "azE", "njn", "azC", "CjB", "azB", "Cjq", "azq", "Cjn", "azn", "zio", "irs", "rfy",
"zim", "inw", "rdz", "zil", "ily", "ikz", "ygo", "zaf", "afy", "yxo", "ziv", "ivy", "adz", "yxm", "ygl", "itz", "yxl", "wco", "yEf", "wto", "wcm", "xvo", "yxv", "wcl", "xvm", "wtl", "xvl",
"slo", "wcv", "tno", "slm", "vro", "tnm", "sll", "vrm", "tnl", "vrl", "lDo", "slv", "nbo", "lDm", "rjo", "nbm", "lDl", "rjm", "nbl", "rjl", "Cbo", "lDv", "ajo", "Cbm", "izo", "ajm", "Cbl",
"izm", "ajl", "izl", "Cbv", "ajv", "zie", "ifw", "rFz", "zid", "idy", "icz", "yge", "aFz", "ywu", "ygd", "ihz", "ywt", "wce", "wsu", "wcd", "xtu", "wst", "xtt", "sku", "tlu", "skt", "vnu",
"tlt", "vnt", "lBu", "nDu", "lBt", "rbu", "nDt", "rbt", "CDu", "abu", "CDt", "iju", "abt", "ijt", "ziF", "iFy", "iEz", "ygF", "ywh", "wcF", "wsh", "xsx", "skh", "tkx", "vlx", "lAx", "nBx",
"rDx", "CBx", "aDx", "ibx", "iCz", "wFc", "yCq", "wFE", "yCn", "wFC", "wFB", "sfc", "wFq", "sfE", "wFn", "sfC", "sfB", "krc", "sfq", "krE", "sfn", "krC", "krB", "Bjc", "krq", "BjE", "krn",
"BjC", "BjB", "Bjq", "Bjn", "yao", "zDf", "Dfy", "yam", "Ddz", "yal", "wEo", "yCf", "who", "wEm", "whm", "wEl", "whl", "sdo", "wEv", "svo", "sdm", "svm", "sdl", "svl", "kno", "sdv", "lro",
"knm", "lrm", "knl", "lrl", "Bbo", "knv", "Djo", "Bbm", "Djm", "Bbl", "Djl", "Bbv", "Djv", "zbe", "bfw", "npz", "zbd", "bdy", "bcz", "yae", "DFz", "yiu", "yad", "bhz", "yit", "wEe", "wgu",
"wEd", "wxu", "wgt", "wxt", "scu", "stu", "sct", "tvu", "stt", "tvt", "klu", "lnu", "klt", "nru", "lnt", "nrt", "BDu", "Dbu", "BDt", "bju", "Dbt", "bjt", "jfs", "rpy", "jdw", "roz", "jcy",
"jcj", "zbF", "bFy", "zjh", "jhy", "bEz", "jgz", "yaF", "yih", "yyx", "wEF", "wgh", "wwx", "xxx", "sch", "ssx", "ttx", "vvx", "kkx", "llx", "nnx", "rrx", "BBx", "DDx", "bbx", "jFw", "rmz",
"jEy", "jEj", "bCz", "jaz", "jCy", "jCj", "jBj", "wCo", "wCm", "wCl", "sFo", "wCv", "sFm", "sFl", "kfo", "sFv", "kfm", "kfl", "Aro", "kfv", "Arm", "Arl", "Arv", "yDe", "Bpz", "yDd", "wCe",
"wau", "wCd", "wat", "sEu", "shu", "sEt", "sht", "kdu", "kvu", "kdt", "kvt", "Anu", "Bru", "Ant", "Brt", "zDp", "Dpy", "Doz", "yDF", "ybh", "wCF", "wah", "wix", "sEh", "sgx", "sxx", "kcx",
"ktx", "lvx", "Alx", "Bnx", "Drx", "bpw", "nuz", "boy", "boj", "Dmz", "bqz", "jps", "ruy", "jow", "ruj", "joi", "job", "bmy", "jqy", "bmj", "jqj", "jmw", "rtj", "jmi", "jmb", "blj", "jnj",
"jli", "jlb", "jkr", "sCu", "sCt", "kFu", "kFt", "Afu", "Aft", "wDh", "sCh", "sax", "kEx", "khx", "Adx", "Avx", "Buz", "Duy", "Duj", "buw", "nxj", "bui", "bub", "Dtj", "bvj", "jus", "rxi",
"jug", "rxb", "jua", "juD", "bti", "jvi", "btb", "jvb", "jtg", "rwr", "jta", "jtD", "bsr", "jtr", "jsq", "jsn", "Bxj", "Dxi", "Dxb", "bxg", "nyr", "bxa", "bxD", "Dwr", "bxr", "bwq", "bwn",
"pjk", "urw", "ejA", "pbs", "uny", "ebk", "pDw", "ulz", "eDs", "pBy", "eBw", "zfc", "fjk", "prw", "zfE", "fbs", "pny", "zfC", "fDw", "plz", "zfB", "fBy", "yrc", "zfq", "frw", "yrE", "zfn",
"fny", "yrC", "flz", "yrB", "xjc", "yrq", "xjE", "yrn", "xjC", "xjB", "uzc", "xjq", "uzE", "xjn", "uzC", "uzB", "pzc", "uzq", "pzE", "uzn", "pzC", "djA", "ors", "ufy", "dbk", "onw", "udz",
"dDs", "oly", "dBw", "okz", "dAy", "zdo", "drs", "ovy", "zdm", "dnw", "otz", "zdl", "dly", "dkz", "yno", "zdv", "dvy", "ynm", "dtz", "ynl", "xbo", "ynv", "xbm", "xbl", "ujo", "xbv", "ujm",
"ujl", "ozo", "ujv", "ozm", "ozl", "crk", "ofw", "uFz", "cns", "ody", "clw", "ocz", "cky", "ckj", "zcu", "cvw", "ohz", "zct", "cty", "csz", "ylu", "cxz", "ylt", "xDu", "xDt", "ubu", "ubt",
"oju", "ojt", "cfs", "oFy", "cdw", "oEz", "ccy", "ccj", "zch", "chy", "cgz", "ykx", "xBx", "uDx", "cFw", "oCz", "cEy", "cEj", "caz", "cCy", "cCj", "FjA", "mrs", "tfy", "Fbk", "mnw", "tdz",
"FDs", "mly", "FBw", "mkz", "FAy", "zFo", "Frs", "mvy", "zFm", "Fnw", "mtz", "zFl", "Fly", "Fkz", "yfo", "zFv", "Fvy", "yfm", "Ftz", "yfl", "wro", "yfv", "wrm", "wrl", "tjo", "wrv", "tjm",
"tjl", "mzo", "tjv", "mzm", "mzl", "qrk", "vfw", "xpz", "hbA", "qns", "vdy", "hDk", "qlw", "vcz", "hBs", "qky", "hAw", "qkj", "hAi", "Erk", "mfw", "tFz", "hrk", "Ens", "mdy", "hns", "qty",
"mcz", "hlw", "Eky", "hky", "Ekj", "hkj", "zEu", "Evw", "mhz", "zhu", "zEt", "hvw", "Ety", "zht", "hty", "Esz", "hsz", "ydu", "Exz", "yvu", "ydt", "hxz", "yvt", "wnu", "xru", "wnt", "xrt",
"tbu", "vju", "tbt", "vjt", "mju", "mjt", "grA", "qfs", "vFy", "gnk", "qdw", "vEz", "gls", "qcy", "gkw", "qcj", "gki", "gkb", "Efs", "mFy", "gvs", "Edw", "mEz", "gtw", "qgz", "gsy", "Ecj",
"gsj", "zEh", "Ehy", "zgx", "gxy", "Egz", "gwz", "ycx", "ytx", "wlx", "xnx", "tDx", "vbx", "mbx", "gfk", "qFw", "vCz", "gds", "qEy", "gcw", "qEj", "gci", "gcb", "EFw", "mCz", "ghw", "EEy",
"ggy", "EEj", "ggj", "Eaz", "giz", "gFs", "qCy", "gEw", "qCj", "gEi", "gEb", "ECy", "gay", "ECj", "gaj", "gCw", "qBj", "gCi", "gCb", "EBj", "gDj", "gBi", "gBb", "Crk", "lfw", "spz", "Cns",
"ldy", "Clw", "lcz", "Cky", "Ckj", "zCu", "Cvw", "lhz", "zCt", "Cty", "Csz", "yFu", "Cxz", "yFt", "wfu", "wft", "sru", "srt", "lju", "ljt", "arA", "nfs", "tpy", "ank", "ndw", "toz", "als",
"ncy", "akw", "ncj", "aki", "akb", "Cfs", "lFy", "avs", "Cdw", "lEz", "atw", "ngz", "asy", "Ccj", "asj", "zCh", "Chy", "zax", "axy", "Cgz", "awz", "yEx", "yhx", "wdx", "wvx", "snx", "trx",
"lbx", "rfk", "vpw", "xuz", "inA", "rds", "voy", "ilk", "rcw", "voj", "iks", "rci", "ikg", "rcb", "ika", "afk", "nFw", "tmz", "ivk", "ads", "nEy", "its", "rgy", "nEj", "isw", "aci", "isi",
"acb", "isb", "CFw", "lCz", "ahw", "CEy", "ixw", "agy", "CEj", "iwy", "agj", "iwj", "Caz", "aiz", "iyz", "ifA", "rFs", "vmy", "idk", "rEw", "vmj", "ics", "rEi", "icg", "rEb", "ica", "icD",
"aFs", "nCy", "ihs", "aEw", "nCj", "igw", "raj", "igi", "aEb", "igb", "CCy", "aay", "CCj", "iiy", "aaj", "iij", "iFk", "rCw", "vlj", "iEs", "rCi", "iEg", "rCb", "iEa", "iED", "aCw", "nBj",
"iaw", "aCi", "iai", "aCb", "iab", "CBj", "aDj", "ibj", "iCs", "rBi", "iCg", "rBb", "iCa", "iCD", "aBi", "iDi", "aBb", "iDb", "iBg", "rAr", "iBa", "iBD", "aAr", "iBr", "iAq", "iAn", "Bfs",
"kpy", "Bdw", "koz", "Bcy", "Bcj", "Bhy", "Bgz", "yCx", "wFx", "sfx", "krx", "Dfk", "lpw", "suz", "Dds", "loy", "Dcw", "loj", "Dci", "Dcb", "BFw", "kmz", "Dhw", "BEy", "Dgy", "BEj", "Dgj",
"Baz", "Diz", "bfA", "nps", "tuy", "bdk", "now", "tuj", "bcs", "noi", "bcg", "nob", "bca", "bcD", "DFs", "lmy", "bhs", "DEw", "lmj", "bgw", "DEi", "bgi", "DEb", "bgb", "BCy", "Day", "BCj",
"biy", "Daj", "bij", "rpk", "vuw", "xxj", "jdA", "ros", "vui", "jck", "rog", "vub", "jcc", "roa", "jcE", "roD", "jcC", "bFk", "nmw", "ttj", "jhk", "bEs", "nmi", "jgs", "rqi", "nmb", "jgg",
"bEa", "jga", "bED", "jgD", "DCw", "llj", "baw", "DCi", "jiw", "bai", "DCb", "jii", "bab", "jib", "BBj", "DDj", "bbj", "jjj", "jFA", "rms", "vti", "jEk", "rmg", "vtb", "jEc", "rma", "jEE",
"rmD", "jEC", "jEB", "bCs", "nli", "jas", "bCg", "nlb", "jag", "rnb", "jaa", "bCD", "jaD", "DBi", "bDi", "DBb", "jbi", "bDb", "jbb", "jCk", "rlg", "vsr", "jCc", "rla", "jCE", "rlD", "jCC",
"jCB", "bBg", "nkr", "jDg", "bBa", "jDa", "bBD", "jDD", "DAr", "bBr", "jDr", "jBc", "rkq", "jBE", "rkn", "jBC", "jBB", "bAq", "jBq", "bAn", "jBn", "jAo", "rkf", "jAm", "jAl", "bAf", "jAv",
"Apw", "kez", "Aoy", "Aoj", "Aqz", "Bps", "kuy", "Bow", "kuj", "Boi", "Bob", "Amy", "Bqy", "Amj", "Bqj", "Dpk", "luw", "sxj", "Dos", "lui", "Dog", "lub", "Doa", "DoD", "Bmw", "ktj", "Dqw",
"Bmi", "Dqi", "Bmb", "Dqb", "Alj", "Bnj", "Drj", "bpA", "nus", "txi", "bok", "nug", "txb", "boc", "nua", "boE", "nuD", "boC", "boB", "Dms", "lti", "bqs", "Dmg", "ltb", "bqg", "nvb", "bqa",
"DmD", "bqD", "Bli", "Dni", "Blb", "bri", "Dnb", "brb", "ruk", "vxg", "xyr", "ruc", "vxa", "ruE", "vxD", "ruC", "ruB", "bmk", "ntg", "twr", "jqk", "bmc", "nta", "jqc", "rva", "ntD", "jqE",
"bmC", "jqC", "bmB", "jqB", "Dlg", "lsr", "bng", "Dla", "jrg", "bna", "DlD", "jra", "bnD", "jrD", "Bkr", "Dlr", "bnr", "jrr", "rtc", "vwq", "rtE", "vwn", "rtC", "rtB", "blc", "nsq", "jnc",
"blE", "nsn", "jnE", "rtn", "jnC", "blB", "jnB", "Dkq", "blq", "Dkn", "jnq", "bln", "jnn", "rso", "vwf", "rsm", "rsl", "bko", "nsf", "jlo", "bkm", "jlm", "bkl", "jll", "Dkf", "bkv", "jlv",
"rse", "rsd", "bke", "jku", "bkd", "jkt", "Aey", "Aej", "Auw", "khj", "Aui", "Aub", "Adj", "Avj", "Bus", "kxi", "Bug", "kxb", "Bua", "BuD", "Ati", "Bvi", "Atb", "Bvb", "Duk", "lxg", "syr",
"Duc", "lxa", "DuE", "lxD", "DuC", "DuB", "Btg", "kwr", "Dvg", "lxr", "Dva", "BtD", "DvD", "Asr", "Btr", "Dvr", "nxc", "tyq", "nxE", "tyn", "nxC", "nxB", "Dtc", "lwq", "bvc", "nxq", "lwn",
"bvE", "DtC", "bvC", "DtB", "bvB", "Bsq", "Dtq", "Bsn", "bvq", "Dtn", "bvn", "vyo", "xzf", "vym", "vyl", "nwo", "tyf", "rxo", "nwm", "rxm", "nwl", "rxl", "Dso", "lwf", "bto", "Dsm", "jvo",
"btm", "Dsl", "jvm", "btl", "jvl", "Bsf", "Dsv", "btv", "jvv", "vye", "vyd", "nwe", "rwu", "nwd", "rwt", "Dse", "bsu", "Dsd", "jtu", "bst", "jtt", "vyF", "nwF", "rwh", "DsF", "bsh", "jsx",
"Ahi", "Ahb", "Axg", "kir", "Axa", "AxD", "Agr", "Axr", "Bxc", "kyq", "BxE", "kyn", "BxC", "BxB", "Awq", "Bxq", "Awn", "Bxn", "lyo", "szf", "lym", "lyl", "Bwo", "kyf", "Dxo", "lyv", "Dxm",
"Bwl", "Dxl", "Awf", "Bwv", "Dxv", "tze", "tzd", "lye", "nyu", "lyd", "nyt", "Bwe", "Dwu", "Bwd", "bxu", "Dwt", "bxt", "tzF", "lyF", "nyh", "BwF", "Dwh", "bwx", "Aiq", "Ain", "Ayo", "kjf",
"Aym", "Ayl", "Aif", "Ayv", "kze", "kzd", "Aye", "Byu", "Ayd", "Byt", "szp" };
 
private static final char[] BR_SET = { 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z', '*', '+', '-' };
 
private static final String[] PDF_TTF = { "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000",
"10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111", "01", "1111111101010100", "11111101000101001" };
 
/* Left and Right Row Address Pattern from Table 2 */
private static final String[] RAPLR = { "", "221311", "311311", "312211", "222211", "213211", "214111", "223111", "313111", "322111", "412111", "421111", "331111", "241111", "232111", "231211",
"321211", "411211", "411121", "411112", "321112", "312112", "311212", "311221", "311131", "311122", "311113", "221113", "221122", "221131", "221221", "222121", "312121", "321121",
"231121", "231112", "222112", "213112", "212212", "212221", "212131", "212122", "212113", "211213", "211123", "211132", "211141", "211231", "211222", "211312", "211321", "211411",
"212311" };
 
/* Centre Row Address Pattern from Table 2 */
private static final String[] RAPC = { "", "112231", "121231", "122131", "131131", "131221", "132121", "141121", "141211", "142111", "133111", "132211", "131311", "122311", "123211", "124111",
"115111", "114211", "114121", "123121", "123112", "122212", "122221", "121321", "121411", "112411", "113311", "113221", "113212", "113122", "122122", "131122", "131113", "122113",
"113113", "112213", "112222", "112312", "112321", "111421", "111331", "111322", "111232", "111223", "111133", "111124", "111214", "112114", "121114", "121123", "121132", "112132",
"112141" };
 
private static final int[] MICRO_VARIANTS = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23,
26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 11, 13, 15, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, 8, 12, 14, 16, 18, 21,
26, 32, 38, 44, 50, 0, 0, 0, 7, 7, 7, 7, 15, 15, 24, 34, 57, 84, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294, 7, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294 };
 
/* rows, columns, error codewords, k-offset */
/* MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F */
private static final int[] MICROCOEFFS = {
/* k = 7 */
76, 925, 537, 597, 784, 691, 437,
/* k = 8 */
237, 308, 436, 284, 646, 653, 428, 379,
/* k = 9 */
567, 527, 622, 257, 289, 362, 501, 441, 205,
/* k = 10 */
377, 457, 64, 244, 826, 841, 818, 691, 266, 612,
/* k = 11 */
462, 45, 565, 708, 825, 213, 15, 68, 327, 602, 904,
/* k = 12 */
597, 864, 757, 201, 646, 684, 347, 127, 388, 7, 69, 851,
/* k = 13 */
764, 713, 342, 384, 606, 583, 322, 592, 678, 204, 184, 394, 692,
/* k = 14 */
669, 677, 154, 187, 241, 286, 274, 354, 478, 915, 691, 833, 105, 215,
/* k = 15 */
460, 829, 476, 109, 904, 664, 230, 5, 80, 74, 550, 575, 147, 868, 642,
/* k = 16 */
274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65,
/* k = 18 */
279, 577, 315, 624, 37, 855, 275, 739, 120, 297, 312, 202, 560, 321, 233, 756, 760, 573,
/* k = 21 */
108, 519, 781, 534, 129, 425, 681, 553, 422, 716, 763, 693, 624, 610, 310, 691, 347, 165, 193, 259, 568,
/* k = 26 */
443, 284, 887, 544, 788, 93, 477, 760, 331, 608, 269, 121, 159, 830, 446, 893, 699, 245, 441, 454, 325, 858, 131, 847, 764, 169,
/* k = 32 */
361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410,
/* k = 38 */
234, 228, 438, 848, 133, 703, 529, 721, 788, 322, 280, 159, 738, 586, 388, 684, 445, 680, 245, 595, 614, 233, 812, 32, 284, 658, 745, 229, 95, 689, 920, 771, 554, 289, 231, 125, 117, 518,
/* k = 44 */
476, 36, 659, 848, 678, 64, 764, 840, 157, 915, 470, 876, 109, 25, 632, 405, 417, 436, 714, 60, 376, 97, 413, 706, 446, 21, 3, 773, 569, 267, 272, 213, 31, 560, 231, 758, 103, 271, 572,
436, 339, 730, 82, 285,
/* k = 50 */
923, 797, 576, 875, 156, 706, 63, 81, 257, 874, 411, 416, 778, 50, 205, 303, 188, 535, 909, 155, 637, 230, 534, 96, 575, 102, 264, 233, 919, 593, 865, 26, 579, 623, 766, 146, 10, 739, 246,
127, 71, 244, 211, 477, 920, 876, 427, 820, 718, 435 };
 
/*
* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24728:2006 tables
* 10, 11 and 12
*/
private static final int[] RAP_TABLE = { 1, 8, 36, 19, 9, 25, 1, 1, 8, 36, 19, 9, 27, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 47, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 9, 8, 36, 19, 17, 33, 1, 9, 8, 36, 19, 17, 35, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, 43, 1, 7, 15, 25, 37,
33, 17, 37, 47, 49, 0, 3, 6, 0, 6, 0, 0, 0, 3, 6, 0, 6, 6, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0, 3, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0 };
 
private String binary_string;
private int ecc;
private LinearEncoding symbology = LinearEncoding.CODE_128;
private String general_field;
private GeneralFieldMode[] general_field_type;
private int cc_width;
private final int[][] pwr928 = new int[69][7];
private final int[] codeWords = new int[180];
private int codeWordCount;
private final int[] bitStr = new int[13];
private int[] inputData;
private CompositeMode cc_mode;
private String linearContent;
private CompositeMode userPreferredMode = CompositeMode.CC_A;
private int target_bitsize;
private int remainder;
private int linearWidth; // Width of Code 128 linear
 
public Composite() {
this.inputDataType = Symbol.DataType.GS1;
}
 
@Override
public void setDataType(final DataType dataType) {
if (dataType != Symbol.DataType.GS1) {
throw new IllegalArgumentException("Only GS1 data type is supported for GS1 Composite symbology.");
}
}
 
@Override
protected boolean gs1Supported() {
return true;
}
 
/**
* Set the type of linear component included in the composite symbol, this will determine how
* the lower part of the symbol is encoded.
*
* @param linearSymbology The symbology of the linear component
*/
public void setSymbology(final LinearEncoding linearSymbology) {
this.symbology = linearSymbology;
}
 
/**
* Returns the type of linear component included in the composite symbol.
*
* @return the type of linear component included in the composite symbol
*/
public LinearEncoding getSymbology() {
return this.symbology;
}
 
/**
* Set the data to be encoded in the linear component of the composite symbol.
*
* @param linearContent the linear data in GS1 format
*/
public void setLinearContent(final String linearContent) {
this.linearContent = linearContent;
}
 
/**
* Returns the data encoded in the linear component of the composite symbol.
*
* @return the data encoded in the linear component of the composite symbol
*/
public String getLinearContent() {
return this.linearContent;
}
 
/**
* Set the preferred encoding method for the 2D component of the composite symbol. This value
* may be ignored if the amount of data supplied is too big for the selected encoding. Mode CC-C
* can only be used with a Code 128 linear component.
*
* @param userMode Preferred mode
*/
public void setPreferredMode(final CompositeMode userMode) {
this.userPreferredMode = userMode;
}
 
/**
* Returns the preferred encoding method for the 2D component of the composite symbol.
*
* @return the preferred encoding method for the 2D component of the composite symbol
*/
public CompositeMode getPreferredMode() {
return this.userPreferredMode;
}
 
@Override
protected void encode() {
 
List<Rectangle2D.Double> linear_rect;
List<TextBox> linear_txt;
final List<Rectangle2D.Double> combine_rect = new ArrayList<>();
final List<TextBox> combine_txt = new ArrayList<>();
String linear_encodeInfo;
int linear_height;
int top_shift = 0; // 2D component x-coordinate shift
int bottom_shift = 0; // linear component x-coordinate shift
this.linearWidth = 0;
 
if (this.linearContent.isEmpty()) {
throw new OkapiException("No linear data set");
}
 
// Manage composite component encoding first
encodeComposite();
 
// Then encode linear component
switch (this.symbology) {
case UPCA:
final Upc upca = new Upc();
upca.setMode(Upc.Mode.UPCA);
upca.setLinkageFlag(true);
upca.setContent(this.linearContent);
linear_rect = upca.rectangles;
linear_txt = upca.texts;
linear_height = upca.symbol_height;
linear_encodeInfo = upca.getEncodeInfo();
bottom_shift = 6;
top_shift = 3;
break;
case UPCE:
final Upc upce = new Upc();
upce.setMode(Upc.Mode.UPCE);
upce.setLinkageFlag(true);
upce.setContent(this.linearContent);
linear_rect = upce.rectangles;
linear_txt = upce.texts;
linear_height = upce.symbol_height;
linear_encodeInfo = upce.getEncodeInfo();
bottom_shift = 6;
top_shift = 3;
break;
case EAN:
final Ean ean = new Ean();
if (eanCalculateVersion() == 8) {
ean.setMode(Ean.Mode.EAN8);
bottom_shift = 14;
} else {
ean.setMode(Ean.Mode.EAN13);
bottom_shift = 6;
top_shift = 3;
}
ean.setLinkageFlag(true);
ean.setContent(this.linearContent);
linear_rect = ean.rectangles;
linear_txt = ean.texts;
linear_height = ean.symbol_height;
linear_encodeInfo = ean.getEncodeInfo();
break;
case CODE_128:
final Code128 code128 = new Code128();
switch (this.cc_mode) {
case CC_A:
code128.setCca();
break;
case CC_B:
code128.setCcb();
break;
case CC_C:
code128.setCcc();
bottom_shift = 7;
break;
}
code128.setDataType(Symbol.DataType.GS1);
code128.setContent(this.linearContent);
this.linearWidth = code128.symbol_width;
linear_rect = code128.rectangles;
linear_txt = code128.texts;
linear_height = code128.symbol_height;
linear_encodeInfo = code128.getEncodeInfo();
break;
case DATABAR_14:
final DataBar14 dataBar14 = new DataBar14();
dataBar14.setLinkageFlag(true);
dataBar14.setMode(Mode.LINEAR);
dataBar14.setContent(this.linearContent);
linear_rect = dataBar14.rectangles;
linear_txt = dataBar14.texts;
linear_height = dataBar14.symbol_height;
linear_encodeInfo = dataBar14.getEncodeInfo();
bottom_shift = 4;
break;
case DATABAR_14_STACK_OMNI:
final DataBar14 dataBar14SO = new DataBar14();
dataBar14SO.setLinkageFlag(true);
dataBar14SO.setMode(Mode.OMNI);
dataBar14SO.setContent(this.linearContent);
linear_rect = dataBar14SO.rectangles;
linear_txt = dataBar14SO.texts;
linear_height = dataBar14SO.symbol_height;
linear_encodeInfo = dataBar14SO.getEncodeInfo();
top_shift = 1;
break;
case DATABAR_14_STACK:
final DataBar14 dataBar14S = new DataBar14();
dataBar14S.setLinkageFlag(true);
dataBar14S.setMode(Mode.STACKED);
dataBar14S.setContent(this.linearContent);
linear_rect = dataBar14S.rectangles;
linear_txt = dataBar14S.texts;
linear_height = dataBar14S.symbol_height;
linear_encodeInfo = dataBar14S.getEncodeInfo();
top_shift = 1;
break;
case DATABAR_LIMITED:
final DataBarLimited dataBarLimited = new DataBarLimited();
dataBarLimited.setLinkageFlag();
dataBarLimited.setContent(this.linearContent);
linear_rect = dataBarLimited.rectangles;
linear_txt = dataBarLimited.texts;
linear_height = dataBarLimited.symbol_height;
linear_encodeInfo = dataBarLimited.getEncodeInfo();
top_shift = 1;
bottom_shift = 10;
break;
case DATABAR_EXPANDED:
final DataBarExpanded dataBarExpanded = new DataBarExpanded();
dataBarExpanded.setLinkageFlag(true);
dataBarExpanded.setStacked(false);
dataBarExpanded.setContent(this.linearContent);
linear_rect = dataBarExpanded.rectangles;
linear_txt = dataBarExpanded.texts;
linear_height = dataBarExpanded.symbol_height;
linear_encodeInfo = dataBarExpanded.getEncodeInfo();
top_shift = 2;
break;
case DATABAR_EXPANDED_STACK:
final DataBarExpanded dataBarExpandedS = new DataBarExpanded();
dataBarExpandedS.setLinkageFlag(true);
dataBarExpandedS.setStacked(true);
dataBarExpandedS.setContent(this.linearContent);
linear_rect = dataBarExpandedS.rectangles;
linear_txt = dataBarExpandedS.texts;
linear_height = dataBarExpandedS.symbol_height;
linear_encodeInfo = dataBarExpandedS.getEncodeInfo();
top_shift = 2;
break;
default:
throw new OkapiException("Linear symbol not recognised");
}
 
if (this.cc_mode == CompositeMode.CC_C && this.symbology == LinearEncoding.CODE_128) {
/*
* Width of composite component depends on width of linear component, so recalculate.
*/
this.row_count = 0;
this.rectangles.clear();
this.symbol_height = 0;
this.symbol_width = 0;
this.encodeInfo.setLength(0);
encodeComposite();
}
 
if (this.cc_mode != CompositeMode.CC_C && this.symbology == LinearEncoding.CODE_128) {
if (this.linearWidth > this.symbol_width) {
top_shift = (this.linearWidth - this.symbol_width) / 2;
}
}
 
for (final Rectangle2D.Double orig : this.rectangles) {
combine_rect.add(new Rectangle2D.Double(orig.x + top_shift, orig.y, orig.width, orig.height));
}
 
for (final Rectangle2D.Double orig : linear_rect) {
combine_rect.add(new Rectangle2D.Double(orig.x + bottom_shift, orig.y + this.symbol_height, orig.width, orig.height));
}
 
int max_x = 0;
for (final Rectangle2D.Double rect : combine_rect) {
if (rect.x + rect.width > max_x) {
max_x = (int) Math.ceil(rect.x + rect.width);
}
}
 
for (final TextBox orig : linear_txt) {
combine_txt.add(new TextBox(orig.x + bottom_shift, orig.y + this.symbol_height, orig.width, orig.text, this.humanReadableAlignment));
}
 
this.rectangles = combine_rect;
this.texts = combine_txt;
this.symbol_height += linear_height;
this.symbol_width = max_x;
info(linear_encodeInfo);
}
 
private void encodeComposite() {
 
if (this.content.length() > 2990) {
throw new OkapiException("2D component input data too long");
}
 
this.cc_mode = this.userPreferredMode;
 
if (this.cc_mode == CompositeMode.CC_C && this.symbology != LinearEncoding.CODE_128) {
/* CC-C can only be used with a GS1-128 linear part */
throw new OkapiException("Invalid mode (CC-C only valid with GS1-128 linear component)");