OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Compare Revisions

Regard whitespace Rev 73 → Rev 74

/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ClickableLabel.java
New file
0,0 → 1,72
package org.openconcerto.modules.extensionbuilder;
 
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
 
import javax.swing.JLabel;
 
public class ClickableLabel extends JLabel implements MouseListener, MouseMotionListener {
 
private Runnable runnable;
private boolean mouseOver;
 
public ClickableLabel(String text, final Runnable r) {
super(text);
this.runnable = r;
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.setForeground(Color.BLUE);
}
 
public void paint(Graphics g) {
super.paint(g);
if (mouseOver) {
Rectangle r = g.getClipBounds();
final int y1 = r.height - getFontMetrics(getFont()).getDescent() + 1;
g.drawLine(0, y1, getFontMetrics(getFont()).stringWidth(getText()), y1);
}
}
 
@Override
public void mouseClicked(MouseEvent e) {
if (this.runnable != null) {
this.runnable.run();
}
}
 
@Override
public void mousePressed(MouseEvent e) {
 
}
 
@Override
public void mouseReleased(MouseEvent e) {
}
 
@Override
public void mouseEntered(MouseEvent e) {
this.mouseOver = true;
this.setCursor(new Cursor(Cursor.HAND_CURSOR));
repaint();
}
 
@Override
public void mouseExited(MouseEvent e) {
this.mouseOver = false;
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
repaint();
}
 
@Override
public void mouseDragged(MouseEvent e) {
}
 
@Override
public void mouseMoved(MouseEvent e) {
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/started.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/started.png
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/Extension.java
New file
0,0 → 1,1389
package org.openconcerto.modules.extensionbuilder;
 
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Log;
import org.openconcerto.erp.config.MenuAndActions;
import org.openconcerto.erp.config.MenuManager;
import org.openconcerto.erp.modules.MenuContext;
import org.openconcerto.modules.extensionbuilder.component.ComponentDescritor;
import org.openconcerto.modules.extensionbuilder.list.ColumnDescriptor;
import org.openconcerto.modules.extensionbuilder.list.ListDescriptor;
import org.openconcerto.modules.extensionbuilder.menu.mainmenu.MenuDescriptor;
import org.openconcerto.modules.extensionbuilder.meu.actions.ActionDescriptor;
import org.openconcerto.modules.extensionbuilder.table.AllTableListModel;
import org.openconcerto.modules.extensionbuilder.table.ElementDescriptor;
import org.openconcerto.modules.extensionbuilder.table.FieldDescriptor;
import org.openconcerto.modules.extensionbuilder.table.TableDescritor;
import org.openconcerto.modules.extensionbuilder.translation.Translation;
import org.openconcerto.modules.extensionbuilder.translation.action.ActionTranslation;
import org.openconcerto.modules.extensionbuilder.translation.field.FieldTranslation;
import org.openconcerto.modules.extensionbuilder.translation.field.TableTranslation;
import org.openconcerto.modules.extensionbuilder.translation.menu.MenuTranslation;
import org.openconcerto.sql.element.GroupSQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.FieldPath;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLName;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.graph.Path;
import org.openconcerto.sql.request.ListSQLRequest;
import org.openconcerto.sql.utils.AlterTable;
import org.openconcerto.sql.utils.ChangeTable;
import org.openconcerto.sql.utils.SQLCreateTable;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.sql.view.IListFrame;
import org.openconcerto.sql.view.ListeAddPanel;
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.SQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
import org.openconcerto.ui.group.LayoutHints;
import org.openconcerto.ui.group.modifier.AddGroupModifier;
import org.openconcerto.ui.group.modifier.AddItemModifier;
import org.openconcerto.ui.group.modifier.MoveToGroupModifier;
import org.openconcerto.utils.CollectionUtils;
 
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>();
 
// Listeners
private List<ChangeListener> listeners = new ArrayList<ChangeListener>();
 
private String name;
private boolean notSaved;
private boolean autoStart;
private boolean isStarted;
 
public Extension(String name) {
this.name = name;
this.notSaved = true;
}
 
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();
 
notSaved = true;
autoStart = false;
isStarted = false;
 
}
 
boolean isStarted() {
return this.isStarted;
}
 
public boolean isAutoStart() {
return autoStart;
}
 
public void start(DBRoot root) throws SQLException {
 
// Ensure that database is configured
boolean databaseOk = setupDatabase(root);
if (!databaseOk) {
Log.get().severe("Extension " + this.getName() + " not started due to database error");
return;
}
// Register translations
 
// Create menus
setupMenu();
Log.get().info("Extension " + this.getName() + " started");
this.isStarted = true;
this.autoStart = true;
fireChanged();
}
 
private void setupMenu() {
// register actions
for (final MenuDescriptor element : getCreateMenuList()) {
if (element.getType().equals(MenuDescriptor.CREATE)) {
MenuManager.getInstance().registerAction(element.getId(), new CreateFrameAbstractAction() {
 
@Override
public JFrame createFrame() {
 
JFrame editFrame = new JFrame();
String componentId = element.getComponentId();
ComponentDescritor n = getCreateComponentFromId(componentId);
final SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(n.getTable());
if (t == null) {
throw new IllegalStateException("No table " + n.getTable());
}
final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
 
final GroupSQLComponent gComponent = new GroupSQLComponent(element, n.getGroup());
editFrame.setTitle(EditFrame.getCreateMessage(element));
editFrame.setContentPane(new EditPanel(gComponent, EditMode.CREATION));
editFrame.pack();
 
return editFrame;
 
}
});
 
} else if (element.getType().equals(MenuDescriptor.LIST)) {
MenuManager.getInstance().registerAction(element.getId(), new CreateFrameAbstractAction() {
 
@Override
public JFrame createFrame() {
final String componentId = element.getListId();
final ListDescriptor listDesc = getCreateListFromId(componentId);
if (listDesc == null) {
throw new IllegalStateException("No ListDescriptor " + componentId);
}
final SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(listDesc.getMainTable());
if (t == null) {
throw new IllegalStateException("No table " + listDesc.getMainTable());
}
final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
final ListSQLRequest req = new ListSQLRequest(element.getTable(), Collections.EMPTY_LIST);
final SQLTableModelSourceOnline source = new SQLTableModelSourceOnline(req);
final List<SQLTableModelColumn> cols = new ArrayList<SQLTableModelColumn>();
for (ColumnDescriptor cDesc : listDesc.getColumns()) {
final String fieldspath = cDesc.getFieldsPaths();
final String[] paths = fieldspath.split(",");
final Set<FieldPath> fps = new LinkedHashSet<FieldPath>();
for (int i = 0; i < paths.length; i++) {
// LOCAL, id_batiment.id_site.nom
final SQLName name = SQLName.parse(paths[i].trim());
final Path p = new Path(element.getTable());
final int stop = name.getItemCount() - 1;
for (int j = 0; j < stop; j++) {
String it = name.getItem(j);
p.addForeignField(it);
}
final FieldPath fp = new FieldPath(p, name.getName());
fps.add(fp);
 
}
cols.add(new BaseSQLTableModelColumn(cDesc.getId(), String.class) {
 
@Override
protected Object show_(SQLRowAccessor r) {
final List<String> l = new ArrayList<String>();
for (final FieldPath fp : fps) {
final String string = fp.getString((SQLRowValues) r);
if (string != null)
l.add(string);
}
return CollectionUtils.join(l, " ");
}
 
@Override
public Set<FieldPath> getPaths() {
return fps;
}
});
 
}
 
source.getColumns().addAll(cols);
 
final IListe list = new IListe(source);
final IListFrame editFrame = new IListFrame(new ListeAddPanel(element, list));
editFrame.pack();
return editFrame;
 
}
});
} else if (element.getType().equals(MenuDescriptor.LIST)) {
// No action to register
} else {
Log.get().warning("unknown type " + element.getType());
}
}
 
final MenuAndActions copy = MenuManager.getInstance().copyMenuAndActions();
// create group
final Group group = copy.getGroup();
initMenuGroup(group);
MenuManager.getInstance().setMenuAndActions(copy);
 
}
 
public void initMenuGroup(final Group group) {
for (MenuDescriptor element : getCreateMenuList()) {
if (element.getType().equals(MenuDescriptor.GROUP)) {
AddGroupModifier add = new AddGroupModifier(element.getId());
if (group.getDescFromID(element.getId()) == null) {
// only add if not exists
add.applyOn(group);
}
String menuId = element.getInsertInMenu();
Group dest = (Group) group.getDescFromID(menuId);
if (dest != null) {
MoveToGroupModifier mode = new MoveToGroupModifier(element.getId(), dest);
mode.applyOn(group);
} else {
Log.get().severe("No group " + menuId + " found to move item " + element.getId());
}
}
}
// create items
for (MenuDescriptor element : getCreateMenuList()) {
if (!element.getType().equals(MenuDescriptor.GROUP)) {
AddItemModifier add = new AddItemModifier(element.getId());
if (group.getDescFromID(element.getId()) == null) {
// only add if not exists
add.applyOn(group);
}
 
String menuId = element.getInsertInMenu();
Group dest = (Group) group.getDescFromID(menuId);
if (dest != null) {
MoveToGroupModifier mode = new MoveToGroupModifier(element.getId(), dest);
mode.applyOn(group);
} else {
Log.get().severe("No group " + menuId + " found to move group " + element.getId());
}
}
}
for (MenuDescriptor element : getRemoveMenuList()) {
String eId = element.getId();
Item item = group.getDescFromID(eId);
if (item != null) {
item.setLocalHint(item.getLocalHint().getBuilder().setVisible(false).build());
} else {
Log.get().severe("No Item " + eId + " found in group " + group.getId());
}
}
System.err.println("Extension.initMenuGroup()" + group.printTree());
 
}
 
public ComponentDescritor getCreateComponentFromId(String id) {
for (ComponentDescritor menuDescriptor : this.createComponentList) {
if (menuDescriptor.getId().equals(id)) {
return menuDescriptor;
}
}
return null;
}
 
private boolean setupDatabase(DBRoot root) throws SQLException {
List<ChangeTable<?>> changesToApply = new ArrayList<ChangeTable<?>>();
List<SQLCreateTable> createToApply = new ArrayList<SQLCreateTable>();
// Create fields and tables if needed
final List<TableDescritor> t = new ArrayList<TableDescritor>();
t.addAll(this.createTableList);
t.addAll(this.modifyTableList);
Set<String> tableNames = new HashSet<String>();
for (TableDescritor tDesc : t) {
String tableName = tDesc.getName();
tableNames.add(tableName);
final SQLTable table = root.getTable(tableName);
final ChangeTable<?> createTable;
if (table == null) {
createTable = new SQLCreateTable(root, tableName);
createToApply.add((SQLCreateTable) createTable);
} else {
createTable = new AlterTable(table);
 
}
// fields creation
boolean mustAdd = false;
for (FieldDescriptor fDesc : tDesc.getFields()) {
final SQLField f = (table == null) ? null : table.getFieldRaw(fDesc.getName());
if (f == null) {
final String type = fDesc.getType();
if (type.equals(FieldDescriptor.TYPE_STRING)) {
int l = 256;
try {
l = Integer.parseInt(fDesc.getLength());
} catch (Exception e) {
Log.get().log(Level.WARNING, "Extension: unable to parse length: " + fDesc.getLength(), e);
}
createTable.addVarCharColumn(fDesc.getName(), l);
} else if (type.equals(FieldDescriptor.TYPE_INTEGER)) {
int defaultVal = 0;
try {
defaultVal = Integer.parseInt(fDesc.getDefaultValue());
} catch (Exception e) {
Log.get().log(Level.WARNING, "Extension: unable to parse default integer value : " + fDesc.getDefaultValue(), e);
}
createTable.addIntegerColumn(fDesc.getName(), defaultVal);
} else if (type.equals(FieldDescriptor.TYPE_DECIMAL)) {
BigDecimal defaultVal = BigDecimal.ZERO;
try {
defaultVal = new BigDecimal(fDesc.getDefaultValue());
} catch (Exception e) {
Log.get().log(Level.WARNING, "Extension: unable to parse default bigdecimal value : " + fDesc.getDefaultValue(), e);
}
createTable.addNumberColumn(fDesc.getName(), BigDecimal.class, defaultVal, false);
} else if (type.equals(FieldDescriptor.TYPE_BOOLEAN)) {
String defaultValue = "false";
if (fDesc.getDefaultValue() != null && fDesc.getDefaultValue().equals("true")) {
defaultValue = "true";
}
createTable.addColumn(fDesc.getName(), "boolean", defaultValue, false);
} else if (type.equals(FieldDescriptor.TYPE_DATE)) {
createTable.addColumn(fDesc.getName(), "date");
} else if (type.equals(FieldDescriptor.TYPE_TIME)) {
createTable.addColumn(fDesc.getName(), "time");
} else if (type.equals(FieldDescriptor.TYPE_DATETIME)) {
createTable.addDateAndTimeColumn(fDesc.getName());
} else if (type.equals(FieldDescriptor.TYPE_REF)) {
// created later
mustAdd = false;
}
mustAdd = true;
} else {
// Le champs existe, on ne fait rien
// checker les types
}
}
if (mustAdd && !(createTable instanceof SQLCreateTable)) {
changesToApply.add(createTable);
}
}
// Let's do it
// FIXME : if changesToApply create field that createToApply : bing
if (!createToApply.isEmpty()) {
root.createTables(createToApply);
}
if (!changesToApply.isEmpty()) {
for (String change : ChangeTable.cat(changesToApply)) {
root.getDBSystemRoot().getDataSource().execute(change);
}
 
}
// Refetch if needed
if (!changesToApply.isEmpty() || !createToApply.isEmpty()) {
root.getSchema().updateVersion();
root.refetch(tableNames);
Log.get().info("Fetching table changes (" + changesToApply.size() + " fields and " + createToApply.size() + " tables)");
}
// Compute foreign keys to create
changesToApply.clear();
for (TableDescritor tDesc : t) {
final SQLTable table = root.getTable(tDesc.getName());
for (FieldDescriptor fDesc : tDesc.getFields()) {
final SQLField f = (table == null) ? null : table.getFieldRaw(fDesc.getName());
if (f == null && fDesc.getType().equals(FieldDescriptor.TYPE_REF)) {
final String fTableName = fDesc.getForeignTable();
final SQLTable fTable = root.getTable(fTableName);
if (fTable != null) {
final AlterTable mTable = new AlterTable(table);
mTable.addForeignColumn(fDesc.getName(), fTable);
changesToApply.add(mTable);
} else {
JOptionPane.showMessageDialog(new JFrame(), "L'extension ne peut pas s'installer car la table " + fTableName + " n'existe pas.");
return false;
}
}
}
}
// Create foreign keys
if (!changesToApply.isEmpty()) {
for (String change : ChangeTable.cat(changesToApply)) {
root.getDBSystemRoot().getDataSource().execute(change);
}
root.getSchema().updateVersion();
root.refetch(tableNames);
Log.get().info("Fetching " + changesToApply.size() + " foreign fields creation");
}
// Create elements for created tables
for (TableDescritor tDesc : t) {
 
tDesc.createElement(this);
}
return true;
}
 
public void stop() {
this.isStarted = false;
this.autoStart = false;
Log.get().info("Extension " + this.getName() + " stopped");
fireChanged();
}
 
public String getName() {
return name;
}
 
@SuppressWarnings("unchecked")
public void importFromXML(String xml) {
 
System.out.println("Extension.importFromXML():" + xml);
if (xml.length() > 0) {
final SAXBuilder sxb = new SAXBuilder();
try {
final Document doc = sxb.build(new StringReader(xml));
final Element root = doc.getRootElement();
if (root.getAttributeValue("autostart", "false").equals("true")) {
this.autoStart = true;
}
// elements parsing
final List<Element> elements = root.getChildren("element");
for (Element eElement : elements) {
final String id = eElement.getAttributeValue("id");
final String tableName = eElement.getAttributeValue("tableName");
ElementDescriptor eDesc = new ElementDescriptor(id, tableName);
// TODO : fkeyaction
this.elementList.add(eDesc);
}
// tables parsing
final List<Element> tables = root.getChildren("table");
for (Element eTable : tables) {
final String type = eTable.getAttributeValue("type");
final String name = eTable.getAttributeValue("name");
final TableDescritor tDesc = new TableDescritor(name);
final List<Element> fields = eTable.getChildren("field");
for (Element field : fields) {
FieldDescriptor f = createFieldDescriptorFrom(name, field);
tDesc.add(f);
}
if (tDesc.getFields().size() > 0) {
if (type.equals("create")) {
this.createTableList.add(tDesc);
} else if (type.equals("modify")) {
this.modifyTableList.add(tDesc);
} else {
throw new IllegalStateException("Unknown table type: " + type);
}
}
 
}
// translations
final List<Element> translations = root.getChildren("translation");
for (Element eTranslation : translations) {
final String lang = eTranslation.getAttributeValue("locale");
if (lang == null) {
throw new IllegalArgumentException("no locale found in translation element");
}
final List<Element> tTables = eTranslation.getChildren("element");
for (Element element : tTables) {
final String tableName = element.getAttributeValue("refid");
final TableTranslation t = new TableTranslation(lang, tableName);
t.setSingular(element.getAttributeValue("singular"));
t.setPlural(element.getAttributeValue("plural"));
this.tableTranslations.add(t);
final List<Element> tFields = element.getChildren("item");
for (Element elementF : tFields) {
final FieldTranslation tF = new FieldTranslation(lang, tableName, elementF.getAttributeValue("id"));
tF.setLabel(elementF.getAttributeValue("label"));
tF.setDocumentation(elementF.getAttributeValue("doc"));
this.fieldTranslations.add(tF);
}
}
 
final List<Element> tMenu = eTranslation.getChildren("menu");
for (Element element : tMenu) {
final MenuTranslation t = new MenuTranslation(lang, element.getAttributeValue("refid"));
t.setLabel(element.getAttributeValue("label"));
this.menuTranslations.add(t);
}
final List<Element> tActions = eTranslation.getChildren("action");
for (Element element : tActions) {
final ActionTranslation t = new ActionTranslation(lang, element.getAttributeValue("refid"));
t.setLabel(element.getAttributeValue("label"));
this.actionTranslations.add(t);
}
}
 
// list parsing
final List<Element> lists = root.getChildren("list");
for (Element eList : lists) {
final String type = eList.getAttributeValue("type");
final String id = eList.getAttributeValue("id");
final String refid = eList.getAttributeValue("refid");
 
final ListDescriptor listDesc = new ListDescriptor(id);
String mainTable = this.getTableNameForElementId(refid);
if (mainTable == null) {
// fallback to table name
mainTable = refid;
}
listDesc.setMainTable(mainTable);
final List<Element> columns = eList.getChildren("column");
for (Element field : columns) {
ColumnDescriptor f = createColumnDescriptorFrom(mainTable, field);
listDesc.add(f);
}
if (listDesc.getColumnCount() > 0) {
if (type.equals("create")) {
this.createListList.add(listDesc);
} else {
throw new IllegalStateException("Unknown table type: " + type);
}
}
 
} // component parsing
final List<Element> components = root.getChildren("component");
for (Element eList : components) {
final String type = eList.getAttributeValue("type");
if (type.equals("create")) {
final String id = eList.getAttributeValue("id");
final String table = eList.getAttributeValue("table");
final ComponentDescritor tDesc = new ComponentDescritor(id);
tDesc.setTable(table);
walkGroup(eList, tDesc.getGroup());
System.out.println("SimpleXMLAddon.importFromXML() " + tDesc);
this.createComponentList.add(tDesc);
}
}
// Menu
final List<Element> menus = root.getChildren("menu");
for (Element eList : menus) {
final String type = eList.getAttributeValue("type");
if (type.equals("create")) {
final List<Element> actions = eList.getChildren("action");
for (Element action : actions) {
final String id = action.getAttributeValue("id");
final String insertInMenu = action.getAttributeValue("insertInMenu");
final String actionType = action.getAttributeValue("type");
if (actionType.equals(MenuDescriptor.LIST)) {
// a list frame
final String listId = action.getAttributeValue("listId");
final MenuDescriptor mDesc = new MenuDescriptor(id);
mDesc.setInsertInMenu(insertInMenu);
mDesc.setType(actionType);
mDesc.setListId(listId);
this.createMenuList.add(mDesc);
} else if (actionType.equals(MenuDescriptor.CREATE)) {
// a create frame
final String componentId = action.getAttributeValue("componentId");
final MenuDescriptor mDesc = new MenuDescriptor(id);
mDesc.setInsertInMenu(insertInMenu);
mDesc.setType(actionType);
mDesc.setComponentId(componentId);
this.createMenuList.add(mDesc);
} else if (actionType.equals(MenuDescriptor.GROUP)) {
// a create frame
final MenuDescriptor mDesc = new MenuDescriptor(id);
mDesc.setInsertInMenu(insertInMenu);
mDesc.setType(actionType);
this.createMenuList.add(mDesc);
} else {
throw new IllegalStateException("Unknown action type " + actionType + " for action " + id);
}
 
}
} else if (type.equals("remove")) {
final List<Element> actions = eList.getChildren("action");
for (Element action : actions) {
final String id = action.getAttributeValue("id");
this.removeMenuList.add(new MenuDescriptor(id));
}
}
}
 
// Actions
final List<Element> actions = root.getChildren("action");
for (Element actionElement : actions) {
final String type = actionElement.getAttributeValue("type");
if (type.equals("create")) {
 
final String id = actionElement.getAttributeValue("id");
final String location = actionElement.getAttributeValue("location");
final String table = actionElement.getAttributeValue("table");
final String componentId = actionElement.getAttributeValue("componentId");
ActionDescriptor action = new ActionDescriptor(id);
action.setLocation(location);
action.setTable(table);
action.setComponentId(componentId);
this.createActionList.add(action);
 
} else {
// TODO: remove
throw new IllegalStateException("Unknown action type " + type);
}
 
}
 
} catch (Exception e) {
System.err.println("SimpleXMLAddon.importFromXML(): parsing error :" + e.getMessage());
e.printStackTrace();
}
}
notSaved = false;
 
fireChanged();
}
 
String toXML() {
final Element rootElement = new Element("extension");
rootElement.setAttribute("id", this.name);
rootElement.setAttribute("autostart", String.valueOf(this.isStarted));
rootElement.setAttribute("format", "1.0");
final Document document = new Document(rootElement);
 
// Element
for (ElementDescriptor eDescriptor : this.elementList) {
final Element eElement = new Element("element");
eElement.setAttribute("tableName", eDescriptor.getTableName());
eElement.setAttribute("id", eDescriptor.getId());
// TODO: fkey action : <fkeyaction action="set_empty|cascade|restrict"
// fields="id_language"/>
rootElement.addContent(eElement);
}
 
// Table create
for (TableDescritor tDescriptor : this.createTableList) {
final Element eTable = new Element("table");
eTable.setAttribute("type", "create");
eTable.setAttribute("name", tDescriptor.getName());
for (FieldDescriptor fDescriptor : tDescriptor.getFields()) {
final Element eField = new Element("field");
eField.setAttribute("name", fDescriptor.getName());
eField.setAttribute("type", fDescriptor.getType());
if (fDescriptor.getLength() != null) {
eField.setAttribute("length", fDescriptor.getLength());
}
if (fDescriptor.getDefaultValue() != null) {
eField.setAttribute("default", fDescriptor.getDefaultValue());
}
if (fDescriptor.getForeignTable() != null) {
eField.setAttribute("ftable", fDescriptor.getForeignTable());
}
eTable.addContent(eField);
}
rootElement.addContent(eTable);
}
 
// Table modify
for (TableDescritor tDescriptor : this.modifyTableList) {
final Element eTable = new Element("table");
eTable.setAttribute("type", "modify");
eTable.setAttribute("name", tDescriptor.getName());
for (FieldDescriptor fDescriptor : tDescriptor.getFields()) {
final Element eField = new Element("field");
eField.setAttribute("name", fDescriptor.getName());
eField.setAttribute("type", fDescriptor.getType());
if (fDescriptor.getLength() != null) {
eField.setAttribute("length", fDescriptor.getLength());
}
if (fDescriptor.getDefaultValue() != null) {
eField.setAttribute("default", fDescriptor.getDefaultValue());
}
if (fDescriptor.getForeignTable() != null) {
eField.setAttribute("ftable", fDescriptor.getForeignTable());
}
eTable.addContent(eField);
}
rootElement.addContent(eTable);
}
// Translations
final HashSet<String> locales = new HashSet<String>();
for (Translation tr : tableTranslations) {
locales.add(tr.getLocale());
}
for (Translation tr : fieldTranslations) {
locales.add(tr.getLocale());
}
for (Translation tr : menuTranslations) {
locales.add(tr.getLocale());
}
for (Translation tr : actionTranslations) {
locales.add(tr.getLocale());
}
final List<String> lLocales = new ArrayList<String>(locales);
Collections.sort(lLocales);
for (String locale : lLocales) {
final Element eTranslation = new Element("translation");
eTranslation.setAttribute("locale", locale);
rootElement.addContent(eTranslation);
// Tables
for (TableTranslation tTranslation : tableTranslations) {
if (tTranslation.getLocale().equals(locale)) {
final Element eTable = new Element("element");
eTable.setAttribute("refid", tTranslation.getTableName());
final String singular = tTranslation.getSingular();
if (singular != null && !singular.isEmpty()) {
eTable.setAttribute("singular", singular);
}
final String plural = tTranslation.getPlural();
if (plural != null && !plural.isEmpty()) {
eTable.setAttribute("plural", plural);
}
for (FieldTranslation fTranslation : fieldTranslations) {
// Fields
if (fTranslation.getLocale().equals(locale) && fTranslation.getTableName().equals(tTranslation.getTableName())) {
final Element eField = new Element("item");
eField.setAttribute("id", fTranslation.getFieldName());
eField.setAttribute("label", fTranslation.getLabel());
if (fTranslation.getDocumentation() != null) {
eField.setAttribute("doc", fTranslation.getDocumentation());
}
eTable.addContent(eField);
}
}
eTranslation.addContent(eTable);
 
}
}
// Menus
for (MenuTranslation tMenu : menuTranslations) {
if (tMenu.getLocale().equals(locale)) {
final Element eMenu = new Element("menu");
eMenu.setAttribute("refid", tMenu.getId());
eMenu.setAttribute("label", tMenu.getLabel());
eTranslation.addContent(eMenu);
}
}
 
// Actions
for (ActionTranslation tAction : actionTranslations) {
if (tAction.getLocale().equals(locale)) {
final Element eMenu = new Element("action");
eMenu.setAttribute("refid", tAction.getId());
eMenu.setAttribute("label", tAction.getLabel());
eTranslation.addContent(eMenu);
}
}
}
 
// Actions
for (ActionDescriptor action : this.createActionList) {
final Element eAction = new Element("action");
eAction.setAttribute("type", "create");
eAction.setAttribute("id", action.getId());
eAction.setAttribute("location", action.getLocation());
eAction.setAttribute("table", action.getTable());
eAction.setAttribute("componentId", action.getComponentId());
rootElement.addContent(eAction);
}
// Menu create
if (!this.createMenuList.isEmpty()) {
final Element eMenu = new Element("menu");
eMenu.setAttribute("type", "create");
for (MenuDescriptor menu : this.createMenuList) {
final Element eActionMenu = new Element("action");
eActionMenu.setAttribute("id", menu.getId());
eActionMenu.setAttribute("insertInMenu", menu.getInsertInMenu());
final String type = menu.getType();
eActionMenu.setAttribute("type", type);
if (!type.equals(MenuDescriptor.CREATE) && !type.equals(MenuDescriptor.LIST) && !type.equals(MenuDescriptor.GROUP)) {
throw new IllegalStateException("Menu type " + type + " not supported");
}
 
if (type.endsWith("list") && menu.getListId() != null) {
eActionMenu.setAttribute("listId", menu.getListId());
} else if (type.endsWith("create") && menu.getComponentId() != null) {
eActionMenu.setAttribute("componentId", menu.getComponentId());
}
eMenu.addContent(eActionMenu);
}
rootElement.addContent(eMenu);
 
}
// Menu remove
if (!this.removeMenuList.isEmpty()) {
final Element eMenu = new Element("menu");
eMenu.setAttribute("type", "remove");
for (MenuDescriptor menu : this.removeMenuList) {
final Element eActionMenu = new Element("action");
eActionMenu.setAttribute("id", menu.getId());
eMenu.addContent(eActionMenu);
}
rootElement.addContent(eMenu);
}
// List create
for (ListDescriptor listDescriptor : this.createListList) {
final Element eList = new Element("list");
eList.setAttribute("type", "create");
eList.setAttribute("id", listDescriptor.getId());
String refFromTable = getRefFromTable(listDescriptor.getMainTable());
if (refFromTable == null) {
refFromTable = listDescriptor.getMainTable();
}
if (refFromTable != null) {
eList.setAttribute("refid", refFromTable);
for (ColumnDescriptor fieldDescriptor : listDescriptor.getColumns()) {
final Element eField = new Element("column");
eField.setAttribute("id", fieldDescriptor.getId());
eField.setAttribute("fields", fieldDescriptor.getFieldsPaths());
eField.setAttribute("style", fieldDescriptor.getStyle());
eList.addContent(eField);
}
 
rootElement.addContent(eList);
}
 
}
// Component create
for (ComponentDescritor componentDescriptor : this.createComponentList) {
final Element eComponent = new Element("component");
eComponent.setAttribute("type", "create");
eComponent.setAttribute("id", componentDescriptor.getId());
eComponent.setAttribute("table", componentDescriptor.getTable());
appendGroup(eComponent, componentDescriptor.getGroup());
 
rootElement.addContent(eComponent);
}
// Component modify
for (ComponentDescritor componentDescriptor : this.modifyComponentList) {
System.out.println(componentDescriptor);
throw new IllegalAccessError("Not yet implemented");
}
// Output
XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
final ByteArrayOutputStream bOut = new ByteArrayOutputStream();
final BufferedOutputStream oStream = new BufferedOutputStream(bOut);
try {
out.output(document, oStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
return bOut.toString("utf8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "";
}
}
 
private void appendGroup(Element eComponent, Group group) {
int size = group.getSize();
for (int i = 0; i < size; i++) {
Item it = group.getItem(i);
final Element gr;
if (it instanceof Group) {
gr = new Element("group");
appendGroup(gr, (Group) it);
} else {
gr = new Element("item");
}
gr.setAttribute("id", it.getId());
if (it.getLocalHint() != null) {
final LayoutHints hints = it.getLocalHint();
final String type;
if (hints.largeWidth()) {
type = "verylarge";
} else if (hints.fillWidth()) {
type = "large";
} else {
type = "normal";
}
gr.setAttribute("type", type);
if (hints.isSeparated()) {
gr.setAttribute("isSeparated", "true");
}
if (hints.showLabel()) {
gr.setAttribute("showLabel", "true");
}
}
 
eComponent.addContent(gr);
 
}
 
}
 
private void walkGroup(Element e, Group group) {
@SuppressWarnings("unchecked")
final List<Element> elements = e.getChildren();
for (Element element : elements) {
String id = element.getAttributeValue("id", "unknown");
String type = element.getAttributeValue("type", "default");
String showLabel = element.getAttributeValue("showLabel", "true");
String isSeparated = element.getAttributeValue("isSeparated", "false");
if (element.getName().equals("item")) {
final Item it = new Item(id);
if (type.equals("large")) {
it.setLocalHint(new LayoutHints(false, false, showLabel.equals("true"), isSeparated.equals("true"), true, false));
} else if (type.equals("verylarge")) {
it.setLocalHint(new LayoutHints(true, false, showLabel.equals("true"), isSeparated.equals("true"), true, false));
} else {
it.setLocalHint(new LayoutHints(false, false, showLabel.equals("true"), isSeparated.equals("true"), false, false));
}
System.out.println("Extension.walkGroup()" + it + " " + it.getLocalHint() + " from " + type);
group.add(it);
 
} else if (element.getName().equals("group")) {
final Group g = new Group(id);
group.add(g);
walkGroup(element, g);
} else {
throw new IllegalStateException("Unknown element: " + element.getName());
}
}
}
 
private FieldDescriptor createFieldDescriptorFrom(String table, Element field) {
FieldDescriptor f = new FieldDescriptor(table, field.getAttributeValue("name"), field.getAttributeValue("type"), field.getAttributeValue("default"), field.getAttributeValue("length"),
field.getAttributeValue("ftable"));
Element child = field.getChild("field");
if (child != null) {
f.setLink(createFieldDescriptorFrom(field.getAttributeValue("ftable"), child));
}
return f;
}
 
private ColumnDescriptor createColumnDescriptorFrom(String table, Element field) {
final ColumnDescriptor f = new ColumnDescriptor(field.getAttributeValue("id"));
f.setFieldsPaths(field.getAttributeValue("fields"));
f.setStyle(field.getAttributeValue("style"));
return f;
}
 
private void fireChanged() {
for (ChangeListener listener : listeners) {
listener.stateChanged(new ChangeEvent(this));
}
 
}
 
public List<TableDescritor> getCreateTableList() {
return createTableList;
}
 
public void addCreateTable(TableDescritor value) {
this.createTableList.add(value);
setChanged();
}
 
public void removeCreateTable(TableDescritor value) {
this.createTableList.remove(value);
setChanged();
}
 
public List<TableDescritor> getModifyTableList() {
return modifyTableList;
}
 
public List<ListDescriptor> getCreateListList() {
return createListList;
}
 
public ListDescriptor getCreateListFromId(String id) {
for (ListDescriptor listDescriptor : this.createListList) {
if (listDescriptor.getId().equals(id)) {
return listDescriptor;
}
}
return null;
}
 
public void addCreateList(ListDescriptor item) {
this.createListList.add(item);
setChanged();
 
}
 
public void removeCreateList(ListDescriptor item) {
this.createListList.remove(item);
setChanged();
}
 
public void addChangeListener(ChangeListener listener) {
if (!this.listeners.contains(listener))
this.listeners.add(listener);
 
}
 
public TableDescritor getOrCreateTableDescritor(String tableName) {
 
for (TableDescritor td : this.modifyTableList) {
if (td.getName().equalsIgnoreCase(tableName)) {
return td;
}
}
// create table descritor for the table
final TableDescritor td = new TableDescritor(tableName);
this.modifyTableList.add(td);
setChanged();
return td;
}
 
public SQLTable getSQLTable(TableDescritor tableDesc) {
try {
SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(tableDesc.getName());
return t;
} catch (Exception e) {
return null;
}
}
 
public boolean isNotSaved() {
return this.notSaved;
}
 
public void setChanged() {
this.notSaved = true;
this.fireChanged();
String xml = this.toXML();
System.out.println(xml);
}
 
// FIXME: filter textfield pour eviter les pb d'insert/update
// TODO: eviter les doublons lors du renommage
 
public void save() {
String xml = this.toXML();
System.out.println(xml);
// delete old version
deleteFromDB();
// insert new version
final SQLTable extensionTable = getExtensionTable();
SQLRowValues v = new SQLRowValues(extensionTable);
v.put("IDENTIFIER", this.getName());
v.put("XML", this.toXML());
try {
v.insert();
this.notSaved = false;
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(new JFrame(), "Error while saving extension");
}
 
this.fireChanged();
}
 
private SQLTable getExtensionTable() {
return ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(ExtensionBuilderModule.TABLE_NAME);
}
 
private void deleteFromDB() {
final SQLTable extensionTable = getExtensionTable();
String query = "DELETE FROM " + extensionTable.getSQL() + " WHERE \"IDENTIFIER\" = " + SQLBase.quoteStringStd(this.getName());
extensionTable.getDBSystemRoot().getDataSource().execute(query);
}
 
public List<String> getAllKnownTableNames() {
final List<String> l = new ArrayList<String>();
final Set<String> s = new HashSet<String>();
for (SQLTable t : AllTableListModel.getAllDatabaseTables()) {
s.add(t.getName());
}
for (TableDescritor td : this.getCreateTableList()) {
s.add(td.getName());
}
s.remove("FWK_MODULE_METADATA");
s.remove("FWK_SCHEMA_METADATA");
s.remove("FWK_UNDEFINED_IDS");
s.remove(ExtensionBuilderModule.TABLE_NAME);
l.addAll(s);
Collections.sort(l, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
});
 
return l;
}
 
public TableDescritor getTableListDescriptor(String tableName) {
for (TableDescritor td : this.createTableList) {
if (td.getName().equalsIgnoreCase(tableName)) {
return td;
}
}
return null;
}
 
public List<String> getTranslatedFieldOfTable(String tableName) {
final List<String> l = new ArrayList<String>();
for (FieldTranslation tr : this.fieldTranslations) {
if (tr.getTableName().equals(tableName)) {
l.add(tr.getFieldName());
}
}
return l;
}
 
public TableTranslation getTableTranslation(String lang, String tableName) {
for (TableTranslation tr : this.tableTranslations) {
if (tr.getLocale().equals(lang) && tr.getTableName().equals(tableName)) {
return tr;
}
}
return null;
}
 
public String getFieldTranslation(String lang, String tableName, String fName) {
for (FieldTranslation tr : this.fieldTranslations) {
if (tr.getLocale().equals(lang) && tr.getTableName().equals(tableName) && tr.getFieldName().equals(fName)) {
return tr.getLabel();
}
}
return null;
}
 
public List<ComponentDescritor> getCreateComponentList() {
return this.createComponentList;
}
 
public void addCreateComponent(ComponentDescritor desc) {
this.createComponentList.add(desc);
}
 
public void removeCreateComponent(ComponentDescritor desc) {
this.createComponentList.remove(desc);
setChanged();
}
 
public List<MenuDescriptor> getCreateMenuList() {
return createMenuList;
}
 
public void addCreateMenu(MenuDescriptor desc) {
this.createMenuList.add(desc);
}
 
public MenuDescriptor getCreateMenuItemFromId(String id) {
for (MenuDescriptor menuDescriptor : this.createMenuList) {
if (menuDescriptor.getId().equals(id)) {
return menuDescriptor;
}
}
return null;
}
 
public List<MenuDescriptor> getRemoveMenuList() {
return removeMenuList;
}
 
public void addRemoveMenu(MenuDescriptor desc) {
this.removeRemoveMenuForId(desc.getId());
this.removeMenuList.add(desc);
}
 
public List<String> getAllKnownFieldName(String tableName) {
final Set<String> l = new HashSet<String>();
// fields created in the extension
 
final List<TableDescritor> desc = getCreateTableList();
for (TableDescritor tableDescritor : desc) {
if (tableDescritor.getName().equals(tableName)) {
final List<FieldDescriptor> fDescs = tableDescritor.getFields();
for (FieldDescriptor fieldDescriptor : fDescs) {
l.add(fieldDescriptor.getName());
}
}
}
// + champs dans la base
final Set<SQLTable> tables = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTables();
for (SQLTable sqlTable : tables) {
final String tName = sqlTable.getName();
if (tName.equals(tableName)) {
Set<String> f = sqlTable.getFieldsName();
for (String string : f) {
l.add(string);
}
 
}
}
 
return new ArrayList<String>(l);
}
 
public List<String> getAllKnownActionNames() {
ArrayList<String> s = new ArrayList<String>();
Collection<SQLElement> elements = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElements();
for (SQLElement element : elements) {
Collection<IListeAction> actions = element.getRowActions();
for (IListeAction action : actions) {
if (action instanceof RowAction) {
RowAction rAction = (RowAction) action;
final String id = rAction.getID();
if (id != null)
s.add(id);
}
}
}
Collections.sort(s);
return s;
}
 
public List<String> getActionNames() {
ArrayList<String> s = new ArrayList<String>();
for (ActionDescriptor action : this.createActionList) {
s.add(action.getId());
}
Collections.sort(s);
return s;
}
 
public List<ActionDescriptor> getActionDescriptors() {
Collections.sort(this.createActionList, new Comparator<ActionDescriptor>() {
 
@Override
public int compare(ActionDescriptor o1, ActionDescriptor o2) {
return o1.getId().compareTo(o2.getId());
}
});
return this.createActionList;
}
 
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();
}
 
public String getTableNameForElementId(String id) {
for (ElementDescriptor element : this.elementList) {
if (element.getId().equals(id)) {
return element.getTableName();
}
}
return null;
}
 
private String getRefFromTable(String table) {
for (ElementDescriptor element : this.elementList) {
if (element.getTableName().equals(table)) {
return element.getId();
}
}
return null;
}
 
public List<MenuTranslation> getMenuTranslations() {
return menuTranslations;
}
 
public List<ActionTranslation> getActionTranslations() {
return actionTranslations;
}
 
public List<FieldTranslation> getFieldTranslations() {
return fieldTranslations;
}
 
public void removeChangeListener(ChangeListener listener) {
this.listeners.remove(listener);
 
}
 
public void setName(String name) {
if (!name.equals(this.name)) {
deleteFromDB();
this.name = name;
save();
setChanged();
}
}
 
public void setupMenu(MenuContext ctxt) {
final Group group = ctxt.getMenuAndActions().getGroup();
initMenuGroup(group);
 
}
 
public void removeRemoveMenuForId(String id) {
for (int i = removeMenuList.size() - 1; i >= 0; i--) {
final MenuDescriptor m = removeMenuList.get(i);
if (m.getId().equals(id)) {
removeMenuList.remove(i);
}
}
 
}
 
public void removeCreateMenuForId(String id) {
for (int i = createMenuList.size() - 1; i >= 0; i--) {
final MenuDescriptor m = createMenuList.get(i);
if (m.getId().equals(id)) {
createMenuList.remove(i);
}
}
 
}
 
public MenuDescriptor getRemoveMenuItemFromId(String itemId) {
for (MenuDescriptor m : removeMenuList) {
if (m.getId().equals(itemId)) {
return m;
}
}
return null;
}
 
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);
for (MenuDescriptor m : descs) {
if (m.getId().equals(previousId)) {
m.setId(newId);
}
}
 
}
 
}
 
