/// <summary> /// This method checks the given <see cref="AOIData"/> shape for invalid characters /// and tests if it is already used in the database. /// It shows referring message boxes when the name is not valid /// and automatically removes invalid characters. /// </summary> /// <param name="shape">Ref. A <see cref="AOIData"/> with /// the area of interest to test.</param> /// <param name="splashDialog">A <see cref="System.ComponentModel.BackgroundWorker"/> with the /// background splash loading dialog worker which shows progress.</param> /// <returns><strong>True</strong>, if the AOI is valid, /// otherwise <strong>false</strong>.</returns> public static bool ValidateShape(ref AOIData shape, System.ComponentModel.BackgroundWorker splashDialog) { shape.ShapeName.Trim(); StringBuilder sb = new StringBuilder(); bool changed = false; for (int i = 0; i < shape.ShapeName.Length; i++) { if (char.IsLetterOrDigit(shape.ShapeName[i])) { sb.Append(shape.ShapeName[i]); } else { changed = true; } } shape.ShapeName = sb.ToString(); if (shape.ShapeName == string.Empty) { if (splashDialog != null && splashDialog.IsBusy) { splashDialog.CancelAsync(); } InformationDialog.Show( "Empty shape name", "Please enter at least one character for the shape name", false, MessageBoxIcon.Information); // Show loading splash screen if it is not running if (splashDialog != null && !splashDialog.IsBusy) { splashDialog.RunWorkerAsync(); } return false; } else if (IOHelpers.IsNumeric(shape.ShapeName[0])) { if (splashDialog != null && splashDialog.IsBusy) { splashDialog.CancelAsync(); } InformationDialog.Show( "Invalid shape name", "Please do not use a number for the first character of the shape name.", false, MessageBoxIcon.Information); // Show loading splash screen if it is not running if (splashDialog != null && !splashDialog.IsBusy) { splashDialog.RunWorkerAsync(); } return false; } else { if (changed) { if (splashDialog != null && splashDialog.IsBusy) { splashDialog.CancelAsync(); } string message = "Please note: Non letter and non digit characters are removed from the shape name." + Environment.NewLine + "Other characters are not allowed for the database entry."; ExceptionMethods.ProcessMessage("Shape name modified", message); // Show loading splash screen if it is not running if (splashDialog != null && !splashDialog.IsBusy) { splashDialog.RunWorkerAsync(); } return true; } if (!CheckForAOIDuplicate(shape, splashDialog)) { return false; } } return true; }
/// <summary> /// This method checks the given <see cref="AOIData"/> /// if it is already used in the database. /// </summary> /// <param name="shape">Ref. A <see cref="AOIData"/> with /// the area of interest to test.</param> /// <param name="splashDialog">A <see cref="System.ComponentModel.BackgroundWorker"/> with the /// background splash loading dialog worker which shows progress.</param> /// <returns><strong>True</strong>, if an AOI with same name and stimulus assignment /// already exists in the database, /// otherwise <strong>false</strong>.</returns> private static bool CheckForAOIDuplicate(AOIData shape, System.ComponentModel.BackgroundWorker splashDialog) { SQLiteOgamaDataSet.AOIsDataTable aoisTable = Document.ActiveDocument.DocDataSet.AOIsAdapter.GetDataByTrialIDAndShapeName(shape.TrialID, shape.ShapeName); if (aoisTable.Rows.Count > 0) { if (splashDialog != null && splashDialog.IsBusy) { splashDialog.CancelAsync(); } string message = "The area of interest " + Environment.NewLine + shape.ShapeType.ToString() + ": " + shape.ShapeName + "already exists." + Environment.NewLine + "Would you like to overwrite it ?"; DialogResult duplicateQuestion = InformationDialog.Show("Overwrite AOI ?", message, true, MessageBoxIcon.Question); // Show loading splash screen if it is not running if (splashDialog != null && !splashDialog.IsBusy) { splashDialog.RunWorkerAsync(); } if (duplicateQuestion == DialogResult.No || duplicateQuestion == DialogResult.Cancel) { return false; } // User clicked yes so update the existing entry // Presuming the DataTable has a column named ShapeName. string expression = "ShapeName = '" + shape.ShapeName + "' AND TrialID = '" + shape.TrialID + "'"; DataRow[] foundRows; // Use the Select method to find all rows matching the filter. foundRows = Document.ActiveDocument.DocDataSet.AOIs.Select(expression); if (foundRows.Length > 0) { foreach (DataRow row in foundRows) { row["ShapeType"] = shape.ShapeType; row["ShapeNumPts"] = shape.ShapeNumPts; row["ShapePts"] = shape.ShapePts; } } return false; } return true; }
/// <summary> /// This method writes a new <see cref="AOIData"/> information /// to the AOI data table of the dataset. /// </summary> /// <remarks>This change has to be afterwards written to the database file /// with a call to /// <code>int affectedRows = Document.ActiveDocument.DocDataSet.TadAOIs.Update( /// Document.ActiveDocument.DocDataSet.AOIs);</code></remarks> /// <param name="aoi">A <see cref="AOIData"/> with the /// new AOI information.</param> /// <param name="splashDialog">A <see cref="System.ComponentModel.BackgroundWorker"/> with the /// background splash loading dialog worker which shows progress.</param> public static bool WriteAOIDataToDataSet(AOIData aoi, System.ComponentModel.BackgroundWorker splashDialog) { // Validate AOIData if (!ValidateShape(ref aoi, splashDialog)) { return false; } // Insert Data in AOI Table SQLiteOgamaDataSet.AOIsRow workAOIData; workAOIData = Document.ActiveDocument.DocDataSet.AOIs.NewAOIsRow(); workAOIData.ShapeName = aoi.ShapeName; workAOIData.ShapeNumPts = aoi.ShapeNumPts; workAOIData.ShapePts = aoi.ShapePts; workAOIData.ShapeType = aoi.ShapeType.ToString().Replace("VectorGraphics.VG", string.Empty); workAOIData.TrialID = aoi.TrialID; workAOIData.ShapeGroup = aoi.Group; workAOIData.SlideNr = aoi.SlideNr; Document.ActiveDocument.DocDataSet.AOIs.AddAOIsRow(workAOIData); return true; }
/// <summary> /// The event handler for the /// <see cref="VectorGraphics.Canvas.PictureModifiable.ShapeAdded"/> event from the /// <see cref="VectorGraphics.Canvas.PictureModifiable"/> <see cref="aoiPicture"/>. /// Updates database with new areas of interest shape given in the event arguments /// </summary> /// <param name="sender"> /// Source of the event. /// </param> /// <param name="e"> /// A <see cref="ShapeEventArgs"/> with the event data. /// </param> private void AOIPictureShapeAdded(object sender, ShapeEventArgs e) { // Skip if no data available if (this.cbbTrial.SelectedItem == null) { return; } string shapeName = e.Shape.Name; int shapePointCount = e.Shape.GetPointCount(); string shapeType = e.Shape.GetType().ToString().Replace("VectorGraphics.Elements.VG", string.Empty); string strShapePoints = ObjectStringConverter.PointFListToString(e.Shape.GetPoints()); int trialID = ((Trial)this.cbbTrial.SelectedItem).ID; // Add new Element to AOITable var aoi = new AOIData(); aoi.ShapeName = shapeName; aoi.ShapeNumPts = shapePointCount; aoi.ShapePts = strShapePoints; aoi.ShapeType = (VGShapeType)Enum.Parse(typeof(VGShapeType), shapeType); aoi.TrialID = trialID; aoi.SlideNr = this.trialTimeLine.HighlightedSlideIndex; if (!Queries.WriteAOIDataToDataSet(aoi, null)) { this.aoiPicture.DeleteShape(e.Shape); } this.ResetButtons(); }
/// <summary> /// The <see cref="Control.Click"/> event handler for the /// <see cref="Button"/> <see cref="btnImportTargets"/>. /// User selected import target areas of slideshow into /// AOIs. So convert them into table entries. /// </summary> /// <param name="sender"> /// Source of the event /// </param> /// <param name="e"> /// An empty <see cref="EventArgs"/> /// </param> private void btnImportTargets_Click(object sender, EventArgs e) { if (MessageBox.Show("Would you like to convert the target areas of the slideshow into AOIs ?") == DialogResult.OK) { foreach (Trial trial in Document.ActiveDocument.ExperimentSettings.SlideShow.Trials) { for (int i = 0; i < trial.Count; i++) { Slide slide = trial[i]; foreach (VGElement element in slide.TargetShapes) { string shapeName = element.Name; int shapePointCount = element.GetPointCount(); string shapeType = element.GetType().ToString().Replace("VectorGraphics.Elements.VG", string.Empty); string strShapePoints = ObjectStringConverter.PointFListToString(element.GetPoints()); var aoi = new AOIData(); aoi.ShapeName = shapeName; aoi.ShapeNumPts = shapePointCount; aoi.ShapePts = strShapePoints; aoi.ShapeType = (VGShapeType)Enum.Parse(typeof(VGShapeType), shapeType); aoi.TrialID = trial.ID; aoi.SlideNr = i; Queries.WriteAOIDataToDataSet(aoi, null); } } } this.ResetButtons(); } }
/// <summary> /// This method generates <see cref="AOIData" /> from each /// row of the import file, which has coordinates of simple rectangles in it. /// </summary> private static void GenerateAOIFromRectangles() { // Clear existing values AOIDataList.Clear(); // Use the decimal separator specified. NumberFormatInfo nfi = CultureInfo.GetCultureInfo("en-US").NumberFormat; if (asciiSettings.DecimalSeparatorCharacter == ',') { nfi = CultureInfo.GetCultureInfo("de-DE").NumberFormat; } // Enumerate the columns in the import file and assign their title. var columnsImportNum = new Dictionary<string, int>(); for (int i = 0; i < asciiSettings.ColumnHeaders.Count; i++) { columnsImportNum.Add(asciiSettings.ColumnHeaders[i], i); } // Get the assigned titles of the import columns for Ogamas columns string importColumnTitleForTrialID = asciiSettings.ColumnAssignments["TrialID"]; string importColumnTitleForSlideNr = asciiSettings.ColumnAssignments["SlideNr"]; string importColumnTitleForShapeName = asciiSettings.ColumnAssignments["NameOfShape"]; string importColumnTitleForTopLeftCornerX = asciiSettings.ColumnAssignments["Left top corner X"]; string importColumnTitleForTopLeftCornerY = asciiSettings.ColumnAssignments["Left top corner Y"]; string importColumnTitleForBottomRightCornerX = asciiSettings.ColumnAssignments["Right bottom corner X"]; string importColumnTitleForBottomRightCornerY = asciiSettings.ColumnAssignments["Right bottom corner Y"]; string importColumnTitleForShapeGroup = asciiSettings.ColumnAssignments["ShapeGroup"]; // Convert the names into column counters. int numTrialIDImportColumn = importColumnTitleForTrialID == string.Empty ? -1 : columnsImportNum[importColumnTitleForTrialID]; int numSlideNrImportColumn = importColumnTitleForSlideNr == string.Empty ? -1 : columnsImportNum[importColumnTitleForSlideNr]; int numShapeNameImportColumn = importColumnTitleForShapeName == string.Empty ? -1 : columnsImportNum[importColumnTitleForShapeName]; int numTopLeftCornerXImportColumn = importColumnTitleForTopLeftCornerX == string.Empty ? -1 : columnsImportNum[importColumnTitleForTopLeftCornerX]; int numTopLeftCornerYImportColumn = importColumnTitleForTopLeftCornerY == string.Empty ? -1 : columnsImportNum[importColumnTitleForTopLeftCornerY]; int numBottomRightCornerXImportColumn = importColumnTitleForBottomRightCornerX == string.Empty ? -1 : columnsImportNum[importColumnTitleForBottomRightCornerX]; int numBottomRightCornerYImportColumn = importColumnTitleForBottomRightCornerY == string.Empty ? -1 : columnsImportNum[importColumnTitleForBottomRightCornerY]; int numShapeGroupImportColumn = importColumnTitleForShapeGroup == string.Empty ? -1 : columnsImportNum[importColumnTitleForShapeGroup]; foreach (string[] items in asciiSettings.Rows) { try { var boundingRect = new RectangleF(); // Calc bounding Rect from X1,X2,Y1,Y2 as given string x1 = "0"; string y1 = "0"; string x2 = "0"; string y2 = "0"; // Create Ogama columns placeholder var newAOIData = new AOIData(); if (numTrialIDImportColumn != -1) { newAOIData.TrialID = Convert.ToInt32(items[numTrialIDImportColumn], nfi); } newAOIData.SlideNr = numSlideNrImportColumn != -1 ? Convert.ToInt32(items[numSlideNrImportColumn], nfi) : 0; if (numShapeNameImportColumn != -1) { newAOIData.ShapeName = items[numShapeNameImportColumn]; } newAOIData.ShapeType = VGShapeType.Rectangle; newAOIData.ShapeNumPts = 4; if (numTopLeftCornerXImportColumn != -1) { x1 = items[numTopLeftCornerXImportColumn]; } if (numTopLeftCornerYImportColumn != -1) { y1 = items[numTopLeftCornerYImportColumn]; } if (numBottomRightCornerXImportColumn != -1) { x2 = items[numBottomRightCornerXImportColumn]; } if (numBottomRightCornerYImportColumn != -1) { y2 = items[numBottomRightCornerYImportColumn]; } boundingRect.X = Convert.ToSingle(x1, nfi); boundingRect.Y = Convert.ToSingle(y1, nfi); boundingRect.Width = Convert.ToSingle(x2, nfi) - boundingRect.X; boundingRect.Height = Convert.ToSingle(y2, nfi) - boundingRect.Y; string pts = "P1:(" + string.Format("{0:F1}", boundingRect.Left) + ";" + string.Format("{0:F1}", boundingRect.Top) + ") P2:(" + string.Format("{0:F1}", boundingRect.Right) + ";" + string.Format("{0:F1}", boundingRect.Top) + ") P3:(" + string.Format("{0:F1}", boundingRect.Right) + ";" + string.Format("{0:F1}", boundingRect.Bottom) + ") P4:(" + string.Format("{0:F1}", boundingRect.Left) + ";" + string.Format("{0:F1}", boundingRect.Bottom) + ")"; newAOIData.ShapePts = pts; if (numShapeGroupImportColumn != -1) { newAOIData.Group = items[numShapeGroupImportColumn]; } if (string.IsNullOrEmpty(newAOIData.Group)) { newAOIData.Group = " "; } // Add new Element to AOITable AOIDataList.Add(newAOIData); } catch (Exception ex) { ExceptionMethods.HandleException(ex); } } }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Eventhandler for UI, Menu, Buttons, Toolbars etc. // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Methods and Eventhandling for Background tasks // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Inherited methods // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region Methods /// <summary> /// This method generates <see cref="AOIData" /> from each /// row of the import file, that has to be on OGAMA import format. /// </summary> private static void GenerateAOIFromOgamaTable() { // Clear existing values AOIDataList.Clear(); // Use the decimal separator specified. NumberFormatInfo nfi = CultureInfo.GetCultureInfo("en-US").NumberFormat; if (asciiSettings.DecimalSeparatorCharacter == ',') { nfi = CultureInfo.GetCultureInfo("de-DE").NumberFormat; } // Enumerate the columns in the import file and assign their title. var columnsImportNum = new Dictionary<string, int>(); for (int i = 0; i < asciiSettings.ColumnHeaders.Count; i++) { columnsImportNum.Add(asciiSettings.ColumnHeaders[i], i); } // Get the assigned titles of the import columns for Ogamas columns string importColumnTitleForTrialID = asciiSettings.ColumnAssignments["TrialID"]; string importColumnTitleForSlideNr = asciiSettings.ColumnAssignments["SlideNr"]; string importColumnTitleForShapeName = asciiSettings.ColumnAssignments["ShapeName"]; string importColumnTitleForShapeType = asciiSettings.ColumnAssignments["ShapeType"]; string importColumnTitleForShapeNumPts = asciiSettings.ColumnAssignments["ShapeNumPts"]; string importColumnTitleForShapePts = asciiSettings.ColumnAssignments["ShapePts"]; string importColumnTitleForShapeGroup = asciiSettings.ColumnAssignments["ShapeGroup"]; // Convert the names into column counters. int numTrialIDImportColumn = importColumnTitleForTrialID == string.Empty ? -1 : columnsImportNum[importColumnTitleForTrialID]; int numSlideNrImportColumn = importColumnTitleForSlideNr == string.Empty ? -1 : columnsImportNum[importColumnTitleForSlideNr]; int numShapeNameImportColumn = importColumnTitleForShapeName == string.Empty ? -1 : columnsImportNum[importColumnTitleForShapeName]; int numShapeTypeImportColumn = importColumnTitleForShapeType == string.Empty ? -1 : columnsImportNum[importColumnTitleForShapeType]; int numShapeNumPtsImportColumn = importColumnTitleForShapeNumPts == string.Empty ? -1 : columnsImportNum[importColumnTitleForShapeNumPts]; int numShapePtsImportColumn = importColumnTitleForShapePts == string.Empty ? -1 : columnsImportNum[importColumnTitleForShapePts]; int numShapeGroupImportColumn = importColumnTitleForShapeGroup == string.Empty ? -1 : columnsImportNum[importColumnTitleForShapeGroup]; foreach (string[] items in asciiSettings.Rows) { try { // Create Ogama columns placeholder var newAOIData = new AOIData(); if (numTrialIDImportColumn != -1) { newAOIData.TrialID = Convert.ToInt32(items[numTrialIDImportColumn], nfi); } newAOIData.SlideNr = numSlideNrImportColumn != -1 ? Convert.ToInt32(items[numSlideNrImportColumn], nfi) : 0; if (numShapeNameImportColumn != -1) { newAOIData.ShapeName = items[numShapeNameImportColumn]; } if (numShapeTypeImportColumn != -1) { newAOIData.ShapeType = (VGShapeType)Enum.Parse(typeof(VGShapeType), items[numShapeTypeImportColumn]); } if (numShapeNumPtsImportColumn != -1) { newAOIData.ShapeNumPts = Convert.ToInt32(items[numShapeNumPtsImportColumn], nfi); } if (numShapePtsImportColumn != -1) { newAOIData.ShapePts = items[numShapePtsImportColumn]; } if (numShapeGroupImportColumn != -1) { newAOIData.Group = items[numShapeGroupImportColumn]; } if (string.IsNullOrEmpty(newAOIData.Group)) { newAOIData.Group = " "; } AOIDataList.Add(newAOIData); } catch (Exception ex) { ExceptionMethods.HandleException(ex); } } }