Ejemplo n.º 1
0
        public override void Initialize(DataGridViewRow row, Action <DataGridViewRow> onLeft)
        {
            base.Initialize(row, onLeft);

            _object = (Template.Anchor.ImageData)row.Tag;
            if (_object == null)
            {
                _object = new Template.Anchor.ImageData();
            }
            FindBestImageMatch.Checked          = _object.FindBestImageMatch;
            BrightnessTolerance.Value           = (decimal)_object.BrightnessTolerance;
            DifferentPixelNumberTolerance.Value = (decimal)_object.DifferentPixelNumberTolerance;
            pictureBox.Image = null;
            if (_object.Image != null)
            {
                System.Drawing.Image i = _object.Image.GetImage();
                pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
                pictureBox.Width    = (int)(i.Width * imageScale);
                pictureBox.Height   = (int)(i.Height * imageScale);
                pictureBox.Image    = i;
            }

            SearchRectangleMargin.Value    = _object.SearchRectangleMargin;
            SearchRectangleMargin.Enabled  = cSearchRectangleMargin.Checked;
            cSearchRectangleMargin.Checked = SearchRectangleMargin.Value >= 0;
        }
        void setAnchorRow(DataGridViewRow row, Template.Anchor a)
        {
            row.Tag = a;
            row.Cells["Id3"].Value             = a.Id;
            row.Cells["Type3"].Value           = a.Type;
            row.Cells["ParentAnchorId3"].Value = a.ParentAnchorId;

            Template.PointF p = a.Position;
            switch (a.Type)
            {
            case Template.Anchor.Types.PdfText:
                {
                    Template.Anchor.PdfText pt = (Template.Anchor.PdfText)a;
                }
                break;

            case Template.Anchor.Types.OcrText:
            {
                Template.Anchor.OcrText ot = (Template.Anchor.OcrText)a;
            }
            break;

            case Template.Anchor.Types.ImageData:
            {
                Template.Anchor.ImageData id = (Template.Anchor.ImageData)a;
            }
            break;

            //case Template.Anchor.Types.Script:
            //    {
            //        Template.Anchor.Script s = (Template.Anchor.Script)a;
            //    }
            //    break;
            default:
                throw new Exception("Unknown option: " + a.Type);
            }
            if (p != null)
            {
                row.Cells["Position3"].Value = Serialization.Json.Serialize(p);
            }

            if (loadingTemplate)
            {
                return;
            }

            if (currentAnchorControl != null && row == currentAnchorControl.Row)
            {
                setCurrentAnchorRow(a.Id, false);
            }

            setConditionsStatus();
        }
 override protected object getObject()
 {
     if (anchor == null)
     {
         anchor = new Template.Anchor.ImageData();
     }
     anchor.FindBestImageMatch            = FindBestImageMatch.Checked;
     anchor.BrightnessTolerance           = (float)BrightnessTolerance.Value;
     anchor.DifferentPixelNumberTolerance = (float)DifferentPixelNumberTolerance.Value;
     anchor.SearchRectangleMargin         = SearchRectangleMargin.Enabled ? (int)SearchRectangleMargin.Value : -1;
     return(anchor);
 }
        protected override void initialize(DataGridViewRow row)
        {
            anchor = (Template.Anchor.ImageData)row.Tag;
            if (anchor == null)
            {
                anchor = new Template.Anchor.ImageData();
            }
            FindBestImageMatch.Checked          = anchor.FindBestImageMatch;
            BrightnessTolerance.Value           = (decimal)anchor.BrightnessTolerance;
            DifferentPixelNumberTolerance.Value = (decimal)anchor.DifferentPixelNumberTolerance;
            pictureBox.Image = null;
            if (anchor.Image != null)
            {
                System.Drawing.Image i = anchor.Image.GetBitmap();
                pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
                pictureBox.Width    = (int)(i.Width * imageScale);
                pictureBox.Height   = (int)(i.Height * imageScale);
                pictureBox.Image    = i;
            }

            SearchRectangleMargin.Value    = anchor.SearchRectangleMargin;
            SearchRectangleMargin.Enabled  = cSearchRectangleMargin.Checked;
            cSearchRectangleMargin.Checked = SearchRectangleMargin.Value >= 0;
        }
        void initializeAnchorsTable()
        {
            Id3.ValueType = typeof(int);

            Type3.ValueType  = typeof(Template.Anchor.Types);
            Type3.DataSource = Enum.GetValues(typeof(Template.Anchor.Types));

            ParentAnchorId3.ValueType     = typeof(int);
            ParentAnchorId3.ValueMember   = "Id";
            ParentAnchorId3.DisplayMember = "Name";

            anchors.EnableHeadersVisualStyles = false;//needed to set row headers

            anchors.CellPainting += delegate(object sender, DataGridViewCellPaintingEventArgs e)
            {
                if (e.RowIndex < 0)
                {
                    return;
                }
                if (e.ColumnIndex != -1)
                {
                    return;
                }
                rowStates?rowState = anchors.Rows[e.RowIndex].HeaderCell.Tag as rowStates?;
                if (rowState == null || rowState == rowStates.NULL)
                {
                    return;
                }
                e.Paint(e.ClipBounds, DataGridViewPaintParts.All);
                string s;
                switch (rowState)
                {
                case rowStates.Selected:
                    return;

                case rowStates.Parent:
                    s = "●";
                    break;

                case rowStates.Condition:
                    s = "▶";
                    break;

                case rowStates.Linked:
                    return;

                default:
                    throw new Exception("Unknown option: " + rowState);
                }
                Rectangle r = e.CellBounds;
                r.X += 2;
                TextRenderer.DrawText(e.Graphics, s, e.CellStyle.Font, r, Color.Black, TextFormatFlags.VerticalCenter | TextFormatFlags.Left);

                e.Handled = true;
            };

            anchors.CellBeginEdit += delegate(object sender, DataGridViewCellCancelEventArgs e)
            {
                if (anchors.Columns[e.ColumnIndex].Name != "ParentAnchorId3")
                {
                    return;
                }
                setAnchorParentAnchorIdList(anchors.Rows[e.RowIndex]);
            };

            anchors.RowsAdded += delegate(object sender, DataGridViewRowsAddedEventArgs e)
            {
            };

            anchors.DataError += delegate(object sender, DataGridViewDataErrorEventArgs e)
            {
                DataGridViewRow r = anchors.Rows[e.RowIndex];
                Message.Error("Anchor[Id=" + r.Cells["Id3"].Value + "] has unacceptable value of " + anchors.Columns[e.ColumnIndex].HeaderText + ":\r\n" + e.Exception.Message);
            };

            anchors.UserDeletedRow += delegate(object sender, DataGridViewRowEventArgs e)
            {
                onAnchorsChanged();
            };

            anchors.UserDeletingRow += delegate(object sender, DataGridViewRowCancelEventArgs e)
            {
                if (anchors.Rows.Count < 3 && anchors.SelectedRows.Count > 0)
                {
                    anchors.SelectedRows[0].Selected = false;//to avoid auto-creating row
                }
            };

            anchors.CurrentCellDirtyStateChanged += delegate
            {
                if (anchors.IsCurrentCellDirty)
                {
                    anchors.CommitEdit(DataGridViewDataErrorContexts.Commit);
                }
            };

            anchors.CellValueChanged += delegate(object sender, DataGridViewCellEventArgs e)
            {
                if (loadingTemplate)
                {
                    return;
                }
                if (e.ColumnIndex < 0)//row's header
                {
                    return;
                }
                var             row = anchors.Rows[e.RowIndex];
                Template.Anchor a   = (Template.Anchor)row.Tag;
                switch (anchors.Columns[e.ColumnIndex].Name)
                {
                //case "Id3":
                //    {
                //        int? anchorId = (int?)row.Cells["Id3"].Value;
                //        if (anchorId == null)
                //            break;
                //        Template.Anchor a = (Template.Anchor)row.Tag;
                //        a.Id = (int)anchorId;
                //        setAnchorRow(row, a);
                //        break;
                //    }
                case "Type3":
                {
                    Template.Anchor.Types t2 = (Template.Anchor.Types)row.Cells["Type3"].Value;
                    if (t2 == a.Type)
                    {
                        break;
                    }
                    Template.Anchor a2;
                    switch (t2)
                    {
                    case Template.Anchor.Types.PdfText:
                        a2 = new Template.Anchor.PdfText();
                        break;

                    case Template.Anchor.Types.OcrText:
                        a2 = new Template.Anchor.OcrText();
                        break;

                    case Template.Anchor.Types.ImageData:
                        a2 = new Template.Anchor.ImageData();
                        break;

                    case Template.Anchor.Types.CvImage:
                        a2 = new Template.Anchor.CvImage();
                        break;

                    //case Template.Anchor.Types.Script:
                    //    a2 = new Template.Anchor.Script();
                    //    break;
                    default:
                        throw new Exception("Unknown option: " + t2);
                    }
                    a2.Id = a.Id;
                    a     = a2;
                    break;
                }

                case "ParentAnchorId3":
                {
                    a.ParentAnchorId = (int?)row.Cells["ParentAnchorId3"].Value;
                    break;
                }
                }
                setAnchorRow(row, a);
                clearImageFromBoxes();
                findAndDrawAnchor(a.Id);
            };

            anchors.SelectionChanged += delegate(object sender, EventArgs e)
            {
                try
                {
                    if (loadingTemplate)
                    {
                        return;
                    }

                    if (settingCurrentAnchorRow)
                    {
                        return;
                    }

                    if (anchors.SelectedRows.Count < 1)
                    {
                        setCurrentAnchorRow(null, true);
                        return;
                    }
                    var             row = anchors.SelectedRows[0];
                    Template.Anchor a   = (Template.Anchor)row.Tag;
                    if (a == null)//hacky forcing to commit a newly added row and display the blank row
                    {
                        int i = anchors.Rows.Add();
                        row = anchors.Rows[i];
                        a   = templateManager.CreateDefaultAnchor();
                        setAnchorRow(row, a);
                        onAnchorsChanged();
                        row.Selected = true;
                        return;
                    }
                    setCurrentAnchorRow(a.Id, false);
                    showAnchorRowAs(a.Id, rowStates.Selected, true);
                    clearImageFromBoxes();
                    findAndDrawAnchor(a.Id);
                }
                catch (Exception ex)
                {
                    Message.Error2(ex);
                }
            };
        }