public void moveMenuItem(String itemId, String parentId) {
for (MenuDescriptor m : createMenuList) {
if (m.getId().equals(itemId)) {
m.setInsertInMenu(parentId);
}
}
 
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/action/AllKnownActionsListModel.java
New file
0,0 → 1,15
package org.openconcerto.modules.extensionbuilder.translation.action;
 
import java.util.List;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultListModel;
 
public class AllKnownActionsListModel extends DefaultListModel {
 
public AllKnownActionsListModel(Extension extension) {
List<String> l = extension.getAllKnownActionNames();
this.addAll(l);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/action/ActionListPanel.java
New file
0,0 → 1,46
package org.openconcerto.modules.extensionbuilder.translation.action;
 
import javax.swing.JPanel;
import javax.swing.JScrollPane;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.list.EditableListPanel;
import org.openconcerto.modules.extensionbuilder.translation.menu.MenuTranslationItemEditor;
import org.openconcerto.ui.group.Item;
 
public class ActionListPanel extends EditableListPanel {
 
private ActionTranslationPanel tableTranslationPanel;
private Extension extension;
 
public ActionListPanel(Extension extension, ActionTranslationPanel tableTranslationPanel) {
super(new AllKnownActionsListModel(extension), "Actions", "", false, false);
this.extension = extension;
this.tableTranslationPanel = tableTranslationPanel;
 
}
 
@Override
public void addNewItem() {
}
 
@Override
public void renameItem(Object item) {
 
}
 
@Override
public void removeItem(Object item) {
}
 
@Override
public void itemSelected(Object item) {
if (item != null) {
tableTranslationPanel.setRightPanel(new JScrollPane(new MenuTranslationItemEditor(new Item(item.toString()), extension)));
} else {
tableTranslationPanel.setRightPanel(new JPanel());
}
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/action/ActionTranslation.java
New file
0,0 → 1,27
package org.openconcerto.modules.extensionbuilder.translation.action;
 
import org.openconcerto.modules.extensionbuilder.translation.Translation;
 
public class ActionTranslation extends Translation {
 
private final String id;
private String label;
 
public ActionTranslation(String lang, String id) {
super(lang);
this.id = id;
}
 
public String getId() {
return id;
}
 
public String getLabel() {
return label;
}
 
public void setLabel(String label) {
this.label = label;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/action/ActionTranslationPanel.java
New file
0,0 → 1,18
package org.openconcerto.modules.extensionbuilder.translation.action;
 
import javax.swing.JComponent;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class ActionTranslationPanel extends AbstractSplittedPanel {
 
public ActionTranslationPanel(Extension extension) {
super(extension);
}
 
@Override
public JComponent createLeftComponent() {
return new ActionListPanel(extension, this);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/Translation.java
New file
0,0 → 1,13
package org.openconcerto.modules.extensionbuilder.translation;
 
public class Translation {
private String locale;
 
public Translation(String lang) {
this.locale = lang;
}
 
public String getLocale() {
return this.locale;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/LocaleSelector.java
New file
0,0 → 1,147
package org.openconcerto.modules.extensionbuilder.translation;
 
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Vector;
 
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
 
public class LocaleSelector extends JPanel {
 
private String lang, country;
private JComboBox comboLang;
private JComboBox comboCountry;
private List<ActionListener> listeners = new ArrayList<ActionListener>();
private boolean interactive = true;
 
public LocaleSelector() {
this.setLayout(new FlowLayout(FlowLayout.LEFT));
final Vector<String> langs = new Vector<String>();
final Locale[] l = Locale.getAvailableLocales();
 
for (int i = 0; i < l.length; i++) {
final String language = ((Locale) l[i]).getLanguage();
if (!langs.contains(language)) {
langs.add(language);
}
}
 
Collections.sort(langs);
comboLang = new JComboBox(langs);
this.add(comboLang);
comboCountry = new JComboBox();
this.add(comboCountry);
 
try {
this.setLocale(Locale.getDefault());
} catch (Exception e) {
System.err.println("LocaleSelector warning: unable to set current language");
}
comboLang.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
if (interactive) {
lang = comboLang.getSelectedItem().toString();
updateCountryFromLang();
country = comboCountry.getSelectedItem().toString();
fireActionPerformed();
}
}
 
});
comboCountry.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
if (interactive) {
country = 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));
}
 
private void updateCountryFromLang() {
 
Vector<String> countries = new Vector<String>();
Locale[] l = Locale.getAvailableLocales();
for (int i = 0; i < l.length; i++) {
Locale lo = (Locale) l[i];
if (lo.getLanguage().equals(lang)) {
countries.add(lo.getCountry());
}
}
Collections.sort(countries);
if (countries.isEmpty()) {
countries.add("");
}
comboCountry.setModel(new DefaultComboBoxModel(countries));
}
 
public Locale getLocale() {
Locale[] l = Locale.getAvailableLocales();
if (country != null) {
 
for (int i = 0; i < l.length; i++) {
Locale lo = (Locale) l[i];
if (lo.getLanguage().equals(lang) && lo.getCountry().equals(country)) {
return lo;
}
}
}
for (int i = 0; i < l.length; i++) {
Locale lo = (Locale) l[i];
if (lo.getLanguage().equals(lang)) {
return lo;
}
}
return null;
}
 
public void setLocale(Locale l) {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("Must be called in EDT");
}
if (l.getLanguage().equals(this.lang) && l.getCountry().equals(this.country)) {
return;
}
this.interactive = false;
this.lang = l.getLanguage();
this.country = l.getCountry();
System.err.println("LocaleSelector.setLocale() " + this.lang + " " + this.country);
this.comboLang.setSelectedItem(lang);
updateCountryFromLang();
this.comboCountry.setSelectedItem(country);
this.interactive = true;
}
 
public void addActionListener(ActionListener actionListener) {
this.listeners.add(actionListener);
}
 
public void fireActionPerformed() {
System.err.println("LocaleSelector.fireActionPerformed():" + this.lang + " " + this.country);
System.err.println("LocaleSelector.fireActionPerformed(); locale: " + this.getLocale());
for (ActionListener listener : this.listeners) {
listener.actionPerformed(new ActionEvent(this, this.hashCode(), ""));
}
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/TranslationMainPanel.java
New file
0,0 → 1,24
package org.openconcerto.modules.extensionbuilder.translation;
 
import java.awt.GridLayout;
 
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.translation.action.ActionTranslationPanel;
import org.openconcerto.modules.extensionbuilder.translation.field.TableTranslationPanel;
import org.openconcerto.modules.extensionbuilder.translation.menu.MenuTranslationPanel;
 
public class TranslationMainPanel extends JPanel {
public TranslationMainPanel(Extension extension) {
this.setLayout(new GridLayout(1, 1));
JTabbedPane p = new JTabbedPane();
p.add("Champs et tables", new TableTranslationPanel(extension));
p.add("Menus", new MenuTranslationPanel(extension));
p.add("Actions contextuelles", new ActionTranslationPanel(extension));
 
this.add(p);
 
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/TableTranslation.java
New file
0,0 → 1,35
package org.openconcerto.modules.extensionbuilder.translation.field;
 
import org.openconcerto.modules.extensionbuilder.translation.Translation;
 
public class TableTranslation extends Translation {
 
private String tableName;
private String singular;
private String plural;
 
public TableTranslation(String lang, String tableName) {
super(lang);
this.tableName = tableName;
}
 
public String getTableName() {
return tableName;
}
 
public void setSingular(String singular) {
this.singular = singular;
}
 
public String getSingular() {
return singular;
}
 
public void setPlural(String plural) {
this.plural = plural;
}
 
public String getPlural() {
return plural;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/TableTranslationPanel.java
New file
0,0 → 1,29
package org.openconcerto.modules.extensionbuilder.translation.field;
 
import javax.swing.JComponent;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.table.TableDescritor;
 
public class TableTranslationPanel extends AbstractSplittedPanel {
 
public TableTranslationPanel(Extension extension) {
super(extension);
split.setDividerLocation(250);
}
 
public void setRightPanel(JComponent p) {
super.setRightPanel(p);
split.setDividerLocation(250);
}
 
@Override
public JComponent createLeftComponent() {
return new AllTableListPanel(extension, this);
}
 
public void select(TableDescritor tableDescriptor) {
((AllTableListPanel) leftComponent).selectItem(tableDescriptor);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/AllKnownTableNameListModel.java
New file
0,0 → 1,15
package org.openconcerto.modules.extensionbuilder.translation.field;
 
import java.util.List;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultListModel;
 
public class AllKnownTableNameListModel extends DefaultListModel {
 
public AllKnownTableNameListModel(Extension extension) {
List<String> l = extension.getAllKnownTableNames();
this.addAll(l);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/AllTableListPanel.java
New file
0,0 → 1,42
package org.openconcerto.modules.extensionbuilder.translation.field;
 
import javax.swing.JPanel;
import javax.swing.JScrollPane;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.list.EditableListPanel;
 
public class AllTableListPanel extends EditableListPanel {
 
private TableTranslationPanel tableTranslationPanel;
private Extension extension;
 
public AllTableListPanel(Extension extension, TableTranslationPanel tableTranslationPanel) {
super(new AllKnownTableNameListModel(extension), "Tables", "", false, false);
this.extension = extension;
this.tableTranslationPanel = tableTranslationPanel;
}
 
@Override
public void addNewItem() {
}
 
@Override
public void renameItem(Object item) {
}
 
@Override
public void removeItem(Object item) {
}
 
@Override
public void itemSelected(Object item) {
if (item != null) {
tableTranslationPanel.setRightPanel(new JScrollPane(new TableTranslationEditorPanel(extension, (String) item)));
} else {
tableTranslationPanel.setRightPanel(new JPanel());
}
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/TableTranslationEditorPanel.java
New file
0,0 → 1,209
package org.openconcerto.modules.extensionbuilder.translation.field;
 
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.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
 
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.translation.LocaleSelector;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
 
public class TableTranslationEditorPanel extends JPanel {
private final List<JComponent> hideableComponents = new ArrayList<JComponent>();
final JTextField textSingular1 = new JTextField();
final JTextField textSingular2 = new JTextField();
final JTextField textPlural1 = new JTextField();
final JTextField textPlural2 = new JTextField();
private Map<String, JTextField> map1 = new HashMap<String, JTextField>();
private Map<String, JTextField> map2 = new HashMap<String, JTextField>();
 
TableTranslationEditorPanel(final Extension extension, final String tableName) {
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
c.gridwidth = 2;
c.fill = GridBagConstraints.NONE;
this.add(new JLabelBold("Table " + tableName), c);
c.gridy++;
c.gridwidth = 1;
 
// Languages
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Langue et pays", SwingConstants.RIGHT), c);
final String[] isoLanguages = Locale.getISOLanguages();
System.out.println(isoLanguages.length);
 
final LocaleSelector comboLang1 = new LocaleSelector();
 
c.weightx = 1;
c.gridx++;
c.fill = GridBagConstraints.NONE;
this.add(comboLang1, c);
c.weightx = 0;
c.gridx++;
c.gridheight = 3;
c.fill = GridBagConstraints.BOTH;
final JSeparator sep = new JSeparator(JSeparator.VERTICAL);
this.add(sep, c);
hideableComponents.add(sep);
c.gridheight = 1;
c.weightx = 1;
c.gridx++;
c.fill = GridBagConstraints.NONE;
final LocaleSelector comboLang2 = new LocaleSelector();
hideableComponents.add(comboLang2);
comboLang2.setLocale(Locale.ENGLISH);
this.add(comboLang2, c);
// Singular
c.gridx = 0;
c.gridy++;
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Singulier", SwingConstants.RIGHT), c);
c.gridx++;
 
this.add(textSingular1, c);
c.gridx += 2;
hideableComponents.add(textSingular2);
this.add(textSingular2, c);
 
// Plural
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(new JLabel("Pluriel", SwingConstants.RIGHT), c);
c.gridx++;
this.add(textPlural1, c);
c.gridx += 2;
hideableComponents.add(textPlural2);
this.add(textPlural2, c);
 
// Fields
c.gridx = 0;
c.gridy++;
c.gridwidth = 2;
c.fill = GridBagConstraints.NONE;
this.add(new JLabelBold("Champs de la table"), c);
c.gridwidth = 1;
 
List<String> fieldsName = getFieldsName(extension, tableName);
c.gridy++;
c.gridheight = fieldsName.size();
c.gridx = 2;
c.fill = GridBagConstraints.BOTH;
final JSeparator sep2 = new JSeparator(JSeparator.VERTICAL);
hideableComponents.add(sep2);
this.add(sep2, c);
 
c.fill = GridBagConstraints.HORIZONTAL;
c.gridheight = 1;
for (String fName : fieldsName) {
c.gridx = 0;
c.weightx = 0;
this.add(new JLabel(fName, SwingConstants.RIGHT), c);
c.gridx++;
final JTextField t1 = new JTextField();
map1.put(fName, t1);
this.add(t1, c);
c.gridx += 2;
final JTextField t2 = new JTextField();
hideableComponents.add(t2);
map2.put(fName, t2);
this.add(t2, c);
c.gridy++;
}
c.gridx = 0;
c.gridy++;
c.weighty = 1;
c.weightx = 0;
this.add(new JPanel(), c);
// TODO: ajouter la checkbox pour masquer
// TODO: repercuter les modifs dans les traductions
 
updateUIFrom(extension, tableName, comboLang1.getLocale(), comboLang2.getLocale());
comboLang1.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
updateUIFrom(extension, tableName, comboLang1.getLocale(), null);
}
});
comboLang2.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
updateUIFrom(extension, tableName, null, comboLang2.getLocale());
}
});
}
 
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);
}
if (l2 != null) {
final String lang = l2.toString();
updateUI(extension, tableName, lang, textSingular2, textPlural2, map2);
}
 
}
 
private void updateUI(Extension extension, String tableName, final String lang, JTextField textSingular, JTextField textPlural, Map<String, JTextField> map) {
final TableTranslation tTrans = extension.getTableTranslation(lang, tableName);
if (tTrans != null && tTrans.getSingular() != null) {
textSingular.setText(tTrans.getSingular());
} else {
textSingular.setText("");
}
if (tTrans != null && tTrans.getPlural() != null) {
textPlural.setText(tTrans.getPlural());
} else {
textPlural.setText("");
}
for (String fName : map.keySet()) {
String t = extension.getFieldTranslation(lang, tableName, fName);
if (t != null) {
map.get(fName).setText(t);
} else {
map.get(fName).setText("");
}
}
}
 
private List<String> getFieldsName(Extension extension, String tableName) {
final Set<String> l = new HashSet<String>();
l.addAll(extension.getAllKnownFieldName(tableName));
 
// + champs traduit dans l'extension
List<String> lT = extension.getTranslatedFieldOfTable(tableName);
l.addAll(lT);
 
l.remove("ARCHIVE");
l.remove("ORDRE");
l.remove("ID_USER_COMMON_CREATE");
l.remove("ID_USER_COMMON_MODIFY");
// Sort
final ArrayList<String> result = new ArrayList<String>();
result.addAll(l);
Collections.sort(result);
return result;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/field/FieldTranslation.java
New file
0,0 → 1,43
package org.openconcerto.modules.extensionbuilder.translation.field;
 
import org.openconcerto.modules.extensionbuilder.translation.Translation;
 
public class FieldTranslation extends Translation {
 
private final String tableName;
private final String fieldName;
private String label;
private String documentation;
 
public FieldTranslation(String lang, String tableName, String fieldName) {
super(lang);
this.tableName = tableName;
this.fieldName = fieldName;
 
}
 
public void setLabel(String label) {
this.label = label;
}
 
public String getTableName() {
return tableName;
}
 
public String getFieldName() {
return fieldName;
}
 
public String getLabel() {
return label;
}
 
public String getDocumentation() {
return documentation;
}
 
public void setDocumentation(String documentation) {
this.documentation = documentation;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/menu/MenuTranslationItemEditor.java
New file
0,0 → 1,114
package org.openconcerto.modules.extensionbuilder.translation.menu;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Locale;
 
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.translation.LocaleSelector;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.group.Item;
import org.openconcerto.ui.group.LayoutHints;
 
public class MenuTranslationItemEditor extends JPanel {
 
final Extension extension;
private JTextField textId;
private JTextField textTranslation1;
private JTextField textTranslation2;
 
public MenuTranslationItemEditor(final Item item, final Extension extension) {
this.extension = extension;
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
 
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Identifiant", SwingConstants.RIGHT), c);
c.gridx++;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridwidth = 3;
textId = new JTextField();
this.add(textId, c);
 
// Language selector
c.gridx = 0;
c.gridy++;
c.weightx = 0;
c.gridwidth = 1;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Langue et pays", SwingConstants.RIGHT), c);
final String[] isoLanguages = Locale.getISOLanguages();
System.out.println(isoLanguages.length);
 
final LocaleSelector comboLang1 = new LocaleSelector();
 
c.weightx = 1;
c.gridx++;
c.fill = GridBagConstraints.NONE;
this.add(comboLang1, c);
c.weightx = 0;
c.gridx++;
c.gridheight = 2;
c.fill = GridBagConstraints.BOTH;
final JSeparator sep = new JSeparator(JSeparator.VERTICAL);
this.add(sep, c);
 
c.gridheight = 1;
c.weightx = 1;
c.gridx++;
c.fill = GridBagConstraints.NONE;
final LocaleSelector comboLang2 = new LocaleSelector();
 
comboLang2.setLocale(Locale.ENGLISH);
this.add(comboLang2, c);
// Traduction
c.gridx = 0;
c.gridy++;
 
c.gridwidth = 1;
 
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Traduction", SwingConstants.RIGHT), c);
c.gridx++;
 
c.weightx = 1;
 
textTranslation1 = new JTextField(20);
 
this.add(textTranslation1, c);
 
c.gridx += 2;
c.fill = GridBagConstraints.HORIZONTAL;
 
c.weightx = 1;
textTranslation2 = new JTextField(20);
this.add(textTranslation2, c);
 
c.gridy++;
c.weighty = 1;
this.add(new JPanel(), c);
 
initUIFrom(item);
 
}
 
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());
}
 
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/menu/MenuTranslation.java
New file
0,0 → 1,27
package org.openconcerto.modules.extensionbuilder.translation.menu;
 
import org.openconcerto.modules.extensionbuilder.translation.Translation;
 
public class MenuTranslation extends Translation {
 
private final String id;
private String label;
 
public MenuTranslation(String lang, String id) {
super(lang);
this.id = id;
}
 
public String getId() {
return id;
}
 
public void setLabel(String label) {
this.label = label;
}
 
public String getLabel() {
return this.label;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation/menu/MenuTranslationPanel.java
New file
0,0 → 1,120
package org.openconcerto.modules.extensionbuilder.translation.menu;
 
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
 
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.component.ActivableMutableTreeNode;
import org.openconcerto.modules.extensionbuilder.menu.mainmenu.MenuItemTreeModel;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
 
public class MenuTranslationPanel extends AbstractSplittedPanel {
 
private MenuItemTreeModel newModel;
private JTree tree;
 
public MenuTranslationPanel(Extension extension) {
super(extension);
fillModel();
}
 
public void fillModel() {
newModel.fillFromDescriptor(extension);
tree.setModel(newModel);
tree.expandRow(0);
}
 
@Override
public JComponent createLeftComponent() {
final JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
final GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 0;
c.insets = new Insets(2, 2, 2, 0);
 
panel.add(new JLabel("Menus"), c);
newModel = new MenuItemTreeModel();
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();
if (userObject == null) {
return "null";
}
if (userObject instanceof Group) {
Group d = (Group) userObject;
return " " + d.getId();
}
return userObject.toString();
}
};
tree.setModel(newModel);
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
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) {
 
final JLabel r = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
final ActivableMutableTreeNode tr = (ActivableMutableTreeNode) value;
if (!tr.isActive()) {
r.setForeground(Color.LIGHT_GRAY);
}
if (tr.getUserObject() instanceof Item) {
r.setText(((Item) tr.getUserObject()).getId());
}
return r;
}
};
 
treeRenderer.setLeafIcon(null);
tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(tree);
comp2.setMinimumSize(new Dimension(250, 150));
comp2.setPreferredSize(new Dimension(250, 150));
c.weighty = 1;
c.gridy++;
c.insets = new Insets(0, 0, 0, 0);
panel.add(comp2, c);
 
// init
 
tree.addMouseListener(new MouseAdapter() {
 
@Override
public void mousePressed(MouseEvent e) {
final TreePath selectionPath = tree.getSelectionPath();
if (selectionPath == null) {
setRightPanel(new JPanel());
} else {
Item i = (Item) ((DefaultMutableTreeNode) selectionPath.getLastPathComponent()).getUserObject();
setRightPanel(new MenuTranslationItemEditor(i, extension));
}
}
});
return panel;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/labels.xml
New file
0,0 → 1,4
<?xml version="1.0" encoding="UTF-8" ?>
<ROOT>
</ROOT>
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ModuleResources_fr.properties
New file
0,0 → 1,2
name=Builder
description=Outil de création de modules simples
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/GroupTreeModel.java
New file
0,0 → 1,122
package org.openconcerto.modules.extensionbuilder.component;
 
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
 
import org.openconcerto.modules.extensionbuilder.table.ForbiddenFieldName;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
 
public class GroupTreeModel extends DefaultTreeModel {
 
private boolean showAll = true;
private GroupDescritor componentDescriptor;
 
public GroupTreeModel() {
super(null, false);
 
}
 
public void setShowAll(boolean b) {
if (b != showAll) {
this.showAll = b;
System.err.println("GroupTreeModel.setShowAll()" + b);
reload();
}
}
 
public void fillFromGroup(GroupDescritor n, Group tableGroup) {
if (n == null) {
throw new IllegalArgumentException("null GroupDescriptor");
}
this.componentDescriptor = n;
final ActivableMutableTreeNode root = new ActivableMutableTreeNode(null);
root.setActive(true);
if (tableGroup == null) {
this.setRoot(root);
return;
}
System.err.println("Desc:");
System.err.println(n.getGroup().printTree());
System.err.println("Table:");
System.err.println(tableGroup.printTree());
 
addToTreeNode(root, n.getGroup(), n, 0);
// Add from tableGroup
// Group filteredTableGroup = new Group(tableGroup.getId());
// filteredTableGroup = Group.copy(tableGroup, filteredTableGroup);
for (int i = 0; i < tableGroup.getSize(); i++) {
Item item = tableGroup.getItem(i);
final String id = item.getId();
if (!n.getGroup().contains(id) && ForbiddenFieldName.isAllowed(id) && !id.equals("ID")) {
addToTreeNode((DefaultMutableTreeNode) root.getFirstChild(), item, n, 0);
}
}
 
// /////////
this.setRoot(root);
}
 
void addToTreeNode(DefaultMutableTreeNode node, Item item, GroupDescritor n, int depth) {
System.err.println("GroupTreeModel.addToTreeNode():" + node + " item:" + item + " Desc:" + n + " Depth:" + depth);
 
if (depth > 50) {
return;
}
depth++;
final ActivableMutableTreeNode newChild = new ActivableMutableTreeNode(item);
 
newChild.setActive(n.containsGroupId(item.getId()));
if (showAll || newChild.isActive()) {
node.add(newChild);
}
if (item instanceof Group) {
final Group gr = (Group) item;
final int childCount = gr.getSize();
for (int i = 0; i < childCount; i++) {
final Item it = gr.getItem(i);
addToTreeNode(newChild, it, n, depth);
}
newChild.setAllowsChildren(true);
} else {
newChild.setAllowsChildren(false);
}
}
 
public void toggleActive(TreePath selectionPath) {
if (selectionPath == null) {
return;
}
final ActivableMutableTreeNode n = (ActivableMutableTreeNode) selectionPath.getLastPathComponent();
 
final Item item = (Item) n.getUserObject();
if (item instanceof Group) {
// A Group is always active
return;
}
n.setActive(!n.isActive());
if (n.isActive()) {
this.componentDescriptor.updateGroupFrom(this);
} else {
this.componentDescriptor.removeGroup(item);
}
reload(n);
componentDescriptor.fireGroupChanged();
}
 
@Override
protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) {
// To update preview while reordering
super.fireTreeNodesInserted(source, path, childIndices, children);
componentDescriptor.fireGroupChanged();
}
 
@Override
public boolean isLeaf(Object node) {
final ActivableMutableTreeNode n = (ActivableMutableTreeNode) node;
if (n.getUserObject() == null)
return super.isLeaf(node);
return !(n.getUserObject() instanceof Group);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ComponentListPanel.java
New file
0,0 → 1,56
package org.openconcerto.modules.extensionbuilder.component;
 
import java.awt.Window;
 
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.list.EditableListPanel;
 
public class ComponentListPanel extends EditableListPanel {
 
private final Extension extension;
private final ComponentCreateMainPanel tableInfoPanel;
 
public ComponentListPanel(final Extension extension, final ComponentCreateMainPanel tableInfoPanel) {
super(new CreateComponentListModel(extension), "Interfaces de saisie", "Ajouter une interface");
this.extension = extension;
this.tableInfoPanel = tableInfoPanel;
}
 
@Override
public void addNewItem() {
((CreateComponentListModel) dataModel).addComponentList();
}
 
@Override
public void renameItem(Object item) {
final ComponentDescritor e = (ComponentDescritor) item;
final Window w = SwingUtilities.windowForComponent(this);
final String s = (String) JOptionPane.showInputDialog(w, "Nouveau nom", "Renommer l'interface de saisie", JOptionPane.PLAIN_MESSAGE, null, null, e.getId());
if ((s != null) && (s.length() > 0)) {
e.setId(s);
e.fireGroupChanged();
reload();
}
}
 
@Override
public void removeItem(Object item) {
((CreateComponentListModel) dataModel).removeElement(item);
extension.removeCreateComponent((ComponentDescritor) item);
}
 
@Override
public void itemSelected(Object item) {
if (item != null) {
ComponentDescritor n = (ComponentDescritor) item;
final ComponentCreatePanel p = new ComponentCreatePanel(n, extension);
tableInfoPanel.setRightPanel(p);
} else {
tableInfoPanel.setRightPanel(new JPanel());
}
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ItemTreeModel.java
New file
0,0 → 1,20
package org.openconcerto.modules.extensionbuilder.component;
 
import java.util.HashSet;
import java.util.Set;
 
import org.openconcerto.modules.extensionbuilder.table.FieldDescriptor;
 
public class ItemTreeModel extends GroupTreeModel {
 
private Set<FieldDescriptor> allFields = new HashSet<FieldDescriptor>();
 
public ItemTreeModel() {
 
}
 
public boolean containsFieldDescritor(FieldDescriptor d) {
return this.allFields.contains(d);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ComponentDescritor.java
New file
0,0 → 1,23
package org.openconcerto.modules.extensionbuilder.component;
 
 
public class ComponentDescritor extends GroupDescritor {
 
private String table;
 
public ComponentDescritor(String id) {
super(id);
 
}
 
public void setTable(String table) {
this.table = table;
 
}
 
public String getTable() {
return table;
}
 
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/CreateComponentListModel.java
New file
0,0 → 1,34
package org.openconcerto.modules.extensionbuilder.component;
 
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultListModel;
 
public class CreateComponentListModel extends DefaultListModel implements ChangeListener {
private final Extension extension;
 
CreateComponentListModel(Extension extension) {
this.extension = extension;
addContent(extension);
extension.addChangeListener(this);
}
 
private void addContent(Extension extension) {
this.addAll(extension.getCreateComponentList());
}
 
@Override
public void stateChanged(ChangeEvent e) {
this.clear();
addContent(extension);
}
 
public void addComponentList() {
final ComponentDescritor l = new ComponentDescritor("Interface de saisie " + (this.getSize() + 1));
this.addElement(l);
extension.addCreateComponent(l);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/GroupEditor.java
New file
0,0 → 1,272
package org.openconcerto.modules.extensionbuilder.component;
 
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
 
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
import org.openconcerto.ui.group.LayoutHints;
import org.openconcerto.ui.tree.ReorderableJTree;
 
public class GroupEditor extends AbstractSplittedPanel {
 
private ComponentDescritor n;
private ItemTreeModel newModel;
private JTree tree;
private Group tableGroup;
 
public GroupEditor(ComponentDescritor n, Extension extension) {
super(extension);
this.n = n;
}
 
@Override
public JComponent createLeftComponent() {
final JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
final GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 0;
c.insets = new Insets(2, 2, 2, 0);
 
panel.add(new JLabelBold("Champs et groupes"), c);
newModel = new ItemTreeModel();
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();
if (userObject == null) {
return "null";
}
if (userObject instanceof Group) {
Group d = (Group) userObject;
return " " + d.getId();
}
return userObject.toString();
}
};
tree.setModel(newModel);
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
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) {
 
final JLabel r = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
final ActivableMutableTreeNode tr = (ActivableMutableTreeNode) value;
if (!tr.isActive()) {
r.setForeground(Color.LIGHT_GRAY);
}
if (tr.getUserObject() instanceof Item) {
r.setText(((Item) tr.getUserObject()).getId());
}
return r;
}
};
 
treeRenderer.setLeafIcon(null);
tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(tree);
comp2.setMinimumSize(new Dimension(250, 150));
comp2.setPreferredSize(new Dimension(250, 150));
c.weighty = 1;
c.gridy++;
c.insets = new Insets(0, 0, 0, 0);
panel.add(comp2, c);
 
c.gridy++;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.SOUTHWEST;
c.insets = new Insets(2, 2, 2, 0);
final JButton addGroupButton = new JButton("Ajouter un groupe");
panel.add(addGroupButton, c);
c.gridy++;
final JButton showHideButton = new JButton("Afficher / Masquer");
showHideButton.setEnabled(false);
panel.add(showHideButton, c);
 
c.gridy++;
final JCheckBox hideCheckbox = new JCheckBox("Afficher les champs masqués");
hideCheckbox.setSelected(true);
 
panel.add(hideCheckbox, c);
 
// init
 
addGroupButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
addNewGroup();
 
}
 
});
 
showHideButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
newModel.toggleActive(tree.getSelectionPath());
}
});
 
hideCheckbox.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
newModel.setShowAll(hideCheckbox.isSelected());
setMainTable(n.getTable());
setRightPanel(new JPanel());
}
});
 
tree.addTreeSelectionListener(new TreeSelectionListener() {
 
@Override
public void valueChanged(TreeSelectionEvent e) {
final Object selectedValue = tree.getSelectionPath();
showHideButton.setEnabled((selectedValue != null));
}
});
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
newModel.toggleActive(tree.getSelectionPath());
}
}
 
@Override
public void mousePressed(MouseEvent e) {
final TreePath selectionPath = tree.getSelectionPath();
if (selectionPath == null) {
setRightPanel(new JPanel());
} else {
Item i = (Item) ((DefaultMutableTreeNode) selectionPath.getLastPathComponent()).getUserObject();
setRightPanel(new ItemEditor(i, n));
}
}
});
return panel;
}
 
protected void addNewGroup() {
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (tree.getModel().getRoot())).getFirstChild();
DefaultMutableTreeNode node = root;
if (node.getChildCount() > 0) {
node = (DefaultMutableTreeNode) node.getFirstChild();
}
if (tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) 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)));
}
 
}
 
