void IPlugIn.ProcessPageRequest(PageRequest request, ViewPage page)
        {
            if (page.Rows.Count == 0)
            {
                page.Icons = new string[0];
                return;
            }
            if (!_requireProcessing)
            {
                var icons = new List <string>();
                for (var i = 0; (i < page.Rows.Count); i++)
                {
                    var rowDir = AnnotationPlugIn.GenerateDataRecordPath(request.Controller, page, null, i);
                    if (Directory.Exists(rowDir))
                    {
                        icons.Add("Attachment");
                    }
                    else
                    {
                        icons.Add(null);
                    }
                }
                page.Icons = icons.ToArray();
                return;
            }
            var expressions = new List <DynamicExpression>(page.Expressions);
            var de          = new DynamicExpression();

            de.Target = "Annotations";
            de.Scope  = DynamicExpressionScope.CategoryVisibility;
            de.Type   = DynamicExpressionType.ClientScript;
            de.Test   = "!this.get_isInserting()";
            de.ViewId = page.View;
            expressions.Add(de);
            page.Expressions = expressions.ToArray();
            if (!_retrieveAnnotations)
            {
                return;
            }
            var field = page.FindField("_Annotation_AttachmentNew");

            if (field != null)
            {
                var fieldIndex = page.Fields.IndexOf(field);
                var newValue   = string.Format("{0},{1}|{2}", request.Controller, field.Name, Regex.Replace(((string)(page.Rows[0][fieldIndex])), "^\\w+\\|(.+)$", "$1"));
                if (field.Name == "_Annotation_AttachmentNew")
                {
                    newValue = ("null|" + newValue);
                }
                page.Rows[0][fieldIndex] = newValue;
            }
            var p = AnnotationPlugIn.GenerateDataRecordPath(request.Controller, page, null, 0);

            if (Directory.Exists(p))
            {
                var files  = Directory.GetFiles(p, "*.xml");
                var values = new List <object>(page.Rows[0]);
                var i      = (files.Length - 1);
                while (i >= 0)
                {
                    var       filename = files[i];
                    var       doc      = new XPathDocument(filename);
                    var       nav      = doc.CreateNavigator().SelectSingleNode("/*");
                    DataField f        = null;
                    if (nav.Name == "note")
                    {
                        f            = new DataField();
                        f.Name       = "_Annotation_Note";
                        f.Type       = "String";
                        f.HeaderText = string.Format(Localizer.Replace("AnnotationNoteDynamicFieldHeaderText", "{0} written at {1}"), ReadNameAndEmail(nav), Convert.ToDateTime(nav.GetAttribute("timestamp", string.Empty)));
                        f.Columns    = 50;
                        f.Rows       = 7;
                        f.TextMode   = TextInputMode.Note;
                        values.Add(nav.Value);
                    }
                    else
                    if (nav.Name == "attachment")
                    {
                        f                 = new DataField();
                        f.Name            = "_Annotation_Attachment";
                        f.Type            = "Byte[]";
                        f.HeaderText      = string.Format(Localizer.Replace("AnnotationAttachmentDynamicFieldHeaderText", "{0} attached <b>{1}</b> at {2}"), ReadNameAndEmail(nav), nav.GetAttribute("fileName", string.Empty), Convert.ToDateTime(nav.GetAttribute("timestamp", string.Empty)));
                        f.OnDemand        = true;
                        f.OnDemandHandler = "AnnotationPlugIn";
                        f.OnDemandStyle   = OnDemandDisplayStyle.Link;
                        if (nav.GetAttribute("contentType", string.Empty).StartsWith("image/"))
                        {
                            f.OnDemandStyle = OnDemandDisplayStyle.Thumbnail;
                        }
                        f.CategoryIndex = (page.Categories.Count - 1);
                        values.Add(nav.GetAttribute("value", string.Empty));
                    }
                    if (f != null)
                    {
                        f.Name          = (f.Name + Path.GetFileNameWithoutExtension(filename));
                        f.AllowNulls    = true;
                        f.CategoryIndex = (page.Categories.Count - 1);
                        if (!(Controller.UserIsInRole("Administrators")))
                        {
                            f.ReadOnly = true;
                        }
                        page.Fields.Add(f);
                    }
                    i = (i - 1);
                }
                page.Rows[0] = values.ToArray();
                if (files.Length > 0)
                {
                    page.Categories[(page.Categories.Count - 1)].Tab = Localizer.Replace("AnnotationTab", "Notes & Attachments");
                    expressions.RemoveAt((expressions.Count - 1));
                    page.Expressions = expressions.ToArray();
                }
            }
            else
            {
                de.Test = "this.get_isEditing() && this.get_view()._displayAnnotations";
                var g = new ActionGroup();
                page.ActionGroups.Add(g);
                g.Scope = "ActionBar";
                g.Flat  = true;
                var a = new Action();
                g.Actions.Add(a);
                a.WhenLastCommandName = "Edit";
                a.WhenView            = page.View;
                a.CommandName         = "ClientScript";
                a.CommandArgument     = "this.get_view()._displayAnnotations=true;this._focusedFieldName = \'_Annotation_No" +
                                        "teNew\';this._raiseSelectedDelayed=false;";
                a.HeaderText       = Localizer.Replace("AnnotationActionHeaderText", "Annotate");
                a.CssClass         = "AttachIcon";
                a.WhenClientScript = "this.get_view()._displayAnnotations!=true;";
            }
        }
        void IPlugIn.PreProcessPageRequest(PageRequest request, ViewPage page)
        {
            var view = _config.SelectSingleNode("//c:view[@id=\'{0}\' and @type=\'Form\']/c:categories", request.View);

            if ((view != null) && ((request.PageSize > 0) && (!request.Inserting && (_config.SelectSingleNode("/c:dataController/c:fields/c:field[@name=\'_Annotation_NoteNew\']") == null))))
            {
                _requireProcessing = true;
                var ns          = ControllerConfiguration.Namespace;
                var expressions = new List <DynamicExpression>(_config.Expressions);
                // create NewXXX fields under "fields" node
                var sb       = new StringBuilder();
                var settings = new XmlWriterSettings();
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                var writer = XmlWriter.Create(sb, settings);
                // NoteNew field
                writer.WriteStartElement("field", ns);
                writer.WriteAttributeString("name", "_Annotation_NoteNew");
                writer.WriteAttributeString("type", "String");
                writer.WriteAttributeString("allowSorting", "false");
                writer.WriteAttributeString("allowQBE", "false");
                writer.WriteAttributeString("label", Localizer.Replace("AnnotationNoteNewFieldLabel", "Notes"));
                writer.WriteAttributeString("computed", "true");
                writer.WriteElementString("formula", ns, "null");
                writer.WriteEndElement();
                var de = new DynamicExpression();
                de.Target = "_Annotation_NoteNew";
                de.Scope  = DynamicExpressionScope.DataFieldVisibility;
                de.Type   = DynamicExpressionType.ClientScript;
                de.Test   = "this.get_isEditing()";
                de.ViewId = request.View;
                expressions.Add(de);
                // AttachmentNew field
                writer.WriteStartElement("field", ns);
                writer.WriteAttributeString("name", "_Annotation_AttachmentNew");
                writer.WriteAttributeString("type", "Byte[]");
                writer.WriteAttributeString("onDemand", "true");
                writer.WriteAttributeString("sourceFields", this.KeyFields);
                writer.WriteAttributeString("onDemandHandler", "AnnotationPlugIn");
                writer.WriteAttributeString("allowQBE", "false");
                writer.WriteAttributeString("allowSorting", "false");
                writer.WriteAttributeString("label", Localizer.Replace("AnnotationAttachmentNewFieldLabel", "Attachment"));
                writer.WriteAttributeString("computed", "true");
                writer.WriteElementString("formula", ns, "null");
                writer.WriteEndElement();
                writer.Close();
                this.Fields.AppendChild(sb.ToString());
                var ade = new DynamicExpression();
                ade.Target = "_Annotation_AttachmentNew";
                ade.Scope  = DynamicExpressionScope.DataFieldVisibility;
                ade.Type   = DynamicExpressionType.ClientScript;
                ade.Test   = "this.get_isEditing()";
                ade.ViewId = request.View;
                expressions.Add(ade);
                // create NewXXX data fields under "view/dataFields" node
                sb     = new StringBuilder();
                writer = XmlWriter.Create(sb);
                writer.WriteStartElement("category", ns);
                writer.WriteAttributeString("id", "Annotations");
                writer.WriteAttributeString("headerText", Localizer.Replace("AnnotationCategoryHeaderText", "Notes and Attachments"));
                writer.WriteElementString("description", ns, Localizer.Replace("AnnotationCategoryDescription", "Enter optional notes and attach files."));
                writer.WriteStartElement("dataFields", ns);
                // _Annotation_NoteNew dataField
                writer.WriteStartElement("dataField", ns);
                writer.WriteAttributeString("fieldName", "_Annotation_NoteNew");
                writer.WriteAttributeString("columns", "50");
                writer.WriteAttributeString("rows", "7");
                writer.WriteEndElement();
                // _Annotation_AttachmentNew
                writer.WriteStartElement("dataField", ns);
                writer.WriteAttributeString("fieldName", "_Annotation_AttachmentNew");
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.Close();
                view.AppendChild(sb.ToString());
                _retrieveAnnotations = !request.Inserting;
                _config.Expressions  = expressions.ToArray();
            }
        }