aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/ui/forms
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/ui/forms')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/forms/FormBooleanFieldWrapper.java80
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/forms/FormFieldFactory.java30
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/forms/FormFieldWrapper.java94
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/forms/FormJidSingleFieldWrapper.java44
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/forms/FormTextFieldWrapper.java97
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/forms/FormWrapper.java72
6 files changed, 417 insertions, 0 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormBooleanFieldWrapper.java b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormBooleanFieldWrapper.java
new file mode 100644
index 00000000..04c3fe20
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormBooleanFieldWrapper.java
@@ -0,0 +1,80 @@
+package de.thedevstack.conversationsplus.ui.forms;
+
+import android.content.Context;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.thedevstack.conversationsplus.R;
+import de.thedevstack.conversationsplus.xmpp.forms.Field;
+
+public class FormBooleanFieldWrapper extends FormFieldWrapper {
+
+ protected CheckBox checkBox;
+
+ protected FormBooleanFieldWrapper(Context context, Field field) {
+ super(context, field);
+ checkBox = (CheckBox) view.findViewById(R.id.field);
+ checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ checkBox.setError(null);
+ invokeOnFormFieldValuesEdited();
+ }
+ });
+ }
+
+ @Override
+ protected void setLabel(String label, boolean required) {
+ CheckBox checkBox = (CheckBox) view.findViewById(R.id.field);
+ checkBox.setText(createSpannableLabelString(label, required));
+ }
+
+ @Override
+ public List<String> getValues() {
+ List<String> values = new ArrayList<>();
+ values.add(Boolean.toString(checkBox.isChecked()));
+ return values;
+ }
+
+ @Override
+ protected void setValues(List<String> values) {
+ if (values.size() == 0) {
+ checkBox.setChecked(false);
+ } else {
+ checkBox.setChecked(Boolean.parseBoolean(values.get(0)));
+ }
+ }
+
+ @Override
+ public boolean validates() {
+ if (checkBox.isChecked() || !field.isRequired()) {
+ return true;
+ } else {
+ checkBox.setError(context.getString(R.string.this_field_is_required));
+ checkBox.requestFocus();
+ return false;
+ }
+ }
+
+ @Override
+ public boolean edited() {
+ if (field.getValues().size() == 0) {
+ return checkBox.isChecked();
+ } else {
+ return super.edited();
+ }
+ }
+
+ @Override
+ protected int getLayoutResource() {
+ return R.layout.form_boolean;
+ }
+
+ @Override
+ void setReadOnly(boolean readOnly) {
+ checkBox.setEnabled(!readOnly);
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormFieldFactory.java b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormFieldFactory.java
new file mode 100644
index 00000000..e726b6cc
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormFieldFactory.java
@@ -0,0 +1,30 @@
+package de.thedevstack.conversationsplus.ui.forms;
+
+import android.content.Context;
+
+import java.util.Hashtable;
+
+import de.thedevstack.conversationsplus.xmpp.forms.Field;
+
+
+
+public class FormFieldFactory {
+
+ private static final Hashtable<String, Class> typeTable = new Hashtable<>();
+
+ static {
+ typeTable.put("text-single", FormTextFieldWrapper.class);
+ typeTable.put("text-multi", FormTextFieldWrapper.class);
+ typeTable.put("text-private", FormTextFieldWrapper.class);
+ typeTable.put("jid-single", FormJidSingleFieldWrapper.class);
+ typeTable.put("boolean", FormBooleanFieldWrapper.class);
+ }
+
+ protected static FormFieldWrapper createFromField(Context context, Field field) {
+ Class clazz = typeTable.get(field.getType());
+ if (clazz == null) {
+ clazz = FormTextFieldWrapper.class;
+ }
+ return FormFieldWrapper.createFromField(clazz, context, field);
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormFieldWrapper.java b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormFieldWrapper.java
new file mode 100644
index 00000000..662d5bb5
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormFieldWrapper.java
@@ -0,0 +1,94 @@
+package de.thedevstack.conversationsplus.ui.forms;
+
+import android.content.Context;
+import android.text.SpannableString;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.StyleSpan;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import java.util.List;
+
+import de.thedevstack.conversationsplus.ConversationsPlusColors;
+import de.thedevstack.conversationsplus.R;
+import de.thedevstack.conversationsplus.xmpp.forms.Field;
+
+public abstract class FormFieldWrapper {
+
+ protected final Context context;
+ protected final Field field;
+ protected final View view;
+ protected OnFormFieldValuesEdited onFormFieldValuesEditedListener;
+
+ protected FormFieldWrapper(Context context, Field field) {
+ this.context = context;
+ this.field = field;
+ LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ this.view = inflater.inflate(getLayoutResource(), null);
+ String label = field.getLabel();
+ if (label == null) {
+ label = field.getFieldName();
+ }
+ setLabel(label, field.isRequired());
+ }
+
+ public final void submit() {
+ this.field.setValues(getValues());
+ }
+
+ public final View getView() {
+ return view;
+ }
+
+ protected abstract void setLabel(String label, boolean required);
+
+ abstract List<String> getValues();
+
+ protected abstract void setValues(List<String> values);
+
+ abstract boolean validates();
+
+ abstract protected int getLayoutResource();
+
+ abstract void setReadOnly(boolean readOnly);
+
+ protected SpannableString createSpannableLabelString(String label, boolean required) {
+ SpannableString spannableString = new SpannableString(label + (required ? " *" : ""));
+ if (required) {
+ int start = label.length();
+ int end = label.length() + 2;
+ spannableString.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), start, end, 0);
+ spannableString.setSpan(new ForegroundColorSpan(ConversationsPlusColors.accent()), start, end, 0);
+ }
+ return spannableString;
+ }
+
+ protected void invokeOnFormFieldValuesEdited() {
+ if (this.onFormFieldValuesEditedListener != null) {
+ this.onFormFieldValuesEditedListener.onFormFieldValuesEdited();
+ }
+ }
+
+ public boolean edited() {
+ return !field.getValues().equals(getValues());
+ }
+
+ public void setOnFormFieldValuesEditedListener(OnFormFieldValuesEdited listener) {
+ this.onFormFieldValuesEditedListener = listener;
+ }
+
+ protected static <F extends FormFieldWrapper> FormFieldWrapper createFromField(Class<F> c, Context context, Field field) {
+ try {
+ F fieldWrapper = c.getDeclaredConstructor(Context.class, Field.class).newInstance(context,field);
+ fieldWrapper.setValues(field.getValues());
+ return fieldWrapper;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public interface OnFormFieldValuesEdited {
+ void onFormFieldValuesEdited();
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormJidSingleFieldWrapper.java b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormJidSingleFieldWrapper.java
new file mode 100644
index 00000000..c86653bf
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormJidSingleFieldWrapper.java
@@ -0,0 +1,44 @@
+package de.thedevstack.conversationsplus.ui.forms;
+
+import android.content.Context;
+import android.text.InputType;
+
+import java.util.List;
+
+import de.thedevstack.conversationsplus.R;
+import de.thedevstack.conversationsplus.xmpp.forms.Field;
+import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException;
+import de.thedevstack.conversationsplus.xmpp.jid.Jid;
+
+public class FormJidSingleFieldWrapper extends FormTextFieldWrapper {
+
+ protected FormJidSingleFieldWrapper(Context context, Field field) {
+ super(context, field);
+ editText.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
+ editText.setHint(R.string.account_settings_example_jabber_id);
+ }
+
+ @Override
+ public boolean validates() {
+ String value = getValue();
+ if (!value.isEmpty()) {
+ try {
+ Jid.fromString(value);
+ } catch (InvalidJidException e) {
+ editText.setError(context.getString(R.string.invalid_jid));
+ editText.requestFocus();
+ return false;
+ }
+ }
+ return super.validates();
+ }
+
+ @Override
+ protected void setValues(List<String> values) {
+ StringBuilder builder = new StringBuilder("");
+ for(String value : values) {
+ builder.append(value);
+ }
+ editText.setText(builder.toString());
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormTextFieldWrapper.java b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormTextFieldWrapper.java
new file mode 100644
index 00000000..f825809c
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormTextFieldWrapper.java
@@ -0,0 +1,97 @@
+package de.thedevstack.conversationsplus.ui.forms;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.thedevstack.conversationsplus.R;
+import de.thedevstack.conversationsplus.xmpp.forms.Field;
+
+public class FormTextFieldWrapper extends FormFieldWrapper {
+
+ protected EditText editText;
+
+ protected FormTextFieldWrapper(Context context, Field field) {
+ super(context, field);
+ editText = (EditText) view.findViewById(R.id.field);
+ editText.setSingleLine(!"text-multi".equals(field.getType()));
+ if ("text-private".equals(field.getType())) {
+ editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ }
+ editText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ editText.setError(null);
+ invokeOnFormFieldValuesEdited();
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+ });
+ }
+
+ @Override
+ protected void setLabel(String label, boolean required) {
+ TextView textView = (TextView) view.findViewById(R.id.label);
+ textView.setText(createSpannableLabelString(label, required));
+ }
+
+ protected String getValue() {
+ return editText.getText().toString();
+ }
+
+ @Override
+ public List<String> getValues() {
+ List<String> values = new ArrayList<>();
+ for (String line : getValue().split("\\n")) {
+ if (line.length() > 0) {
+ values.add(line);
+ }
+ }
+ return values;
+ }
+
+ @Override
+ protected void setValues(List<String> values) {
+ StringBuilder builder = new StringBuilder("");
+ for(int i = 0; i < values.size(); ++i) {
+ builder.append(values.get(i));
+ if (i < values.size() - 1 && "text-multi".equals(field.getType())) {
+ builder.append("\n");
+ }
+ }
+ editText.setText(builder.toString());
+ }
+
+ @Override
+ public boolean validates() {
+ if (getValue().trim().length() > 0 || !field.isRequired()) {
+ return true;
+ } else {
+ editText.setError(context.getString(R.string.this_field_is_required));
+ editText.requestFocus();
+ return false;
+ }
+ }
+
+ @Override
+ protected int getLayoutResource() {
+ return R.layout.form_text;
+ }
+
+ @Override
+ void setReadOnly(boolean readOnly) {
+ editText.setEnabled(!readOnly);
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormWrapper.java b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormWrapper.java
new file mode 100644
index 00000000..8ff9efae
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/forms/FormWrapper.java
@@ -0,0 +1,72 @@
+package de.thedevstack.conversationsplus.ui.forms;
+
+import android.content.Context;
+import android.widget.LinearLayout;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.thedevstack.conversationsplus.xmpp.forms.Data;
+import de.thedevstack.conversationsplus.xmpp.forms.Field;
+
+public class FormWrapper {
+
+ private final LinearLayout layout;
+
+ private final Data form;
+
+ private final List<FormFieldWrapper> fieldWrappers = new ArrayList<>();
+
+ private FormWrapper(Context context, LinearLayout linearLayout, Data form) {
+ this.form = form;
+ this.layout = linearLayout;
+ this.layout.removeAllViews();
+ for(Field field : form.getFields()) {
+ FormFieldWrapper fieldWrapper = FormFieldFactory.createFromField(context,field);
+ if (fieldWrapper != null) {
+ layout.addView(fieldWrapper.getView());
+ fieldWrappers.add(fieldWrapper);
+ }
+ }
+ }
+
+ public Data submit() {
+ for(FormFieldWrapper fieldWrapper : fieldWrappers) {
+ fieldWrapper.submit();
+ }
+ this.form.submit();
+ return this.form;
+ }
+
+ public boolean validates() {
+ boolean validates = true;
+ for(FormFieldWrapper fieldWrapper : fieldWrappers) {
+ validates &= fieldWrapper.validates();
+ }
+ return validates;
+ }
+
+ public void setOnFormFieldValuesEditedListener(FormFieldWrapper.OnFormFieldValuesEdited listener) {
+ for(FormFieldWrapper fieldWrapper : fieldWrappers) {
+ fieldWrapper.setOnFormFieldValuesEditedListener(listener);
+ }
+ }
+
+ public void setReadOnly(boolean b) {
+ for(FormFieldWrapper fieldWrapper : fieldWrappers) {
+ fieldWrapper.setReadOnly(b);
+ }
+ }
+
+ public boolean edited() {
+ boolean edited = false;
+ for(FormFieldWrapper fieldWrapper : fieldWrappers) {
+ edited |= fieldWrapper.edited();
+ }
+ return edited;
+ }
+
+ public static FormWrapper createInLayout(Context context, LinearLayout layout, Data form) {
+ return new FormWrapper(context, layout, form);
+ }
+}