public void setMainTable(String table) {
n.setTable(table);
 
initGroupFromTable(extension.getAllKnownFieldName(table));
newModel.fillFromGroup(n, this.tableGroup);
 
tree.expandRow(0);
}
 
public void initGroupFromTable(List<String> fields) {
System.out.println("GroupEditor.initGroupFromTable()");
System.out.println("GroupEditor.initGroupFromTable Component group");
 
this.tableGroup = new Group(n.getId());
for (String field : fields) {
Item i = n.getItemFromId(field);
Item newItem = new Item(field);
 
if (i != null) {
System.out.println("GroupEditor.initGroupFromTable() searching found: " + i + ":" + i.getLocalHint());
newItem.setLocalHint(new LayoutHints(i.getLocalHint()));
}
this.tableGroup.add(newItem);
}
System.out.println("GroupEditor.initGroupFromTable Table group");
 
}
 
public Group getFilteredGroup() {
// Parcours du Tree
Group filteredGroup = new Group(n.getId());
if (n.getTable() == null) {
throw new IllegalStateException("Not table defined for " + n);
}
walk(newModel, filteredGroup, newModel.getRoot());
filteredGroup = (Group) filteredGroup.getItem(0);
 
return filteredGroup;
}
 
protected void walk(ItemTreeModel model, Group gr, Object o) {
int cc = model.getChildCount(o);
for (int i = 0; i < cc; i++) {
ActivableMutableTreeNode child = (ActivableMutableTreeNode) model.getChild(o, i);
if (child.isActive()) {
final Item userObject = (Item) child.getUserObject();
if (userObject instanceof Group) {
final Group item = new Group(userObject.getId());
item.setLocalHint(new LayoutHints(userObject.getLocalHint()));
gr.add(item);
walk(model, item, child);
} else {
final Item item = new Item(userObject.getId());
item.setLocalHint(new LayoutHints(userObject.getLocalHint()));
final SQLTable table = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(n.getTable());
if (table.contains(userObject.getId())) {
SQLField field = table.getField(userObject.getId());
if (!field.isPrimaryKey() && !field.getName().endsWith("ORDRE") && !field.getName().endsWith("ARCHIVE")) {
gr.add(item);
}
}
}
 
}
}
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ItemEditor.java
New file
0,0 → 1,228
package org.openconcerto.modules.extensionbuilder.component;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
import org.openconcerto.ui.group.LayoutHints;
import org.openconcerto.ui.group.LayoutHintsBuilder;
 
public class ItemEditor extends JPanel {
 
private JTextField textId;
private JComboBox comboType;
private JCheckBox checkSeparated;
private JCheckBox checkLabel;
private boolean isEditingGroup;
private JCheckBox checkFillH;
 
public ItemEditor(final Item item, final ComponentDescritor component) {
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
if (item instanceof Group) {
this.isEditingGroup = true;
}
 
if (this.isEditingGroup) {
// Identifiant du groupe
c.weightx = 0;
this.add(new JLabel("Identifiant", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
textId = new JTextField(30);
this.add(textId, c);
c.gridy++;
} else {
// Label du champs
c.gridwidth = 2;
String label = item.getId();
SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(component.getTable());
if (t != null) {
SQLField field = t.getField(item.getId());
if (field != null) {
final String labelFor = ComptaPropsConfiguration.getTranslator(t).getLabelFor(field);
if (labelFor != null) {
label += " (" + labelFor + ")";
}
}
}
this.add(new JLabelBold(label), c);
c.gridy++;
}
c.gridwidth = 1;
 
if (!this.isEditingGroup) {
c.gridx = 0;
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Type", SwingConstants.RIGHT), c);
c.gridx++;
c.fill = GridBagConstraints.NONE;
c.weightx = 1;
comboType = new JComboBox(new String[] { "normal", "large", "très large" });
this.add(comboType, c);
c.gridy++;
}
c.gridx = 0;
 
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0;
final JLabel labelSep = new JLabel("Sépararer le label", SwingConstants.RIGHT);
if (this.isEditingGroup) {
labelSep.setText("Dissocier");
}
this.add(labelSep, c);
c.gridx++;
c.fill = GridBagConstraints.NONE;
checkSeparated = new JCheckBox();
c.weightx = 1;
this.add(checkSeparated, c);
c.gridx = 0;
c.gridy++;
if (!this.isEditingGroup) {
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0;
this.add(new JLabel("Afficher le label", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
c.fill = GridBagConstraints.NONE;
checkLabel = new JCheckBox();
 
this.add(checkLabel, c);
 
c.gridy++;
 
c.gridx = 0;
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Maximiser la taille", SwingConstants.RIGHT), c);
c.gridx++;
c.fill = GridBagConstraints.NONE;
c.weightx = 1;
checkFillH = new JCheckBox();
this.add(checkFillH, c);
c.gridy++;
}
 
JPanel spacer = new JPanel();
c.weighty = 1;
 
this.add(spacer, c);
initUIFrom(item);
 
// Listeners
if (isEditingGroup) {
textId.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
 
}
 
@Override
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
 
}
 
@Override
public void changedUpdate(DocumentEvent e) {
item.setId(textId.getText());
component.fireGroupChanged();
 
}
});
}
checkSeparated.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
item.setLocalHint(item.getLocalHint().getBuilder().setSeparated(checkSeparated.isSelected()).build());
component.fireGroupChanged();
}
});
 
