Esempio n. 1
0
        RectangleF?getFieldActualRectangle(Template.Field field)
        {
            if (!field.IsSet())
            {
                throw new Exception("Field is not set.");
            }
            if (field.Rectangle.Width <= Settings.Constants.CoordinateDeviationMargin || field.Rectangle.Height <= Settings.Constants.CoordinateDeviationMargin)
            {
                throw new Exception("Rectangle is malformed.");
            }
            RectangleF r = field.Rectangle.GetSystemRectangleF();

            if (field.LeftAnchor != null)
            {
                Page.AnchorActualInfo aai = GetAnchorActualInfo(field.LeftAnchor.Id);
                if (!aai.Found)
                {
                    return(null);
                }
                float right = r.Right;
                r.X    += aai.Shift.Width - field.LeftAnchor.Shift;
                r.Width = right - r.X;
            }
            if (field.TopAnchor != null)
            {
                Page.AnchorActualInfo aai = GetAnchorActualInfo(field.TopAnchor.Id);
                if (!aai.Found)
                {
                    return(null);
                }
                float bottom = r.Bottom;
                r.Y     += aai.Shift.Height - field.TopAnchor.Shift;
                r.Height = bottom - r.Y;
            }
            if (field.RightAnchor != null)
            {
                Page.AnchorActualInfo aai = GetAnchorActualInfo(field.RightAnchor.Id);
                if (!aai.Found)
                {
                    return(null);
                }
                r.Width += aai.Shift.Width - field.RightAnchor.Shift;
            }
            if (field.BottomAnchor != null)
            {
                Page.AnchorActualInfo aai = GetAnchorActualInfo(field.BottomAnchor.Id);
                if (!aai.Found)
                {
                    return(null);
                }
                r.Height += aai.Shift.Height - field.BottomAnchor.Shift;
            }
            if (r.Width <= 0 || r.Height <= 0)
            {
                return(null);
            }
            return(r);
        }