Ejemplo n.º 6
0
        bool _findAnchor(Template.Anchor a, PointF parentAnchorPoint0, Func <PointF, bool> proceedOnFound)
        {
            if (!a.IsSet())
            {
                return(false);
            }
            RectangleF rectangle = a.Rectangle();
            RectangleF searchRectangle;

            {
                if (a.ParentAnchorId != null)
                {
                    RectangleF pameir = pageCollection.ActiveTemplate.Anchors.Find(x => x.Id == a.ParentAnchorId).Rectangle();
                    rectangle.X += parentAnchorPoint0.X - pameir.X;
                    rectangle.Y += parentAnchorPoint0.Y - pameir.Y;
                }
                if (a.SearchRectangleMargin >= 0)
                {
                    searchRectangle = getSearchRectangle(rectangle, a.SearchRectangleMargin);
                }
                else
                {
                    searchRectangle = new RectangleF();//not used, just stub to compile
                }
            }

            switch (a.Type)
            {
            case Template.Anchor.Types.PdfText:
            {
                Template.Anchor.PdfText pt = (Template.Anchor.PdfText)a;
                List <Template.Anchor.PdfText.CharBox> cbs = pt.CharBoxs;
                if (pt.IgnoreInvisibleChars)
                {
                    cbs = cbs.Where(x => !Pdf.InvisibleCharacters.Contains(x.Char)).ToList();
                }
                if (cbs.Count < 1)
                {
                    int w = (int)(Bitmap.Width * Settings.Constants.Image2PdfResolutionRatio - rectangle.Width);
                    int h = (int)(Bitmap.Height * Settings.Constants.Image2PdfResolutionRatio - rectangle.Height);
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            RectangleF actualR = new RectangleF(i, j, rectangle.Width, rectangle.Height);
                            if (PdfCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && (!pt.IgnoreInvisibleChars || !Pdf.InvisibleCharacters.Contains(x.Char))) == null &&
                                !proceedOnFound(actualR.Location)
                                )
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                IEnumerable <Pdf.CharBox> tcb0s;
                if (pt.SearchRectangleMargin < 0)
                {
                    tcb0s = PdfCharBoxs.Where(x => x.Char == cbs[0].Char);
                }
                else
                {
                    tcb0s = PdfCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                }
                List <Pdf.CharBox> tcbs = new List <Pdf.CharBox>();
                foreach (Pdf.CharBox tcb0 in tcb0s)
                {
                    tcbs.Clear();
                    tcbs.Add(tcb0);
                    for (int i = 1; i < cbs.Count; i++)
                    {
                        PointF p;
                        if (pt.PositionDeviationIsAbsolute)
                        {
                            p = new PointF(tcb0.R.X + cbs[i].Rectangle.X - cbs[0].Rectangle.X, tcb0.R.Y + cbs[i].Rectangle.Y - cbs[0].Rectangle.Y);
                        }
                        else
                        {
                            p = new PointF(tcbs[i - 1].R.X + cbs[i].Rectangle.X - cbs[i - 1].Rectangle.X, tcbs[i - 1].R.Y + cbs[i].Rectangle.Y - cbs[i - 1].Rectangle.Y);
                        }
                        foreach (Pdf.CharBox bt in PdfCharBoxs.Where(x => x.Char == cbs[i].Char))
                        {
                            if (Math.Abs(bt.R.X - p.X) <= pt.PositionDeviation && Math.Abs(bt.R.Y - p.Y) <= pt.PositionDeviation)
                            {
                                tcbs.Add(bt);
                                break;
                            }
                        }
                        if (tcbs.Count - 1 < i)
                        {
                            break;
                        }
                    }
                    if (tcbs.Count == cbs.Count)
                    {
                        SizeF      shift   = new SizeF(tcbs[0].R.X - cbs[0].Rectangle.X, tcbs[0].R.Y - cbs[0].Rectangle.Y);
                        RectangleF actualR = new RectangleF(rectangle.X + shift.Width, rectangle.Y + shift.Height, rectangle.Width, rectangle.Height);
                        if (PdfCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && !tcbs.Contains(x) && (!pt.IgnoreInvisibleChars || !Pdf.InvisibleCharacters.Contains(x.Char))) == null &&
                            !proceedOnFound(actualR.Location)
                            )
                        {
                            return(true);
                        }
                    }
                }
            }
                return(false);

            case Template.Anchor.Types.OcrText:
            {
                Template.Anchor.OcrText ot = (Template.Anchor.OcrText)a;
                List <Template.Anchor.OcrText.CharBox> cbs = ot.CharBoxs;
                if (cbs.Count < 1)
                {
                    int w = (int)(ActiveTemplateBitmap.Width * Settings.Constants.Image2PdfResolutionRatio - rectangle.Width);
                    int h = (int)(ActiveTemplateBitmap.Height * Settings.Constants.Image2PdfResolutionRatio - rectangle.Height);
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            RectangleF actualR = new RectangleF(i, j, rectangle.Width, rectangle.Height);
                            if (ActiveTemplateOcrCharBoxs.FirstOrDefault(x => actualR.Contains(x.R)) == null &&
                                !proceedOnFound(actualR.Location)
                                )
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                List <Ocr.CharBox>        contaningOcrCharBoxs;
                PointF                    searchRectanglePosition = new PointF(0, 0);
                IEnumerable <Ocr.CharBox> tcb0s;
                if (ot.OcrEntirePage)
                {
                    contaningOcrCharBoxs = ActiveTemplateOcrCharBoxs;
                    if (ot.SearchRectangleMargin < 0)
                    {
                        tcb0s = contaningOcrCharBoxs.Where(x => x.Char == cbs[0].Char);
                    }
                    else
                    {
                        tcb0s = contaningOcrCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                    }
                }
                else if (ot.SearchRectangleMargin < 0)
                {
                    contaningOcrCharBoxs = ActiveTemplateOcrCharBoxs;
                    tcb0s = contaningOcrCharBoxs.Where(x => x.Char == cbs[0].Char);
                }
                else
                {
                    RectangleF contaningRectangle = searchRectangle;
                    for (int i = 1; i < ot.CharBoxs.Count; i++)
                    {
                        contaningRectangle = RectangleF.Union(contaningRectangle, getSearchRectangle(ot.CharBoxs[i].Rectangle.GetSystemRectangleF(), a.SearchRectangleMargin));
                    }
                    contaningOcrCharBoxs    = Ocr.This.GetCharBoxs(GetRectangleFromActiveTemplateBitmap(contaningRectangle.X / Settings.Constants.Image2PdfResolutionRatio, contaningRectangle.Y / Settings.Constants.Image2PdfResolutionRatio, contaningRectangle.Width / Settings.Constants.Image2PdfResolutionRatio, contaningRectangle.Height / Settings.Constants.Image2PdfResolutionRatio));
                    searchRectanglePosition = new PointF(contaningRectangle.X < 0 ? 0 : contaningRectangle.X, contaningRectangle.Y < 0 ? 0 : contaningRectangle.Y);
                    RectangleF unshiftedMainElementSearchRectangle = new RectangleF(searchRectangle.X - searchRectanglePosition.X, searchRectangle.Y - searchRectanglePosition.Y, searchRectangle.Width, searchRectangle.Height);
                    tcb0s = contaningOcrCharBoxs.Where(x => x.Char == cbs[0].Char && unshiftedMainElementSearchRectangle.Contains(x.R));
                }
                List <Ocr.CharBox> tcbs = new List <Ocr.CharBox>();
                foreach (Ocr.CharBox tcb0 in tcb0s)
                {
                    tcbs.Clear();
                    tcbs.Add(tcb0);
                    for (int i = 1; i < cbs.Count; i++)
                    {
                        PointF p;
                        if (ot.PositionDeviationIsAbsolute)
                        {
                            p = new PointF(tcb0.R.X + cbs[i].Rectangle.X - cbs[0].Rectangle.X, tcb0.R.Y + cbs[i].Rectangle.Y - cbs[0].Rectangle.Y);
                        }
                        else
                        {
                            p = new PointF(tcbs[i - 1].R.X + cbs[i].Rectangle.X - cbs[i - 1].Rectangle.X, tcbs[i - 1].R.Y + cbs[i].Rectangle.Y - cbs[i - 1].Rectangle.Y);
                        }
                        foreach (Ocr.CharBox bt in contaningOcrCharBoxs.Where(x => x.Char == cbs[i].Char))
                        {
                            if (Math.Abs(bt.R.X - p.X) <= ot.PositionDeviation && Math.Abs(bt.R.Y - p.Y) <= ot.PositionDeviation)
                            {
                                tcbs.Add(bt);
                                break;
                            }
                        }
                        if (tcbs.Count - 1 < i)
                        {
                            break;
                        }
                    }
                    if (tcbs.Count == cbs.Count)
                    {
                        SizeF      shift   = new SizeF(tcbs[0].R.X - cbs[0].Rectangle.X, tcbs[0].R.Y - cbs[0].Rectangle.Y);
                        RectangleF actualR = new RectangleF(rectangle.X + shift.Width, rectangle.Y + shift.Height, rectangle.Width, rectangle.Height);
                        if (contaningOcrCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && !tcbs.Contains(x)) == null &&
                            !proceedOnFound(actualR.Location)
                            )
                        {
                            return(true);
                        }
                    }
                }
            }
                return(false);

            case Template.Anchor.Types.ImageData:
            {
                Template.Anchor.ImageData idv = (Template.Anchor.ImageData)a;
                Point     searchRectanglePosition;
                ImageData id0;
                if (idv.SearchRectangleMargin < 0)
                {
                    id0 = ActiveTemplateImageData;
                    searchRectanglePosition = new Point(0, 0);
                }
                else
                {
                    searchRectanglePosition = new Point(searchRectangle.X < 0 ? 0 : (int)searchRectangle.X, searchRectangle.Y < 0 ? 0 : (int)searchRectangle.Y);
                    id0 = new ImageData(GetRectangleFromActiveTemplateBitmap(searchRectangle.X / Settings.Constants.Image2PdfResolutionRatio, searchRectangle.Y / Settings.Constants.Image2PdfResolutionRatio, searchRectangle.Width / Settings.Constants.Image2PdfResolutionRatio, searchRectangle.Height / Settings.Constants.Image2PdfResolutionRatio));
                }
                Point?p_ = idv.Image.FindWithinImage(id0, idv.BrightnessTolerance, idv.DifferentPixelNumberTolerance, idv.FindBestImageMatch);
                if (p_ == null)
                {
                    return(false);
                }
                Point p = (Point)p_;
                return(!proceedOnFound(new PointF(searchRectanglePosition.X + p.X, searchRectanglePosition.Y + p.Y)));
            }

            default:
                throw new Exception("Unknown option: " + a.Type);
            }
        }