if (!isEditingGroup) {
checkLabel.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
item.setLocalHint(item.getLocalHint().getBuilder().setShowLabel(checkLabel.isSelected()).build());
component.fireGroupChanged();
}
});
checkFillH.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
item.setLocalHint(item.getLocalHint().getBuilder().setFillHeight(checkFillH.isSelected()).build());
component.fireGroupChanged();
}
});
 
comboType.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
int i = comboType.getSelectedIndex();
final LayoutHintsBuilder h = item.getLocalHint().getBuilder();
if (i == 0) {
h.setFillWidth(false);
h.setLargeWidth(false);
} else if (i == 1) {
h.setFillWidth(true);
h.setLargeWidth(false);
} else if (i == 2) {
h.setFillWidth(true);
h.setLargeWidth(true);
} else {
throw new IllegalStateException("No hints for index " + i);
}
item.setLocalHint(h.build());
component.fireGroupChanged();
}
});
}
}
 
private void initUIFrom(Item item) {
 
final LayoutHints localHint = item.getLocalHint();
 
checkSeparated.setSelected(localHint.isSeparated());
 
if (!isEditingGroup) {
if (localHint.fillWidth() && localHint.largeWidth()) {
comboType.setSelectedIndex(2);
} else if (localHint.fillWidth()) {
comboType.setSelectedIndex(1);
} else {
comboType.setSelectedIndex(0);
}
checkFillH.setSelected(localHint.fillHeight());
checkLabel.setSelected(localHint.showLabel());
} else {
textId.setText(item.getId());
 
}
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ComponentCreatePanel.java
New file
0,0 → 1,150
package org.openconcerto.modules.extensionbuilder.component;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Log;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.list.AllTablesComboBoxModel;
import org.openconcerto.sql.element.GroupSQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.view.EditPanel;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.group.Group;
 
public class ComponentCreatePanel extends JPanel {
 
private GroupEditor panel;
private JFrame previewFrame;
private Group oldGroup;
 
public ComponentCreatePanel(final ComponentDescritor n, Extension extension) {
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
c.gridwidth = 2;
 
this.add(new JLabelBold(n.getId()), c);
c.gridy++;
c.gridwidth = 1;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Table principale", SwingConstants.RIGHT), c);
c.gridx++;
c.fill = GridBagConstraints.NONE;
final JComboBox comboTable = new JComboBox(new AllTablesComboBoxModel(extension));
this.add(comboTable, c);
c.gridx = 0;
c.gridy++;
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 2;
c.fill = GridBagConstraints.BOTH;
 
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));
} else {
comboTable.setSelectedItem(mainTable);
panel.setMainTable(mainTable);
}
this.add(panel, c);
 
final JButton previewButton = new JButton("Prévisualiser");
c.gridy++;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.EAST;
this.add(previewButton, c);
 
// Listeners
 
comboTable.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
panel.setMainTable((String) comboTable.getSelectedItem());
 
}
});
previewButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
 
final SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(n.getTable());
if (t == null) {
JOptionPane.showMessageDialog(ComponentCreatePanel.this, "La table doit être créée avant de pouvoir prévisualiser.");
return;
}
final Group group = panel.getFilteredGroup();
 
final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
if (element == null) {
Log.get().warning("No element for table: " + t.getName());
}
final GroupSQLComponent gComponent = new GroupSQLComponent(element, group);
oldGroup = group;
if (previewFrame == null || !previewFrame.isVisible()) {
previewFrame = new JFrame();
previewFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
previewFrame.setTitle("Preview: " + group.getId());
}
final EditPanel panel = new EditPanel(gComponent, EditMode.CREATION);
previewFrame.setContentPane(panel);
previewFrame.pack();
if (!previewFrame.isVisible()) {
FrameUtil.show(previewFrame);
}
 
};
 
});
n.addGroupChangeListener(new ChangeListener() {
 
@Override
public void stateChanged(ChangeEvent e) {
if (previewFrame == null || !previewFrame.isVisible()) {
return;
}
final Group group = panel.getFilteredGroup();
if (group.equalsDesc(oldGroup)) {
// Avoid refresh when group doesn't change
return;
}
oldGroup = group;
final SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(n.getTable());
if (t == null) {
return;
}
final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
 
final GroupSQLComponent gComponent = new GroupSQLComponent(element, group);
 
previewFrame.setContentPane(new EditPanel(gComponent, EditMode.CREATION));
previewFrame.pack();
if (!previewFrame.isVisible()) {
FrameUtil.show(previewFrame);
}
 
}
});
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ActivableMutableTreeNode.java
New file
0,0 → 1,20
package org.openconcerto.modules.extensionbuilder.component;
 
import javax.swing.tree.DefaultMutableTreeNode;
 
