using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using CMS.CMSHelper;
using CMS.FormControls;
using CMS.FormEngine;
using CMS.GlobalHelper;
using CMS.SettingsProvider;
///
/// This form control must be used with name 'options' only. Another blank form control must be registered to hold second value. Second name must be 'query'.
///
public partial class CMSFormControls_System_OptionsSelector : FormEngineUserControl
{
#region "Properties"
///
/// Gets or sets the enabled state of the control.
///
public override bool Enabled
{
get
{
return txtValue.Enabled;
}
set
{
txtValue.Enabled = value;
radOptions.Enabled = value;
radSQL.Enabled = value;
radNone.Enabled = value;
}
}
///
/// Gets or sets form control value. Form control must be called options. Second blank form control must be created with name 'query'.
///
public override object Value
{
get
{
if (radOptions.Checked)
{
return txtValue.Text.Trim();
}
return null;
}
set
{
txtValue.Text = LoadTextFromData(ValidationHelper.GetString(value, null));
}
}
///
/// Returns values of other related fields.
///
public override object[,] GetOtherValues()
{
object[,] values = new object[1, 2];
values[0, 0] = "query";
if (radSQL.Checked)
{
values[0, 1] = txtValue.Text.Trim();
}
else
{
values[0, 1] = null;
}
return values;
}
#endregion
#region "Methods
///
/// Page load.
///
protected void Page_Load(object sender, EventArgs e)
{
if (!StopProcessing)
{
CheckFieldEmptiness = false;
// Clear control
if ((Form == null) || (Form.Data == null))
{
radNone.Checked = true;
txtValue.Text = null;
}
}
else
{
Visible = false;
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (Form.FormType == FormTypeEnum.BizForm)
{
if (!CMSContext.CurrentUser.IsAuthorizedPerResource("CMS.Form", "EditSQLQueries"))
{
radSQL.Enabled = false;
if (radSQL.Checked)
{
txtValue.Enabled = false;
radOptions.Attributes["onclick"] = "document.getElementById('" + txtValue.ClientID + "').disabled = false;";
}
}
}
if (!FieldInfo.AllowEmpty)
{
radNone.Visible = false;
if (radNone.Checked)
{
radOptions.Checked = true;
}
}
}
///
/// Returns true if user control is valid.
///
public override bool IsValid()
{
bool valid = true;
// Check 'options' validity
if (radOptions.Checked)
{
// Some option must be included
if (string.IsNullOrEmpty(txtValue.Text.Trim()))
{
ValidationError += GetString("TemplateDesigner.ErrorDropDownListOptionsEmpty") + " ";
valid = false;
}
else
{
// Parse lines
int lineIndex = 0;
string[] lines = txtValue.Text.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
string[] items = null;
for (lineIndex = 0; lineIndex <= lines.GetUpperBound(0); lineIndex++)
{
// Loop through only not-empty lines
if ((lines[lineIndex] != null) && (lines[lineIndex].Trim() != ""))
{
// Get line items
items = lines[lineIndex].Replace(FormHelper.SEMICOLON_TO_REPLACE, FormHelper.REPLACED_SEMICOLON).Split(';');
// Every line must have value and item element
if (items.Length != 2)
{
ValidationError += GetString("TemplateDesigner.ErrorDropDownListOptionsInvalidFormat") + " ";
valid = false;
break;
}
else
{
// Check valid Double format
if (FieldInfo.DataType == FormFieldDataTypeEnum.Decimal)
{
if (!ValidationHelper.IsDouble(items[0]) && !(FieldInfo.AllowEmpty && string.IsNullOrEmpty(items[0])))
{
ValidationError += string.Format(GetString("TemplateDesigner.ErrorDropDownListOptionsInvalidDoubleFormat"), lineIndex + 1) + " ";
valid = false;
break;
}
}
// Check valid Integer format
else if (FieldInfo.DataType == FormFieldDataTypeEnum.Integer)
{
if (!ValidationHelper.IsInteger(items[0]) && !(FieldInfo.AllowEmpty && string.IsNullOrEmpty(items[0])))
{
ValidationError += string.Format(GetString("TemplateDesigner.ErrorDropDownListOptionsInvalidIntFormat"), lineIndex + 1) + " ";
valid = false;
break;
}
}
// Check valid Long integer format
else if (FieldInfo.DataType == FormFieldDataTypeEnum.LongInteger)
{
if (!ValidationHelper.IsLong(items[0]) && !(FieldInfo.AllowEmpty && string.IsNullOrEmpty(items[0])))
{
ValidationError += string.Format(GetString("TemplateDesigner.ErrorDropDownListOptionsInvalidLongIntFormat"), lineIndex + 1) + " ";
valid = false;
break;
}
}
// Check valid Date time format
else if (FieldInfo.DataType == FormFieldDataTypeEnum.DateTime)
{
if ((ValidationHelper.GetDateTime(items[0], DateTimeHelper.ZERO_TIME) == DateTimeHelper.ZERO_TIME) && !FieldInfo.AllowEmpty)
{
ValidationError += string.Format(GetString("TemplateDesigner.ErrorDropDownListOptionsInvalidDateTimeFormat"), lineIndex + 1) + " ";
valid = false;
break;
}
}
}
}
}
}
}
// Check sql query validity
else if (radSQL.Checked && (string.IsNullOrEmpty(txtValue.Text.Trim())))
{
ValidationError += GetString("TemplateDesigner.ErrorDropDownListQueryEmpty") + " ";
valid = false;
}
if (!ContainsColumn("options"))
{
ValidationError += String.Format(GetString("formcontrol.missingcolumn"), "options", GetString("templatedesigner.fieldtypes.longtext"));
valid = false;
}
if (!ContainsColumn("query"))
{
ValidationError += String.Format(GetString("formcontrol.missingcolumn"), "query", GetString("templatedesigner.fieldtypes.longtext"));
valid = false;
}
return valid;
}
#endregion
#region "Data loading methods"
///
/// Loads text into textbox from value or from 'query' column.
///
/// Value parameter
/// Returns text of options or query
private string LoadTextFromData(string txtValue)
{
// Options data
if (!String.IsNullOrEmpty(txtValue))
{
return LoadTextFromOptions(txtValue);
}
// Query selected
else if (ContainsColumn("query"))
{
return LoadTextFromQuery();
}
return null;
}
///
/// Load text from 'options' value
///
/// Raw text data
/// Returns parsed data
private string LoadTextFromOptions(string txtValue)
{
// Initialize variables
XmlDocument xmlDoc = new XmlDocument();
MatchCollection foundLines = null;
// Preselect radio buttons
SetRadioButtons(true);
// Try to load xml with option items
if (TryLoadXmlOptions(txtValue, xmlDoc))
{
// Options selected
return ParseXMLWithOptions(xmlDoc);
}
// Try to load XML as regular expression
else if (TryLoadRegexOptions(txtValue, ref foundLines))
{
// Complete text from found groups
return GetFromRegex(foundLines);
}
// If loading XML failed then return text without parsing
return txtValue;
}
///
/// Get lines from regular expresion.
///
/// Text to be parsed
/// Matched collection
/// Returns TRUE if regular expression found any matches
private bool TryLoadRegexOptions(string text, ref MatchCollection foundLines)
{
Regex regex = RegexHelper.GetRegex(FormHelper.OPTIONS_REGEX);
foundLines = regex.Matches(text);
return foundLines.Count > 0;
}
///
/// Completes text from found regex groups.
///
/// Matched regex groups representing lines.
/// Returns completed text
private string GetFromRegex(MatchCollection foundLines)
{
StringBuilder returnString = new StringBuilder();
string dataField = null;
string textField = null;
foreach (Match match in foundLines)
{
dataField = ValidationHelper.GetString(match.Groups["value"], null).Replace(";", FormHelper.SEMICOLON_TO_REPLACE);
textField = ValidationHelper.GetString(match.Groups["text"], null).Replace(";", FormHelper.SEMICOLON_TO_REPLACE);
dataField = ConvertSpecialFormats(dataField);
returnString.Append(dataField + ";" + textField + "\n");
}
return returnString.ToString();
}
///
/// Sets options/query radiobuttons
///
/// Returns query text
private string LoadTextFromQuery()
{
string query = ValidationHelper.GetString(Form.Data.GetValue("query"), "").Trim();
if (!String.IsNullOrEmpty(query))
{
SetRadioButtons(false);
return query;
}
return null;
}
///
/// Tries to load XML document with option items.
///
/// Text with option items
/// XML document which will be loaded with items
/// Returns true if loading was successful
private bool TryLoadXmlOptions(string txtValue, XmlDocument xmlDoc)
{
if (txtValue.StartsWithCSafe("<"))
{
try
{
xmlDoc.LoadXml("" + txtValue + "");
if ((xmlDoc != null) && (xmlDoc.SelectNodes("options/item").Count > 0))
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
else
{
return false;
}
}
///
/// Parse XML with options data.
///
/// XML document
/// Returns parsed text
private string ParseXMLWithOptions(XmlDocument xmlDoc)
{
StringBuilder returnString = new StringBuilder();
string dataField = null;
string textField = null;
// Loop through all items in XML
foreach (XmlNode optionItem in xmlDoc.SelectNodes("options/item"))
{
dataField = optionItem.Attributes["value"].Value.Replace(";", FormHelper.SEMICOLON_TO_REPLACE);
textField = optionItem.Attributes["text"].Value.Replace(";", FormHelper.SEMICOLON_TO_REPLACE);
dataField = ConvertSpecialFormats(dataField);
returnString.Append(dataField + ";" + textField + "\n");
}
return returnString.ToString();
}
///
/// Displays value in correct format for current culture
///
/// Current value
/// Returns converted data
private string ConvertSpecialFormats(string value)
{
// Convert decimal value
if (FieldInfo.DataType == FormFieldDataTypeEnum.Decimal)
{
return FormHelper.GetDoubleValueInCurrentCulture(value);
}
// Covert date time value
else if (FieldInfo.DataType == FormFieldDataTypeEnum.DateTime)
{
return FormHelper.GetDateTimeValueInCurrentCulture(value).ToString();
}
return value;
}
///
/// Sets radio buttons according to selected value options/query.
///
/// Indicates if options radiobutton should be selected
private void SetRadioButtons(bool options)
{
radOptions.Checked = options;
radSQL.Checked = !options;
}
#endregion
}