Esempio n. 2
0
        bool setFieldRowValue(DataGridViewRow row, bool setEmpty)
        {
            Template.Field f = (Template.Field)row.Tag;
            if (f == null)
            {
                return(false);
            }
            if (!f.IsSet())
            {
                setRowStatus(statuses.WARNING, row, "Not set");
                return(false);
            }
            DataGridViewCell c = row.Cells["Value"];

            if (c is DataGridViewImageCell && c.Value != null)
            {
                ((Bitmap)c.Value).Dispose();
            }
            if (setEmpty)
            {
                c.Value = null;
                setRowStatus(statuses.NEUTRAL, row, "");
                return(false);
            }
            clearImageFromBoxes();
            object v = extractFieldAndDrawSelectionBox(f);

            if (f.Type == Template.Field.Types.ImageData)
            {
                if (!(c is DataGridViewImageCell))
                {
                    c.Dispose();
                    c = new DataGridViewImageCell();
                    row.Cells["Value"] = c;
                }
            }
            else
            {
                if (c is DataGridViewImageCell)
                {
                    c.Dispose();
                    c = new DataGridViewTextBoxCell();
                    row.Cells["Value"] = c;
                }
            }
            c.Value = v;
            if (c.Value != null)
            {
                setRowStatus(statuses.SUCCESS, row, "Found");
            }
            else
            {
                setRowStatus(statuses.ERROR, row, "Error");
            }
            return(v != null);
        }
        internal Template GetTemplateFromUI(bool saving)
        {
            Template t = new Template();

            if (saving && string.IsNullOrWhiteSpace(name.Text))
            {
                throw new Exception("Name is empty!");
            }

            t.Name = name.Text.Trim();

            t.TextAutoInsertSpace = new TextAutoInsertSpace
            {
                Threshold      = (float)textAutoInsertSpaceThreshold.Value,
                Representative = Regex.Unescape(textAutoInsertSpaceRepresentative.Text),
            };

            t.CvImageScalePyramidStep = (int)CvImageScalePyramidStep.Value;
            t.TesseractPageSegMode    = (Tesseract.PageSegMode)TesseractPageSegMode.SelectedItem;

            if (SingleFieldFromFieldImage.Checked)
            {
                t.FieldOcrMode |= Template.FieldOcrModes.SingleFieldFromFieldImage;
            }
            else
            {
                t.FieldOcrMode &= ~Template.FieldOcrModes.SingleFieldFromFieldImage;
            }
            if (ColumnFieldFromFieldImage.Checked)
            {
                t.FieldOcrMode |= Template.FieldOcrModes.ColumnFieldFromFieldImage;
            }
            else
            {
                t.FieldOcrMode &= ~Template.FieldOcrModes.ColumnFieldFromFieldImage;
            }

            bitmapPreparationForm.SetTemplate(t);

            bool?      removeNotLinkedAnchors = null;
            List <int> conditionAnchorIds     = null;

            if (saving)
            {
                conditionAnchorIds = new List <int>();
                foreach (DataGridViewRow r in conditions.Rows)
                {
                    Template.Condition c = (Template.Condition)r.Tag;
                    if (c != null && c.IsSet())
                    {
                        conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value));
                    }
                }
                conditionAnchorIds = conditionAnchorIds.Distinct().ToList();
            }
            t.Anchors = new List <Template.Anchor>();
            foreach (DataGridViewRow r in anchors.Rows)
            {
                Template.Anchor a = (Template.Anchor)r.Tag;
                if (a == null)
                {
                    continue;
                }

                if (saving)
                {
                    if (!a.IsSet())
                    {
                        throw new Exception("Anchor[Id=" + a.Id + "] is not set!");
                    }

                    if (!conditionAnchorIds.Contains(a.Id))
                    {
                        bool engaged = false;
                        foreach (DataGridViewRow rr in anchors.Rows)
                        {
                            Template.Anchor a_ = (Template.Anchor)rr.Tag;
                            if (a_ == null)
                            {
                                continue;
                            }
                            if (a_.ParentAnchorId == a.Id)
                            {
                                engaged = true;
                                break;
                            }
                        }
                        if (!engaged)
                        {
                            foreach (DataGridViewRow rr in fields.Rows)
                            {
                                Template.Field m = (Template.Field)rr.Tag;
                                if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id))
                                {
                                    engaged = true;
                                    break;
                                }
                            }
                            if (!engaged)
                            {
                                if (a.Id != t.ScalingAnchorId)
                                {
                                    if (removeNotLinkedAnchors == null)
                                    {
                                        removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Remove them?");
                                    }
                                    if (removeNotLinkedAnchors == true)
                                    {
                                        continue;
                                    }
                                }
                            }
                        }
                    }
                }
                t.Anchors.Add((Template.Anchor)Serialization.Json.Clone2(a));
            }
            t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList();

            if (saving)
            {
                t.GetScalingAnchor();//check is it is correct;
            }
            t.Conditions = new List <Template.Condition>();
            foreach (DataGridViewRow r in conditions.Rows)
            {
                Template.Condition c = (Template.Condition)r.Tag;
                if (c == null)
                {
                    continue;
                }
                if (saving)
                {
                    if (!c.IsSet())
                    {
                        throw new Exception("Condition[name=" + c.Name + "] is not set!");
                    }
                    BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id));
                }
                t.Conditions.Add(Serialization.Json.Clone(c));
            }
            if (saving)
            {
                var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault();
                if (dcs != null)
                {
                    throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!");
                }
            }

            t.Fields = new List <Template.Field>();
            foreach (DataGridViewRow r in fields.Rows)
            {
                Template.Field f = (Template.Field)r.Tag;
                if (f == null)
                {
                    continue;
                }
                if (saving && !f.IsSet())
                {
                    throw new Exception("Field[" + r.Index + "] is not set!");
                }
                if (saving)
                {
                    foreach (int?ai in new List <int?> {
                        f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id
                    })
                    {
                        if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null)
                        {
                            throw new Exception("Anchor[Id=" + ai + " does not exist.");
                        }
                    }
                }
                t.Fields.Add(Serialization.Json.Clone(f));
            }
            if (saving)
            {
                if (t.Fields.Count < 1)
                {
                    throw new Exception("Fields is empty!");
                }
                //var dfs = t.Fields.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault();
                //if (dfs != null)
                //    throw new Exception("Field '" + dfs.First().Name + "' is duplicated!");

                //foreach (string columnOfTable in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable != null).Select(x => x.ColumnOfTable))
                //{
                //    Dictionary<string, List<Template.Field>> fieldName2orderedFields = new Dictionary<string, List<Template.Field>>();
                //    foreach (Template.Field.PdfText pt in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable == columnOfTable))
                //    {
                //        List<Template.Field> fs;
                //        if (!fieldName2orderedFields.TryGetValue(pt.Name, out fs))
                //        {
                //            fs = new List<Template.Field>();
                //            fieldName2orderedFields[pt.Name] = fs;
                //        }
                //        fs.Add(pt);
                //    }
                //    int definitionCount = fieldName2orderedFields.Max(x => x.Value.Count());
                //    foreach (string fn in fieldName2orderedFields.Keys)
                //        if (definitionCount > fieldName2orderedFields[fn].Count)
                //            throw new Exception("Field '" + fn + "' is column of table " + columnOfTable + " and so it must have the same number of definitions as the rest column fields!");
                //}

                //foreach (Template.Field f0 in t.Fields)
                //{
                //    int tableDefinitionsCount = t.Fields.Where(x => x.Name == f0.Name).Count();
                //    string fn = t.Fields.Where(x => x.ColumnOfTable == f0.Name).GroupBy(x => x.Name).Where(x => x.Count() > tableDefinitionsCount).FirstOrDefault()?.First().Name;
                //    if (fn != null)
                //        throw new Exception("Field '" + fn + "' is a column of table field " + f0.Name + " so " + f0.Name + " must have number of definitions not less then that of " + fn + ".");
                //}

                //it is done only to avoid unneeded OCR
                //string fn = t.Fields.Where(x => x.ColumnOfTable != null && (x.DefaultValueType != Template.Field.ValueTypes.PdfText && x.DefaultValueType != Template.Field.ValueTypes.PdfTextLines)).FirstOrDefault()?.Name;
                //if (fn != null)
                //    throw new Exception("Field '" + fn + "' is a column of a table field. Its default value type can be either " + Template.Field.ValueTypes.PdfText + " or " + Template.Field.ValueTypes.PdfTextLines);
            }

            if (saving)
            {
                t.Editor = new Template.EditorSettings
                {
                    TestFile         = testFile.Text,
                    TestPictureScale = pictureScale.Value,
                    ExtractFieldsAutomaticallyWhenPageChanged = ExtractFieldsAutomaticallyWhenPageChanged.Checked,
                    ShowFieldTextLineSeparators = ShowFieldTextLineSeparators.Checked,
                    CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked,
                };
            }

            return(t);
        }