public class ActivableMutableTreeNode extends DefaultMutableTreeNode {
private boolean active = true;
 
public ActivableMutableTreeNode(Object obj) {
super(obj);
}
 
public void setActive(boolean active) {
this.active = active;
}
 
public boolean isActive() {
return active;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/ComponentCreateMainPanel.java
New file
0,0 → 1,25
package org.openconcerto.modules.extensionbuilder.component;
 
import javax.swing.JComponent;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class ComponentCreateMainPanel extends AbstractSplittedPanel {
 
public ComponentCreateMainPanel(Extension extension) {
super(extension);
split.setDividerLocation(0.5D);
}
 
@Override
public JComponent createLeftComponent() {
return new ComponentListPanel(extension, this);
}
 
public void select(ComponentDescritor listDescriptor) {
// TODO selectionner
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/component/GroupDescritor.java
New file
0,0 → 1,135
package org.openconcerto.modules.extensionbuilder.component;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
import org.openconcerto.ui.group.LayoutHints;
 
public class GroupDescritor {
 
private String id;
 
private Group group;
private List<ChangeListener> groupChangeListener = new ArrayList<ChangeListener>();
 
public GroupDescritor(String id) {
this.id = id;
this.group = new Group(id);
}
 
public String getId() {
return id;
}
 
public void setId(String id) {
this.id = id;
}
 
public Group getGroup() {
return group;
}
 
@Override
public String toString() {
return this.getId();
}
 
public boolean containsGroupId(String gId) {
return containsGroup(group, gId);
}
 
private boolean containsGroup(Item item, String gId) {
if (item.getId().equals(gId)) {
return true;
}
if (item instanceof Group) {
Group group = (Group) item;
final int size = group.getSize();
for (int i = 0; i < size; i++) {
boolean b = containsGroup(group.getItem(i), gId);
if (b) {
return true;
}
}
}
return false;
}
 
public Item getItemFromId(String id) {
return getItemFromId(group, id);
}
 
private Item getItemFromId(Item item, String gId) {
if (item.getId().equals(gId)) {
return item;
}
if (item instanceof Group) {
Group group = (Group) item;
final int size = group.getSize();
for (int i = 0; i < size; i++) {
Item b = getItemFromId(group.getItem(i), gId);
if (b != null) {
return b;
}
}
}
return null;
}
 
public void removeGroup(Item gr) {
remove(this.group, gr.getId());
 
}
 
private void remove(Item item, String gId) {
if (item instanceof Group) {
Group group2 = (Group) item;
group2.remove(gId);
}
}
 
public void updateGroupFrom(GroupTreeModel model) {
this.group = new Group(this.getId());
walk(model, this.group, model.getRoot());
this.group = (Group) this.group.getItem(0);
 
}
 
protected void walk(GroupTreeModel model, Group gr, Object o) {
int cc = model.getChildCount(o);
for (int i = 0; i < cc; i++) {
ActivableMutableTreeNode child = (ActivableMutableTreeNode) model.getChild(o, i);
if (child.isActive()) {
final Item userObject = (Item) child.getUserObject();
if (userObject instanceof Group) {
final Group item = new Group(userObject.getId());
item.setLocalHint(new LayoutHints(userObject.getLocalHint()));
gr.add(item);
walk(model, item, child);
} else {
final Item item = new Item(userObject.getId());
item.setLocalHint(new LayoutHints(userObject.getLocalHint()));
gr.add(item);
}
 
}
}
}
 
public void addGroupChangeListener(ChangeListener changeListener) {
this.groupChangeListener.add(changeListener);
 
}
 
public void fireGroupChanged() {
for (ChangeListener l : this.groupChangeListener) {
l.stateChanged(new ChangeEvent(this));
}
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/MenuCreateMainPanel.java
New file
0,0 → 1,22
package org.openconcerto.modules.extensionbuilder.menu;
 
import javax.swing.JComponent;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class MenuCreateMainPanel extends AbstractSplittedPanel {
 
public MenuCreateMainPanel(Extension extension) {
super(extension);
split.setDividerLocation(0.5D);
}
 
@Override
public JComponent createLeftComponent() {
return new MenuListPanel(extension, this);
}
 
 
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/MenuListPanel.java
New file
0,0 → 1,13
package org.openconcerto.modules.extensionbuilder.menu;
 
import javax.swing.JComponent;
 
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class MenuListPanel extends JComponent {
 
public MenuListPanel(Extension extension, MenuCreateMainPanel menuCreateMainPanel) {
// TODO Auto-generated constructor stub
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/MenuMainPanel.java
New file
0,0 → 1,24
package org.openconcerto.modules.extensionbuilder.menu;
 
import java.awt.GridLayout;
 
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
 
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;
 
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.add(tab);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/mainmenu/MenuDescriptor.java
New file
0,0 → 1,62
package org.openconcerto.modules.extensionbuilder.menu.mainmenu;
 
public class MenuDescriptor {
 
public static final String CREATE = "create";
public static final String LIST = "list";
public static final String GROUP = "group";
private String id;
private String listId;
private String componentId;
private String type;
private String insertInMenu;
 
public MenuDescriptor(String id) {
this.id = id;
}
 
public String getId() {
return id;
}
 
public void setId(String id) {
this.id = id;
}
 
public String getListId() {
return listId;
}
 
public void setListId(String listId) {
this.listId = listId;
}
 
public String getComponentId() {
return componentId;
}
 
public void setComponentId(String componentId) {
this.componentId = componentId;
}
 
/**
*
* @return "list" or "create"
* */
public String getType() {
return type;
}
 
public void setType(String type) {
this.type = type;
}
 
public String getInsertInMenu() {
return insertInMenu;
}
 
public void setInsertInMenu(String insertInMenu) {
this.insertInMenu = insertInMenu;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/mainmenu/MenuItemTreeModel.java
New file
0,0 → 1,196
package org.openconcerto.modules.extensionbuilder.menu.mainmenu;
 
import java.util.Enumeration;
import java.util.List;
 
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
 
import org.openconcerto.erp.config.MenuManager;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.component.ActivableMutableTreeNode;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
 
public class MenuItemTreeModel extends DefaultTreeModel {
 
private boolean showAll = true;
private Extension extension;
 
public MenuItemTreeModel() {
super(null, false);
 
}
 
public void setShowAll(boolean b) {
this.showAll = b;
System.err.println("MenuItemTreeModel.setShowAll(): " + b);
}
 
public void fillFromDescriptor(Extension extension) {
 
if (extension == null) {
throw new IllegalArgumentException("null extension");
}
if (this.extension != null) {
// this.extension.removeChangeListener(this);
}
this.extension = extension;
// this.extension.addChangeListener(this);
final Group currentMenuGroup = MenuManager.getInstance().getGroup();
Group menuGroup = Group.copy(currentMenuGroup, new Group(currentMenuGroup.getId()));
 
extension.initMenuGroup(menuGroup);
 
final ActivableMutableTreeNode root = new ActivableMutableTreeNode(null);
root.setActive(true);
if (menuGroup == null) {
return;
}
// FIXME manque des items...
System.out.println(MenuManager.getInstance().getGroup().printTree());
 
addToTreeNode(root, menuGroup, 0);
setRoot(root);
 
}
 
void addToTreeNode(DefaultMutableTreeNode node, Item item, int depth) {
if (depth > 50) {
return;
}
depth++;
final ActivableMutableTreeNode newChild = new ActivableMutableTreeNode(item);
newChild.setActive(isActive(item.getId()));
if (showAll || newChild.isActive()) {
node.add(newChild);
}
if (item instanceof Group) {
final Group gr = (Group) item;
final int childCount = gr.getSize();
for (int i = 0; i < childCount; i++) {
final Item it = gr.getItem(i);
addToTreeNode(newChild, it, depth);
}
newChild.setAllowsChildren(true);
} else {
newChild.setAllowsChildren(false);
}
}
 
private boolean isActive(String id) {
List<MenuDescriptor> l = extension.getRemoveMenuList();
for (MenuDescriptor menuDescriptor : l) {
if (menuDescriptor.getId().equals(id)) {
return false;
}
}
return true;
}
 
public void toggleActive(TreePath selectionPath) {
if (selectionPath == null) {
return;
}
final ActivableMutableTreeNode n = (ActivableMutableTreeNode) selectionPath.getLastPathComponent();
 
final Item item = (Item) n.getUserObject();
if (item instanceof Group) {
// A Group is always active
return;
}
n.setActive(!n.isActive());
final String id = item.getId();
setActive(n.isActive(), id);
}
 
public void setActive(boolean active, String id) {
if (active) {
extension.removeRemoveMenuForId(id);
} else {
extension.addRemoveMenu(new MenuDescriptor(id));
}
extension.setChanged();
 
DefaultMutableTreeNode n = getNode(id);
if (n != null) {
if (n instanceof ActivableMutableTreeNode) {
((ActivableMutableTreeNode) n).setActive(active);
}
 
reload(n);
}
 
}
 
@Override
public boolean isLeaf(Object node) {
final ActivableMutableTreeNode n = (ActivableMutableTreeNode) node;
if (n.getUserObject() == null)
return super.isLeaf(node);
return !(n.getUserObject() instanceof Group);
}
 
@Override
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());
super.insertNodeInto(newChild, parent, index);
extension.setChanged();
}
 
@SuppressWarnings("rawtypes")
public void renameMenuItem(String previousId, String newId) {
DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.getRoot();
 
for (Enumeration e = root.breadthFirstEnumeration(); e.hasMoreElements();) {
final DefaultMutableTreeNode current = (DefaultMutableTreeNode) e.nextElement();
 
final String idFromNode = getIdFromNode(current);
if (idFromNode != null && idFromNode.equals(previousId)) {
setId(current, newId);
 
reload(current);
 
}
}
 
extension.renameMenuItem(previousId, newId);
extension.setChanged();
 
}
 
private void setId(DefaultMutableTreeNode node, String newId) {
Object o = node.getUserObject();
if (o == null)
return;
((Item) o).setId(newId);
 
}
 
private static String getIdFromNode(DefaultMutableTreeNode node) {
Object o = node.getUserObject();
if (o == null)
return null;
return ((Item) o).getId();
}
 
@SuppressWarnings("rawtypes")
public DefaultMutableTreeNode getNode(String id) {
DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.getRoot();
 
for (Enumeration e = root.breadthFirstEnumeration(); e.hasMoreElements();) {
final DefaultMutableTreeNode current = (DefaultMutableTreeNode) e.nextElement();
 
final String idFromNode = getIdFromNode(current);
if (idFromNode != null && idFromNode.equals(id)) {
return current;
 
}
}
return null;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/mainmenu/MainMenuPanel.java
New file
0,0 → 1,16
package org.openconcerto.modules.extensionbuilder.menu.mainmenu;
 
import java.awt.GridLayout;
 
import javax.swing.JPanel;
 
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class MainMenuPanel extends JPanel {
 
public MainMenuPanel(Extension extension) {
this.setLayout(new GridLayout(1, 1));
this.add(new MainMenuGroupEditor(extension));
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/menu/mainmenu/MenuItemEditor.java
New file
0,0 → 1,246
package org.openconcerto.modules.extensionbuilder.menu.mainmenu;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
 
import javax.swing.Action;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.config.MenuManager;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.component.ComponentDescritor;
import org.openconcerto.modules.extensionbuilder.list.ListDescriptor;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.IListFrame;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
 
public class MenuItemEditor extends JPanel {
private JTextField textId;
private JComboBox comboActionType;
private JComboBox comboActionChoice;
private JCheckBox shownInMenu;
private boolean isEditingGroup;
final Extension extension;
private Vector<String> componentIds;
private Vector<String> listIds;
protected String previousId;
private MenuItemTreeModel treeModel;
 
public MenuItemEditor(MenuItemTreeModel model, final Item item, final Extension extension) {
this.extension = extension;
this.treeModel = model;
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
if (item instanceof Group) {
this.isEditingGroup = true;
}
 
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Identifiant", SwingConstants.RIGHT), c);
c.gridx++;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridwidth = 2;
textId = new JTextField();
 
this.add(textId, c);
c.gridy++;
 
c.gridwidth = 1;
if (!this.isEditingGroup) {
c.weightx = 0;
c.gridx = 0;
this.add(new JLabel("Action", SwingConstants.RIGHT), c);
c.gridx++;
 
c.fill = GridBagConstraints.HORIZONTAL;
comboActionType = new JComboBox();
 
this.add(comboActionType, c);
c.gridx++;
c.weightx = 1;
comboActionChoice = new JComboBox();
this.add(comboActionChoice, c);
 
c.gridy++;
}
 
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.weightx = 0;
c.fill = GridBagConstraints.NONE;
shownInMenu = new JCheckBox("Afficher dans le menu");
 
this.add(shownInMenu, c);
 
JPanel spacer = new JPanel();
c.gridx = 1;
c.gridy++;
c.weighty = 1;
 
this.add(spacer, c);
initUIFrom(item.getId());
 
// Listeners
if (!isEditingGroup) {
// comboActionType
comboActionType.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
int type = cb.getSelectedIndex();
if (type == 0) {
comboActionChoice.setModel(new DefaultComboBoxModel(componentIds));
} else {
comboActionChoice.setModel(new DefaultComboBoxModel(listIds));
}
 
}
});
 
}
shownInMenu.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
final boolean selected = shownInMenu.isSelected();
 
treeModel.setActive(selected, item.getId());
}
});
 
}
 
private void initUIFrom(String itemId) {
boolean hasCreated = extension.getCreateMenuItemFromId(itemId) != null;
textId.setEnabled(hasCreated);
previousId = itemId;
if (hasCreated) {
textId.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
}
 
@Override
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
}
 
@Override
public void changedUpdate(DocumentEvent e) {
String t = textId.getText();
System.err.println("MenuItemEditor.initUIFrom(...).new DocumentListener() {...}.changedUpdate()" + t);
 
if (!previousId.equals(t)) {
treeModel.renameMenuItem(previousId, t);
previousId = t;
 
}
}
});
}
 
shownInMenu.setSelected(extension.getRemoveMenuItemFromId(itemId) == null);
if (textId != null) {
textId.setText(itemId);
}
if (!isEditingGroup) {
comboActionType.setEnabled(true);
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" }));
//
final List<ComponentDescritor> compDescList = extension.getCreateComponentList();
componentIds = new Vector<String>(compDescList.size());
for (ComponentDescritor componentDescritor : compDescList) {
componentIds.add(componentDescritor.getId());
}
 
Collections.sort(componentIds);
 
final List<ListDescriptor> listDescList = extension.getCreateListList();
listIds = new Vector<String>(listDescList.size());
for (ListDescriptor listDescritor : listDescList) {
listIds.add(listDescritor.getId());
}
 
Collections.sort(listIds);
//
 
String type = desc.getType();
if (type.equals(MenuDescriptor.CREATE)) {
final String componentId = desc.getComponentId();
if (!componentIds.contains(componentId)) {
componentIds.add(componentId);
}
comboActionType.setSelectedIndex(0);
comboActionChoice.setModel(new DefaultComboBoxModel(componentIds));
comboActionChoice.setSelectedItem(componentId);
 
} else if (type.equals(MenuDescriptor.LIST)) {
final String listId = desc.getListId();
if (!listIds.contains(listId)) {
listIds.add(listId);
}
comboActionType.setSelectedIndex(1);
comboActionChoice.setModel(new DefaultComboBoxModel(listIds));
comboActionChoice.setSelectedItem(listId);
 
} else {
throw new IllegalArgumentException("Unknown type " + type);
}
} else {
if (actionForId != null) {
if (actionForId instanceof CreateFrameAbstractAction) {
CreateFrameAbstractAction a = (CreateFrameAbstractAction) actionForId;
JFrame frame = a.createFrame();
if (frame != null) {
if (frame instanceof EditFrame) {
comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Saisie" }));
} else if (frame instanceof IListFrame) {
comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Liste" }));
} else {
comboActionType.setModel(new DefaultComboBoxModel(new String[] { "Autre" }));
}
 
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() }));
}
 
} 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
New file
0,0 → 1,342
package org.openconcerto.modules.extensionbuilder.menu.mainmenu;
 
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
 
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.component.ActivableMutableTreeNode;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.Item;
import org.openconcerto.ui.group.LayoutHints;
import org.openconcerto.ui.tree.ReorderableJTree;
 
public class MainMenuGroupEditor extends AbstractSplittedPanel {
 
private MenuItemTreeModel newModel;
private JTree tree;
 
public MainMenuGroupEditor(Extension extension) {
super(extension);
fillModel();
}
 
public void fillModel() {
newModel.fillFromDescriptor(extension);
tree.setModel(newModel);
expand();
 
}
 
private void expand() {
tree.expandRow(0);
 
final List<MenuDescriptor> m = new ArrayList<MenuDescriptor>();
m.addAll(extension.getCreateMenuList());
m.addAll(extension.getRemoveMenuList());
for (MenuDescriptor menuDescriptor : m) {
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
@SuppressWarnings("unchecked")
final Enumeration<DefaultMutableTreeNode> e = root.depthFirstEnumeration();
while (e.hasMoreElements()) {
final DefaultMutableTreeNode node = e.nextElement();
final Object userObject = node.getUserObject();
if (userObject != null) {
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);
}
}
}
}
}
 
@Override
public JComponent createLeftComponent() {
final JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
final GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 0;
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);
 
final DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer() {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final ActivableMutableTreeNode tr = (ActivableMutableTreeNode) value;
if (tr.getUserObject() instanceof Item) {
final String id = ((Item) tr.getUserObject()).getId();
value = id;
}
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) {
r.setForeground(new Color(50, 80, 150));
}
}
if (!tr.isActive()) {
r.setForeground(Color.LIGHT_GRAY);
}
return r;
}
};
 
treeRenderer.setLeafIcon(null);
tree.setCellRenderer(treeRenderer);
final JScrollPane comp2 = new JScrollPane(tree);
comp2.setMinimumSize(new Dimension(250, 150));
comp2.setPreferredSize(new Dimension(250, 150));
c.weighty = 1;
c.gridy++;
c.insets = new Insets(0, 0, 0, 0);
panel.add(comp2, c);
 
c.gridy++;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.SOUTHWEST;
c.insets = new Insets(2, 2, 2, 0);
final JButton addGroupButton = new JButton("Ajouter un menu");
panel.add(addGroupButton, c);
c.gridy++;
final JButton addItemButton = new JButton("Ajouter une action");
panel.add(addItemButton, c);
c.gridy++;
final JButton removeButton = new JButton("Supprimer ");
removeButton.setEnabled(false);
panel.add(removeButton, c);
 
c.gridy++;
final JCheckBox hideCheckbox = new JCheckBox("Afficher les champs masqués");
hideCheckbox.setSelected(true);
panel.add(hideCheckbox, c);
 
// Listeners
addGroupButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
addNewGroup();
}
 
});
addItemButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
addNewItem();
}
 
});
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final TreePath selectionPath = 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();
fillModel();
}
 
}
}
});
hideCheckbox.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
newModel.setShowAll(hideCheckbox.isSelected());
newModel.fillFromDescriptor(extension);
}
 
});
tree.addTreeSelectionListener(new TreeSelectionListener() {
 
@Override
public void valueChanged(TreeSelectionEvent e) {
final TreePath selectionPath = 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);
}
} else {
removeButton.setEnabled(false);
}
 
}
});
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
newModel.toggleActive(tree.getSelectionPath());
}
}
 
@Override
public void mousePressed(MouseEvent e) {
final TreePath selectionPath = tree.getSelectionPath();
if (selectionPath == null) {
setRightPanel(new JPanel());
} else {
Item i = (Item) ((DefaultMutableTreeNode) selectionPath.getLastPathComponent()).getUserObject();
setRightPanel(new MenuItemEditor(newModel, i, extension));
}
}
});
tree.getModel().addTreeModelListener(new TreeModelListener() {
 
@Override
public void treeStructureChanged(TreeModelEvent e) {
// Postpone expand because default behaviour is collapsing tree
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
expand();
}
});
}
 
@Override
public void treeNodesRemoved(TreeModelEvent e) {
}
 
@Override
public void treeNodesInserted(TreeModelEvent e) {
}
 
@Override
public void treeNodesChanged(TreeModelEvent e) {
}
});
return panel;
}
 
protected void addNewGroup() {
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (tree.getModel().getRoot())).getFirstChild();
DefaultMutableTreeNode node = root;
if (node.getChildCount() > 0) {
node = (DefaultMutableTreeNode) node.getFirstChild();
}
if (tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
}
if (node != root) {
final String newGroupId = "group" + node.getParent().getChildCount() + 1;
DefaultMutableTreeNode newNode = new ActivableMutableTreeNode(new Group(newGroupId));
final DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
parent.insert(newNode, parent.getIndex(node));
 
final MenuDescriptor desc = new MenuDescriptor(newGroupId);
desc.setType(MenuDescriptor.GROUP);
desc.setInsertInMenu(((Item) parent.getUserObject()).getId());
extension.addCreateMenu(desc);
extension.setChanged();
 
newModel.reload();
tree.setSelectionPath(new TreePath(newModel.getPathToRoot(newNode)));
}
extension.setChanged();
}
 
protected void addNewItem() {
final DefaultMutableTreeNode root = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) (tree.getModel().getRoot())).getFirstChild();
DefaultMutableTreeNode node = root;
if (node.getChildCount() > 0) {
node = (DefaultMutableTreeNode) node.getFirstChild();
}
if (tree.getSelectionPath() != null) {
node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
}
if (node != root) {
final String newActionId = "action" + node.getParent().getChildCount() + 1;
DefaultMutableTreeNode newNode = new ActivableMutableTreeNode(new Item(newActionId));
final DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
parent.insert(newNode, parent.getIndex(node));
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)));
}
 
}
 
// public Group getFilteredGroup() {
// // Parcours du Tree
// Group filteredGroup = new Group(n.getId());
//
// walk(newModel, filteredGroup, newModel.getRoot());
// filteredGroup = (Group) filteredGroup.getItem(0);
// filteredGroup.dumpTwoColumn();
// return filteredGroup;
// }
 
