package com.applang.components; import java.awt.Container; import java.awt.Image; import javax.swing.JComponent; import javax.swing.JLabel; import org.w3c.dom.Document; import com.applang.components.DataView.ProjectionModel; import android.content.Context; import android.content.res.Resources; import android.database.Cursor; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import static com.applang.Util.*; import static com.applang.Util2.*; public class DataForm { private static final String TAG = DataForm.class.getSimpleName(); public DataForm(Context context, ManagerBase<?> manager, ProjectionModel projectionModel, Object...resource) { mManager = manager; boolean standard = notAvailable(0, resource); if (standard) resource = objects("standard_form.xml"); builder = new Builder(context, resource[0]); mProjectionModel = projectionModel; if (mProjectionModel != null) { BidiMultiMap projection = mProjectionModel.getProjection(); projection = new BidiMultiMap( projection.getValues(0), projection.getValues(1), projection.getValues(2), vlist(), projection.getValues(4)); for (Object key : projection.getKeys()) { String name = stringValueOf(key); String type = stringValueOf(projection.getValue(key, 2)); String style = stringValueOf(projection.getValue(key, 4)); if (nullOrEmpty(style)) style = type.toLowerCase(); fields.add(standard ? builder.addStandardField(key, name, style) : layout.findViewWithTag(name)); } } } public Builder builder; private ValList fields = vlist(); private ViewGroup layout = null; public Container getContainer() { return ViewGroup.build(layout, true); } public ProjectionModel mProjectionModel; private int fieldType(BidiMultiMap projection, Object key) { return fieldTypeAffinity(stringValueOf(projection.getValue(key, 2))); } private Object doConversion(BidiMultiMap projection, Object key, Object value, String oper) { Object conversion = projection.getValue(key, 1); if (notNullOrEmpty(conversion)) return ScriptManager.doConversion(value, stringValueOf(conversion), oper); else return value; } public Object[] getContent() { BidiMultiMap projection = mProjectionModel.getProjection(); ValList list = vlist(); ValList keys = projection.getKeys(); for (int i = 0; i < keys.size(); i++) list.add(getContent(projection, keys.get(i))); return list.toArray(); } private Object getContent(BidiMultiMap projection, Object key) { Object value = null; View view = getFieldView(projection, key); if (view != null) { switch (fieldType(projection, key)) { case Cursor.FIELD_TYPE_BLOB: value = ((ImageView)view).getImage(); break; default: if (view instanceof TextEdit) { TextEdit textEdit = (TextEdit)view; if (textEdit.getTextToggle() != null) value = textEdit.getScript(); else value = textEdit.getText(); } else value = ((EditText)view).getText(); } } return doConversion(projection, key, value, "pull"); } private View getFieldView(BidiMultiMap projection, Object key) { return (View) fields.get(projection.getKeys().indexOf(key)); } public void setContent(final Object[] values) { final BidiMultiMap projection = mProjectionModel.getProjection(); mManager.blockDirty(new Job<Void>() { public void perform(Void t, Object[] parms) throws Exception { ValList keys = projection.getKeys(); for (int i = 0; i < keys.size(); i++) { Object key = keys.get(i); setContent(projection, key, values[i]); } } }); } private void setContent(BidiMultiMap projection, final Object key, Object value) { View view = getFieldView(projection, key); if (view != null) { final Object o = doConversion(projection, key, value, "push"); switch (fieldType(projection, key)) { case Cursor.FIELD_TYPE_BLOB: ((ImageView)view).setImage((Image) o); break; default: String text = stringValueOf(o); if (view instanceof TextEdit) { TextEdit textEdit = (TextEdit)view; if (textEdit.getTextToggle() != null) { textEdit.setScript(text); textEdit.setText(textEdit.getScript()); } else textEdit.setText(text); } else ((EditText)view).setText(text); } } } private ManagerBase<?> mManager; private Job<JComponent> onChanged = new Job<JComponent>() { public void perform(JComponent t, Object[] params) throws Exception { mManager.setDirty(true); } }; public class Builder { protected LayoutInflater inflater = null; public Builder(Context context, Object resource) { inflater = LayoutInflater.from(context); if (nullOrEmpty(resource)) { layout = new ViewGroup(context); } else if (resource instanceof Integer) { Document document = context.getResources().getXml((Integer) resource); layout = (ViewGroup) inflater.inflate(document.getDocumentElement()); } else { View view = inflater.inflate(templatePath(stringValueOf(resource))); if (view instanceof ViewGroup) layout = (ViewGroup) view; else { layout = new ViewGroup(context); addView(view, view.getLayoutParams()); } } layout.setTag("form"); } protected String templatePath(String name) { return Resources.getRelativePath(6, name); } public TextView getLabel(ViewGroup vg) { return (TextView) vg.getChildAt(0); } public void setLabelText(Object text, ViewGroup vg) { TextView textView = getLabel(vg); textView.setText(stringValueOf(text)); } public View getEdit(ViewGroup vg) { return vg.getChildAt(1); } public void addView(View view, ViewGroup.LayoutParams params) { layout.addView(view, params); } public View addStandardField(Object description, String name, String style) { ViewGroup vg = (ViewGroup) inflater.inflate( templatePath("standard_field.xml"), name, style); addView(vg, vg.getLayoutParams()); setLabelText(description, vg); JLabel label = getLabel(vg).taggedComponent(); View vw = getEdit(vg); if (vw instanceof EditText) { ((EditText) vw).setOnTextChanged(onChanged); if (vw instanceof TextEdit) { TextEdit te = (TextEdit) vw; if (te.getTextToggle() != null) te.getTextToggle().setOnTextChanged(onChanged); } } label.setLabelFor(vw.taggedComponent()); return vg.findViewWithTag(name); } public View addField(Object description, String key, String type) { ViewGroup vg = null; switch (fieldTypeAffinity(type)) { case Cursor.FIELD_TYPE_STRING: vg = addStringField(description, key); break; case Cursor.FIELD_TYPE_INTEGER: vg = addIntegerField(description, key); break; case Cursor.FIELD_TYPE_FLOAT: vg = addFloatField(description, key); break; case Cursor.FIELD_TYPE_BLOB: vg = addBlobField(description, key); break; default: Log.w(TAG, String.format("type of field '%s' not identified : %s", key, type)); break; } if (vg != null) return vg.findViewWithTag(key); else return null; } public ViewGroup addTextField(Object description, Object...params) { ViewGroup vg = (ViewGroup) inflater.inflate(templatePath("field_text.xml"), params); addView(vg, vg.getLayoutParams()); setLabelText(description, vg); return vg; } public ViewGroup addStringField(Object description, Object...params) { ViewGroup vg = (ViewGroup) inflater.inflate(templatePath("field_string.xml"), params); addView(vg, vg.getLayoutParams()); setLabelText(description, vg); return vg; } public ViewGroup addIntegerField(Object description, Object...params) { ViewGroup vg = (ViewGroup) inflater.inflate(templatePath("field_integer.xml"), params); addView(vg, vg.getLayoutParams()); setLabelText(description, vg); return vg; } public ViewGroup addFloatField(Object description, Object...params) { ViewGroup vg = (ViewGroup) inflater.inflate(templatePath("field_float.xml"), params); addView(vg, vg.getLayoutParams()); setLabelText(description, vg); return vg; } public ViewGroup addBlobField(Object description, Object...params) { ViewGroup vg = (ViewGroup) inflater.inflate(templatePath("field_blob.xml"), params); addView(vg, vg.getLayoutParams()); setLabelText(description, vg); return vg; } } }