Template.Anchor getAnchor(int?anchorId, out DataGridViewRow row) { if (anchorId != null) { foreach (DataGridViewRow r in anchors.Rows) { Template.Anchor a = (Template.Anchor)r.Tag; if (a != null && a.Id == anchorId) { row = r; return(a); } } } row = null; return(null); }
void _setAnchorStatus(int anchorId) { Template.Anchor a = getAnchor(anchorId, out DataGridViewRow row); if (a == null || row == null) { return; } if (pages == null) { return; } a = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == anchorId); if (a == null) { throw new Exception("Anchor[Id=" + a.Id + "] does not exist."); } bool set = true; for (Template.Anchor a_ = a; a_ != null; a_ = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == a_.ParentAnchorId)) { if (!a_.IsSet()) { set = false; getAnchor(a_.Id, out DataGridViewRow r_); setRowStatus(statuses.WARNING, r_, "Not set"); } } if (!set) { return; } Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(a.Id); getAnchor(a.Id, out DataGridViewRow r); if (!aai.Found) { setRowStatus(statuses.ERROR, r, "Not found"); } else { setRowStatus(statuses.SUCCESS, r, "Found"); } }
//internal AnchorActualInfo GetAnchorActualInfo(int anchorId) //{ // Template.Anchor a = PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == anchorId); // if (a == null) // throw new Exception("Anchor[id=" + anchorId + "] does not exist."); // if (!a.IsSet()) // throw new Exception("Anchor[id=" + anchorId + "] is not set."); // StringBuilder sb = new StringBuilder(Serialization.Json.Serialize(a, false)); // for (int? id = a.ParentAnchorId; id != null;) // { // Template.Anchor pa = PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == id); // sb.Append(Serialization.Json.Serialize(pa, false)); // id = pa.ParentAnchorId; // } // string sa = sb.ToString(); // if (!anchorHashes2anchorActualInfo.TryGetValue(sa, out AnchorActualInfo anchorActualInfo)) // { // anchorActualInfo = new AnchorActualInfo(a, this); // anchorHashes2anchorActualInfo[sa] = anchorActualInfo; // } // return anchorActualInfo; //} //Dictionary<string, AnchorActualInfo> anchorHashes2anchorActualInfo = new Dictionary<string, AnchorActualInfo>(); internal AnchorActualInfo GetAnchorActualInfo(int anchorId) { Template.Anchor a = PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == anchorId); if (a == null) { throw new Exception("Anchor[id=" + anchorId + "] does not exist."); } if (!a.IsSet()) { throw new Exception("Anchor[id=" + anchorId + "] is not set."); } if (!anchorIds2anchorActualInfo.TryGetValue(a.Id, out AnchorActualInfo anchorActualInfo)) { anchorActualInfo = new AnchorActualInfo(a, this); anchorIds2anchorActualInfo[a.Id] = anchorActualInfo; } return(anchorActualInfo); }
internal AnchorActualInfo(Template.Anchor anchor, Page page) { Anchor = anchor; for (int?id = anchor.ParentAnchorId; id != null;) { Template.Anchor pa = page.PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == id); if (anchor == pa) { throw new Exception("Reference loop: anchor[Id=" + anchor.Id + "] is linked by an ancestor anchor."); } id = pa.ParentAnchorId; } findAnchor(page, (PointF p) => { Position = p; return(false); }); }
void setAnchorParentAnchorIdList(DataGridViewRow row) { Template.Anchor currentRowAnchor = (Template.Anchor)row.Tag; if (currentRowAnchor == null) { return; } SortedSet <int> ais = new SortedSet <int>(); List <Template.Anchor> as_ = new List <Template.Anchor>(); foreach (DataGridViewRow r in anchors.Rows) { if (r.Tag != null) { Template.Anchor a = (Template.Anchor)r.Tag; if (a.Id < 1) { continue; } as_.Add(a); ais.Add(a.Id); } } foreach (Template.Anchor a_ in as_) { for (Template.Anchor a = a_; a != null; a = as_.FirstOrDefault(x => x.Id == a.ParentAnchorId)) { if (a.Id == currentRowAnchor.Id) { ais.Remove(a_.Id); break; } } } List <dynamic> ais_ = ais.Select(x => new { Id = x, Name = x.ToString() }).ToList <dynamic>(); ais_.Insert(0, new { Id = -1, Name = string.Empty });//commbobox returns value null for -1 (and throws an unclear expection if Id=null) DataGridViewComboBoxCell c = row.Cells[anchors.Columns["ParentAnchorId3"].Index] as DataGridViewComboBoxCell; c.DataSource = ais_; }
void findAnchor(Page page, Func <PointF, bool> findNext) { if (Anchor.ParentAnchorId != null) { Template.Anchor pa = page.PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == Anchor.ParentAnchorId); AnchorActualInfo paai = new AnchorActualInfo(pa); paai.findAnchor(page, (PointF p) => { bool found = page.findAnchor(Anchor, p, findNext); if (found) { paai.Position = p; ParentAnchorActualInfo = paai; } return(!found); }); } else { page.findAnchor(Anchor, new PointF(), findNext); } }
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); } }; }
bool findAndDrawAnchor(int anchorId) { if (pages == null) { return(false); } pages.ActiveTemplate = getTemplateFromUI(false); Template.Anchor a = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == anchorId); if (a == null) { throw new Exception("Anchor[Id=" + a.Id + "] does not exist."); } bool set = true; for (Template.Anchor a_ = a; a_ != null; a_ = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == a_.ParentAnchorId)) { if (a != a_) { showAnchorRowAs(a_.Id, rowStates.Parent, false); } if (!a_.IsSet()) { set = false; getAnchor(a_.Id, out DataGridViewRow r_); setRowStatus(statuses.WARNING, r_, "Not set"); } } if (!set) { return(false); } getAnchor(a.Id, out DataGridViewRow r); if (!pages[currentPageI].GetAnchorActualInfo(a.Id).Found) { setRowStatus(statuses.ERROR, r, "Not found"); return(false); } setRowStatus(statuses.SUCCESS, r, "Found"); for (Template.Anchor a_ = a; a_ != null; a_ = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == a_.ParentAnchorId)) { SizeF shift = pages[currentPageI].GetAnchorActualInfo(a_.Id).Shift; RectangleF r_ = a_.Rectangle(); r_.X += shift.Width; r_.Y += shift.Height; if (a_ == a) { if (currentAnchorControl != null) { drawBoxes(Settings.Appearance.SelectionBoxColor, Settings.Appearance.SelectionBoxBorderWidth, new List <RectangleF> { r_ }); owners2resizebleBox[a_] = new ResizebleBox(a_, r_, Settings.Appearance.SelectionBoxBorderWidth); } else { drawBoxes(Settings.Appearance.AnchorBoxColor, Settings.Appearance.AnchorBoxBorderWidth, new List <RectangleF> { r_ }); } } else { drawBoxes(Settings.Appearance.AscendantAnchorBoxColor, Settings.Appearance.AscendantAnchorBoxBorderWidth, new List <RectangleF> { r_ }); } List <RectangleF> bs = null; switch (a_.Type) { case Template.Anchor.Types.PdfText: { var pt = (Template.Anchor.PdfText)a_; bs = pt.CharBoxs.Select(x => new RectangleF(x.Rectangle.X + shift.Width, x.Rectangle.Y + shift.Height, x.Rectangle.Width, x.Rectangle.Height)).ToList(); } break; case Template.Anchor.Types.OcrText: { var ot = (Template.Anchor.OcrText)a_; bs = ot.CharBoxs.Select(x => new RectangleF(x.Rectangle.X + shift.Width, x.Rectangle.Y + shift.Height, x.Rectangle.Width, x.Rectangle.Height)).ToList(); } break; case Template.Anchor.Types.ImageData: //bs = new List<System.Drawing.RectangleF> { rs[0] }; break; case Template.Anchor.Types.CvImage: //bs = new List<System.Drawing.RectangleF> { rs[0] }; break; default: throw new Exception("Unknown option: " + a_.Type); } if (bs != null) { if (a_ == a) { drawBoxes(Settings.Appearance.AnchorBoxColor, Settings.Appearance.AnchorBoxBorderWidth, bs); } else { drawBoxes(Settings.Appearance.AscendantAnchorBoxColor, Settings.Appearance.AscendantAnchorBoxBorderWidth, bs); } } } return(true); }
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); } }
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(); } }; }
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(); } }; }
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.CvImage: // { // Template.Anchor.CvImage ci = (Template.Anchor.CvImage)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); } //if (a.Id == GetTemplateFromUI(false).ScalingAnchorId) //{ // ReloadPageActiveTemplateBitmap(); // return; //} setConditionsStatus(); }
internal Template GetTemplateFromUI(bool saving) { Template t = new Template(); if (saving && string.IsNullOrWhiteSpace(name.Text)) { throw new Exception("Name is empty!"); } t.Name = name.Text.Trim(); t.TextAutoInsertSpace = new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpace_Threshold.Value, IgnoreSourceSpaces = textAutoInsertSpace_IgnoreSourceSpaces.Checked, //Representative//default }; t.TesseractPageSegMode = (Tesseract.PageSegMode)TesseractPageSegMode.SelectedItem; t.AdjustLineBorders = AdjustLineBorders.Checked; t.SingleFieldFromFieldImage = SingleFieldFromFieldImage.Checked; t.ColumnCellFromCellImage = ColumnCellFromCellImage.Checked; if (CharSizeFilterMinWidth.Value > 0 || CharSizeFilterMaxWidth.Value > 0 || CharSizeFilterMinHeight.Value > 0 || CharSizeFilterMaxHeight.Value > 0) { t.CharFilter = new CharFilter { MinWidth = (float)CharSizeFilterMinWidth.Value, MaxWidth = (float)CharSizeFilterMaxWidth.Value, MinHeight = (float)CharSizeFilterMinHeight.Value, MaxHeight = (float)CharSizeFilterMaxHeight.Value } } ; if (LinePaddingY.Value > 0) { t.LinePaddingY = (int)LinePaddingY.Value; } bitmapPreparationForm.SetTemplate(t); bool? removeNotLinkedAnchors = null; List <int> conditionAnchorIds = null; if (saving) { conditionAnchorIds = new List <int>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c != null && c.IsSet()) { conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value)); } } conditionAnchorIds = conditionAnchorIds.Distinct().ToList(); } t.Anchors = new List <Template.Anchor>(); foreach (DataGridViewRow r in anchors.Rows) { Template.Anchor a = (Template.Anchor)r.Tag; if (a == null) { continue; } if (saving) { if (!a.IsSet()) { throw new Exception("Anchor[Id=" + a.Id + "] is not set!"); } if (!conditionAnchorIds.Contains(a.Id)) { bool engaged = false; foreach (DataGridViewRow rr in anchors.Rows) { Template.Anchor a_ = (Template.Anchor)rr.Tag; if (a_ == null) { continue; } if (a_.ParentAnchorId == a.Id) { engaged = true; break; } } if (!engaged) { foreach (DataGridViewRow rr in fields.Rows) { Template.Field m = (Template.Field)rr.Tag; if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id)) { engaged = true; break; } } if (!engaged) { if (a.Id != t.ScalingAnchorId) { if (removeNotLinkedAnchors == null) { removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Remove them?", this); } if (removeNotLinkedAnchors == true) { continue; } } } } } } t.Anchors.Add((Template.Anchor)Serialization.Json.Clone2(a)); } t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList(); if (saving) { t.GetScalingAnchor();//check is it is correct; } t.Conditions = new List <Template.Condition>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c == null) { continue; } if (saving) { if (!c.IsSet()) { throw new Exception("Condition[name=" + c.Name + "] is not set!"); } BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id)); } t.Conditions.Add((Template.Condition)Serialization.Json.Clone2(c)); } if (saving) { var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); if (dcs != null) { throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!"); } } t.Fields = new List <Template.Field>(); foreach (DataGridViewRow r in fields.Rows) { Template.Field f = (Template.Field)r.Tag; if (f == null) { continue; } if (saving && !f.IsSet()) { throw new Exception("Field[" + r.Index + "] is not set!"); } if (saving) { foreach (int?ai in new List <int?> { f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id }) { if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null) { throw new Exception("Anchor[Id=" + ai + " does not exist."); } } } t.Fields.Add((Template.Field)Serialization.Json.Clone2(f)); } if (saving) { if (t.Fields.Count < 1) { throw new Exception("Fields is empty!"); } var fs = t.Fields.GroupBy(x => x.Name).Where(x => x.GroupBy(a => a.GetType()).Count() > 1).FirstOrDefault(); if (fs != null) { throw new Exception("Definitions of the field '" + fs.First().Name + "' are not of the same type!"); } } if (saving) { t.Editor = new Template.EditorSettings { //TestFile = testFile.Text, TestPictureScale = pictureScale.Value, ExtractFieldsAutomaticallyWhenPageChanged = ExtractFieldsAutomaticallyWhenPageChanged.Checked, ShowFieldTextLineSeparators = ShowFieldTextLineSeparators.Checked, CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked, }; } return(t); } }
void setCurrentAnchorRow(int?anchorId, bool clearSelection) { if (settingCurrentAnchorRow) { return; } try { settingCurrentAnchorRow = true; if (anchorId == null) { anchors.ClearSelection(); anchors.CurrentCell = null; currentAnchorControl = null; return; } Template.Anchor a = getAnchor(anchorId, out DataGridViewRow row); if (row == null || a == null) { throw new Exception("Anchor[Id=" + anchorId + "] does not exist."); } if (anchors.CurrentCell?.RowIndex != row.Index) { anchors.CurrentCell = anchors[0, row.Index]; } if (clearSelection) { anchors.ClearSelection(); } else { setCurrentConditionRow(null); setCurrentFieldRow(null); } Template.Anchor.Types t = ((Template.Anchor)row.Tag).Type; switch (t) { case Template.Anchor.Types.PdfText: { currentAnchorControl = new AnchorPdfTextControl(new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpace_Threshold.Value, IgnoreSourceSpaces = textAutoInsertSpace_IgnoreSourceSpaces.Checked /*, Representative//default*/ }); } break; case Template.Anchor.Types.OcrText: { currentAnchorControl = new AnchorOcrTextControl(new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpace_Threshold.Value, IgnoreSourceSpaces = textAutoInsertSpace_IgnoreSourceSpaces.Checked /*, Representative//default*/ }); } break; case Template.Anchor.Types.ImageData: { currentAnchorControl = new AnchorImageDataControl((float)pictureScale.Value); } break; case Template.Anchor.Types.CvImage: { currentAnchorControl = new AnchorCvImageControl((float)pictureScale.Value); } break; default: throw new Exception("Unknown option: " + t); } currentAnchorControl.Initialize(row, (DataGridViewRow r) => { setAnchorRow(r, a); }); settingsControlHeader.Text = "Anchor [" + a?.Id + "]:"; } finally { settingCurrentAnchorRow = false; } }
void onAnchorsChanged() { SortedSet <int> ais = new SortedSet <int>(); List <Template.Anchor> as_ = new List <Template.Anchor>(); foreach (DataGridViewRow r in anchors.Rows) { if (r.Tag != null) { Template.Anchor a = (Template.Anchor)r.Tag; as_.Add(a); if (a.Id > 0) { ais.Add(a.Id); } } } foreach (DataGridViewRow r in anchors.Rows) { if (r.Tag == null) { continue; } Template.Anchor a = (Template.Anchor)r.Tag; if (/*a.IsSet() &&*/ a.Id <= 0) { a.Id = 1; //if (ais.Count > 0) // anchorId = ais.Max() + 1; foreach (int i in ais) { if (a.Id < i) { break; } if (a.Id == i) { a.Id++; } } ais.Add(a.Id); r.Cells["Id3"].Value = a.Id; } } foreach (DataGridViewRow r in anchors.Rows) { if (r.Tag == null) { continue; } Template.Anchor a = (Template.Anchor)r.Tag; if (a.ParentAnchorId == null) { continue; } if (!ais.Contains((int)a.ParentAnchorId)) { r.Cells["ParentAnchorId3"].Value = null; } } foreach (DataGridViewRow r in fields.Rows) { if (r.Tag == null) { continue; } Template.Field f = (Template.Field)r.Tag; if (f.LeftAnchor != null && !ais.Contains(f.LeftAnchor.Id)) { r.Cells["LeftAnchorId"].Value = null; } if (f.TopAnchor != null && !ais.Contains(f.TopAnchor.Id)) { r.Cells["TopAnchorId"].Value = null; } if (f.RightAnchor != null && !ais.Contains(f.RightAnchor.Id)) { r.Cells["RightAnchorId"].Value = null; } if (f.BottomAnchor != null && !ais.Contains(f.BottomAnchor.Id)) { r.Cells["BottomAnchorId"].Value = null; } } setConditionsStatus(); { List <dynamic> ais_ = ais.Select(x => new { Id = x, Name = x.ToString() }).ToList <dynamic>(); ais_.Insert(0, new { Id = -1, Name = string.Empty });//commbobox returns value null for -1 (and throws an unclear expection if Id=null) LeftAnchorId.DataSource = ais_; TopAnchorId.DataSource = ais_; RightAnchorId.DataSource = ais_; BottomAnchorId.DataSource = ais_; } }
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); } }
AnchorActualInfo(Template.Anchor anchor) { Anchor = anchor; }
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(); }
void setCurrentConditionRow(DataGridViewRow row) { if (settingCurrentConditionRow) { return; } try { settingCurrentConditionRow = true; currentConditionRow = row; if (row == null) { conditions.ClearSelection(); conditions.CurrentCell = null; return; } if (conditions.CurrentCell?.RowIndex != row.Index) { conditions.CurrentCell = conditions[0, row.Index]; } Template.Condition c = (Template.Condition)row.Tag; bool firstAnchor = true; foreach (int ai in BooleanEngine.GetAnchorIds(c.Value)) { Template.Anchor a = getAnchor(ai, out DataGridViewRow r); if (r == null) { continue; } if (firstAnchor) { firstAnchor = false; showAnchorRowAs(ai, rowStates.Linked, true); setCurrentAnchorRow(ai, true); clearImageFromBoxes(); } else { showAnchorRowAs(ai, rowStates.Condition, false); } findAndDrawAnchor(ai); } if (firstAnchor) { showAnchorRowAs(null, rowStates.NULL, true); setCurrentAnchorRow(null, true); } setCurrentFieldRow(null); setConditionStatus(currentConditionRow); } finally { settingCurrentConditionRow = false; } }
void setCurrentAnchorRow(int?anchorId, bool clearSelection) { if (settingCurrentAnchorRow) { return; } try { settingCurrentAnchorRow = true; if (anchorId == null) { anchors.ClearSelection(); anchors.CurrentCell = null; currentAnchorControl = null; return; } Template.Anchor a = getAnchor(anchorId, out DataGridViewRow row); if (row == null || a == null) { throw new Exception("Anchor[Id=" + anchorId + "] does not exist."); } anchors.CurrentCell = anchors[0, row.Index]; if (clearSelection) { anchors.ClearSelection(); } else { setCurrentConditionRow(null); setCurrentFieldRow(null); } Template.Anchor.Types t = ((Template.Anchor)row.Tag).Type; switch (t) { case Template.Anchor.Types.PdfText: { currentAnchorControl = new AnchorPdfTextControl(new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpaceThreshold.Value, Representative = Regex.Unescape(textAutoInsertSpaceRepresentative.Text) }); } break; case Template.Anchor.Types.OcrText: { currentAnchorControl = new AnchorOcrTextControl(new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpaceThreshold.Value, Representative = Regex.Unescape(textAutoInsertSpaceRepresentative.Text) }); } break; case Template.Anchor.Types.ImageData: { currentAnchorControl = new AnchorImageDataControl((float)pictureScale.Value); } break; case Template.Anchor.Types.CvImage: { currentAnchorControl = new AnchorCvImageControl((float)pictureScale.Value); } break; //case Template.Anchor.Types.Script: // { // if (currentAnchorControl == null || !(currentAnchorControl is AnchorScriptControl)) // currentAnchorControl = new AnchorScriptControl(); // } // break; default: throw new Exception("Unknown option: " + t); } currentAnchorControl.Initialize(row, (DataGridViewRow r) => { setAnchorRow(r, a); }); } finally { settingCurrentAnchorRow = false; } }
Template getTemplateFromUI(bool saving) { Template t = new Template(); if (saving && string.IsNullOrWhiteSpace(name.Text)) { throw new Exception("Name is empty!"); } t.Name = name.Text.Trim(); t.TextAutoInsertSpace = new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpaceThreshold.Value, Representative = textAutoInsertSpaceRepresentative.Text, }; t.PageRotation = (Template.PageRotations)pageRotation.SelectedIndex; t.AutoDeskew = autoDeskew.Checked; t.AutoDeskewThreshold = (int)autoDeskewThreshold.Value; bool?removeNotLinkedAnchors = null; t.Anchors = new List <Template.Anchor>(); List <int> conditionAnchorIds = null; if (saving) { conditionAnchorIds = new List <int>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c != null && c.IsSet()) { conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value)); } } conditionAnchorIds = conditionAnchorIds.Distinct().ToList(); } foreach (DataGridViewRow r in anchors.Rows) { Template.Anchor a = (Template.Anchor)r.Tag; if (a == null) { continue; } if (saving) { if (!a.IsSet()) { throw new Exception("Anchor[Id=" + a.Id + "] is not set!"); } bool engaged = false; if (conditionAnchorIds.Contains(a.Id)) { engaged = true; } if (!engaged) { foreach (DataGridViewRow rr in anchors.Rows) { Template.Anchor a_ = (Template.Anchor)rr.Tag; if (a_ == null) { continue; } if (a_.ParentAnchorId == a.Id) { engaged = true; break; } } } if (!engaged) { foreach (DataGridViewRow rr in fields.Rows) { Template.Field m = (Template.Field)rr.Tag; if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id)) { engaged = true; break; } } } if (!engaged) { if (removeNotLinkedAnchors == null) { removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Should they be removed?"); } if (removeNotLinkedAnchors == true) { continue; } } } t.Anchors.Add(a); } t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList(); t.Conditions = new List <Template.Condition>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c == null) { continue; } if (saving) { if (!c.IsSet()) { throw new Exception("Condition[name=" + c.Name + "] is not set!"); } BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id)); } t.Conditions.Add(c); } if (saving) { var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); if (dcs != null) { throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!"); } } t.Fields = new List <Template.Field>(); foreach (DataGridViewRow r in fields.Rows) { Template.Field f = (Template.Field)r.Tag; if (f == null) { continue; } if (saving && !f.IsSet()) { throw new Exception("Field[" + r.Index + "] is not set!"); } if (saving) { foreach (int?ai in new List <int?> { f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id }) { if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null) { throw new Exception("Anchor[Id=" + ai + " does not exist."); } } } t.Fields.Add(f); } if (saving) { if (t.Fields.Count < 1) { throw new Exception("Fields is empty!"); } //var dfs = t.Fields.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); //if (dfs != null) // throw new Exception("Field '" + dfs.First().Name + "' is duplicated!"); //foreach (string columnOfTable in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable != null).Select(x => x.ColumnOfTable)) //{ // Dictionary<string, List<Template.Field>> fieldName2orderedFields = new Dictionary<string, List<Template.Field>>(); // foreach (Template.Field.PdfText pt in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable == columnOfTable)) // { // List<Template.Field> fs; // if (!fieldName2orderedFields.TryGetValue(pt.Name, out fs)) // { // fs = new List<Template.Field>(); // fieldName2orderedFields[pt.Name] = fs; // } // fs.Add(pt); // } // int definitionCount = fieldName2orderedFields.Max(x => x.Value.Count()); // foreach (string fn in fieldName2orderedFields.Keys) // if (definitionCount > fieldName2orderedFields[fn].Count) // throw new Exception("Field '" + fn + "' is column of table " + columnOfTable + " and so it must have the same number of definitions as the rest column fields!"); //} foreach (Template.Field f0 in t.Fields) { int tableDefinitionsCount = t.Fields.Where(x => x.Name == f0.Name).Count(); string fn = t.Fields.Where(x => x.ColumnOfTable == f0.Name).GroupBy(x => x.Name).Where(x => x.Count() > tableDefinitionsCount).FirstOrDefault()?.First().Name; if (fn != null) { throw new Exception("Field '" + fn + "' is a column of table field " + f0.Name + " so " + f0.Name + " must have number of definitions not less then that of " + fn + "."); } } } if (saving) { t.Editor = new Template.EditorSettings { TestFile = testFile.Text, TestPictureScale = pictureScale.Value, ExtractFieldsAutomaticallyWhenPageChanged = ExtractFieldsAutomaticallyWhenPageChanged.Checked, CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked, }; } return(t); }
internal Template GetTemplateFromUI(bool saving) { Template t = new Template(); if (saving && string.IsNullOrWhiteSpace(name.Text)) { throw new Exception("Name is empty!"); } t.Name = name.Text.Trim(); t.TextAutoInsertSpace = new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpaceThreshold.Value, Representative = Regex.Unescape(textAutoInsertSpaceRepresentative.Text), }; t.CvImageScalePyramidStep = (int)CvImageScalePyramidStep.Value; t.TesseractPageSegMode = (Tesseract.PageSegMode)TesseractPageSegMode.SelectedItem; if (SingleFieldFromFieldImage.Checked) { t.FieldOcrMode |= Template.FieldOcrModes.SingleFieldFromFieldImage; } else { t.FieldOcrMode &= ~Template.FieldOcrModes.SingleFieldFromFieldImage; } if (ColumnFieldFromFieldImage.Checked) { t.FieldOcrMode |= Template.FieldOcrModes.ColumnFieldFromFieldImage; } else { t.FieldOcrMode &= ~Template.FieldOcrModes.ColumnFieldFromFieldImage; } bitmapPreparationForm.SetTemplate(t); bool? removeNotLinkedAnchors = null; List <int> conditionAnchorIds = null; if (saving) { conditionAnchorIds = new List <int>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c != null && c.IsSet()) { conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value)); } } conditionAnchorIds = conditionAnchorIds.Distinct().ToList(); } t.Anchors = new List <Template.Anchor>(); foreach (DataGridViewRow r in anchors.Rows) { Template.Anchor a = (Template.Anchor)r.Tag; if (a == null) { continue; } if (saving) { if (!a.IsSet()) { throw new Exception("Anchor[Id=" + a.Id + "] is not set!"); } if (!conditionAnchorIds.Contains(a.Id)) { bool engaged = false; foreach (DataGridViewRow rr in anchors.Rows) { Template.Anchor a_ = (Template.Anchor)rr.Tag; if (a_ == null) { continue; } if (a_.ParentAnchorId == a.Id) { engaged = true; break; } } if (!engaged) { foreach (DataGridViewRow rr in fields.Rows) { Template.Field m = (Template.Field)rr.Tag; if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id)) { engaged = true; break; } } if (!engaged) { if (a.Id != t.ScalingAnchorId) { if (removeNotLinkedAnchors == null) { removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Remove them?"); } if (removeNotLinkedAnchors == true) { continue; } } } } } } t.Anchors.Add((Template.Anchor)Serialization.Json.Clone2(a)); } t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList(); if (saving) { t.GetScalingAnchor();//check is it is correct; } t.Conditions = new List <Template.Condition>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c == null) { continue; } if (saving) { if (!c.IsSet()) { throw new Exception("Condition[name=" + c.Name + "] is not set!"); } BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id)); } t.Conditions.Add(Serialization.Json.Clone(c)); } if (saving) { var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); if (dcs != null) { throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!"); } } t.Fields = new List <Template.Field>(); foreach (DataGridViewRow r in fields.Rows) { Template.Field f = (Template.Field)r.Tag; if (f == null) { continue; } if (saving && !f.IsSet()) { throw new Exception("Field[" + r.Index + "] is not set!"); } if (saving) { foreach (int?ai in new List <int?> { f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id }) { if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null) { throw new Exception("Anchor[Id=" + ai + " does not exist."); } } } t.Fields.Add(Serialization.Json.Clone(f)); } if (saving) { if (t.Fields.Count < 1) { throw new Exception("Fields is empty!"); } //var dfs = t.Fields.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); //if (dfs != null) // throw new Exception("Field '" + dfs.First().Name + "' is duplicated!"); //foreach (string columnOfTable in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable != null).Select(x => x.ColumnOfTable)) //{ // Dictionary<string, List<Template.Field>> fieldName2orderedFields = new Dictionary<string, List<Template.Field>>(); // foreach (Template.Field.PdfText pt in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable == columnOfTable)) // { // List<Template.Field> fs; // if (!fieldName2orderedFields.TryGetValue(pt.Name, out fs)) // { // fs = new List<Template.Field>(); // fieldName2orderedFields[pt.Name] = fs; // } // fs.Add(pt); // } // int definitionCount = fieldName2orderedFields.Max(x => x.Value.Count()); // foreach (string fn in fieldName2orderedFields.Keys) // if (definitionCount > fieldName2orderedFields[fn].Count) // throw new Exception("Field '" + fn + "' is column of table " + columnOfTable + " and so it must have the same number of definitions as the rest column fields!"); //} //foreach (Template.Field f0 in t.Fields) //{ // int tableDefinitionsCount = t.Fields.Where(x => x.Name == f0.Name).Count(); // string fn = t.Fields.Where(x => x.ColumnOfTable == f0.Name).GroupBy(x => x.Name).Where(x => x.Count() > tableDefinitionsCount).FirstOrDefault()?.First().Name; // if (fn != null) // throw new Exception("Field '" + fn + "' is a column of table field " + f0.Name + " so " + f0.Name + " must have number of definitions not less then that of " + fn + "."); //} //it is done only to avoid unneeded OCR //string fn = t.Fields.Where(x => x.ColumnOfTable != null && (x.DefaultValueType != Template.Field.ValueTypes.PdfText && x.DefaultValueType != Template.Field.ValueTypes.PdfTextLines)).FirstOrDefault()?.Name; //if (fn != null) // throw new Exception("Field '" + fn + "' is a column of a table field. Its default value type can be either " + Template.Field.ValueTypes.PdfText + " or " + Template.Field.ValueTypes.PdfTextLines); } if (saving) { t.Editor = new Template.EditorSettings { TestFile = testFile.Text, TestPictureScale = pictureScale.Value, ExtractFieldsAutomaticallyWhenPageChanged = ExtractFieldsAutomaticallyWhenPageChanged.Checked, ShowFieldTextLineSeparators = ShowFieldTextLineSeparators.Checked, CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked, }; } return(t); }
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); } }; }