protected void walk(MenuItemTreeModel model, Group gr, Object o) {
int cc = model.getChildCount(o);
for (int i = 0; i < cc; i++) {
ActivableMutableTreeNode child = (ActivableMutableTreeNode) model.getChild(o, i);
if (child.isActive()) {
final Item userObject = (Item) child.getUserObject();
if (userObject instanceof Group) {
final Group item = new Group(userObject.getId());
item.setLocalHint(new LayoutHints(userObject.getLocalHint()));
gr.add(item);
walk(model, item, child);
} else {
final Item item = new Item(userObject.getId());
item.setLocalHint(new LayoutHints(userObject.getLocalHint()));
gr.add(item);
}
 
}
}
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionListPanel.java
New file
0,0 → 1,42
package org.openconcerto.modules.extensionbuilder;
 
import java.awt.GridLayout;
 
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
 
public class ExtensionListPanel extends JPanel {
private JPanel rPanel = new JPanel();
private JSplitPane split;
private ExtensionBuilderModule extensionBuilderModule;
final ExtensionMainListPanel newLeftComponent;
 
public ExtensionListPanel(ExtensionBuilderModule extensionBuilderModule) {
if (extensionBuilderModule == null) {
throw new IllegalArgumentException("null ExtensionBuilderModule");
}
this.extensionBuilderModule = extensionBuilderModule;
this.setLayout(new GridLayout(1, 1));
newLeftComponent = new ExtensionMainListPanel(this);
this.split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, newLeftComponent, rPanel);
this.add(this.split);
newLeftComponent.fill();
}
 
public void setRightPanel(JComponent p) {
this.invalidate();
this.split.setRightComponent(p);
this.revalidate();
this.repaint();
}
 
public ExtensionBuilderModule getExtensionBuilderModule() {
return extensionBuilderModule;
}
 
public void modelChanged() {
newLeftComponent.modelChanged();
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionListModel.java
New file
0,0 → 1,64
package org.openconcerto.modules.extensionbuilder;
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.openconcerto.modules.extensionbuilder.list.EditableListPanel;
import org.openconcerto.ui.DefaultListModel;
 
public class ExtensionListModel extends DefaultListModel implements ChangeListener {
 
private ExtensionListPanel moduleListPanel;
 
ExtensionListModel(ExtensionListPanel moduleListPanel) {
this.moduleListPanel = moduleListPanel;
}
 
public void fill(final EditableListPanel list) {
addAll(moduleListPanel.getExtensionBuilderModule().getExtensions());
final int size = this.getSize();
if (size > 0) {
final Object firstElement = firstElement();
list.selectItem(firstElement);
}
for (int i = 0; i < size; i++) {
Extension e = (Extension) this.get(i);
e.addChangeListener(this);
}
 
}
 
public void addNewModule() {
final Extension e = new Extension("extension " + (this.size() + 1));
this.addElement(e);
e.addChangeListener(this);
}
 
@Override
public void addElement(Object obj) {
final Extension e = (Extension) obj;
moduleListPanel.getExtensionBuilderModule().add(e);
e.addChangeListener(this);
super.addElement(obj);
}
 
@Override
public boolean removeElement(Object obj) {
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);
extenstion.removeChangeListener(this);
return super.removeElement(obj);
}
return false;
}
 
@Override
public void stateChanged(ChangeEvent e) {
moduleListPanel.modelChanged();
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionBuilderModule.java
New file
0,0 → 1,143
package org.openconcerto.modules.extensionbuilder;
 
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
 
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Log;
import org.openconcerto.erp.config.MainFrame;
import org.openconcerto.erp.modules.AbstractModule;
import org.openconcerto.erp.modules.ComponentsContext;
import org.openconcerto.erp.modules.DBContext;
import org.openconcerto.erp.modules.MenuContext;
import org.openconcerto.erp.modules.ModuleFactory;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.DBSystemRoot;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.utils.SQLCreateTable;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.utils.i18n.TranslationManager;
 
public final class ExtensionBuilderModule extends AbstractModule {
 
public static final String TABLE_NAME = "EXTENSION_XML";
private final ArrayList<Extension> extensions = new ArrayList<Extension>();
 
public ExtensionBuilderModule(ModuleFactory f) throws IOException {
super(f);
 
}
 
@Override
protected void install(DBContext ctxt) {
super.install(ctxt);
if (ctxt.getRoot().getTable(TABLE_NAME) == null) {
final SQLCreateTable createTable = ctxt.getCreateTable(TABLE_NAME);
createTable.addVarCharColumn("IDENTIFIER", 256);
createTable.addVarCharColumn("XML", 30000);
}
}
 
@Override
protected void setupComponents(ComponentsContext ctxt) {
// ctxt.putAdditionalField("CLIENT", "ID_FIDELITY_CARD");
 
}
 
@Override
protected void setupMenu(MenuContext ctxt) {
final DBRoot root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
final DBSystemRoot systemRoot = root.getDBSystemRoot();
 
// Load extensions
SQLSelect query = new SQLSelect(systemRoot, true);
final SQLTable table = systemRoot.findTable(ExtensionBuilderModule.TABLE_NAME);
query.addSelect(table.getField("IDENTIFIER"));
query.addSelect(table.getField("XML"));
 
@SuppressWarnings("unchecked")
final List<Map<String, String>> result = systemRoot.getDataSource().execute(query.asString());
if (result == null || result.isEmpty()) {
return;
}
for (Map<String, String> row : result) {
final Extension e = new Extension(row.get("IDENTIFIER"));
e.importFromXML(row.get("XML"));
this.extensions.add(e);
}
 
ctxt.addMenuItem(new AbstractAction("Gestionnaire d'extensions") {
 
@Override
public void actionPerformed(ActionEvent e) {
Log.get().info("Opening Extension Builder frame");
JFrame f = new JFrame("OpenConcerto Extension Builder - création simplifiée d'extensions");
f.setSize(800, 600);
f.setContentPane(new ExtensionListPanel(ExtensionBuilderModule.this));
f.setLocationRelativeTo(null);
FrameUtil.show(f);
}
}, "menu.extension");
 
// Start previously started extensions
for (Extension extension : extensions) {
if (extension.isAutoStart()) {
try {
extension.setupMenu(ctxt);
} catch (Throwable e) {
JOptionPane.showMessageDialog(new JFrame(), "Impossible de démarrer l'extension " + extension.getName() + "\n" + e.getMessage());
e.printStackTrace();
}
}
}
}
 
@Override
protected void start() {
Log.get().info("Starting Extension Builder");
final DBRoot root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
 
// Start previously started extensions
for (Extension extension : extensions) {
if (extension.isAutoStart()) {
try {
extension.start(root);
} catch (Throwable e) {
JOptionPane.showMessageDialog(new JFrame(), "Impossible de démarrer l'extension " + extension.getName() + "\n" + e.getMessage());
e.printStackTrace();
}
}
}
 
}
 
@Override
protected void stop() {
for (Extension extension : extensions) {
extension.stop();
}
this.extensions.clear();
}
 
public List<Extension> getExtensions() {
return this.extensions;
}
 
public void add(Extension e) {
this.extensions.add(e);
}
 
public void remove(Extension extension) {
this.extensions.remove(extension);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ModuleResources.properties
New file
0,0 → 1,2
name=Builder
description=Tool for simple modules creation
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ListDescriptor.java
New file
0,0 → 1,50
package org.openconcerto.modules.extensionbuilder.list;
 
import java.util.ArrayList;
import java.util.List;
 
public class ListDescriptor {
 
private final List<ColumnDescriptor> columns = new ArrayList<ColumnDescriptor>();
private String id;
 
private String mainTable;
 
public ListDescriptor(String id) {
this.id = id;
}
 
public String getId() {
return id;
}
 
public void setId(String id) {
this.id = id;
}
 
public void setMainTable(String mainTable) {
this.mainTable = mainTable;
}
 
public String getMainTable() {
return mainTable;
}
 
public List<ColumnDescriptor> getColumns() {
return columns;
}
 
@Override
public String toString() {
return this.id;
}
 
public void add(ColumnDescriptor f) {
this.columns.add(f);
 
}
 
public int getColumnCount() {
return this.columns.size();
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ColumnDescriptor.java
New file
0,0 → 1,50
package org.openconcerto.modules.extensionbuilder.list;
 
import java.util.ArrayList;
import java.util.List;
 
import org.openconcerto.utils.StringUtils;
 
public class ColumnDescriptor {
private List<String> fieldPaths = new ArrayList<String>();
private String id;
private String style = "concat";
 
public ColumnDescriptor(String id) {
this.id = id;
}
 
public String getId() {
return id;
}
 
public String getFieldsPaths() {
String r = "";
final int size = fieldPaths.size();
for (int i = 0; i < size; i++) {
String fieldPath = fieldPaths.get(i);
if (i != 0) {
r += ",";
}
r += fieldPath;
}
return r;
}
 
public void setFieldsPaths(String paths) {
final List<String> l = StringUtils.fastSplit(paths, ',');
fieldPaths.clear();
for (String string : l) {
fieldPaths.add(string.trim());
}
}
 
public String getStyle() {
return style;
}
 
public void setStyle(String style) {
this.style = style;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/CreateListListModel.java
New file
0,0 → 1,39
package org.openconcerto.modules.extensionbuilder.list;
 
import java.util.List;
 
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultListModel;
 
public class CreateListListModel extends DefaultListModel implements ChangeListener {
private final Extension extension;
 
CreateListListModel(Extension extension) {
this.extension = extension;
addContent();
extension.addChangeListener(this);
}
 
private void addContent() {
this.addAll(extension.getCreateListList());
}
 
@Override
public void stateChanged(ChangeEvent e) {
this.clear();
addContent();
}
 
public void addNewList() {
final ListDescriptor l = new ListDescriptor("liste " + (this.getSize() + 1));
final List<String> allKnownTableNames = extension.getAllKnownTableNames();
final String mainTable = allKnownTableNames.get(0);
l.setMainTable(mainTable);
this.addElement(l);
extension.addCreateList(l);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/AllTablesComboBoxModel.java
New file
0,0 → 1,19
package org.openconcerto.modules.extensionbuilder.list;
 
import java.util.List;
 
import javax.swing.DefaultComboBoxModel;
 
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class AllTablesComboBoxModel extends DefaultComboBoxModel {
 
public AllTablesComboBoxModel(Extension extension) {
List<String> l = extension.getAllKnownTableNames();
for (String n : l) {
this.addElement(n);
}
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ListCreatePanel.java
New file
0,0 → 1,63
package org.openconcerto.modules.extensionbuilder.list;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
 
public class ListCreatePanel extends JPanel {
 
private FieldDescSelector panel;
 
public ListCreatePanel(ListDescriptor n, Extension extension) {
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
c.gridwidth = 2;
 
this.add(new JLabelBold(n.getId()), c);
c.gridy++;
c.gridwidth = 1;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Table principale", SwingConstants.RIGHT), c);
c.gridx++;
c.fill = GridBagConstraints.NONE;
final JComboBox comboTable = new JComboBox(new AllTablesComboBoxModel(extension));
this.add(comboTable, c);
c.gridx = 0;
c.gridy++;
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 2;
c.fill = GridBagConstraints.BOTH;
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));
} else {
comboTable.setSelectedItem(mainTable);
panel.setMainTable(mainTable);
}
this.add(panel, c);
 
comboTable.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
panel.setMainTable((String) comboTable.getSelectedItem());
 
}
});
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ref.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ref.png
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/FieldDescSelector.java
New file
0,0 → 1,224
package org.openconcerto.modules.extensionbuilder.list;
 
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
 
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.table.FieldDescriptor;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.DefaultListModel;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.list.ReorderableJList;
 
public class FieldDescSelector extends JPanel {
private FieldTreeModel treeModel;
private DefaultListModel listModel;
private final JTree tree;
private JList list;
private ListDescriptor listDescriptor;
 
FieldDescSelector(ListDescriptor desc, Extension extension) {
this.listDescriptor = desc;
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
this.add(new JLabelBold("Champs disponibles"), c);
c.gridx += 2;
this.add(new JLabelBold("Colonnes affichés"), c);
 
// Col 0
c.gridx = 0;
c.gridy++;
treeModel = new FieldTreeModel(extension);
this.tree = new JTree(treeModel) {
@Override
public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
if (userObject == null)
return "null";
FieldDescriptor d = (FieldDescriptor) userObject;
 
if (d.getForeignTable() != null) {
return " " + d.getName() + " référence vers la table " + d.getForeignTable();
}
return " " + d.getName();
}
};
tree.setRootVisible(false);
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);
c.gridheight = 2;
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
this.add(new JScrollPane(tree), c);
// Col 1
c.gridx = 1;
c.gridheight = 1;
c.weightx = 0;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.NORTH;
final JButton buttonAdd = new JButton(">");
this.add(buttonAdd, c);
c.gridy++;
final JButton buttonRemove = new JButton("<");
this.add(buttonRemove, c);
// Col 2
c.gridx = 2;
c.gridy--;
c.gridheight = 2;
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
listModel = new DefaultListModel() {
@Override
public void addElement(Object obj) {
if (!(obj instanceof ColumnDescriptor)) {
throw new IllegalArgumentException(obj + " is not a ColumnDescriptor");
}
super.addElement(obj);
}
 
};
list = new ReorderableJList();
list.setModel(listModel);
list.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
ColumnDescriptor f = (ColumnDescriptor) value;
String label = f.getFieldsPaths();
return super.getListCellRendererComponent(list, label, index, isSelected, cellHasFocus);
}
});
this.add(new JScrollPane(list), c);
// Listeners
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
addTreeSelectionToList();
}
}
 
});
buttonAdd.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
addTreeSelectionToList();
 
}
});
buttonRemove.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
deleteSelectedInList();
 
}
});
list.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
deleteSelectedInList();
}
e.consume();
}
});
 
}
 
public void setMainTable(String table) {
treeModel.fillFromTable(table);
listModel.removeAllElements();
for (ColumnDescriptor d : this.listDescriptor.getColumns()) {
this.listModel.addElement(d);
}
}
 
private void deleteSelectedInList() {
Object[] vals = list.getSelectedValues();
if (vals == null)
return;
for (int i = 0; i < vals.length; i++) {
Object object = vals[i];
this.listModel.removeElement(object);
}
list.clearSelection();
}
 
private void addTreeSelectionToList() {
final TreePath[] paths = tree.getSelectionPaths();
if (paths == null)
return;
for (int i = 0; i < paths.length; i++) {
TreePath treePath = paths[i];
Object[] obj = treePath.getPath();
FieldDescriptor d = null;
FieldDescriptor root = null;
for (int j = 0; j < obj.length; j++) {
final Object object = obj[j];
if (object != null) {
final FieldDescriptor f = (FieldDescriptor) (((DefaultMutableTreeNode) object).getUserObject());
if (f != null) {
final FieldDescriptor fieldDescriptor = new FieldDescriptor(f);
if (root == null) {
root = fieldDescriptor;
 
}
if (d != null) {
d.setLink(fieldDescriptor);
}
d = fieldDescriptor;
}
}
}
 
// On ne met pas les foreigns keys
if (d != null && root != null) {
boolean add = true;
final String extendedLabel = root.getPath();
final int size = listModel.getSize();
// Check if already in the list
for (int j = 0; j < size; j++) {
if (((ColumnDescriptor) listModel.getElementAt(j)).getFieldsPaths().contains(extendedLabel)) {
add = false;
break;
}
}
if (add) {
final ColumnDescriptor colDesc = new ColumnDescriptor(root.getPath());
colDesc.setFieldsPaths(root.getPath());
listModel.addElement(colDesc);
listDescriptor.add(colDesc);
}
}
}
tree.clearSelection();
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/FieldTreeModel.java
New file
0,0 → 1,90
package org.openconcerto.modules.extensionbuilder.list;
 
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.table.FieldDescriptor;
import org.openconcerto.modules.extensionbuilder.table.TableDescritor;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLTable;
 
public class FieldTreeModel extends DefaultTreeModel {
 
private Extension extension;
private Set<FieldDescriptor> allFields = new HashSet<FieldDescriptor>();
 
public FieldTreeModel(Extension extension) {
super(null, false);
this.extension = extension;
}
 
public void fillFromTable(String table) {
System.out.println("FieldTreeModel.fillFromTable():" + table);
final DefaultMutableTreeNode root = new DefaultMutableTreeNode();
if (table == null) {
this.setRoot(root);
return;
}
addToTreeNode(root, table, 0);
this.setRoot(root);
}
 
void addToTreeNode(DefaultMutableTreeNode node, String tableName, int depth) {
if (depth > 4) {
return;
}
depth++;
// 1/ On regarde depuis le CreateTable
TableDescritor desc = this.extension.getTableListDescriptor(tableName);
if (desc == null) {
// 2/ On regarde dans la base
try {
SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(tableName);
if (t != null) {
desc = new TableDescritor(t.getName());
Set<SQLField> fields = t.getFields();
for (SQLField sqlField : fields) {
String name = sqlField.getName();
String table = null;
final SQLTable foreignTable = sqlField.getForeignTable();
if (foreignTable != null && foreignTable.getDBRoot().equals(t.getDBRoot())) {
table = foreignTable.getName();
}
if (!sqlField.isPrimaryKey() && !name.equals("ORDRE") && !name.equals("ARCHIVE") && !name.startsWith("ID_USER_COMMON")) {
FieldDescriptor d = new FieldDescriptor(tableName, name, "", "", "", table);
desc.add(d);
}
}
desc.sortFields();
}
} catch (Exception e) {
desc = null;
}
}
if (desc != null) {
List<FieldDescriptor> fields = desc.getFields();
for (FieldDescriptor fieldDescriptor : fields) {
final DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(fieldDescriptor);
node.add(newChild);
this.allFields.add(fieldDescriptor);
if (fieldDescriptor.getForeignTable() != null) {
addToTreeNode(newChild, fieldDescriptor.getForeignTable(), depth);
newChild.setAllowsChildren(true);
} else {
newChild.setAllowsChildren(false);
}
}
this.setRoot(root);
}
}
 
public boolean containsFieldDescritor(FieldDescriptor d) {
return this.allFields.contains(d);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ListCreateMainPanel.java
New file
0,0 → 1,24
package org.openconcerto.modules.extensionbuilder.list;
 
import javax.swing.JComponent;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class ListCreateMainPanel extends AbstractSplittedPanel {
 
public ListCreateMainPanel(Extension extension) {
super(extension);
}
 
@Override
public JComponent createLeftComponent() {
return new ListListPanel(extension, this);
}
 
public void select(ListDescriptor listDescriptor) {
// TODO selectionner
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/EditableListPanel.java
New file
0,0 → 1,168
package org.openconcerto.modules.extensionbuilder.list;
 
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
 
public abstract class EditableListPanel extends JPanel {
 
protected JList list;
protected ListModel dataModel;
private JButton removeButton = null;
private JButton renameButton = null;
 
public EditableListPanel(final ListModel dataModel, String title, String addLabel) {
this(dataModel, title, addLabel, true, true);
}
 
public EditableListPanel(final ListModel dataModel, String title, String addLabel, boolean editable, boolean canRename) {
this.dataModel = dataModel;
this.setOpaque(false);
 
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 0;
c.insets = new Insets(2, 2, 2, 0);
if (title != null) {
this.add(new JLabel(title), c);
}
list = new JList(dataModel);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane comp2 = new JScrollPane(list);
comp2.setMinimumSize(new Dimension(150, 150));
comp2.setPreferredSize(new Dimension(150, 150));
c.weighty = 1;
c.gridy++;
c.insets = new Insets(0, 0, 0, 0);
this.add(comp2, c);
 
if (editable) {
 
c.gridy++;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.SOUTHWEST;
c.insets = new Insets(2, 2, 2, 0);
final JButton addButton = new JButton(addLabel);
this.add(addButton, c);
c.gridy++;
if (canRename) {
renameButton = new JButton("Renommer");
this.add(renameButton, c);
renameButton.setEnabled(false);
renameButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
if (list.getSelectedValue() != null) {
renameItem(list.getSelectedValue());
}
}
 
});
c.gridy++;
}
 
removeButton = new JButton("Supprimer");
removeButton.setEnabled(false);
this.add(removeButton, c);
 
// init
 
addButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
addNewItem();
if (dataModel.getSize() > 0) {
selectItem(dataModel.getElementAt(dataModel.getSize() - 1));
}
}
 
});
 
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (list.getSelectedValue() != null) {
removeItem(list.getSelectedValue());
}
}
});
}
list.addListSelectionListener(new ListSelectionListener() {
 
@Override
public void valueChanged(ListSelectionEvent e) {
final Object selectedValue = list.getSelectedValue();
if (removeButton != null) {
removeButton.setEnabled(selectedValue != null);
}
if (renameButton != null) {
renameButton.setEnabled(selectedValue != null);
}
if (!e.getValueIsAdjusting() && selectedValue != null) {
 
itemSelected(selectedValue);
 
}
if (selectedValue == null) {
itemSelected(null);
}
 
}
});
 
}
 
/**
* Select an item in the list
* */
public void selectItem(Object item) {
list.setSelectedValue(item, true);
}
 
/**
* Called when the user click "add"
* */
public abstract void addNewItem();
 
/**
* Called when the user click "rename"
* */
public abstract void renameItem(Object item);
 
/**
* Called when the user click "remove"
* */
public abstract void removeItem(Object item);
 
/**
* Called when the user select an item in the list
*
* @param item the item, null if all the items are deselected
* */
public abstract void itemSelected(Object item);
 
public void reload() {
list.invalidate();
list.repaint();
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/list/ListListPanel.java
New file
0,0 → 1,53
package org.openconcerto.modules.extensionbuilder.list;
 
import java.awt.Window;
 
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
 
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class ListListPanel extends EditableListPanel {
 
private final Extension extension;
private final ListCreateMainPanel tableInfoPanel;
 
public ListListPanel(final Extension extension, final ListCreateMainPanel tableInfoPanel) {
super(new CreateListListModel(extension), "Listes", "Ajouter une liste");
this.extension = extension;
this.tableInfoPanel = tableInfoPanel;
}
 
@Override
public void addNewItem() {
((CreateListListModel) dataModel).addNewList();
}
 
@Override
public void renameItem(Object item) {
final ListDescriptor e = (ListDescriptor) 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.getId());
if ((s != null) && (s.length() > 0)) {
e.setId(s);
}
}
 
@Override
public void removeItem(Object item) {
((CreateListListModel) dataModel).removeElement(item);
extension.removeCreateList((ListDescriptor) item);
}
 
@Override
public void itemSelected(Object item) {
if (item != null) {
ListDescriptor n = (ListDescriptor) item;
final ListCreatePanel p = new ListCreatePanel(n, extension);
tableInfoPanel.setRightPanel(p);
} else {
tableInfoPanel.setRightPanel(new JPanel());
}
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/AbstractSplittedPanel.java
New file
0,0 → 1,32
package org.openconcerto.modules.extensionbuilder;
 
import java.awt.GridLayout;
 
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
 
public abstract class AbstractSplittedPanel extends JPanel {
protected JSplitPane split;
protected JComponent leftComponent;
protected Extension extension;
 
public AbstractSplittedPanel(Extension extension) {
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);
}
 
public void setRightPanel(JComponent p) {
this.invalidate();
split.setRightComponent(p);
this.revalidate();
this.repaint();
}
 
public abstract JComponent createLeftComponent();
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionMainListPanel.java
New file
0,0 → 1,77
package org.openconcerto.modules.extensionbuilder;
 
import java.awt.Component;
import java.awt.Window;
 
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
 
import org.openconcerto.modules.extensionbuilder.list.EditableListPanel;
 
public class ExtensionMainListPanel extends EditableListPanel {
 
private ExtensionListPanel moduleListPanel;
 
ExtensionMainListPanel(final ExtensionListPanel moduleListPanel) {
super(new ExtensionListModel(moduleListPanel), "Vos extensions", "Créer une extension");
this.moduleListPanel = moduleListPanel;
this.list.setFixedCellHeight(new JLabel("A").getPreferredSize().height + 8);
this.list.setCellRenderer(new DefaultListCellRenderer() {
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;
if (e.isStarted()) {
listCellRendererComponent.setIcon(new ImageIcon(ExtensionMainListPanel.this.getClass().getResource("started.png")));
}
return listCellRendererComponent;
}
 
});
}
 
public void fill() {
((ExtensionListModel) dataModel).fill(this);
 
}
 
@Override
public void addNewItem() {
((ExtensionListModel) dataModel).addNewModule();
}
 
@Override
public void renameItem(Object item) {
final Extension e = (Extension) item;
final Window w = SwingUtilities.windowForComponent(this);
final String s = (String) JOptionPane.showInputDialog(w, "Nouveau nom", "Renommer l'extension", JOptionPane.PLAIN_MESSAGE, null, null, e.getName());
if ((s != null) && (s.length() > 0)) {
e.setName(s);
}
}
 
@Override
public void removeItem(Object item) {
((ExtensionListModel) dataModel).removeElement(item);
}
 
@Override
public void itemSelected(Object item) {
if (item != null) {
final ExtensionInfoPanel p = new ExtensionInfoPanel((Extension) item, moduleListPanel);
moduleListPanel.setRightPanel(p);
} else {
moduleListPanel.setRightPanel(new JPanel());
}
 
}
 
public void modelChanged() {
list.invalidate();
list.repaint();
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/translation_fr.xml
New file
0,0 → 1,3
<translation lang="fr">
<menu id="menu.extension" label="Extensions" />
</translation>
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/ActionMainPanel.java
New file
0,0 → 1,18
package org.openconcerto.modules.extensionbuilder.meu.actions;
 
import javax.swing.JComponent;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class ActionMainPanel extends AbstractSplittedPanel {
 
public ActionMainPanel(Extension extension) {
super(extension);
}
 
@Override
public JComponent createLeftComponent() {
return new ActionListPanel(extension, this);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/ActionItemEditor.java
New file
0,0 → 1,181
package org.openconcerto.modules.extensionbuilder.meu.actions;
 
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.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;
 
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.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.component.ComponentDescritor;
import org.openconcerto.ui.DefaultGridBagConstraints;
 
public class ActionItemEditor extends JPanel {
 
final Extension extension;
private JTextField textId;
private JComboBox comboComponent;
private JTextField textTable;
private JComboBox comboLocation;
 
public ActionItemEditor(final ActionDescriptor actionDescriptor, final Extension extension) {
this.extension = extension;
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
 
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Identifiant", SwingConstants.RIGHT), c);
c.gridx++;
 
c.weightx = 1;
 
textId = new JTextField();
this.add(textId, c);
 
//
final List<ComponentDescritor> l = extension.getCreateComponentList();
final Vector<ComponentDescritor> v = new Vector<ComponentDescritor>(l);
Collections.sort(v, new Comparator<ComponentDescritor>() {
 
@Override
public int compare(ComponentDescritor o1, ComponentDescritor o2) {
return o1.getId().compareTo(o2.getId());
}
});
c.gridx = 0;
c.gridy++;
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Composant", SwingConstants.RIGHT), c);
c.gridx++;
comboComponent = new JComboBox(v);
comboComponent.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
value = ((ComponentDescritor) value).getId();
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
});
c.fill = GridBagConstraints.NONE;
this.add(comboComponent, c);
 
c.gridx = 0;
c.gridy++;
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
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);
// Location
c.gridx = 0;
c.gridy++;
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
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);
c.gridy++;
c.weighty = 1;
this.add(new JPanel(), c);
 
initUIFrom(actionDescriptor);
 
comboComponent.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
final ComponentDescritor componentDescritor = getComponentDescritor(comboComponent.getSelectedItem().toString());
if (componentDescritor != null) {
textTable.setText(componentDescritor.getTable());
actionDescriptor.setComponentId(componentDescritor.getId());
actionDescriptor.setTable(componentDescritor.getTable());
} else {
textTable.setText("");
}
}
});
comboLocation.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
int index = comboLocation.getSelectedIndex();
if (index == 0) {
actionDescriptor.setLocation(ActionDescriptor.LOCATION_HEADER_POPUP);
} else if (index == 1) {
actionDescriptor.setLocation(ActionDescriptor.LOCATION_POPUP);
} else {
actionDescriptor.setLocation(ActionDescriptor.LOCATION_HEADER);
}
 
}
});
textId.getDocument().addDocumentListener(new DocumentListener() {
 
@Override
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
 
}
 
@Override
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
 
}
 
@Override
public void changedUpdate(DocumentEvent e) {
actionDescriptor.setId(textId.getText());
}
});
 
}
 