Ejemplo n.º 7
0
        public TemplateForm(TemplateManager templateManager)
        {
            InitializeComponent();

            Icon = Win.AssemblyRoutines.GetAppIcon();
            Text = Program.FullName + " - Template Editor";

            templateManager.TemplateForm = this;
            this.templateManager         = templateManager;

            this.bitmapPreparationForm = new ScanTemplateForm(this);

            initializeAnchorsTable();
            initializeConditionsTable();
            initializeFieldsTable();

            TesseractPageSegMode.DataSource = Enum.GetValues(typeof(Tesseract.PageSegMode));

            picture.MouseDown += delegate(object sender, MouseEventArgs e)
            {
                if (pages == null)
                {
                    return;
                }

                Point p = new Point((int)(e.X / (float)pictureScale.Value), (int)(e.Y / (float)pictureScale.Value));

                ResizebleBox rb = findResizebleBox(p, out ResizebleBoxSides resizebleBoxSide);
                if (rb != null)
                {
                    drawingMode        = resizebleBoxSide == ResizebleBoxSides.Left || resizebleBoxSide == ResizebleBoxSides.Right ? DrawingModes.resizingSelectionBoxV : DrawingModes.resizingSelectionBoxH;
                    Cursor.Current     = drawingMode == DrawingModes.resizingSelectionBoxV ? Cursors.VSplit : Cursors.HSplit;
                    selectionBoxPoint0 = rb.R.Location;
                    selectionBoxPoint1 = rb.R.Location;
                    selectionBoxPoint2 = new Point(rb.R.Right, rb.R.Bottom);
                }
                else
                {
                    if (ModifierKeys.HasFlag(Keys.Shift))
                    {
                        drawingMode          = DrawingModes.movingImage;
                        Cursor.Current       = Cursors.SizeAll;
                        screenMousePosition0 = Control.MousePosition;
                        imageScrollPostion0  = new Point(splitContainer1.Panel2.HorizontalScroll.Value, splitContainer1.Panel2.VerticalScroll.Value);//to avoid jerking
                    }
                    else
                    {
                        drawingMode        = DrawingModes.drawingSelectionBox;
                        selectionBoxPoint0 = p;
                        selectionBoxPoint1 = p;
                        selectionBoxPoint2 = p;
                    }
                }
                showSelectionCoordinates(selectionBoxPoint1);
            };

            picture.MouseWheel += delegate(object sender, MouseEventArgs e)
            {
                if (pages == null)
                {
                    return;
                }
            };

            picture.MouseMove += delegate(object sender, MouseEventArgs e)
            {
                if (pages == null)
                {
                    return;
                }

                Point p;

                if (drawingMode == DrawingModes.movingImage)
                {
                    p = Control.MousePosition;
                    int h = imageScrollPostion0.X + screenMousePosition0.X - p.X;
                    if (h < splitContainer1.Panel2.HorizontalScroll.Minimum)
                    {
                        h = splitContainer1.Panel2.HorizontalScroll.Minimum;
                    }
                    else if (h > splitContainer1.Panel2.HorizontalScroll.Maximum)
                    {
                        h = splitContainer1.Panel2.HorizontalScroll.Maximum;
                    }
                    splitContainer1.Panel2.HorizontalScroll.Value = h;
                    int v = imageScrollPostion0.Y + screenMousePosition0.Y - p.Y;
                    if (v < splitContainer1.Panel2.VerticalScroll.Minimum)
                    {
                        v = splitContainer1.Panel2.VerticalScroll.Minimum;
                    }
                    else if (v > splitContainer1.Panel2.VerticalScroll.Maximum)
                    {
                        v = splitContainer1.Panel2.VerticalScroll.Maximum;
                    }
                    splitContainer1.Panel2.VerticalScroll.Value = v;
                    return;
                }

                p = new Point((int)(e.X / (float)pictureScale.Value), (int)(e.Y / (float)pictureScale.Value));

                switch (drawingMode)
                {
                case DrawingModes.NULL:
                    showSelectionCoordinates(p);

                    if (findResizebleBox(p, out ResizebleBoxSides resizebleBoxSide) != null)
                    {
                        Cursor.Current = resizebleBoxSide == ResizebleBoxSides.Left || resizebleBoxSide == ResizebleBoxSides.Right ? Cursors.VSplit : Cursors.HSplit;
                    }
                    else
                    {
                        Cursor.Current = Cursors.Default;
                    }
                    return;

                case DrawingModes.drawingSelectionBox:
                    if (selectionBoxPoint0.X < p.X)
                    {
                        selectionBoxPoint1.X = selectionBoxPoint0.X;
                        selectionBoxPoint2.X = p.X;
                    }
                    else
                    {
                        selectionBoxPoint1.X = p.X;
                        selectionBoxPoint2.X = selectionBoxPoint0.X;
                    }
                    if (selectionBoxPoint0.Y < p.Y)
                    {
                        selectionBoxPoint1.Y = selectionBoxPoint0.Y;
                        selectionBoxPoint2.Y = p.Y;
                    }
                    else
                    {
                        selectionBoxPoint1.Y = p.Y;
                        selectionBoxPoint2.Y = selectionBoxPoint0.Y;
                    }
                    break;

                case DrawingModes.resizingSelectionBoxV:
                    if (Math.Abs(selectionBoxPoint2.X - p.X) < Math.Abs(p.X - selectionBoxPoint1.X))
                    {
                        selectionBoxPoint2.X = p.X;
                    }
                    else
                    {
                        selectionBoxPoint1.X = p.X;
                    }
                    break;

                case DrawingModes.resizingSelectionBoxH:
                    if (Math.Abs(selectionBoxPoint2.Y - p.Y) < Math.Abs(p.Y - selectionBoxPoint1.Y))
                    {
                        selectionBoxPoint2.Y = p.Y;
                    }
                    else
                    {
                        selectionBoxPoint1.Y = p.Y;
                    }
                    break;
                }
                showSelectionCoordinates(selectionBoxPoint1, selectionBoxPoint2);
                RectangleF r = new RectangleF(selectionBoxPoint1.X, selectionBoxPoint1.Y, selectionBoxPoint2.X - selectionBoxPoint1.X, selectionBoxPoint2.Y - selectionBoxPoint1.Y);
                clearImageFromBoxes();
                drawBoxes(Settings.Appearance.SelectionBoxColor, Settings.Appearance.SelectionBoxBorderWidth, new List <System.Drawing.RectangleF> {
                    r
                });
            };

            picture.MouseUp += delegate(object sender, MouseEventArgs e)
            {
                try
                {
                    if (pages == null)
                    {
                        return;
                    }

                    if (drawingMode == DrawingModes.NULL)
                    {
                        return;
                    }
                    if (drawingMode == DrawingModes.movingImage)
                    {
                        Cursor.Current = Cursors.Default;
                    }
                    drawingMode = DrawingModes.NULL;

                    Template.RectangleF r = new Template.RectangleF(selectionBoxPoint1.X, selectionBoxPoint1.Y, selectionBoxPoint2.X - selectionBoxPoint1.X, selectionBoxPoint2.Y - selectionBoxPoint1.Y);
                    if (r.Width == 0 || r.Y == 0)//accidental tap
                    {
                        return;
                    }

                    switch (settingMode)
                    {
                    case SettingModes.SetAnchor:
                    {
                        if (currentAnchorControl == null)
                        {
                            break;
                        }

                        //currentAnchorControl.SetTagFromControl();???
                        Template.Anchor a = (Template.Anchor)currentAnchorControl.Row.Tag;

                        if (pages[currentPageI].DetectedImageScale >= 0 && pages[currentPageI].DetectedImageScale < 1 && a.Id == GetTemplateFromUI(false).ScalingAnchorId)
                        {
                            Message.Exclaim("When the detected image scale is not 1, changing coordinates of the scaling anchor must not be done. Either switch off scaling by anchor and reload the page or open a page where the detected image scale is 1.", this);
                            break;
                        }

                        a.Position = new Template.PointF {
                            X = r.X, Y = r.Y
                        };
                        try
                        {
                            switch (a.Type)
                            {
                            case Template.Anchor.Types.PdfText:
                            {
                                Template.Anchor.PdfText pt = (Template.Anchor.PdfText)a;
                                pt.CharBoxs = new List <Template.Anchor.PdfText.CharBox>();
                                foreach (Pdf.CharBox cb in Pdf.GetCharBoxsSurroundedByRectangle(pages[currentPageI].PdfCharBoxs, r.GetSystemRectangleF(), true))
                                {
                                    pt.CharBoxs.Add(new Template.Anchor.PdfText.CharBox
                                            {
                                                Char      = cb.Char,
                                                Rectangle = new Template.RectangleF(cb.R.X, cb.R.Y, cb.R.Width, cb.R.Height),
                                            });
                                }
                                pt.Size = new Template.SizeF {
                                    Width = r.Width, Height = r.Height
                                };
                            }
                            break;

                            case Template.Anchor.Types.OcrText:
                            {
                                Template.Anchor.OcrText ot = (Template.Anchor.OcrText)a;
                                ot.CharBoxs = new List <Template.Anchor.OcrText.CharBox>();
                                var selectedOcrCharBoxs = new List <Ocr.CharBox>();
                                if (ot.OcrEntirePage)
                                {
                                    selectedOcrCharBoxs.AddRange(Ocr.GetCharBoxsSurroundedByRectangle(pages[currentPageI].ActiveTemplateOcrCharBoxs, r.GetSystemRectangleF()));
                                }
                                else
                                {
                                    using (Bitmap b = pages[currentPageI].GetRectangleFromActiveTemplateBitmap(r.X / Settings.Constants.Pdf2ImageResolutionRatio, r.Y / Settings.Constants.Pdf2ImageResolutionRatio, r.Width / Settings.Constants.Pdf2ImageResolutionRatio, r.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                                    {
                                        if (b == null)
                                        {
                                            throw new Exception("Selected image is empty.");
                                        }
                                        foreach (Ocr.CharBox cb in Ocr.This.GetCharBoxs(b, pages.ActiveTemplate.TesseractPageSegMode))
                                        {
                                            cb.R.X += r.X;
                                            cb.R.Y += r.Y;
                                            selectedOcrCharBoxs.Add(cb);
                                        }
                                    }
                                }
                                foreach (Ocr.CharBox cb in selectedOcrCharBoxs)
                                {
                                    ot.CharBoxs.Add(new Template.Anchor.OcrText.CharBox
                                            {
                                                Char      = cb.Char,
                                                Rectangle = new Template.RectangleF(cb.R.X, cb.R.Y, cb.R.Width, cb.R.Height),
                                            });
                                }
                                ot.Size = new Template.SizeF {
                                    Width = r.Width, Height = r.Height
                                };
                            }
                            break;

                            case Template.Anchor.Types.ImageData:
                            {
                                Template.Anchor.ImageData id = (Template.Anchor.ImageData)a;
                                using (Bitmap b = pages[currentPageI].GetRectangleFromActiveTemplateBitmap(r.X / Settings.Constants.Pdf2ImageResolutionRatio, r.Y / Settings.Constants.Pdf2ImageResolutionRatio, r.Width / Settings.Constants.Pdf2ImageResolutionRatio, r.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                                {
                                    if (b == null)
                                    {
                                        throw new Exception("Selected image is empty.");
                                    }
                                    id.Image = new ImageData(b);
                                }
                            }
                            break;

                            case Template.Anchor.Types.CvImage:
                            {
                                Template.Anchor.CvImage ci = (Template.Anchor.CvImage)a;
                                using (Bitmap b = pages[currentPageI].GetRectangleFromActiveTemplateBitmap(r.X / Settings.Constants.Pdf2ImageResolutionRatio, r.Y / Settings.Constants.Pdf2ImageResolutionRatio, r.Width / Settings.Constants.Pdf2ImageResolutionRatio, r.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                                {
                                    if (b == null)
                                    {
                                        throw new Exception("Selected image is empty.");
                                    }
                                    ci.Image = new CvImage(b);
                                }
                            }
                            break;

                            default:
                                throw new Exception("Unknown option: " + a.Type);
                            }
                            setAnchorRow(currentAnchorControl.Row, a);
                            clearImageFromBoxes();
                            findAndDrawAnchor(a.Id);
                        }
                        finally
                        {
                            anchors.EndEdit();
                        }
                    }
                    break;

                    case SettingModes.SetField:
                    {
                        if (fields.SelectedRows.Count < 1)
                        {
                            break;
                        }
                        var            row = fields.SelectedRows[0];
                        Template.Field f   = (Template.Field)row.Tag;
                        f.Rectangle = r;

                        if (f.LeftAnchor != null)
                        {
                            Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(f.LeftAnchor.Id);
                            f.LeftAnchor.Shift = aai.Shift.Width;
                        }
                        if (f.TopAnchor != null)
                        {
                            Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(f.TopAnchor.Id);
                            f.TopAnchor.Shift = aai.Shift.Height;
                        }
                        if (f.RightAnchor != null)
                        {
                            Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(f.RightAnchor.Id);
                            f.RightAnchor.Shift = aai.Shift.Width;
                        }
                        if (f.BottomAnchor != null)
                        {
                            Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(f.BottomAnchor.Id);
                            f.BottomAnchor.Shift = aai.Shift.Height;
                        }

                        setFieldRow(row, f);
                    }
                    break;

                    case SettingModes.NULL:
                        break;

                    default:
                        throw new Exception("Unknown option: " + settingMode);
                    }
                }
                catch (Exception ex)
                {
                    Message.Error2(ex, this);
                }
            };

            Shown += delegate
            {
                Application.DoEvents();//make form be drawn completely
                setUIFromTemplate(templateManager.Template);
            };

            this.EnumControls((Control c) =>
            {
                if (c is SplitContainer s)
                {
                    s.BackColor        = Color.FromArgb(80, 70, 0);
                    s.SplitterWidth    = 2;
                    s.Panel1.BackColor = SystemColors.Control;
                    s.Panel2.BackColor = SystemColors.Control;
                }
            }, true);

            testFile.TextChanged += delegate
            {
                try
                {
                    dispose(false);

                    if (string.IsNullOrWhiteSpace(testFile.Text))
                    {
                        return;
                    }

                    templateManager.LastTestFile = testFile.Text;

                    testFile.SelectionStart = testFile.Text.Length;
                    testFile.ScrollToCaret();

                    if (!File.Exists(testFile.Text))
                    {
                        string m = "File '" + testFile.Text + "' does not exist!";
                        Log.Error(m);
                        Message.Error(m, this);
                        return;
                    }

                    pages            = new PageCollection(testFile.Text, true);
                    totalPageNumber  = pages.TotalCount;
                    lTotalPages.Text = " / " + totalPageNumber;
                    showPage(1);
                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                    Message.Error(ex, this);
                }
            };

            pictureScale.ValueChanged += delegate
            {
                if (!loadingTemplate)
                {
                    setScaledImage();
                }
            };

            Load += delegate
            {
                //Application.DoEvents();//make form be drawn completely
                //BeginInvoke((Action<Template>)setUIFromTemplate, templateManager.Template);
            };

            FormClosed += delegate
            {
                bitmapPreparationForm.Close();
            };

            bSave.Click           += Save_Click;
            bOK.Click             += OK_Click;
            bCancel.Click         += delegate { Close(); };
            Help.LinkClicked      += Help_LinkClicked;
            Configure.LinkClicked += Configure_LinkClicked;
            About.LinkClicked     += About_LinkClicked;

            bTestFile.Click += delegate(object sender, EventArgs e)
            {
                OpenFileDialog d = new OpenFileDialog();
                if (!string.IsNullOrWhiteSpace(testFile.Text))
                {
                    d.InitialDirectory = PathRoutines.GetFileDir(testFile.Text);
                }
                else
                if (!string.IsNullOrWhiteSpace(templateManager.TestFileDefaultFolder))
                {
                    d.InitialDirectory = templateManager.TestFileDefaultFolder;
                }

                d.Filter = "PDF|*.pdf|"
                           + "All files (*.*)|*.*";
                if (d.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }
                testFile.Text = d.FileName;
            };

            ShowPdfText.LinkClicked += ShowPdfText_LinkClicked;
            ShowOcrText.LinkClicked += ShowOcrText_LinkClicked;
            ShowAsJson.LinkClicked  += showAsJson_LinkClicked;

            tCurrentPage.Leave += delegate
            {
                changeCurrentPage();
            };
            tCurrentPage.KeyDown += delegate(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    changeCurrentPage();
                }
            };
        }
Ejemplo n.º 8
0
        public TemplateForm(TemplateManager templateManager)
        {
            InitializeComponent();

            Icon = Win.AssemblyRoutines.GetAppIcon();
            Text = Program.FullName + ": Template Editor";

            this.templateManager = templateManager;

            initializeAnchorsTable();
            initializeConditionsTable();
            initializeFieldsTable();

            picture.MouseDown += delegate(object sender, MouseEventArgs e)
            {
                if (pages == null)
                {
                    return;
                }

                Point p = new Point((int)(e.X / (float)pictureScale.Value), (int)(e.Y / (float)pictureScale.Value));

                ResizebleBox rb = findResizebleBox(p, out ResizebleBoxSides resizebleBoxSide);
                if (rb != null)
                {
                    drawingMode        = resizebleBoxSide == ResizebleBoxSides.Left || resizebleBoxSide == ResizebleBoxSides.Right ? DrawingModes.resizingSelectionBoxV : DrawingModes.resizingSelectionBoxH;
                    Cursor.Current     = drawingMode == DrawingModes.resizingSelectionBoxV ? Cursors.VSplit : Cursors.HSplit;
                    selectionBoxPoint0 = rb.R.Location;
                    selectionBoxPoint1 = rb.R.Location;
                    selectionBoxPoint2 = new Point(rb.R.Right, rb.R.Bottom);
                }
                else
                {
                    drawingMode        = DrawingModes.drawingSelectionBox;
                    selectionBoxPoint0 = p;
                    selectionBoxPoint1 = p;
                    selectionBoxPoint2 = p;
                }
                selectionCoordinates.Text = selectionBoxPoint1.ToString();
            };

            picture.MouseMove += delegate(object sender, MouseEventArgs e)
            {
                if (pages == null)
                {
                    return;
                }

                Point p = new Point((int)(e.X / (float)pictureScale.Value), (int)(e.Y / (float)pictureScale.Value));

                switch (drawingMode)
                {
                case DrawingModes.NULL:
                    selectionCoordinates.Text = p.ToString();

                    if (findResizebleBox(p, out ResizebleBoxSides resizebleBoxSide) != null)
                    {
                        Cursor.Current = resizebleBoxSide == ResizebleBoxSides.Left || resizebleBoxSide == ResizebleBoxSides.Right ? Cursors.VSplit : Cursors.HSplit;
                    }
                    else
                    {
                        Cursor.Current = Cursors.Default;
                    }
                    return;

                case DrawingModes.drawingSelectionBox:
                    if (selectionBoxPoint0.X < p.X)
                    {
                        selectionBoxPoint1.X = selectionBoxPoint0.X;
                        selectionBoxPoint2.X = p.X;
                    }
                    else
                    {
                        selectionBoxPoint1.X = p.X;
                        selectionBoxPoint2.X = selectionBoxPoint0.X;
                    }
                    if (selectionBoxPoint0.Y < p.Y)
                    {
                        selectionBoxPoint1.Y = selectionBoxPoint0.Y;
                        selectionBoxPoint2.Y = p.Y;
                    }
                    else
                    {
                        selectionBoxPoint1.Y = p.Y;
                        selectionBoxPoint2.Y = selectionBoxPoint0.Y;
                    }
                    break;

                case DrawingModes.resizingSelectionBoxV:
                    if (Math.Abs(selectionBoxPoint2.X - p.X) < Math.Abs(p.X - selectionBoxPoint1.X))
                    {
                        selectionBoxPoint2.X = p.X;
                    }
                    else
                    {
                        selectionBoxPoint1.X = p.X;
                    }
                    break;

                case DrawingModes.resizingSelectionBoxH:
                    if (Math.Abs(selectionBoxPoint2.Y - p.Y) < Math.Abs(p.Y - selectionBoxPoint1.Y))
                    {
                        selectionBoxPoint2.Y = p.Y;
                    }
                    else
                    {
                        selectionBoxPoint1.Y = p.Y;
                    }
                    break;
                }
                selectionCoordinates.Text = selectionBoxPoint1.ToString() + ":" + selectionBoxPoint2.ToString();
                RectangleF r = new RectangleF(selectionBoxPoint1.X, selectionBoxPoint1.Y, selectionBoxPoint2.X - selectionBoxPoint1.X, selectionBoxPoint2.Y - selectionBoxPoint1.Y);
                clearImageFromBoxes();
                drawBoxes(Settings.Appearance.SelectionBoxColor, Settings.Appearance.SelectionBoxBorderWidth, new List <System.Drawing.RectangleF> {
                    r
                });
            };

            picture.MouseUp += delegate(object sender, MouseEventArgs e)
            {
                try
                {
                    if (pages == null)
                    {
                        return;
                    }

                    if (drawingMode == DrawingModes.NULL)
                    {
                        return;
                    }
                    drawingMode = DrawingModes.NULL;

                    Template.RectangleF r = new Template.RectangleF(selectionBoxPoint1.X, selectionBoxPoint1.Y, selectionBoxPoint2.X - selectionBoxPoint1.X, selectionBoxPoint2.Y - selectionBoxPoint1.Y);
                    if (r.Width == 0 || r.Y == 0)//accidental tap
                    {
                        return;
                    }

                    switch (settingMode)
                    {
                    case SettingModes.SetAnchor:
                    {
                        if (currentAnchorControl == null)
                        {
                            break;
                        }

                        currentAnchorControl.SetTagFromControl();
                        Template.Anchor a = (Template.Anchor)currentAnchorControl.Row.Tag;
                        a.Position = new Template.PointF {
                            X = r.X, Y = r.Y
                        };
                        try
                        {
                            switch (a.Type)
                            {
                            case Template.Anchor.Types.PdfText:
                            {
                                Template.Anchor.PdfText pt = (Template.Anchor.PdfText)a;
                                pt.CharBoxs = new List <Template.Anchor.PdfText.CharBox>();
                                List <Pdf.Line> lines = Pdf.GetLines(Pdf.GetCharBoxsSurroundedByRectangle(pages[currentPageI].PdfCharBoxs, r.GetSystemRectangleF(), true), null);
                                foreach (Pdf.Line l in lines)
                                {
                                    foreach (Pdf.CharBox cb in l.CharBoxs)
                                    {
                                        pt.CharBoxs.Add(new Template.Anchor.PdfText.CharBox
                                                {
                                                    Char      = cb.Char,
                                                    Rectangle = new Template.RectangleF(cb.R.X, cb.R.Y, cb.R.Width, cb.R.Height),
                                                });
                                    }
                                }
                                pt.Size = new Template.SizeF {
                                    Width = r.Width, Height = r.Height
                                };
                            }
                            break;

                            case Template.Anchor.Types.OcrText:
                            {
                                Template.Anchor.OcrText ot = (Template.Anchor.OcrText)a;
                                ot.CharBoxs = new List <Template.Anchor.OcrText.CharBox>();
                                var selectedOcrCharBoxs = new List <Ocr.CharBox>();
                                if (ot.OcrEntirePage)
                                {
                                    selectedOcrCharBoxs.AddRange(Ocr.GetCharBoxsSurroundedByRectangle(pages[currentPageI].ActiveTemplateOcrCharBoxs, r.GetSystemRectangleF()));
                                }
                                else
                                {
                                    foreach (Ocr.CharBox cb in Ocr.This.GetCharBoxs(pages[currentPageI].GetRectangleFromActiveTemplateBitmap(r.X / Settings.Constants.Image2PdfResolutionRatio, r.Y / Settings.Constants.Image2PdfResolutionRatio, r.Width / Settings.Constants.Image2PdfResolutionRatio, r.Height / Settings.Constants.Image2PdfResolutionRatio)))
                                    {
                                        cb.R.X += r.X;
                                        cb.R.Y += r.Y;
                                        selectedOcrCharBoxs.Add(cb);
                                    }
                                }
                                foreach (Ocr.Line l in Ocr.GetLines(selectedOcrCharBoxs, null))
                                {
                                    foreach (Ocr.CharBox cb in l.CharBoxs)
                                    {
                                        ot.CharBoxs.Add(new Template.Anchor.OcrText.CharBox
                                                {
                                                    Char      = cb.Char,
                                                    Rectangle = new Template.RectangleF(cb.R.X, cb.R.Y, cb.R.Width, cb.R.Height),
                                                });
                                    }
                                }
                                ot.Size = new Template.SizeF {
                                    Width = r.Width, Height = r.Height
                                };
                            }
                            break;

                            case Template.Anchor.Types.ImageData:
                            {
                                Template.Anchor.ImageData id = (Template.Anchor.ImageData)a;
                                using (Bitmap b = pages[currentPageI].GetRectangleFromActiveTemplateBitmap(r.X / Settings.Constants.Image2PdfResolutionRatio, r.Y / Settings.Constants.Image2PdfResolutionRatio, r.Width / Settings.Constants.Image2PdfResolutionRatio, r.Height / Settings.Constants.Image2PdfResolutionRatio))
                                {
                                    id.Image = new ImageData(b);
                                }
                            }
                            break;

                            case Template.Anchor.Types.CvImage:
                            {
                                Template.Anchor.CvImage ci = (Template.Anchor.CvImage)a;
                                using (Bitmap b = pages[currentPageI].GetRectangleFromActiveTemplateBitmap(r.X / Settings.Constants.Image2PdfResolutionRatio, r.Y / Settings.Constants.Image2PdfResolutionRatio, r.Width / Settings.Constants.Image2PdfResolutionRatio, r.Height / Settings.Constants.Image2PdfResolutionRatio))
                                {
                                    ci.Image = new CvImage(b);
                                }
                            }
                            break;

                            default:
                                throw new Exception("Unknown option: " + a.Type);
                            }
                            setAnchorRow(currentAnchorControl.Row, a);
                            clearImageFromBoxes();
                            findAndDrawAnchor(a.Id);
                        }
                        finally
                        {
                            anchors.EndEdit();
                        }
                    }
                    break;

                    case SettingModes.SetField:
                    {
                        if (fields.SelectedRows.Count < 1)
                        {
                            break;
                        }
                        var            row = fields.SelectedRows[0];
                        Template.Field f   = (Template.Field)row.Tag;
                        f.Rectangle = r;

                        if (f.LeftAnchor != null)
                        {
                            Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(f.LeftAnchor.Id);
                            f.LeftAnchor.Shift = aai.Shift.Width;
                        }
                        if (f.TopAnchor != null)
                        {
                            Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(f.TopAnchor.Id);
                            f.TopAnchor.Shift = aai.Shift.Height;
                        }
                        if (f.RightAnchor != null)
                        {
                            Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(f.RightAnchor.Id);
                            f.RightAnchor.Shift = aai.Shift.Width;
                        }
                        if (f.BottomAnchor != null)
                        {
                            Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(f.BottomAnchor.Id);
                            f.BottomAnchor.Shift = aai.Shift.Height;
                        }

                        setFieldRow(row, f);
                        extractFieldAndDrawSelectionBox(f);
                        //owners2resizebleBox[f] = new ResizebleBox(f, f.Rectangle.GetSystemRectangleF(), Settings.Appearance.SelectionBoxBorderWidth);
                    }
                    break;

                    case SettingModes.NULL:
                        break;

                    default:
                        throw new Exception("Unknown option: " + settingMode);
                    }
                }
                catch (Exception ex)
                {
                    Message.Error2(ex);
                }
            };

            Shown += delegate
            {
                Application.DoEvents();//make form be drawn completely
                setUIFromTemplate(templateManager.Template);
            };

            FormClosed += delegate
            {
                if (scaledCurrentPageBitmap != null)
                {
                    scaledCurrentPageBitmap.Dispose();
                    scaledCurrentPageBitmap = null;
                }
                if (pages != null)
                {
                    pages.Dispose();
                    pages = null;
                }

                templateManager.LastTestFile = testFile.Text;
            };

            this.EnumControls((Control c) =>
            {
                if (c is SplitContainer s)
                {
                    s.BackColor        = Color.FromArgb(80, 70, 0);
                    s.SplitterWidth    = 2;
                    s.Panel1.BackColor = SystemColors.Control;
                    s.Panel2.BackColor = SystemColors.Control;
                }
            }, true);

            testFile.TextChanged += delegate
            {
                try
                {
                    if (picture.Image != null)
                    {
                        picture.Image.Dispose();
                        picture.Image = null;
                    }
                    if (scaledCurrentPageBitmap != null)
                    {
                        scaledCurrentPageBitmap.Dispose();
                        scaledCurrentPageBitmap = null;
                    }
                    if (pages != null)
                    {
                        pages.Dispose();
                        pages = null;
                    }

                    if (string.IsNullOrWhiteSpace(testFile.Text))
                    {
                        return;
                    }

                    testFile.SelectionStart = testFile.Text.Length;
                    testFile.ScrollToCaret();

                    if (!File.Exists(testFile.Text))
                    {
                        Win.LogMessage.Error("File '" + testFile.Text + "' does not exist!");
                        return;
                    }

                    pages            = new PageCollection(testFile.Text);
                    totalPageNumber  = pages.PdfReader.NumberOfPages;
                    lTotalPages.Text = " / " + totalPageNumber;
                    showPage(1);
                }
                catch (Exception ex)
                {
                    Win.LogMessage.Error(ex);
                }
            };

            pictureScale.ValueChanged += delegate
            {
                if (!loadingTemplate)
                {
                    setScaledImage();
                }
            };

            pageRotation.SelectedIndexChanged += delegate
            {
                reloadPageBitmaps();
                //showPage(currentPageI);
            };

            autoDeskew.CheckedChanged += delegate
            {
                reloadPageBitmaps();
                //showPage(currentPageI);
            };

            Load += delegate
            {
            };

            save.Click            += Save_Click;
            cancel.Click          += delegate { Close(); };
            Help.LinkClicked      += Help_LinkClicked;
            Configure.LinkClicked += Configure_LinkClicked;
            About.LinkClicked     += About_LinkClicked;

            bTestFile.Click += delegate(object sender, EventArgs e)
            {
                OpenFileDialog d = new OpenFileDialog();
                if (!string.IsNullOrWhiteSpace(testFile.Text))
                {
                    d.InitialDirectory = PathRoutines.GetFileDir(testFile.Text);
                }
                else
                if (!string.IsNullOrWhiteSpace(templateManager.TestFileDefaultFolder))
                {
                    d.InitialDirectory = templateManager.TestFileDefaultFolder;
                }

                d.Filter = "PDF|*.pdf|"
                           + "All files (*.*)|*.*";
                if (d.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }
                testFile.Text = d.FileName;
            };

            ShowPdfText.LinkClicked += ShowPdfText_LinkClicked;
            ShowOcrText.LinkClicked += ShowOcrText_LinkClicked;
            ShowAsJson.LinkClicked  += showAsJson_LinkClicked;

            tCurrentPage.Leave += delegate
            {
                changeCurrentPage();
            };
            tCurrentPage.KeyDown += delegate(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    changeCurrentPage();
                }
            };
        }
Ejemplo n.º 9
0
        bool findAnchor(Template.Anchor a, PointF parentAnchorPoint0, Func <PointF, bool> findNext)
        {
            if (!a.IsSet())
            {
                return(false);
            }
            RectangleF rectangle = a.Rectangle();
            RectangleF searchRectangle;

            {
                if (a.ParentAnchorId != null)
                {
                    RectangleF pameir = PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == a.ParentAnchorId).Rectangle();
                    rectangle.X += parentAnchorPoint0.X - pameir.X;
                    rectangle.Y += parentAnchorPoint0.Y - pameir.Y;
                }
                if (a.SearchRectangleMargin >= 0)
                {
                    searchRectangle = getSearchRectangle(rectangle, a.SearchRectangleMargin);
                }
                else
                {
                    searchRectangle = new RectangleF();//not used, just stub to compile
                }
            }

            switch (a.Type)
            {
            case Template.Anchor.Types.PdfText:
            {
                Template.Anchor.PdfText pt = (Template.Anchor.PdfText)a;
                List <Template.Anchor.PdfText.CharBox> cbs = pt.CharBoxs;
                if (pt.IgnoreInvisibleChars)
                {
                    cbs = cbs.Where(x => !Pdf.InvisibleCharacters.Contains(x.Char)).ToList();
                }
                if (cbs.Count < 1)
                {
                    int w = Size.Width;
                    int h = Size.Height;
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            RectangleF actualR = new RectangleF(i, j, rectangle.Width, rectangle.Height);
                            if (        //check that the rectangle contains nothing
                                PdfCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && (!pt.IgnoreInvisibleChars || !Pdf.InvisibleCharacters.Contains(x.Char))) == null &&
                                !findNext(actualR.Location)
                                )
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                IEnumerable <Pdf.CharBox> tcb0s;
                if (pt.SearchRectangleMargin < 0)
                {
                    tcb0s = PdfCharBoxs.Where(x => x.Char == cbs[0].Char);
                }
                else
                {
                    tcb0s = PdfCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                }
                List <Pdf.CharBox> tcbs = new List <Pdf.CharBox>();
                foreach (Pdf.CharBox tcb0 in tcb0s)
                {
                    tcbs.Clear();
                    tcbs.Add(tcb0);
                    for (int i = 1; i < cbs.Count; i++)
                    {
                        PointF p;
                        if (pt.PositionDeviationIsAbsolute)
                        {
                            p = new PointF(tcb0.R.X + cbs[i].Rectangle.X - cbs[0].Rectangle.X, tcb0.R.Y + cbs[i].Rectangle.Y - cbs[0].Rectangle.Y);
                        }
                        else
                        {
                            p = new PointF(tcbs[i - 1].R.X + cbs[i].Rectangle.X - cbs[i - 1].Rectangle.X, tcbs[i - 1].R.Y + cbs[i].Rectangle.Y - cbs[i - 1].Rectangle.Y);
                        }
                        foreach (Pdf.CharBox bt in PdfCharBoxs.Where(x => x.Char == cbs[i].Char))
                        {
                            if (Math.Abs(bt.R.X - p.X) <= pt.PositionDeviation && Math.Abs(bt.R.Y - p.Y) <= pt.PositionDeviation)
                            {
                                tcbs.Add(bt);
                                break;
                            }
                        }
                        if (tcbs.Count - 1 < i)
                        {
                            break;
                        }
                    }
                    if (tcbs.Count == cbs.Count)
                    {
                        SizeF      shift   = new SizeF(tcbs[0].R.X - cbs[0].Rectangle.X, tcbs[0].R.Y - cbs[0].Rectangle.Y);
                        RectangleF actualR = new RectangleF(rectangle.X + shift.Width, rectangle.Y + shift.Height, rectangle.Width, rectangle.Height);
                        if (        //check that the found rectangle contains only the anchor's boxes
                            (pt.IgnoreOtherCharsInRectangle || PdfCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && !tcbs.Contains(x) && (!pt.IgnoreInvisibleChars || !Pdf.InvisibleCharacters.Contains(x.Char))) == null) &&
                            !findNext(actualR.Location)
                            )
                        {
                            return(true);
                        }
                    }
                }
            }
                return(false);

            case Template.Anchor.Types.OcrText:
            {
                Template.Anchor.OcrText ot = (Template.Anchor.OcrText)a;
                List <Template.Anchor.OcrText.CharBox> cbs = ot.CharBoxs;
                if (cbs.Count < 1)
                {
                    int w = (int)(ActiveTemplateBitmap.Width * Settings.Constants.Pdf2ImageResolutionRatio - rectangle.Width);
                    int h = (int)(ActiveTemplateBitmap.Height * Settings.Constants.Pdf2ImageResolutionRatio - rectangle.Height);
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            RectangleF actualR = new RectangleF(i, j, rectangle.Width, rectangle.Height);
                            if (ActiveTemplateOcrCharBoxs.FirstOrDefault(x => actualR.Contains(x.R)) == null &&
                                !findNext(actualR.Location)
                                )
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                List <Ocr.CharBox>        searchRectangleOcrCharBoxs;
                IEnumerable <Ocr.CharBox> tcb0s;
                if (ot.OcrEntirePage)
                {
                    searchRectangleOcrCharBoxs = ActiveTemplateOcrCharBoxs;
                    if (ot.SearchRectangleMargin < 0)
                    {
                        tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char);
                    }
                    else
                    {
                        tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                    }
                }
                else if (ot.SearchRectangleMargin < 0)
                {
                    searchRectangleOcrCharBoxs = ActiveTemplateOcrCharBoxs;
                    tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char);
                }
                else
                {
                    //RectangleF contaningRectangle = searchRectangle;
                    //for (int i = 1; i < ot.CharBoxs.Count; i++)
                    //    contaningRectangle = RectangleF.Union(contaningRectangle, getSearchRectangle(ot.CharBoxs[i].Rectangle.GetSystemRectangleF(), a.SearchRectangleMargin));
                    //searchRectangleOcrCharBoxs = Ocr.This.GetCharBoxs(GetRectangleFromActiveTemplateBitmap(contaningRectangle.X / Settings.Constants.Pdf2ImageResolutionRatio, contaningRectangle.Y / Settings.Constants.Pdf2ImageResolutionRatio, contaningRectangle.Width / Settings.Constants.Pdf2ImageResolutionRatio, contaningRectangle.Height / Settings.Constants.Pdf2ImageResolutionRatio));
                    //PointF searchRectanglePosition = new PointF(contaningRectangle.X < 0 ? 0 : contaningRectangle.X, contaningRectangle.Y < 0 ? 0 : contaningRectangle.Y);
                    //searchRectangleOcrCharBoxs.ForEach(x => { x.R.X += contaningRectangle.X; x.R.Y += contaningRectangle.Y; });
                    //RectangleF mainElementSearchRectangle = new RectangleF(searchRectangle.X - searchRectanglePosition.X, searchRectangle.Y - searchRectanglePosition.Y, searchRectangle.Width, searchRectangle.Height);
                    //tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char && contaningRectangle.Contains(x.R));
                    using (Bitmap b = GetRectangleFromActiveTemplateBitmap(searchRectangle.X / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Y / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Width / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                    {
                        if (b == null)
                        {
                            return(false);
                        }
                        searchRectangleOcrCharBoxs = Ocr.This.GetCharBoxs(b, PageCollection.ActiveTemplate.TesseractPageSegMode);
                    }
                    PointF searchRectanglePosition = new PointF(searchRectangle.X < 0 ? 0 : searchRectangle.X, searchRectangle.Y < 0 ? 0 : searchRectangle.Y);
                    searchRectangleOcrCharBoxs.ForEach(x => { x.R.X += searchRectanglePosition.X; x.R.Y += searchRectanglePosition.Y; });
                    tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                }
                List <Ocr.CharBox> tcbs = new List <Ocr.CharBox>();
                foreach (Ocr.CharBox tcb0 in tcb0s)
                {
                    tcbs.Clear();
                    tcbs.Add(tcb0);
                    for (int i = 1; i < cbs.Count; i++)
                    {
                        PointF p;
                        if (ot.PositionDeviationIsAbsolute)
                        {
                            p = new PointF(tcb0.R.X + cbs[i].Rectangle.X - cbs[0].Rectangle.X, tcb0.R.Y + cbs[i].Rectangle.Y - cbs[0].Rectangle.Y);
                        }
                        else
                        {
                            p = new PointF(tcbs[i - 1].R.X + cbs[i].Rectangle.X - cbs[i - 1].Rectangle.X, tcbs[i - 1].R.Y + cbs[i].Rectangle.Y - cbs[i - 1].Rectangle.Y);
                        }
                        foreach (Ocr.CharBox bt in searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[i].Char))
                        {
                            if (Math.Abs(bt.R.X - p.X) <= ot.PositionDeviation && Math.Abs(bt.R.Y - p.Y) <= ot.PositionDeviation)
                            {
                                tcbs.Add(bt);
                                break;
                            }
                        }
                        if (tcbs.Count - 1 < i)
                        {
                            break;
                        }
                    }
                    if (tcbs.Count == cbs.Count)
                    {
                        SizeF      shift   = new SizeF(tcbs[0].R.X - cbs[0].Rectangle.X, tcbs[0].R.Y - cbs[0].Rectangle.Y);
                        RectangleF actualR = new RectangleF(rectangle.X + shift.Width, rectangle.Y + shift.Height, rectangle.Width, rectangle.Height);
                        if (        //check that the found rectangle contains only the anchor's boxes
                            searchRectangleOcrCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && !tcbs.Contains(x)) == null &&
                            !findNext(actualR.Location)
                            )
                        {
                            return(true);
                        }
                    }
                }
            }
                return(false);

            case Template.Anchor.Types.ImageData:
            {
                Template.Anchor.ImageData idv = (Template.Anchor.ImageData)a;
                Point     searchRectanglePosition;
                ImageData id0;
                if (idv.SearchRectangleMargin < 0)
                {
                    id0 = ActiveTemplateImageData;
                    searchRectanglePosition = new Point(0, 0);
                }
                else
                {
                    searchRectanglePosition = new Point(searchRectangle.X < 0 ? 0 : (int)searchRectangle.X, searchRectangle.Y < 0 ? 0 : (int)searchRectangle.Y);
                    using (Bitmap b = GetRectangleFromActiveTemplateBitmap(searchRectangle.X / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Y / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Width / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                    {
                        if (b == null)
                        {
                            return(false);
                        }
                        id0 = new ImageData(b);
                    }
                }
                Point?p_ = idv.Image.FindWithinImage(id0, idv.BrightnessTolerance, idv.DifferentPixelNumberTolerance, idv.FindBestImageMatch);
                if (p_ == null)
                {
                    return(false);
                }
                Point p = (Point)p_;
                return(!findNext(new PointF(searchRectanglePosition.X + p.X, searchRectanglePosition.Y + p.Y)));
            }

            case Template.Anchor.Types.CvImage:
            {
                Template.Anchor.CvImage civ = (Template.Anchor.CvImage)a;
                Point   searchRectanglePosition;
                CvImage ci0;
                if (civ.SearchRectangleMargin < 0)
                {
                    ci0 = ActiveTemplateCvImage;
                    searchRectanglePosition = new Point(0, 0);
                }
                else
                {
                    searchRectanglePosition = new Point(searchRectangle.X < 0 ? 0 : (int)searchRectangle.X, searchRectangle.Y < 0 ? 0 : (int)searchRectangle.Y);
                    using (Bitmap b = GetRectangleFromActiveTemplateBitmap(searchRectangle.X / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Y / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Width / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                    {
                        if (b == null)
                        {
                            return(false);
                        }
                        ci0 = new CvImage(b);
                    }
                }
                if (civ.FindBestImageMatch)
                {
                    //CvImage.Match m = civ.Image.FindFirstMatchWithinImage(ci0, civ.Threshold, civ.ScaleDeviation, PageCollection.ActiveTemplate.CvImageScalePyramidStep);
                    CvImage.Match m = civ.Image.FindBestMatchWithinImage(ci0, civ.Threshold, civ.ScaleDeviation, PageCollection.ActiveTemplate.CvImageScalePyramidStep);
                    if (m == null)
                    {
                        return(false);
                    }
                    Point p = m.Rectangle.Location;
                    return(!findNext(new PointF(searchRectanglePosition.X + p.X, searchRectanglePosition.Y + p.Y)));
                }
                else
                {        //!!!this returns rather the first match than the best match
                    bool found = false;
                    civ.Image.FindMatchesWithinImage(ci0, civ.Threshold, civ.ScaleDeviation, PageCollection.ActiveTemplate.CvImageScalePyramidStep,
                                                     (CvImage.Match m) =>
                        {
                            found = !findNext(new PointF(searchRectanglePosition.X + m.Rectangle.X, searchRectanglePosition.Y + m.Rectangle.Y));
                            return(!found);
                        }
                                                     );
                    return(found);
                }
            }

            default:
                throw new Exception("Unknown option: " + a.Type);
            }
        }
Ejemplo n.º 10
0
        void setAnchorRow(DataGridViewRow row, Template.Anchor a)
        {
            row.Tag = a;
            row.Cells["Id3"].Value                   = a.Id;
            row.Cells["Type3"].Value                 = a.Type;
            row.Cells["ParentAnchorId3"].Value       = a.ParentAnchorId;
            row.Cells["SearchRectangleMargin"].Value = a.SearchRectangleMargin < 0 ? "-" : a.SearchRectangleMargin.ToString();

            DataGridViewCell patternCell = row.Cells["Pattern"];

            if (patternCell.Value != null && patternCell.Value is IDisposable)
            {
                ((IDisposable)patternCell.Value).Dispose();
            }
            if (a is Template.Anchor.CvImage || a is Template.Anchor.ImageData)
            {
                if (!(patternCell is DataGridViewImageCell))
                {
                    patternCell.Dispose();
                    patternCell = new DataGridViewImageCell {
                        ImageLayout = DataGridViewImageCellLayout.NotSet
                    };
                    row.Cells["Pattern"] = patternCell;
                }
            }
            else
            {
                if (patternCell is DataGridViewImageCell)
                {
                    patternCell.Dispose();
                    patternCell          = new DataGridViewTextBoxCell {
                    };
                    row.Cells["Pattern"] = patternCell;
                }
            }
            row.Cells["Pattern"].ReadOnly = true;
            switch (a.Type)
            {
            case Template.Anchor.Types.PdfText:
                {
                    Template.Anchor.PdfText pt = (Template.Anchor.PdfText)a;
                    if (pt.CharBoxs == null)
                    {
                        patternCell.Value = null;
                        break;
                    }
                    StringBuilder sb = new StringBuilder();
                    foreach (var l in Page.GetLines(pt.CharBoxs.Select(x => new Pdf.CharBox {
                        Char = x.Char, R = x.Rectangle.GetSystemRectangleF()
                    }), new TextAutoInsertSpace {
                        IgnoreSourceSpaces = textAutoInsertSpace_IgnoreSourceSpaces.Checked, Threshold = (float)textAutoInsertSpace_Threshold.Value                                                                                                                                                             /*, Representative*/
                    }, null))
                    {
                        foreach (var cb in l.CharBoxs)
                        {
                            sb.Append(cb.Char);
                        }
                        sb.Append("\r\n");
                    }
                    patternCell.Value = sb.ToString();
                }
                break;

            case Template.Anchor.Types.OcrText:
            {
                Template.Anchor.OcrText ot = (Template.Anchor.OcrText)a;
                if (ot.CharBoxs == null)
                {
                    patternCell.Value = null;
                    break;
                }
                StringBuilder sb = new StringBuilder();
                foreach (var l in Page.GetLines(ot.CharBoxs.Select(x => new Ocr.CharBox {
                        Char = x.Char, R = x.Rectangle.GetSystemRectangleF()
                    }), new TextAutoInsertSpace {
                        IgnoreSourceSpaces = textAutoInsertSpace_IgnoreSourceSpaces.Checked, Threshold = (float)textAutoInsertSpace_Threshold.Value                                                                                                                                                             /*, Representative*/
                    }, null))
                {
                    foreach (var cb in l.CharBoxs)
                    {
                        sb.Append(cb.Char);
                    }
                    sb.Append("\r\n");
                }
                patternCell.Value = sb.ToString();
            }
            break;

            case Template.Anchor.Types.ImageData:
            {
                Template.Anchor.ImageData id = (Template.Anchor.ImageData)a;
                Bitmap b = null;
                if (id.Image != null)
                {
                    b = id.Image.GetBitmap();
                    Size s = patternCell.Size;
                    if (s.Height < b.Height * pictureScale.Value)
                    {
                        s.Width = int.MaxValue;
                        Win.ImageRoutines.Scale(ref b, s);
                    }
                    else if (pictureScale.Value != 1)
                    {
                        Win.ImageRoutines.Scale(ref b, (float)pictureScale.Value);
                    }
                }
                patternCell.Value = b;
            }
            break;

            case Template.Anchor.Types.CvImage:
            {
                Template.Anchor.CvImage ci = (Template.Anchor.CvImage)a;
                Bitmap b = null;
                if (ci.Image != null)
                {
                    b = ci.Image.GetBitmap();
                    Size s = patternCell.Size;
                    if (s.Height < b.Height * pictureScale.Value)
                    {
                        s.Width = int.MaxValue;
                        Win.ImageRoutines.Scale(ref b, s);
                    }
                    else if (pictureScale.Value != 1)
                    {
                        Win.ImageRoutines.Scale(ref b, (float)pictureScale.Value);
                    }
                }
                patternCell.Value = b;
            }
            break;

            default:
                throw new Exception("Unknown option: " + a.Type);
            }

            Template.PointF p = a.Position;
            if (p != null)
            {
                row.Cells["Position3"].Value = Serialization.Json.Serialize(p);
            }

            if (loadingTemplate)
            {
                return;
            }

            if (currentAnchorControl != null && row == currentAnchorControl.Row)
            {
                setCurrentAnchorRow(a.Id, false);
            }

            setConditionsStatus();
        }
Ejemplo n.º 11
0
        void initializeAnchorsTable()
        {
            Id3.ValueType = typeof(int);

            Type3.ValueType  = typeof(Template.Anchor.Types);
            Type3.DataSource = Enum.GetValues(typeof(Template.Anchor.Types));

            ParentAnchorId3.ValueType     = typeof(int);
            ParentAnchorId3.ValueMember   = "Id";
            ParentAnchorId3.DisplayMember = "Name";

            Pattern.DefaultCellStyle.NullValue = null; //to avoid error when changing cell type to image

            anchors.EnableHeadersVisualStyles = false; //needed to set row headers

            anchors.CellPainting += delegate(object sender, DataGridViewCellPaintingEventArgs e)
            {
                if (e.RowIndex < 0)
                {
                    return;
                }
                if (e.ColumnIndex != -1)
                {
                    return;
                }
                rowStates?rowState = anchors.Rows[e.RowIndex].HeaderCell.Tag as rowStates?;
                if (rowState == null || rowState == rowStates.NULL)
                {
                    return;
                }
                e.Paint(e.ClipBounds, DataGridViewPaintParts.All);
                string s;
                switch (rowState)
                {
                case rowStates.Selected:
                    return;

                case rowStates.Parent:
                    s = "●";
                    break;

                case rowStates.Condition:
                    s = "▶";
                    break;

                case rowStates.Linked:
                    return;

                default:
                    throw new Exception("Unknown option: " + rowState);
                }
                Rectangle r = e.CellBounds;
                r.X += 2;
                TextRenderer.DrawText(e.Graphics, s, e.CellStyle.Font, r, Color.Black, TextFormatFlags.VerticalCenter | TextFormatFlags.Left);

                e.Handled = true;
            };

            anchors.CellBeginEdit += delegate(object sender, DataGridViewCellCancelEventArgs e)
            {
                string cn = anchors.Columns[e.ColumnIndex].Name;
                if (cn == "SearchRectangleMargin")
                {
                    DataGridViewCell c = anchors[e.ColumnIndex, e.RowIndex];
                    if (string.IsNullOrWhiteSpace((string)c.Value) || !int.TryParse((string)c.Value, out int searchRectangleMargin))
                    {
                        c.Value = Settings.Constants.InitialSearchRectangleMargin.ToString();
                    }
                    return;
                }
                if (cn == "ParentAnchorId3")
                {
                    setAnchorParentAnchorIdList(anchors.Rows[e.RowIndex]);
                    return;
                }
            };

            anchors.RowsAdded += delegate(object sender, DataGridViewRowsAddedEventArgs e)
            {
            };

            anchors.DataError += delegate(object sender, DataGridViewDataErrorEventArgs e)
            {
                DataGridViewRow r = anchors.Rows[e.RowIndex];
                Message.Error("Anchor[Id=" + r.Cells["Id3"].Value + "] has unacceptable value of " + anchors.Columns[e.ColumnIndex].HeaderText + ":\r\n" + e.Exception.Message, this);
            };

            anchors.UserDeletedRow += delegate(object sender, DataGridViewRowEventArgs e)
            {
                onAnchorsChanged();
            };

            anchors.UserDeletingRow += delegate(object sender, DataGridViewRowCancelEventArgs e)
            {
                if (anchors.Rows.Count < 3 && anchors.SelectedRows.Count > 0)
                {
                    anchors.SelectedRows[0].Selected = false;//to avoid auto-creating row
                }
            };

            //anchors.CellFormatting += delegate (object sender, DataGridViewCellFormattingEventArgs e)
            //  {
            //      if (anchors.Columns[e.ColumnIndex].Name == "Pattern")
            //          e.FormattingApplied = false;
            //  };

            anchors.CurrentCellDirtyStateChanged += delegate(object sender, EventArgs e)
            {
                if (anchors.IsCurrentCellDirty)
                {
                    //string cn = anchors.Columns[anchors.CurrentCell.ColumnIndex].Name;
                    //if (cn == "SearchRectangleMargin")
                    //    return;
                    anchors.CommitEdit(DataGridViewDataErrorContexts.Commit);
                }
            };

            anchors.RowValidating += delegate(object sender, DataGridViewCellCancelEventArgs e)
            {
                //if (loadingTemplate)
                //    return;
                //DataGridViewRow r = anchors.Rows[e.RowIndex];
                //try
                //{
                //    if (r.Tag != null)
                //    {
                //        //if (!string.IsNullOrWhiteSpace((string)r.Cells["SearchRectangleMargin"].Value) && !int.TryParse((string)r.Cells["SearchRectangleMargin"].Value, out int searchRectangleMargin))
                //        //    throw new Exception("SearchRectangleMargin must be a non-negative integer.");
                //    }
                //}
                //catch (Exception ex)
                //{
                //    Message.Error2(ex, this);
                //    e.Cancel = true;
                //}
            };

            bool isWithinCellValueChanged = false;

            anchors.CellValueChanged += delegate(object sender, DataGridViewCellEventArgs e)
            {
                if (loadingTemplate || isWithinCellValueChanged)
                {
                    return;
                }
                try
                {
                    isWithinCellValueChanged = true;

                    if (e.ColumnIndex < 0)//row's header
                    {
                        return;
                    }
                    var              row = anchors.Rows[e.RowIndex];
                    Template.Anchor  a   = (Template.Anchor)row.Tag;
                    DataGridViewCell c   = anchors[e.ColumnIndex, e.RowIndex];
                    switch (anchors.Columns[e.ColumnIndex].Name)
                    {
                    case "ParentAnchorId3":
                    {
                        a.ParentAnchorId = (int?)row.Cells["ParentAnchorId3"].Value;
                        break;
                    }

                    case "Pattern":
                        return;

                    case "Type3":
                    {
                        Template.Anchor.Types t2 = (Template.Anchor.Types)c.Value;
                        if (t2 == a.Type)
                        {
                            break;
                        }
                        Template.Anchor a2;
                        switch (t2)
                        {
                        case Template.Anchor.Types.PdfText:
                            a2 = new Template.Anchor.PdfText();
                            break;

                        case Template.Anchor.Types.OcrText:
                            a2 = new Template.Anchor.OcrText();
                            break;

                        case Template.Anchor.Types.ImageData:
                            a2 = new Template.Anchor.ImageData();
                            break;

                        case Template.Anchor.Types.CvImage:
                            a2 = new Template.Anchor.CvImage();
                            break;

                        default:
                            throw new Exception("Unknown option: " + t2);
                        }
                        a2.Id = a.Id;
                        a     = a2;
                        break;
                    }

                    case "SearchRectangleMargin":
                    {
                        if (string.IsNullOrWhiteSpace((string)c.Value) || !int.TryParse((string)c.Value, out int searchRectangleMargin))
                        {
                            a.SearchRectangleMargin = -1;
                            break;
                        }
                        a.SearchRectangleMargin = searchRectangleMargin < 0 ? -1 : searchRectangleMargin;
                        break;
                    }
                    }
                    setAnchorRow(row, a);
                    clearImageFromBoxes();
                    findAndDrawAnchor(a.Id);
                }
                finally
                {
                    isWithinCellValueChanged = false;
                }
            };

            anchors.SelectionChanged += delegate(object sender, EventArgs e)
            {
                try
                {
                    if (loadingTemplate)
                    {
                        return;
                    }

                    if (settingCurrentAnchorRow)
                    {
                        return;
                    }

                    if (anchors.SelectedRows.Count < 1)
                    {
                        setCurrentAnchorRow(null, true);
                        return;
                    }
                    var             row = anchors.SelectedRows[0];
                    Template.Anchor a   = (Template.Anchor)row.Tag;
                    if (a == null)//hacky forcing to commit a newly added row and display the blank row
                    {
                        int i = anchors.Rows.Add();
                        row = anchors.Rows[i];
                        a   = templateManager.CreateDefaultAnchor();
                        setAnchorRow(row, a);
                        onAnchorsChanged();
                        row.Selected = true;
                        return;
                    }
                    setCurrentAnchorRow(a.Id, false);
                    showAnchorRowAs(a.Id, rowStates.Selected, true);
                    clearImageFromBoxes();
                    findAndDrawAnchor(a.Id);
                }
                catch (Exception ex)
                {
                    Message.Error2(ex, this);
                }
            };
        }