/// <summary> /// Implements support for data forms. Data Forms are defined in the following XEPs: /// /// XEP-0004: Data Forms: /// http://xmpp.org/extensions/xep-0004.html /// /// XEP-0122: Data Forms Validation: /// http://xmpp.org/extensions/xep-0122.html /// /// XEP-0141: Data Forms Layout /// http://xmpp.org/extensions/xep-0141.html /// /// XEP-0221: Data Forms Media Element /// http://xmpp.org/extensions/xep-0221.html /// /// XEP-0331: Data Forms - Color Field Types /// http://xmpp.org/extensions/xep-0331.html /// /// XEP-0336: Data Forms - Dynamic Forms /// http://xmpp.org/extensions/xep-0336.html /// /// XEP-0348: Signing Forms: /// http://xmpp.org/extensions/xep-0348.html /// </summary> /// <param name="Client">XMPP Client.</param> /// <param name="Type">Type of data form.</param> /// <param name="From">From where the form came.</param> /// <param name="To">To where the form was sent.</param> /// <param name="Fields">Data form fields.</param> public DataForm(XmppClient Client, FormType Type, string From, string To, params Field[] Fields) { this.client = Client; this.onSubmit = null; this.onCancel = null; this.type = Type; this.from = From; this.to = To; foreach (Field F in Fields) { F.Form = this; if (!string.IsNullOrEmpty(F.Var)) { this.fieldsByVar[F.Var] = F; } } this.title = string.Empty; this.instructions = new string[0]; this.fields = Fields; this.records = new Field[0][]; this.header = new Field[0]; this.hasPages = false; this.pages = new Page[] { new Page(this, this.title, this.fields) }; }
/// <summary> /// This method joins two forms. The current form represents the old form (which is probably being viewed by a user), and <paramref name="NewForm"/> /// represents the new updated form. The method makes sure values that are currently being edited (and which the server is unaware off) are kept, while /// all other changes are transferred to the current form. /// </summary> /// <param name="NewForm">New version of form.</param> public void Join(DataForm NewForm) { Field[] OldFields = this.fields; this.fieldsByVar = NewForm.fieldsByVar; this.type = NewForm.type; this.fields = NewForm.fields; this.header = NewForm.header; this.records = NewForm.records; this.pages = NewForm.pages; this.instructions = NewForm.instructions; this.title = NewForm.title; foreach (Field OldField in OldFields) { if (!this.fieldsByVar.TryGetValue(OldField.Var, out Field NewField)) { continue; } if (!OldField.Edited) { continue; } NewField.SetValue(OldField.ValueStrings); } DataFormEventHandler h = this.OnRemoteUpdate; if (h != null) { try { h(this.client, this); } catch (Exception ex) { this.client.Exception(ex); } } }
/// <summary> /// Implements support for data forms. Data Forms are defined in the following XEPs: /// /// XEP-0004: Data Forms: /// http://xmpp.org/extensions/xep-0004.html /// /// XEP-0122: Data Forms Validation: /// http://xmpp.org/extensions/xep-0122.html /// /// XEP-0141: Data Forms Layout /// http://xmpp.org/extensions/xep-0141.html /// /// XEP-0221: Data Forms Media Element /// http://xmpp.org/extensions/xep-0221.html /// /// XEP-0331: Data Forms - Color Field Types /// http://xmpp.org/extensions/xep-0331.html /// /// XEP-0336: Data Forms - Dynamic Forms /// http://xmpp.org/extensions/xep-0336.html /// /// XEP-0348: Signing Forms: /// http://xmpp.org/extensions/xep-0348.html /// </summary> /// <param name="Client">XMPP Client.</param> /// <param name="X">Data Form definition.</param> /// <param name="OnSubmit">Method called when the form is submitted.</param> /// <param name="OnCancel">Method called when the form is cancelled.</param> /// <param name="From">From where the form came.</param> /// <param name="To">To where the form was sent.</param> public DataForm(XmppClient Client, XmlElement X, DataFormEventHandler OnSubmit, DataFormEventHandler OnCancel, string From, string To) { List <string> Instructions = new List <string>(); List <Field> Fields = new List <Field>(); List <Field[]> Records = new List <Field[]>(); List <Page> Pages = null; this.client = Client; this.onSubmit = OnSubmit; this.onCancel = OnCancel; this.from = From; this.to = To; switch (XML.Attribute(X, "type").ToLower()) { case "cancel": this.type = FormType.Cancel; break; case "form": this.type = FormType.Form; break; case "result": this.type = FormType.Result; break; case "submit": this.type = FormType.Submit; break; default: this.type = FormType.Undefined; break; } foreach (XmlNode N in X.ChildNodes) { switch (N.LocalName) { case "instructions": Instructions.Add(N.InnerText.Trim()); break; case "title": this.title = N.InnerText.Trim(); break; case "field": Field Field = this.ParseField((XmlElement)N, out Media Media); Fields.Add(Field); if (Field.PostBack) { this.containsPostBackFields = true; } if (!string.IsNullOrEmpty(Field.Var)) { this.fieldsByVar[Field.Var] = Field; } if (Media != null) { Field = new MediaField(this, Guid.NewGuid().ToString(), string.Empty, false, null, null, string.Empty, new StringDataType(), new BasicValidation(), Media, string.Empty, false, true, false); Fields.Add(Field); this.fieldsByVar[Field.Var] = Field; this.hasMedia = true; } break; case "reported": List <Field> Header = new List <Field>(); foreach (XmlNode N2 in N.ChildNodes) { if (N2.LocalName == "field") { Field = this.ParseField((XmlElement)N2, out Media); Header.Add(Field); } } this.header = Header.ToArray(); break; case "item": List <Field> Record = new List <Field>(); foreach (XmlNode N2 in N.ChildNodes) { if (N2.LocalName == "field") { Field = this.ParseField((XmlElement)N2, out Media); Record.Add(Field); } } Records.Add(Record.ToArray()); break; case "page": if (Pages == null) { Pages = new List <Page>(); } Pages.Add(new Page(this, (XmlElement)N)); break; } } this.instructions = Instructions.ToArray(); this.fields = Fields.ToArray(); this.records = Records.ToArray(); if (this.header == null) { this.header = new Field[0]; } if (this.hasPages = (Pages != null)) { this.pages = Pages.ToArray(); } else if (this.fields.Length > 0) { this.pages = new Page[] { new Page(this, this.title, this.fields) } } ; else { this.pages = new Page[] { new Page(this, this.title, new ReportedReference(this)) } }; if (this.hasMedia) { Dictionary <string, byte[]> Bob = new Dictionary <string, byte[]>(StringComparer.CurrentCultureIgnoreCase); foreach (XmlNode N in X.ParentNode.ChildNodes) { if (N is XmlElement E && E.LocalName == "data" && E.NamespaceURI == BobClient.Namespace) { string Cid = XML.Attribute(E, "cid"); byte[] Bin = Convert.FromBase64String(E.InnerText); Bob["cid:" + Cid] = Bin; } } foreach (Field F in this.fields) { if (F is MediaField MediaField && MediaField.Media != null) { foreach (KeyValuePair <string, Uri> Uri in MediaField.Media.URIs) { switch (Uri.Value.Scheme.ToLower()) { case "cid": if (Bob.TryGetValue(Uri.Value.ToString(), out byte[] Bin))
/// <summary> /// Implements support for data forms. Data Forms are defined in the following XEPs: /// /// XEP-0004: Data Forms: /// http://xmpp.org/extensions/xep-0004.html /// /// XEP-0122: Data Forms Validation: /// http://xmpp.org/extensions/xep-0122.html /// /// XEP-0141: Data Forms Layout /// http://xmpp.org/extensions/xep-0141.html /// /// XEP-0221: Data Forms Media Element /// http://xmpp.org/extensions/xep-0221.html /// /// XEP-0331: Data Forms - Color Field Types /// http://xmpp.org/extensions/xep-0331.html /// /// XEP-0336: Data Forms - Dynamic Forms /// http://xmpp.org/extensions/xep-0336.html /// /// XEP-0348: Signing Forms: /// http://xmpp.org/extensions/xep-0348.html /// </summary> /// <param name="Client">XMPP Client.</param> /// <param name="X">Data Form definition.</param> /// <param name="OnSubmit">Method called when the form is submitted.</param> /// <param name="OnCancel">Method called when the form is cancelled.</param> /// <param name="From">From where the form came.</param> /// <param name="To">To where the form was sent.</param> public DataForm(XmppClient Client, XmlElement X, DataFormEventHandler OnSubmit, DataFormEventHandler OnCancel, string From, string To) { List <string> Instructions = new List <string>(); List <Field> Fields = new List <Field>(); List <Field[]> Records = new List <Field[]>(); List <Page> Pages = null; this.client = Client; this.onSubmit = OnSubmit; this.onCancel = OnCancel; this.from = From; this.to = To; switch (XML.Attribute(X, "type").ToLower()) { case "cancel": this.type = FormType.Cancel; break; case "form": this.type = FormType.Form; break; case "result": this.type = FormType.Result; break; case "submit": this.type = FormType.Submit; break; default: this.type = FormType.Undefined; break; } foreach (XmlNode N in X.ChildNodes) { switch (N.LocalName) { case "instructions": Instructions.Add(N.InnerText.Trim()); break; case "title": this.title = N.InnerText.Trim(); break; case "field": Field Field = this.ParseField((XmlElement)N, out Media Media); Fields.Add(Field); if (Field.PostBack) { this.containsPostBackFields = true; } if (!string.IsNullOrEmpty(Field.Var)) { this.fieldsByVar[Field.Var] = Field; } if (!(Media is null)) { Field = new MediaField(this, Guid.NewGuid().ToString(), string.Empty, false, null, null, string.Empty, new StringDataType(), new BasicValidation(), Media, string.Empty, false, true, false); Fields.Add(Field); this.fieldsByVar[Field.Var] = Field; this.hasMedia = true; } break; case "reported": List <Field> Header = new List <Field>(); foreach (XmlNode N2 in N.ChildNodes) { if (N2.LocalName == "field") { Field = this.ParseField((XmlElement)N2, out Media); Header.Add(Field); } } this.header = Header.ToArray(); break; case "item": List <Field> Record = new List <Field>(); foreach (XmlNode N2 in N.ChildNodes) { if (N2.LocalName == "field") { Field = this.ParseField((XmlElement)N2, out Media); Record.Add(Field); } } Records.Add(Record.ToArray()); break; case "page": if (Pages is null) { Pages = new List <Page>(); } Pages.Add(new Page(this, (XmlElement)N)); break; } } this.instructions = Instructions.ToArray(); this.fields = Fields.ToArray(); this.records = Records.ToArray(); if (this.header is null) { this.header = new Field[0]; } if (this.hasPages = (!(Pages is null))) { this.pages = Pages.ToArray(); }
/// <summary> /// Sets the form method handlers for the Submit and Cancel methods. /// </summary> /// <param name="OnSubmit">Callback method for the Submit method.</param> /// <param name="OnCancel">Callback method for the Cancel method.</param> public void SetMethodHandlers(DataFormEventHandler OnSubmit, DataFormEventHandler OnCancel) { this.onSubmit = OnSubmit; this.onCancel = OnCancel; }
/// <summary> /// Implements support for data forms. Data Forms are defined in the following XEPs: /// /// XEP-0004: Data Forms: /// http://xmpp.org/extensions/xep-0004.html /// /// XEP-0122: Data Forms Validation: /// http://xmpp.org/extensions/xep-0122.html /// /// XEP-0141: Data Forms Layout /// http://xmpp.org/extensions/xep-0141.html /// /// XEP-0221: Data Forms Media Element /// http://xmpp.org/extensions/xep-0221.html /// /// XEP-0331: Data Forms - Color Field Types /// http://xmpp.org/extensions/xep-0331.html /// /// XEP-0336: Data Forms - Dynamic Forms /// http://xmpp.org/extensions/xep-0336.html /// /// XEP-0348: Signing Forms: /// http://xmpp.org/extensions/xep-0348.html /// </summary> /// <param name="Client">XMPP Client.</param> /// <param name="X">Data Form definition.</param> /// <param name="OnSubmit">Method called when the form is submitted.</param> /// <param name="OnCancel">Method called when the form is cancelled.</param> /// <param name="From">From where the form came.</param> /// <param name="To">To where the form was sent.</param> public DataForm(XmppClient Client, XmlElement X, DataFormEventHandler OnSubmit, DataFormEventHandler OnCancel, string From, string To) { List <string> Instructions = new List <string>(); List <Field> Fields = new List <Field>(); List <Field[]> Records = new List <Field[]>(); List <Page> Pages = null; this.client = Client; this.onSubmit = OnSubmit; this.onCancel = OnCancel; this.from = From; this.to = To; switch (XML.Attribute(X, "type").ToLower()) { case "cancel": this.type = FormType.Cancel; break; case "form": this.type = FormType.Form; break; case "result": this.type = FormType.Result; break; case "submit": this.type = FormType.Submit; break; default: this.type = FormType.Undefined; break; } foreach (XmlNode N in X.ChildNodes) { switch (N.LocalName) { case "instructions": Instructions.Add(N.InnerText.Trim()); break; case "title": this.title = N.InnerText.Trim(); break; case "field": Field Field = this.ParseField((XmlElement)N); Fields.Add(Field); if (Field.PostBack) { this.containsPostBackFields = true; } if (!string.IsNullOrEmpty(Field.Var)) { this.fieldsByVar[Field.Var] = Field; } break; case "reported": List <Field> Header = new List <Field>(); foreach (XmlNode N2 in N.ChildNodes) { if (N2.LocalName == "field") { Field = this.ParseField((XmlElement)N2); Header.Add(Field); } } this.header = Header.ToArray(); break; case "item": List <Field> Record = new List <Field>(); foreach (XmlNode N2 in N.ChildNodes) { if (N2.LocalName == "field") { Field = this.ParseField((XmlElement)N2); Record.Add(Field); } } Records.Add(Record.ToArray()); break; case "page": if (Pages == null) { Pages = new List <Page>(); } Pages.Add(new Page(this, (XmlElement)N)); break; } } this.instructions = Instructions.ToArray(); this.fields = Fields.ToArray(); this.records = Records.ToArray(); if (this.header == null) { this.header = new Field[0]; } if (this.hasPages = (Pages != null)) { this.pages = Pages.ToArray(); } else if (this.fields.Length > 0) { this.pages = new Page[] { new Page(this, this.title, this.fields) } } ; else { this.pages = new Page[] { new Page(this, this.title, new ReportedReference(this)) } }; }