private void initUIFrom(ActionDescriptor item) {
 
textId.setText(item.getId());
final ComponentDescritor componentDescritor = getComponentDescritor(item.getComponentId());
if (componentDescritor != null) {
comboComponent.setSelectedItem(componentDescritor);
}
textTable.setText(item.getTable());
String loc = item.getLocation();
if (loc.equals(ActionDescriptor.LOCATION_HEADER_POPUP)) {
comboLocation.setSelectedIndex(0);
} else if (loc.equals(ActionDescriptor.LOCATION_HEADER)) {
comboLocation.setSelectedIndex(2);
} else {
comboLocation.setSelectedIndex(1);
}
}
 
private ComponentDescritor getComponentDescritor(String componentId) {
List<ComponentDescritor> l = extension.getCreateComponentList();
for (ComponentDescritor componentDescritor : l) {
if (componentDescritor.getId().equals(componentId)) {
return componentDescritor;
}
}
return null;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/AllKnownActionsListModel.java
New file
0,0 → 1,14
package org.openconcerto.modules.extensionbuilder.meu.actions;
 
import java.util.List;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultListModel;
 
public class AllKnownActionsListModel extends DefaultListModel {
 
public AllKnownActionsListModel(Extension module) {
List<ActionDescriptor> l = module.getActionDescriptors();
this.addAll(l);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/ActionListPanel.java
New file
0,0 → 1,61
package org.openconcerto.modules.extensionbuilder.meu.actions;
 
import java.awt.Component;
import java.awt.Window;
 
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.list.EditableListPanel;
 
public class ActionListPanel extends EditableListPanel {
 
private ActionMainPanel tableTranslationPanel;
private Extension extension;
 
public ActionListPanel(Extension extension, ActionMainPanel tableTranslationPanel) {
super(new AllKnownActionsListModel(extension), "Actions", "", true, true);
this.extension = extension;
this.tableTranslationPanel = tableTranslationPanel;
list.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
value = ((ActionDescriptor) value).getId();
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
});
}
 
@Override
public void addNewItem() {
}
 
@Override
public void renameItem(Object item) {
final ActionDescriptor e = (ActionDescriptor) 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.getId());
if ((s != null) && (s.length() > 0)) {
e.setId(s);
}
}
 
@Override
public void removeItem(Object item) {
}
 
@Override
public void itemSelected(Object item) {
if (item != null) {
tableTranslationPanel.setRightPanel(new JScrollPane(new ActionItemEditor((ActionDescriptor) item, extension)));
} else {
tableTranslationPanel.setRightPanel(new JPanel());
}
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/meu/actions/ActionDescriptor.java
New file
0,0 → 1,49
package org.openconcerto.modules.extensionbuilder.meu.actions;
 
public class ActionDescriptor {
 
private String id;
private String location; // 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";
 
public ActionDescriptor(String id) {
this.id = id;
}
 
public String getId() {
return id;
}
 
public void setId(String id) {
this.id = id;
}
 
public String getLocation() {
return location;
}
 
public void setLocation(String location) {
this.location = location;
}
 
public String getTable() {
return table;
}
 
public void setTable(String table) {
this.table = table;
}
 
public String getComponentId() {
return componentId;
}
 
public void setComponentId(String componentId) {
this.componentId = componentId;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableCreatePanel.java
New file
0,0 → 1,95
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
 
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.DefaultListModel;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.utils.Tuple2;
 
public class TableCreatePanel extends JPanel {
private final Extension extension;
 
public TableCreatePanel(final TableDescritor desc, final Extension extension) {
this.extension = extension;
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
this.add(new JLabelBold("Table " + desc.getName()), c);
c.weightx = 1;
c.gridy++;
final Tuple2<JPanel, GridBagConstraints> l = createEditorList(desc);
this.add(l.get0(), c);
c.gridy++;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.WEST;
JButton buttonAdd = new JButton("Ajouter un champs");
 
this.add(buttonAdd, c);
c.gridy++;
JPanel spacer = new JPanel();
c.weighty = 1;
this.add(spacer, c);
buttonAdd.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
FieldDescriptor f = new FieldDescriptor(desc.getName(), "field" + ((l.get0().getComponentCount() / 2) + 1), "string", "", "200", "");
GridBagConstraints c1 = l.get1();
desc.add(f);
addField(desc, l.get0(), c1, f);
l.get0().revalidate();
extension.setChanged();
}
});
 
}
 
Tuple2<JPanel, GridBagConstraints> createEditorList(final TableDescritor desc) {
JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
List<FieldDescriptor> fields = desc.getFields();
for (final FieldDescriptor field : fields) {
addField(desc, p, c, field);
}
Tuple2<JPanel, GridBagConstraints> result = Tuple2.create(p, c);
return result;
 
}
 
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(field);
p.add(editor, c);
 
c.gridx++;
c.weightx = 0;
final JButton close = new JButton(new ImageIcon(DefaultListModel.class.getResource("close_popup.png")));
 
p.add(close, c);
close.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
desc.remove(field);
p.remove(editor);
p.remove(close);
p.revalidate();
extension.setChanged();
}
});
c.gridy++;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableModifyInfoPanel.java
New file
0,0 → 1,236
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
 
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.modules.extensionbuilder.ClickableLabel;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.DefaultListModel;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.utils.Tuple2;
 
public class TableModifyInfoPanel extends JPanel implements Scrollable {
// TODO: tooltip sur un champs pour indiquer quelles extensions l'utilisent
 
public TableModifyInfoPanel(SQLTable t, final TableDescritor desc, final TableModifyLeftPanel leftPanel) {
this.setLayout(new GridBagLayout());
this.setBackground(Color.WHITE);
GridBagConstraints c = new DefaultGridBagConstraints();
c.weightx = 1;
 
Set<SQLField> fields = t.getFields();
List<SQLField> allFields = new ArrayList<SQLField>();
for (SQLField sqlField : fields) {
final String fName = sqlField.getName();
if (!fName.equalsIgnoreCase("ARCHIVE") && !fName.equalsIgnoreCase("ORDRE")) {
allFields.add(sqlField);
}
}
Collections.sort(allFields, new Comparator<SQLField>() {
 
@Override
public int compare(SQLField o1, SQLField o2) {
 
return o1.getName().compareTo(o2.getName());
}
});
 
List<SQLTable> lt = new ArrayList<SQLTable>(t.getDBSystemRoot().getGraph().getReferentTables(t));
Collections.sort(lt, new Comparator<SQLTable>() {
 
@Override
public int compare(SQLTable o1, SQLTable o2) {
 
return o1.getName().compareTo(o2.getName());
}
});
if (lt.size() > 0) {
this.add(new JLabel(lt.size() + " champs des tables suivantes référencent la table " + t.getName() + " :"), c);
c.gridy++;
c.weightx = 0;
for (final SQLTable sqlTable : lt) {
this.add(new ClickableLabel(sqlTable.getName(), new Runnable() {
 
@Override
public void run() {
leftPanel.selectTable(sqlTable.getName());
 
}
}), c);
c.gridy++;
}
c.gridy++;
c.weightx = 1;
this.add(new JLabel(" "), c);
c.gridy++;
}
this.add(new JLabel("Cette table contient " + allFields.size() + " champs :"), c);
 
c.gridy++;
for (SQLField sqlField : allFields) {
String str = "";
 
JPanel line = new JPanel();
line.add(new JLabelBold(sqlField.getName()));
line.setOpaque(false);
line.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
try {
String label = ComptaPropsConfiguration.getTranslator(t).getLabelFor(sqlField);
if (label != null) {
str += " (" + label + ")";
}
} catch (Exception e) {
// No label...
}
String type = sqlField.getTypeDecl().toLowerCase();
if (type.contains("double") || type.contains("real") || type.contains("float")) {
type = "nombre décimal";
} else if (type.contains("int")) {
type = "nombre entier";
} else if (type.contains("text") || type.contains("varchar")) {
type = "texte";
} else if (type.contains("boolean")) {
type = "booléen";
} else if (type.contains("timestamp")) {
type = "date et heure";
}
if (sqlField.isKey() && sqlField.getForeignTable() != null) {
final SQLTable foreignTable = sqlField.getForeignTable();
str += " référence vers la table ";
line.add(new JLabel(str));
if (foreignTable.getDBRoot().equals(t.getDBRoot())) {
line.add(new ClickableLabel(foreignTable.getName(), new Runnable() {
@Override
public void run() {
leftPanel.selectTable(foreignTable.getName());
}
}));
} else {
line.add(new JLabel(foreignTable.getName()));
}
SQLElement e = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(foreignTable);
if (e != null) {
line.add(new JLabel(" (cad " + e.getSingularName() + ")"));
}
 
} else if (sqlField.isPrimaryKey()) {
str += " clef primaire";
line.add(new JLabel(str));
} else {
str += " de type " + type;
line.add(new JLabel(str));
}
 
this.add(line, c);
c.gridy++;
}
 
final JPanel spacer = new JPanel();
spacer.setOpaque(false);
c.weighty = 1;
c.gridy++;
this.add(spacer, c);
 
}
 
Tuple2<JPanel, GridBagConstraints> createEditorList(final TableDescritor desc) {
JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
List<FieldDescriptor> fields = desc.getFields();
for (final FieldDescriptor field : fields) {
addField(desc, p, c, field);
}
Tuple2<JPanel, GridBagConstraints> result = Tuple2.create(p, c);
return result;
 
}
 
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(field);
p.add(editor, c);
 
c.gridx++;
c.weightx = 0;
final JButton close = new JButton(new ImageIcon(DefaultListModel.class.getResource("close_popup.png")));
 
p.add(close, c);
close.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
desc.remove(field);
p.remove(editor);
p.remove(close);
p.revalidate();
}
});
c.gridy++;
}
 
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
 
public int getScrollableUnitIncrement(final Rectangle visibleRect, final int orientation, final int direction) {
switch (orientation) {
case SwingConstants.VERTICAL:
return visibleRect.height / 10;
case SwingConstants.HORIZONTAL:
return visibleRect.width / 10;
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
 
public int getScrollableBlockIncrement(final Rectangle visibleRect, final int orientation, final int direction) {
switch (orientation) {
case SwingConstants.VERTICAL:
return visibleRect.height;
case SwingConstants.HORIZONTAL:
return visibleRect.width;
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
 
public boolean getScrollableTracksViewportWidth() {
if (getParent() instanceof JViewport) {
return ((JViewport) getParent()).getWidth() > getPreferredSize().width;
}
return false;
}
 
public boolean getScrollableTracksViewportHeight() {
if (getParent() instanceof JViewport) {
return ((JViewport) getParent()).getHeight() > getPreferredSize().height;
}
return false;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/AllTableListModel.java
New file
0,0 → 1,41
package org.openconcerto.modules.extensionbuilder.table;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.ui.DefaultListModel;
 
public class AllTableListModel extends DefaultListModel {
 
public AllTableListModel(Extension module) {
 
final List<SQLTable> tables = getAllDatabaseTables();
this.addAll(tables);
}
 
/**
* Retourne les tables de la base (limité au schema de la société)
* */
public static List<SQLTable> getAllDatabaseTables() {
final Set<SQLTable> res = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTables();
final List<SQLTable> tables = new ArrayList<SQLTable>();
// TODO: filtrer les FWK_**
tables.addAll(res);
Collections.sort(tables, new Comparator<SQLTable>() {
 
@Override
public int compare(SQLTable o1, SQLTable o2) {
 
return o1.getName().compareTo(o2.getName());
}
});
return tables;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableCreateMainPanel.java
New file
0,0 → 1,22
package org.openconcerto.modules.extensionbuilder.table;
 
import javax.swing.JComponent;
 
import org.openconcerto.modules.extensionbuilder.AbstractSplittedPanel;
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class TableCreateMainPanel extends AbstractSplittedPanel {
 
public TableCreateMainPanel(Extension extension) {
super(extension);
}
 
public void select(TableDescritor tableDescriptor) {
((TableListPanel) leftComponent).selectItem(tableDescriptor);
}
 
@Override
public JComponent createLeftComponent() {
return new TableListPanel(extension, this);
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/ForbiddenFieldName.java
New file
0,0 → 1,9
package org.openconcerto.modules.extensionbuilder.table;
 
public class ForbiddenFieldName {
public static boolean isAllowed(String field) {
String f = field.toUpperCase();
return !(f.equals("ARCHIVE") || f.equals("ORDRE") || f.equals("ID_USER_CREATE") || f.equals("ID_USER_COMMON_CREATE") || f.equals("ID_USER_MODIFY") || f.equals("ID_USER_COMMON_MODIFY")
|| f.equals("MODIFICATION_DATE") || f.equals("CREATION_DATE"));
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableListPanel.java
New file
0,0 → 1,56
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.Window;
 
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.list.EditableListPanel;
 
public class TableListPanel extends EditableListPanel {
 
private final Extension extension;
private final TableCreateMainPanel tableInfoPanel;
 
public TableListPanel(final Extension extension, final TableCreateMainPanel tableInfoPanel) {
super(new CreateTableListModel(extension), "Tables", "Ajouter une table");
this.extension = extension;
this.tableInfoPanel = tableInfoPanel;
}
 
@Override
public void addNewItem() {
((CreateTableListModel) dataModel).addNewTable();
}
 
@Override
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());
if ((s != null) && (s.length() > 0)) {
e.setName(s);
}
}
 
@Override
public void removeItem(Object item) {
((CreateTableListModel) dataModel).removeElement(item);
extension.removeCreateTable((TableDescritor) item);
}
 
@Override
public void itemSelected(Object item) {
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));
} else {
tableInfoPanel.setRightPanel(new JPanel());
}
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/ModifiedTableListModel.java
New file
0,0 → 1,39
package org.openconcerto.modules.extensionbuilder.table;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultListModel;
 
public class ModifiedTableListModel extends DefaultListModel implements ChangeListener {
private final Extension extension;
 
ModifiedTableListModel(Extension extension) {
this.extension = extension;
addContent(extension);
extension.addChangeListener(this);
}
 
private void addContent(Extension extension) {
final List<TableDescritor> modifyTableList = extension.getModifyTableList();
final ArrayList<TableDescritor> newList = new ArrayList<TableDescritor>(modifyTableList.size());
for (TableDescritor tableDescritor : modifyTableList) {
if (tableDescritor.getFields().size() > 0) {
newList.add(tableDescritor);
}
}
this.addAll(newList);
}
 
@Override
public void stateChanged(ChangeEvent e) {
this.clear();
addContent(extension);
this.fireContentsChanged(this, 0, this.getSize());
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableDescritor.java
New file
0,0 → 1,102
package org.openconcerto.modules.extensionbuilder.table;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Log;
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.modules.extensionbuilder.component.ComponentDescritor;
import org.openconcerto.modules.extensionbuilder.menu.mainmenu.MenuDescriptor;
import org.openconcerto.sql.element.GroupSQLComponent;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLTable;
 
public class TableDescritor {
private String name;
private List<FieldDescriptor> fields = new ArrayList<FieldDescriptor>();
 
public TableDescritor(String string) {
this.name = string;
 
}
 
public void createElement(final Extension ext) {
// 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) {
 
@Override
protected List<String> getListFields() {
return new ArrayList<String>(0);
}
 
@Override
protected SQLComponent createComponent() {
 
for (final ComponentDescritor cDescriptor : ext.getCreateComponentList()) {
if (cDescriptor.getTable().equals(table.getTable().getName())) {
 
final GroupSQLComponent gComponent = new GroupSQLComponent(this, cDescriptor.getGroup());
return gComponent;
 
}
}
JOptionPane.showMessageDialog(new JFrame(), "Unable to create default creation component for table " + name);
return null;
}
};
conf.getDirectory().addSQLElement(e);
Log.get().info("Autocreate element for table: " + table.getName());
}
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
public List<FieldDescriptor> getFields() {
return fields;
}
 
public void add(FieldDescriptor f) {
fields.add(f);
 
}
 
public void remove(FieldDescriptor field) {
fields.remove(field);
 
}
 
@Override
public String toString() {
return name;
}
 
public void sortFields() {
Collections.sort(this.fields, new Comparator<FieldDescriptor>() {
 
@Override
public int compare(FieldDescriptor o1, FieldDescriptor o2) {
return o1.getName().compareToIgnoreCase(o2.getName());
}
});
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableMainPanel.java
New file
0,0 → 1,28
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.GridLayout;
 
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
 
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class TableMainPanel extends JPanel {
 
private TableCreateMainPanel component;
 
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);
tab.addTab("Tables modifiées", new TableModifyMainPanel(extension));
this.add(tab);
}
 
public void select(TableDescritor tableDescriptor) {
component.select(tableDescriptor);
 
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableModifyPanel.java
New file
0,0 → 1,113
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
 
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.DefaultListModel;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.utils.Tuple2;
 
public class TableModifyPanel extends JPanel {
private final Extension extension;
 
// TODO: tooltip sur un champs pour indiquer quels modules l'utilisent
 
public TableModifyPanel(SQLTable t, final TableDescritor desc, final Extension extension, final TableModifyLeftPanel leftPanel) {
this.extension = extension;
this.setLayout(new GridBagLayout());
 
GridBagConstraints c = new DefaultGridBagConstraints();
c.weightx = 1;
this.add(new JLabelBold("Table " + desc.getName()), c);
 
c.weightx = 1;
c.gridy++;
final Tuple2<JPanel, GridBagConstraints> l = createEditorList(desc);
this.add(l.get0(), c);
c.gridy++;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.WEST;
JButton buttonAdd = new JButton("Ajouter un champs");
 
this.add(buttonAdd, c);
c.gridy++;
if (t != null) {
this.add(new JLabel("Structure actuelle dans la base de données"), c);
 
c.gridy++;
TableModifyInfoPanel info = new TableModifyInfoPanel(t, desc, leftPanel);
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
this.add(new JScrollPane(info), c);
} else {
final JPanel spacer = new JPanel();
spacer.setOpaque(false);
c.weighty = 1;
 
this.add(spacer, c);
}
buttonAdd.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
FieldDescriptor f = new FieldDescriptor(desc.getName(), "field" + ((l.get0().getComponentCount() / 2) + 1), "string", "", "200", "");
desc.add(f);
GridBagConstraints c1 = l.get1();
addField(desc, l.get0(), c1, f);
l.get0().revalidate();
extension.setChanged();
}
});
}
 
private Tuple2<JPanel, GridBagConstraints> createEditorList(final TableDescritor desc) {
JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
List<FieldDescriptor> fields = desc.getFields();
for (final FieldDescriptor field : fields) {
addField(desc, p, c, field);
}
Tuple2<JPanel, GridBagConstraints> result = Tuple2.create(p, c);
return result;
 
}
 
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(field);
p.add(editor, c);
 
c.gridx++;
c.weightx = 0;
final JButton close = new JButton(new ImageIcon(DefaultListModel.class.getResource("close_popup.png")));
 
p.add(close, c);
close.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
desc.remove(field);
p.remove(editor);
p.remove(close);
p.revalidate();
extension.setChanged();
}
});
c.gridy++;
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/FieldDescriptor.java
New file
0,0 → 1,137
package org.openconcerto.modules.extensionbuilder.table;
 
public class FieldDescriptor {
public static final String TYPE_STRING = "string";
public static final String TYPE_INTEGER = "integer";
public static final String TYPE_DECIMAL = "decimal";
public static final String TYPE_BOOLEAN = "boolean";
public static final String TYPE_DATE = "date";
public static final String TYPE_TIME = "time";
public static final String TYPE_DATETIME = "dateAndTime";
public static final String TYPE_REF = "ref";
private final String table;
 
private String name;
private String type;
private String defaultValue;
private String length;
private FieldDescriptor link;
private String foreignTable;
 
public FieldDescriptor(String table, String name, String type, String defaultValue, String length, String foreingTable) {
this.table = table;
this.name = name;
this.type = type;
this.defaultValue = defaultValue;
this.length = length;
this.foreignTable = foreingTable;
}
 
public FieldDescriptor(FieldDescriptor f) {
this.name = f.name;
this.type = f.type;
this.defaultValue = f.defaultValue;
this.length = f.length;
this.table = f.table;
this.foreignTable = f.foreignTable;
}
 
@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();
}
return string;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
public String getType() {
return type;
}
 
public void setType(String type) {
this.type = type;
}
 
public String getDefaultValue() {
return defaultValue;
}
 
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
 
public String getLength() {
return length;
}
 
public void setLength(String length) {
this.length = length;
}
 
public String getTable() {
return table;
}
 
public void setLink(FieldDescriptor fieldDescriptor) {
this.link = fieldDescriptor;
}
 
public FieldDescriptor getLink() {
return link;
}
 
public void setForeignTable(String foreignTable) {
this.foreignTable = foreignTable;
}
 
public String getForeignTable() {
return foreignTable;
}
 
public String getExtendedLabel() {
FieldDescriptor f = this;
String label = f.getName();
while (f.getLink() != null) {
label += " / " + f.getLink().getName();
f = f.getLink();
}
return label;
}
 
@Override
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());
} else {
return false;
}
}
return false;
}
 
@Override
public int hashCode() {
return this.table.hashCode();
}
 
public String getPath() {
FieldDescriptor f = this;
String label = f.getName();
while (f.getLink() != null) {
label += "." + f.getLink().getName();
f = f.getLink();
}
return label;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableModifyMainPanel.java
New file
0,0 → 1,27
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.GridLayout;
 
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
 
import org.openconcerto.modules.extensionbuilder.Extension;
 
public class TableModifyMainPanel extends JPanel {
private JSplitPane split;
 
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);
}
 
public void setRightPanel(JComponent p) {
this.invalidate();
split.setRightComponent(p);
this.revalidate();
this.repaint();
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/CreateTableListModel.java
New file
0,0 → 1,47
package org.openconcerto.modules.extensionbuilder.table;
 
import java.util.List;
 
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.ui.DefaultListModel;
 
public class CreateTableListModel extends DefaultListModel implements ChangeListener {
 
private Extension extension;
 
CreateTableListModel(Extension extension) {
this.extension = extension;
loadContent(extension);
this.extension.addChangeListener(this);
}
 
private void loadContent(Extension extension) {
final List<TableDescritor> createTableList = extension.getCreateTableList();
if (this.size() != createTableList.size()) {
this.clear();
this.addAll(createTableList);
}
}
 
public void addNewTable() {
// FIXME: ensure table does not exists
final TableDescritor obj = new TableDescritor("TABLE_" + this.size());
this.addElement(obj);
extension.addCreateTable(obj);
}
 
@Override
public boolean removeElement(Object obj) {
extension.removeCreateTable((TableDescritor) obj);
return super.removeElement(obj);
}
 
@Override
public void stateChanged(ChangeEvent e) {
this.loadContent(extension);
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/ElementDescriptor.java
New file
0,0 → 1,24
package org.openconcerto.modules.extensionbuilder.table;
 
public class ElementDescriptor {
private String id;
private String tableName;
 
public ElementDescriptor(String id, String tableName) {
this.id = id;
this.tableName = tableName;
}
 
public String getId() {
return id;
}
 
public String getTableName() {
return tableName;
}
 
@Override
public String toString() {
return "ElementDescriptor id: " + id + " table: " + tableName;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/FieldDescriptorEditor.java
New file
0,0 → 1,205
package org.openconcerto.modules.extensionbuilder.table;
 
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.Collections;
import java.util.Set;
 
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.ui.DefaultGridBagConstraints;
 
public class FieldDescriptorEditor extends JPanel implements ActionListener, DocumentListener {
final JComboBox comboType;
private JTextField textName;
private JLabel labelOption;
private JTextField textOption;
private String[] types = { "Texte", "Nombre entier", "Nombre décimal", "Booléen", "Date", "Heure", "Date et heure", "Référence" };
private String[] xmltypes = { "string", "integer", "decimal", "boolean", "date", "time", "dateAndTime", "ref" };
private JComboBox comboOption;
 
private static final String[] vBoolean = { "oui", "non" };
private static final String[] vDate = { "vide", "jour actuel" };
private static final String[] vTime = { "vide", "heure actuelle" };
private static final String[] vDateTime = { "vide", "date actuelle" };
FieldDescriptor fd;
 
FieldDescriptorEditor(FieldDescriptor fd) {
this.fd = fd;
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
this.add(new JLabel("Type"), c);
c.gridx++;
 
comboType = new JComboBox(types);
comboType.setOpaque(false);
this.add(comboType, c);
c.gridx++;
this.add(new JLabel("Nom"), c);
c.gridx++;
c.weightx = 1;
textName = new JTextField(10);
this.add(textName, c);
c.weightx = 0;
c.gridx++;
labelOption = new JLabel("Longeur max");
this.add(labelOption, c);
c.gridx++;
textOption = new JTextField(6);
c.gridx++;
this.add(textOption, c);
comboOption = new JComboBox();
 
this.add(comboOption, c);
 
updateFrom(fd);
comboType.addActionListener(this);
comboOption.addActionListener(this);
textOption.getDocument().addDocumentListener(this);
}
 
private void updateFrom(FieldDescriptor fd) {
if (fd.getType().equals("string")) {
comboType.setSelectedIndex(0);
labelOption.setText("Longueur max");
textOption.setVisible(true);
textOption.setText(fd.getLength());
comboOption.setVisible(false);
} else if (fd.getType().equals("integer")) {
comboType.setSelectedIndex(1);
labelOption.setText("Valeur par défaut");
textOption.setVisible(true);
textOption.setText(fd.getDefaultValue());
comboOption.setVisible(false);
} else if (fd.getType().equals("decimal")) {
comboType.setSelectedIndex(2);
labelOption.setText("Valeur par défaut");
textOption.setVisible(true);
textOption.setText(fd.getDefaultValue());
comboOption.setVisible(false);
} else if (fd.getType().equals("boolean")) {
comboType.setSelectedIndex(3);
labelOption.setText("Valeur par défaut");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(vBoolean));
if (fd.getDefaultValue().equals("true")) {
comboOption.setSelectedIndex(0);
} else {
comboOption.setSelectedIndex(1);
}
 
} else if (fd.getType().equals("date")) {
comboType.setSelectedIndex(4);
labelOption.setText("Valeur par défaut");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(vDate));
if (fd.getDefaultValue() == null || !fd.getDefaultValue().equals("now")) {
comboOption.setSelectedIndex(0);
} else {
comboOption.setSelectedIndex(1);
}
} else if (fd.getType().equals("time")) {
comboType.setSelectedIndex(5);
labelOption.setText("Valeur par défaut");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(vTime));
if (!fd.getDefaultValue().equals("now")) {
comboOption.setSelectedIndex(0);
} else {
comboOption.setSelectedIndex(1);
}
} else if (fd.getType().equals("dateAndTime")) {
comboType.setSelectedIndex(6);
labelOption.setText("Valeur par défaut");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(vDateTime));
if (!fd.getDefaultValue().equals("now")) {
comboOption.setSelectedIndex(0);
} else {
comboOption.setSelectedIndex(1);
}
} else if (fd.getType().equals("ref")) {
comboType.setSelectedIndex(7);
labelOption.setText("Table");
textOption.setVisible(false);
comboOption.setVisible(true);
comboOption.setModel(new DefaultComboBoxModel(getTables()));
String tableName = fd.getForeignTable();
comboOption.setSelectedItem(tableName);
} else {
throw new IllegalArgumentException("Unknow type " + fd.getType());
}
textName.setText(fd.getName().trim());
 
}
 
private String[] getTables() {
final ComptaPropsConfiguration instanceCompta = ComptaPropsConfiguration.getInstanceCompta();
Set<SQLTable> t = instanceCompta.getRootSociete().getTables();
ArrayList<String> names = new ArrayList<String>(t.size());
for (SQLTable table : t) {
// TODO: Creer un renderer
// final SQLElement element = instanceCompta.getDirectory().getElement(table);
// String e = table.getName();
// if (element != null) {
// e += " (" + element.getPluralName().toLowerCase() + ")";
// }
names.add(table.getName());
}
Collections.sort(names);
 
return names.toArray(new String[names.size()]);
}
 
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == this.comboType) {
final String type = xmltypes[comboType.getSelectedIndex()];
if (!type.equals(fd.getType())) {
this.fd.setType(type);
updateFrom(fd);
}
} else if (e.getSource() == this.comboOption) {
// TODO combo -> FieldDescriptor
}
 
}
 
private void updateText(DocumentEvent e) {
// TODO text -> FieldDescriptor
 
}
 
@Override
public void insertUpdate(DocumentEvent e) {
updateText(e);
 
}
 
@Override
public void removeUpdate(DocumentEvent e) {
updateText(e);
 
}
 
@Override
public void changedUpdate(DocumentEvent e) {
updateText(e);
 
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/SQLTableListCellRenderer.java
New file
0,0 → 1,28
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.Component;
 
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLTable;
 
public class SQLTableListCellRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
SQLTable t = (SQLTable) value;
value = getQualifiedName(t);
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
 
public static final String getQualifiedName(SQLTable t) {
String value = t.getName();
SQLElement e = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
if (e != null) {
value = t.getName() + " (" + e.getPluralName() + ")";
}
return value;
}
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/table/TableModifyLeftPanel.java
New file
0,0 → 1,116
package org.openconcerto.modules.extensionbuilder.table;
 
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
 
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
 
import org.openconcerto.modules.extensionbuilder.Extension;
import org.openconcerto.sql.model.SQLTable;
 
public class TableModifyLeftPanel extends JPanel {
private final TableModifyMainPanel tableModifyMainPanel;
private final Extension extension;
private JList listTableModified;
private JList listTableAll;
 
TableModifyLeftPanel(Extension extension, TableModifyMainPanel tableModifyMainPanel) {
this.extension = extension;
this.tableModifyMainPanel = tableModifyMainPanel;
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(2, 2, 2, 0);
this.add(new JLabel("Tables modifiées"), c);
 
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
c.gridy++;
c.insets = new Insets(0, 0, 0, 0);
this.add(createModifiedTableList(extension), c);
c.gridy++;
c.weighty = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(2, 2, 2, 0);
this.add(new JLabel("Toutes les tables"), c);
c.weighty = 2;
c.fill = GridBagConstraints.BOTH;
c.gridy++;
c.insets = new Insets(0, 0, 0, 0);
this.add(createAllTableList(extension), c);
}
 
private JComponent createModifiedTableList(final Extension extension) {
final ModifiedTableListModel dataModel = new ModifiedTableListModel(extension);
listTableModified = new JList(dataModel);
listTableModified.addListSelectionListener(new ListSelectionListener() {
 
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
final TableDescritor tableDesc = (TableDescritor) 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();
}
}
 
}
});
final JScrollPane comp2 = new JScrollPane(listTableModified);
comp2.setMinimumSize(new Dimension(250, 150));
comp2.setPreferredSize(new Dimension(250, 150));
return comp2;
}
 
private JComponent createAllTableList(final Extension extension) {
final AllTableListModel dataModel = new AllTableListModel(extension);
listTableAll = new JList(dataModel);
listTableAll.addListSelectionListener(new ListSelectionListener() {
 
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
final SQLTable table = (SQLTable) 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();
}
}
 
}
});
listTableAll.setCellRenderer(new SQLTableListCellRenderer());
final JScrollPane comp2 = new JScrollPane(listTableAll);
comp2.setMinimumSize(new Dimension(150, 150));
comp2.setPreferredSize(new Dimension(150, 150));
return comp2;
}
 
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();
}
}
 
}
/trunk/Modules/Module Extension Builder/src/org/openconcerto/modules/extensionbuilder/ExtensionInfoPanel.java
New file
0,0 → 1,548
package org.openconcerto.modules.extensionbuilder;
 
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.modules.extensionbuilder.component.ComponentCreateMainPanel;
import org.openconcerto.modules.extensionbuilder.component.ComponentDescritor;
import org.openconcerto.modules.extensionbuilder.list.ListCreateMainPanel;
import org.openconcerto.modules.extensionbuilder.list.ListDescriptor;
import org.openconcerto.modules.extensionbuilder.menu.MenuMainPanel;
import org.openconcerto.modules.extensionbuilder.table.TableDescritor;
import org.openconcerto.modules.extensionbuilder.table.TableMainPanel;
import org.openconcerto.modules.extensionbuilder.translation.TranslationMainPanel;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.ReloadPanel;
import org.openconcerto.ui.warning.JLabelWarning;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.StreamUtils;
 