Esempio n. 4
0
        object setFieldRowValue(DataGridViewRow row, bool setEmpty)
        {
            Template.Field f = (Template.Field)row.Tag;
            if (f == null)
            {
                return(null);
            }
            if (!f.IsSet())
            {
                setRowStatus(statuses.WARNING, row, "Not set");
                return(null);
            }
            DataGridViewCell valueCell = row.Cells["Value"];

            if (valueCell.Value != null && valueCell.Value is IDisposable)
            {
                ((IDisposable)valueCell.Value).Dispose();
            }
            if (f is Template.Field.Image || f is Template.Field.OcrTextLineImages)
            {
                if (!(valueCell is DataGridViewImageCell))
                {
                    valueCell.Dispose();
                    valueCell          = new DataGridViewImageCell();
                    row.Cells["Value"] = valueCell;
                }
            }
            else
            {
                if (valueCell is DataGridViewImageCell)
                {
                    valueCell.Dispose();
                    valueCell          = new DataGridViewTextBoxCell();
                    row.Cells["Value"] = valueCell;
                }
            }
            if (setEmpty)
            {
                valueCell.Value = null;
                setRowStatus(statuses.NEUTRAL, row, "");
                return(null);
            }
            clearImageFromBoxes();
            object v = extractFieldAndDrawSelectionBox(f);

            if (v != null)
            {
                switch (f.Type)
                {
                case Template.Field.Types.PdfText:
                    valueCell.Value = Page.NormalizeText((string)v);
                    break;

                case Template.Field.Types.PdfTextLines:
                    valueCell.Value = Page.NormalizeText(string.Join("\r\n", (List <string>)v));
                    break;

                case Template.Field.Types.PdfCharBoxs:
                    valueCell.Value = Page.NormalizeText(Serialization.Json.Serialize(v));
                    break;

                case Template.Field.Types.OcrText:
                    valueCell.Value = Page.NormalizeText((string)v);
                    break;

                case Template.Field.Types.OcrTextLines:
                    valueCell.Value = Page.NormalizeText(string.Join("\r\n", (List <string>)v));
                    break;

                case Template.Field.Types.OcrCharBoxs:
                    valueCell.Value = Page.NormalizeText(Serialization.Json.Serialize(v));
                    break;

                case Template.Field.Types.Image:
                {
                    Bitmap b = (Bitmap)v;
                    Size   s = valueCell.Size;
                    if (s.Height < b.Height * pictureScale.Value)
                    {
                        s.Width = int.MaxValue;
                        b       = Win.ImageRoutines.GetScaled(b, s);
                    }
                    else if (pictureScale.Value != 1)
                    {
                        b = Win.ImageRoutines.GetScaled(b, (float)pictureScale.Value);
                    }
                    valueCell.Value = b;
                    break;
                }

                case Template.Field.Types.OcrTextLineImages:
                {
                    List <Bitmap> bs = (List <Bitmap>)v;
                    if (bs.Count < 1)
                    {
                        break;
                    }
                    Bitmap b = bs[0];
                    Size   s = valueCell.Size;
                    if (s.Height < b.Height * pictureScale.Value)
                    {
                        s.Width = int.MaxValue;
                        b       = Win.ImageRoutines.GetScaled(b, s);
                    }
                    else if (pictureScale.Value != 1)
                    {
                        b = Win.ImageRoutines.GetScaled(b, (float)pictureScale.Value);
                    }
                    valueCell.Value = b;
                    break;
                }

                default:
                    throw new Exception("Unknown option: " + f.Type);
                }
            }
            else
            {
                valueCell.Value = v;
            }

            if (valueCell.Value != null)
            {
                setRowStatus(statuses.SUCCESS, row, "Found");
            }
            else
            {
                setRowStatus(statuses.ERROR, row, "Not found");
            }

            return(v);
        }
        internal Template GetTemplateFromUI(bool saving)
        {
            Template t = new Template();

            if (saving && string.IsNullOrWhiteSpace(name.Text))
            {
                throw new Exception("Name is empty!");
            }

            t.Name = name.Text.Trim();

            t.TextAutoInsertSpace = new TextAutoInsertSpace
            {
                Threshold          = (float)textAutoInsertSpace_Threshold.Value,
                IgnoreSourceSpaces = textAutoInsertSpace_IgnoreSourceSpaces.Checked,
                //Representative//default
            };

            t.TesseractPageSegMode      = (Tesseract.PageSegMode)TesseractPageSegMode.SelectedItem;
            t.AdjustLineBorders         = AdjustLineBorders.Checked;
            t.SingleFieldFromFieldImage = SingleFieldFromFieldImage.Checked;
            t.ColumnCellFromCellImage   = ColumnCellFromCellImage.Checked;
            if (CharSizeFilterMinWidth.Value > 0 || CharSizeFilterMaxWidth.Value > 0 || CharSizeFilterMinHeight.Value > 0 || CharSizeFilterMaxHeight.Value > 0)
            {
                t.CharFilter = new CharFilter {
                    MinWidth = (float)CharSizeFilterMinWidth.Value, MaxWidth = (float)CharSizeFilterMaxWidth.Value, MinHeight = (float)CharSizeFilterMinHeight.Value, MaxHeight = (float)CharSizeFilterMaxHeight.Value
                }
            }
            ;
            if (LinePaddingY.Value > 0)
            {
                t.LinePaddingY = (int)LinePaddingY.Value;
            }

            bitmapPreparationForm.SetTemplate(t);

            bool?      removeNotLinkedAnchors = null;
            List <int> conditionAnchorIds     = null;

            if (saving)
            {
                conditionAnchorIds = new List <int>();
                foreach (DataGridViewRow r in conditions.Rows)
                {
                    Template.Condition c = (Template.Condition)r.Tag;
                    if (c != null && c.IsSet())
                    {
                        conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value));
                    }
                }
                conditionAnchorIds = conditionAnchorIds.Distinct().ToList();
            }
            t.Anchors = new List <Template.Anchor>();
            foreach (DataGridViewRow r in anchors.Rows)
            {
                Template.Anchor a = (Template.Anchor)r.Tag;
                if (a == null)
                {
                    continue;
                }

                if (saving)
                {
                    if (!a.IsSet())
                    {
                        throw new Exception("Anchor[Id=" + a.Id + "] is not set!");
                    }

                    if (!conditionAnchorIds.Contains(a.Id))
                    {
                        bool engaged = false;
                        foreach (DataGridViewRow rr in anchors.Rows)
                        {
                            Template.Anchor a_ = (Template.Anchor)rr.Tag;
                            if (a_ == null)
                            {
                                continue;
                            }
                            if (a_.ParentAnchorId == a.Id)
                            {
                                engaged = true;
                                break;
                            }
                        }
                        if (!engaged)
                        {
                            foreach (DataGridViewRow rr in fields.Rows)
                            {
                                Template.Field m = (Template.Field)rr.Tag;
                                if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id))
                                {
                                    engaged = true;
                                    break;
                                }
                            }
                            if (!engaged)
                            {
                                if (a.Id != t.ScalingAnchorId)
                                {
                                    if (removeNotLinkedAnchors == null)
                                    {
                                        removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Remove them?", this);
                                    }
                                    if (removeNotLinkedAnchors == true)
                                    {
                                        continue;
                                    }
                                }
                            }
                        }
                    }
                }
                t.Anchors.Add((Template.Anchor)Serialization.Json.Clone2(a));
            }
            t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList();

            if (saving)
            {
                t.GetScalingAnchor();//check is it is correct;
            }
            t.Conditions = new List <Template.Condition>();
            foreach (DataGridViewRow r in conditions.Rows)
            {
                Template.Condition c = (Template.Condition)r.Tag;
                if (c == null)
                {
                    continue;
                }
                if (saving)
                {
                    if (!c.IsSet())
                    {
                        throw new Exception("Condition[name=" + c.Name + "] is not set!");
                    }
                    BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id));
                }
                t.Conditions.Add((Template.Condition)Serialization.Json.Clone2(c));
            }
            if (saving)
            {
                var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault();
                if (dcs != null)
                {
                    throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!");
                }
            }

            t.Fields = new List <Template.Field>();
            foreach (DataGridViewRow r in fields.Rows)
            {
                Template.Field f = (Template.Field)r.Tag;
                if (f == null)
                {
                    continue;
                }
                if (saving && !f.IsSet())
                {
                    throw new Exception("Field[" + r.Index + "] is not set!");
                }
                if (saving)
                {
                    foreach (int?ai in new List <int?> {
                        f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id
                    })
                    {
                        if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null)
                        {
                            throw new Exception("Anchor[Id=" + ai + " does not exist.");
                        }
                    }
                }
                t.Fields.Add((Template.Field)Serialization.Json.Clone2(f));
            }
            if (saving)
            {
                if (t.Fields.Count < 1)
                {
                    throw new Exception("Fields is empty!");
                }

                var fs = t.Fields.GroupBy(x => x.Name).Where(x => x.GroupBy(a => a.GetType()).Count() > 1).FirstOrDefault();
                if (fs != null)
                {
                    throw new Exception("Definitions of the field '" + fs.First().Name + "' are not of the same type!");
                }
            }

            if (saving)
            {
                t.Editor = new Template.EditorSettings
                {
                    //TestFile = testFile.Text,
                    TestPictureScale = pictureScale.Value,
                    ExtractFieldsAutomaticallyWhenPageChanged = ExtractFieldsAutomaticallyWhenPageChanged.Checked,
                    ShowFieldTextLineSeparators = ShowFieldTextLineSeparators.Checked,
                    CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked,
                };
            }

            return(t);
        }
    }
        Template getTemplateFromUI(bool saving)
        {
            Template t = new Template();

            if (saving && string.IsNullOrWhiteSpace(name.Text))
            {
                throw new Exception("Name is empty!");
            }

            t.Name = name.Text.Trim();

            t.TextAutoInsertSpace = new TextAutoInsertSpace
            {
                Threshold      = (float)textAutoInsertSpaceThreshold.Value,
                Representative = textAutoInsertSpaceRepresentative.Text,
            };

            t.PageRotation        = (Template.PageRotations)pageRotation.SelectedIndex;
            t.AutoDeskew          = autoDeskew.Checked;
            t.AutoDeskewThreshold = (int)autoDeskewThreshold.Value;

            bool?removeNotLinkedAnchors = null;

            t.Anchors = new List <Template.Anchor>();
            List <int> conditionAnchorIds = null;

            if (saving)
            {
                conditionAnchorIds = new List <int>();
                foreach (DataGridViewRow r in conditions.Rows)
                {
                    Template.Condition c = (Template.Condition)r.Tag;
                    if (c != null && c.IsSet())
                    {
                        conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value));
                    }
                }
                conditionAnchorIds = conditionAnchorIds.Distinct().ToList();
            }
            foreach (DataGridViewRow r in anchors.Rows)
            {
                Template.Anchor a = (Template.Anchor)r.Tag;
                if (a == null)
                {
                    continue;
                }

                if (saving)
                {
                    if (!a.IsSet())
                    {
                        throw new Exception("Anchor[Id=" + a.Id + "] is not set!");
                    }

                    bool engaged = false;
                    if (conditionAnchorIds.Contains(a.Id))
                    {
                        engaged = true;
                    }
                    if (!engaged)
                    {
                        foreach (DataGridViewRow rr in anchors.Rows)
                        {
                            Template.Anchor a_ = (Template.Anchor)rr.Tag;
                            if (a_ == null)
                            {
                                continue;
                            }
                            if (a_.ParentAnchorId == a.Id)
                            {
                                engaged = true;
                                break;
                            }
                        }
                    }
                    if (!engaged)
                    {
                        foreach (DataGridViewRow rr in fields.Rows)
                        {
                            Template.Field m = (Template.Field)rr.Tag;
                            if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id))
                            {
                                engaged = true;
                                break;
                            }
                        }
                    }
                    if (!engaged)
                    {
                        if (removeNotLinkedAnchors == null)
                        {
                            removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Should they be removed?");
                        }
                        if (removeNotLinkedAnchors == true)
                        {
                            continue;
                        }
                    }
                }

                t.Anchors.Add(a);
            }
            t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList();

            t.Conditions = new List <Template.Condition>();
            foreach (DataGridViewRow r in conditions.Rows)
            {
                Template.Condition c = (Template.Condition)r.Tag;
                if (c == null)
                {
                    continue;
                }
                if (saving)
                {
                    if (!c.IsSet())
                    {
                        throw new Exception("Condition[name=" + c.Name + "] is not set!");
                    }
                    BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id));
                }
                t.Conditions.Add(c);
            }
            if (saving)
            {
                var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault();
                if (dcs != null)
                {
                    throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!");
                }
            }

            t.Fields = new List <Template.Field>();
            foreach (DataGridViewRow r in fields.Rows)
            {
                Template.Field f = (Template.Field)r.Tag;
                if (f == null)
                {
                    continue;
                }
                if (saving && !f.IsSet())
                {
                    throw new Exception("Field[" + r.Index + "] is not set!");
                }
                if (saving)
                {
                    foreach (int?ai in new List <int?> {
                        f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id
                    })
                    {
                        if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null)
                        {
                            throw new Exception("Anchor[Id=" + ai + " does not exist.");
                        }
                    }
                }
                t.Fields.Add(f);
            }
            if (saving)
            {
                if (t.Fields.Count < 1)
                {
                    throw new Exception("Fields is empty!");
                }
                //var dfs = t.Fields.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault();
                //if (dfs != null)
                //    throw new Exception("Field '" + dfs.First().Name + "' is duplicated!");

                //foreach (string columnOfTable in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable != null).Select(x => x.ColumnOfTable))
                //{
                //    Dictionary<string, List<Template.Field>> fieldName2orderedFields = new Dictionary<string, List<Template.Field>>();
                //    foreach (Template.Field.PdfText pt in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable == columnOfTable))
                //    {
                //        List<Template.Field> fs;
                //        if (!fieldName2orderedFields.TryGetValue(pt.Name, out fs))
                //        {
                //            fs = new List<Template.Field>();
                //            fieldName2orderedFields[pt.Name] = fs;
                //        }
                //        fs.Add(pt);
                //    }
                //    int definitionCount = fieldName2orderedFields.Max(x => x.Value.Count());
                //    foreach (string fn in fieldName2orderedFields.Keys)
                //        if (definitionCount > fieldName2orderedFields[fn].Count)
                //            throw new Exception("Field '" + fn + "' is column of table " + columnOfTable + " and so it must have the same number of definitions as the rest column fields!");
                //}
                foreach (Template.Field f0 in t.Fields)
                {
                    int    tableDefinitionsCount = t.Fields.Where(x => x.Name == f0.Name).Count();
                    string fn = t.Fields.Where(x => x.ColumnOfTable == f0.Name).GroupBy(x => x.Name).Where(x => x.Count() > tableDefinitionsCount).FirstOrDefault()?.First().Name;
                    if (fn != null)
                    {
                        throw new Exception("Field '" + fn + "' is a column of table field " + f0.Name + " so " + f0.Name + " must have number of definitions not less then that of " + fn + ".");
                    }
                }
            }

            if (saving)
            {
                t.Editor = new Template.EditorSettings
                {
                    TestFile         = testFile.Text,
                    TestPictureScale = pictureScale.Value,
                    ExtractFieldsAutomaticallyWhenPageChanged   = ExtractFieldsAutomaticallyWhenPageChanged.Checked,
                    CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked,
                };
            }

            return(t);
        }