public class ExtensionInfoPanel extends JPanel implements ChangeListener {
private Extension extension;
 
private JFrame frameTableEditor;
 
private JFrame frameListEditor;
private JFrame frameMenuEditor;
private JFrame frameTranslationEditor;
 
ExtensionInfoPanel(Extension extension, ExtensionListPanel moduleListPanel) {
this.extension = extension;
this.extension.addChangeListener(this);
reloadUI();
}
 
@Override
public void stateChanged(ChangeEvent e) {
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
reloadUI();
 
}
});
 
}
 
private void reloadUI() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("Not in AWT");
}
System.out.println("ExtensionInfoPanel.reloadUI()");
this.setBackground(Color.WHITE);
this.invalidate();
this.removeAll();
 
this.setLayout(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
c.insets = new Insets(0, 0, 0, 0);
 
this.add(createToolbar(), c);
c.gridy++;
 
this.add(new JSeparator(JSeparator.HORIZONTAL), c);
c.gridy++;
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
 
this.add(createInfoPanel(), c);
this.revalidate();
}
 
private JPanel createToolbar() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEADING));
panel.add(new JLabelBold(this.extension.getName()));
final ReloadPanel reload = new ReloadPanel();
panel.add(reload);
final JButton startButton = new JButton("Démarrer");
 
panel.add(startButton);
startButton.setEnabled(!extension.isStarted());
final JButton stopButton = new JButton("Arrêter");
panel.add(stopButton);
stopButton.setEnabled(extension.isStarted());
final JButton saveButton = new JButton("Enregister");
saveButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
extension.save();
 
}
});
saveButton.setEnabled(extension.isNotSaved());
panel.add(saveButton);
// TODO: a mettre en clic droit sur la liste gauche
final JButton exportButton = new JButton("Exporter");
panel.add(exportButton);
final JButton importButton = new JButton("Importer");
panel.add(importButton);
 
exportButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
String xml = extension.toXML();
System.out.println(xml);
FileDialog fDialog = new FileDialog(new JFrame(), "Export", FileDialog.SAVE);
fDialog.setFile(extension.getName() + ".ocext");
fDialog.setVisible(true);
String fileName = fDialog.getFile();
if (fileName != null) {
File file = new File(fDialog.getDirectory(), fDialog.getFile());
byte[] bytes = xml.getBytes(Charset.forName("UTF-8"));
byte[] open = "openconcerto".getBytes();
final int length = bytes.length;
for (int i = 0; i < length; i++) {
bytes[i] = (byte) (bytes[i] ^ open[i % 12]);
}
BufferedOutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(file));
GZIPOutputStream gZ = new GZIPOutputStream(out);
gZ.write(bytes);
gZ.close();
} catch (Exception e1) {
ExceptionHandler.handle("Unable to save extension " + file.getAbsolutePath(), e1);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e1) {
// Nothing
}
}
}
 
}
 
}
});
importButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
final FileDialog fDialog = new FileDialog(new JFrame(), "Import", FileDialog.LOAD);
fDialog.setVisible(true);
final String fileName = fDialog.getFile();
String xml = "";
if (fileName != null && fileName.endsWith(".ocext")) {
File file = new File(fDialog.getDirectory(), fDialog.getFile());
if (file.exists()) {
FileInputStream fIn = null;
GZIPInputStream gIn = null;
try {
fIn = new FileInputStream(file);
BufferedInputStream bIn = new BufferedInputStream(fIn);
gIn = new GZIPInputStream(bIn);
final ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamUtils.copy(gIn, out);
out.close();
// decode
byte[] bytes = out.toByteArray();
byte[] open = "openconcerto".getBytes();
final int length = bytes.length;
for (int i = 0; i < length; i++) {
bytes[i] = (byte) (bytes[i] ^ open[i % 12]);
}
xml = new String(bytes, Charset.forName("UTF-8"));
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(new JFrame(), "Invalid extension");
} finally {
if (gIn != null) {
try {
gIn.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (fIn != null) {
try {
fIn.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
 
}
 
}
// Create extension from XML
extension.stop();
if (!xml.isEmpty()) {
if (!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();
}
 
}
});
startButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
reload.setMode(ReloadPanel.MODE_ROTATE);
new Thread(new Runnable() {
 
@Override
public void run() {
final DBRoot root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
try {
extension.start(root);
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}).start();
}
});
stopButton.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
reload.setMode(ReloadPanel.MODE_ROTATE);
new Thread(new Runnable() {
@Override
public void run() {
extension.stop();
}
}).start();
}
});
return panel;
}
 
private JPanel createInfoPanel() {
final JPanel panel = new JPanel();
panel.setOpaque(false);
final GridBagConstraints c = new DefaultGridBagConstraints();
panel.setLayout(new GridBagLayout());
c.fill = GridBagConstraints.NONE;
c.gridy++;
// --------- TABLES
panel.add(new JLabelBold("Tables et champs de la base de données"), c);
c.gridy++;
final List<TableDescritor> createTableList = this.extension.getCreateTableList();
if (createTableList.size() > 0) {
 
panel.add(new JLabel("Cette extension crée " + createTableList.size() + " tables :"), c);
c.gridy++;
c.gridwidth = 1;
for (final TableDescritor sqlCreateTable : createTableList) {
c.gridx = 0;
c.weightx = 0;
JPanel line = new JPanel();
line.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
line.setOpaque(false);
line.add(new JLabel("- " + sqlCreateTable.getName()));
if (sqlCreateTable.getFields().size() > 0) {
line.add(new JLabel(" " + sqlCreateTable.getFields().size() + " champs"));
} else {
line.add(new JLabelWarning(" " + "aucun champ"));
}
panel.add(line, c);
c.gridy++;
}
 
}
final List<TableDescritor> modifyTableList = this.extension.getModifyTableList();
if (modifyTableList.size() > 0) {
String tables = "";
for (int i = 0; i < modifyTableList.size(); i++) {
String tableName = modifyTableList.get(i).getName();
if (i < modifyTableList.size() - 1) {
tables += tableName + ", ";
} else {
tables += tableName;
}
}
if (modifyTableList.size() > 1) {
panel.add(new JLabel("Tables modifiées : " + tables), c);
} else {
panel.add(new JLabel("Table modifiée : " + tables), c);
}
c.gridy++;
}
final JButton buttonCreateTable = new JButton("Afficher les tables");
panel.add(buttonCreateTable, c);
c.gridy++;
panel.add(new JLabel(" "), c);
c.gridy++;
// --------- UI
panel.add(new JLabelBold("Interfaces de saisie"), c);
c.gridy++;
List<ComponentDescritor> createComponentList = extension.getCreateComponentList();
if (createComponentList.size() > 0) {
String components = "";
for (int i = 0; i < createComponentList.size(); i++) {
String tableName = createComponentList.get(i).getId();
if (i < createComponentList.size() - 1) {
components += tableName + ", ";
} else {
components += tableName;
}
}
 
if (createComponentList.size() > 1) {
panel.add(new JLabel("Interfaces créées : " + components), c);
} else {
panel.add(new JLabel("Interface créée : " + components), c);
}
c.gridy++;
}
 
final JButton buttonCreateComponent = new JButton("Afficher les interfaces");
panel.add(buttonCreateComponent, c);
c.gridy++;
panel.add(new JLabel(" "), c);
c.gridy++;
 
// --------- LIST
panel.add(new JLabelBold("Listes"), c);
c.gridy++;
List<ListDescriptor> createListList = extension.getCreateListList();
if (createListList.size() > 0) {
String components = "";
for (int i = 0; i < createListList.size(); i++) {
String tableName = createListList.get(i).getId();
if (i < createListList.size() - 1) {
components += tableName + ", ";
} else {
components += tableName;
}
}
 
if (createListList.size() > 1) {
panel.add(new JLabel("Listes créées : " + components), c);
} else {
panel.add(new JLabel("Liste créée : " + components), c);
}
c.gridy++;
}
 
final JButton buttonCreateList = new JButton("Afficher les listes");
panel.add(buttonCreateList, c);
c.gridy++;
panel.add(new JLabel(" "), c);
c.gridy++;
// --------- 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();
if (actionCount > 0) {
if (actionCount > 1)
panel.add(new JLabel(actionCount + " actions"), c);
else
panel.add(new JLabel(actionCount + " action"), c);
 
c.gridy++;
}
if (menuCount > 0) {
if (menuCount > 1)
panel.add(new JLabel(menuCount + " ajouts de menu"), c);
else
panel.add(new JLabel(menuCount + " ajout de menu"), c);
c.gridy++;
}
if (menuCount2 > 0) {
if (menuCount2 > 1)
panel.add(new JLabel(menuCount2 + " suppressions de menu"), c);
else
panel.add(new JLabel(menuCount2 + " suppression de menu"), c);
c.gridy++;
}
final JButton buttonCreateMenu = new JButton("Afficher les menus");
panel.add(buttonCreateMenu, c);
c.gridy++;
panel.add(new JLabel(" "), c);
 
c.gridy++;
 
// --------- TRANSLATIONS
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();
if (fieldTranslationCount > 0) {
if (fieldTranslationCount > 1)
panel.add(new JLabel(fieldTranslationCount + " traductions de champs"), c);
else
panel.add(new JLabel(fieldTranslationCount + " traduction de champs"), c);
 
c.gridy++;
}
if (menuTranslationCount > 0) {
if (menuTranslationCount > 1)
panel.add(new JLabel(menuTranslationCount + " traductions de menu"), c);
else
panel.add(new JLabel(menuTranslationCount + " traduction de menu"), c);
c.gridy++;
}
 
if (actionTranslationCount > 0) {
if (actionTranslationCount > 1)
panel.add(new JLabel(actionTranslationCount + " traductions d'action"), c);
else
panel.add(new JLabel(actionTranslationCount + " traduction d'action"), c);
c.gridy++;
}
 
final JButton buttonCreateTranslation = new JButton("Afficher les traductions");
panel.add(buttonCreateTranslation, c);
c.gridy++;
panel.add(new JLabel(" "), c);
c.gridy++;
c.weighty = 1;
c.gridwidth = 2;
c.weightx = 1;
panel.add(new JLabel(" "), c);
c.gridy++;
//
buttonCreateTable.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
openTableEditor();
}
});
buttonCreateList.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
openListEditor();
}
});
buttonCreateComponent.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
openComponentEditor();
}
});
buttonCreateMenu.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
openMenuEditor();
}
});
buttonCreateTranslation.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
openTranslationEditor();
}
});
return panel;
}
 
private void openTableEditor() {
final TableMainPanel contentPane = new TableMainPanel(extension);
openEditor(frameTableEditor, contentPane, "Tables dans la base de données");
 
}
 
private void openListEditor() {
final ListCreateMainPanel contentPane = new ListCreateMainPanel(extension);
openEditor(frameListEditor, contentPane, "Listes personnalisées");
 
}
 
protected void openComponentEditor() {
final ComponentCreateMainPanel contentPane = new ComponentCreateMainPanel(extension);
openEditor(frameListEditor, contentPane, "Interfaces personnalisées");
 
}
 
protected void openMenuEditor() {
final MenuMainPanel contentPane = new MenuMainPanel(extension);
openEditor(frameMenuEditor, contentPane, "Menus et actions");
 
}
 
protected void openTranslationEditor() {
final TranslationMainPanel contentPane = new TranslationMainPanel(extension);
openEditor(frameTranslationEditor, contentPane, "Traductions");
 
}
 
private void openEditor(JFrame frame, JPanel mainPanel, String title) {
if (frame == null) {
frame = new JFrame();
frame.setTitle(extension.getName() + " - " + title);
frame.setContentPane(mainPanel);
frame.setMinimumSize(new Dimension(796, 560));
frame.pack();
frame.setLocationRelativeTo(ExtensionInfoPanel.this);
}
FrameUtil.show(frame);
}
}
/trunk/Modules/Module Extension Builder/.settings/org.eclipse.jdt.core.prefs
New file
0,0 → 1,11
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
/trunk/Modules/Module Extension Builder/.classpath
New file
0,0 → 1,7
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry combineaccessrules="false" kind="src" path="/OpenConcerto GoogleCode"/>
<classpathentry kind="output" path="bin"/>
</classpath>
/trunk/Modules/Module Extension Builder/module.properties
New file
0,0 → 1,6
# [\p{Alnum}_.]{3,}
id=org.openconcerto.modules.extensionbuilder
entryPoint=ExtensionBuilderModule
# \p{Digit}(\.\p{Digit}+)?
version=1.0
contact=ILM Informatique
/trunk/Modules/Module Extension Builder/.project
New file
0,0 → 1,17
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Module Extension Builder</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>