/// <summary> /// The <see cref="Control.Validating"/> event handler for /// the <see cref="TextBox"/> <see cref="txbYSizeEyeMon"/>. /// Checks y size of tracking monitor text field for correct numeric entry. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">A <see cref="CancelEventArgs"/> with the event data.</param> private void fldYSizeEyeMon_Validating(object sender, CancelEventArgs e) { if (!IOHelpers.IsNumeric(this.txbYSizeEyeMon.Text)) { e.Cancel = true; ExceptionMethods.ProcessErrorMessage("The screen height has to be a numerical value"); } }
/// <summary> /// The <see cref="Control.Validating"/> event handler for /// the <see cref="TextBox"/> <see cref="txbSamplingRateMouse"/>. /// Checks mouse sampling rate text field for correct numeric entry. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">A <see cref="CancelEventArgs"/> with the event data.</param> private void txbSamplingRateMouse_Validating(object sender, CancelEventArgs e) { if (!IOHelpers.IsNumeric(this.txbSamplingRateMouse.Text)) { e.Cancel = true; ExceptionMethods.ProcessErrorMessage("The sampling rate has to be a numerical value"); } }
/////////////////////////////////////////////////////////////////////////////// // Public methods // /////////////////////////////////////////////////////////////////////////////// #region PUBLICMETHODS /// <summary> /// This method parses the given file under the conditions specified /// in this <see cref="ASCIISettings"/> and returns the values as a collection /// of <see cref="string"/> arrays. /// </summary> /// <param name="importFile">The file to parse.</param> /// <param name="numberOfImportLines">An <see cref="int"/> /// with the max number of lines to import. /// Set it to -1 to use all lines.</param> /// <param name="columnHeaders">ref. A list of <see cref="string"/>s /// that represent the import file column headers.</param> /// <returns>A list of <see cref="string"/> arrays with the separated items of /// the file, that are read using the current <see cref="ASCIISettings"/></returns> /// <exception cref="System.IO.FileNotFoundException">Thrown, when /// the file to import does not exist.</exception> public List <string[]> ParseFile( string importFile, int numberOfImportLines, ref List <string> columnHeaders) { // Check import file. if (!File.Exists(importFile)) { throw new FileNotFoundException("The import file could not be found"); } // Create return list. List <string[]> fileRows = new List <string[]>(); // Check out parameter. if (columnHeaders == null) { columnHeaders = new List <string>(); } else { columnHeaders.Clear(); } string line = string.Empty; int counter = 0; int columncount = 0; // Begin reading File try { using (StreamReader importReader = new StreamReader(importFile)) { // Read ImportFile while ((line = importReader.ReadLine()) != null) { // ignore empty lines if (line.Trim() == string.Empty) { continue; } // Ignore Quotes if applicable if (this.IgnoreQuotes && line.Trim().Substring(0, this.IgnoreQuotationString.Length) == this.IgnoreQuotationString) { continue; } // Ignore lines that do not have the "use only" quotation // string if (this.UseQuotes && !line.Contains(this.UseQuotationString)) { continue; } // ignore lines with ignore trigger if (this.IgnoreTriggerStringLines && line.Contains(this.IgnoreTriggerString)) { continue; } // Split Tab separated line items string[] items = line.Split(this.ColumnSeparatorCharacter); // Skip first line if filled with column titles if (this.ColumnTitlesAtFirstRow && counter == 0) { counter++; columncount = items.Length; // Fill column header list for (int i = 0; i < columncount; i++) { string headerText = items[i].Replace(' ', '-'); columnHeaders.Add(headerText); } continue; } // Use only numeric starting lines if applicable if (this.IgnoreNotNumeralLines && !IOHelpers.IsNumeric(line[0])) { continue; } // Set columncount in first valid line if (counter == 0) { columncount = items.Length; } // Skip small lines if applicable if (this.IgnoreSmallLines && columncount > items.Length) { continue; } if (counter == 0 && !this.ColumnTitlesAtFirstRow) { // Fill column header list for (int i = 0; i < items.Length; i++) { string headerText = "Column" + i; columnHeaders.Add(headerText); } } // Add row to import list fileRows.Add(items); // Increase counter counter++; // Cancel import, if only a part for preview should be imported. if (counter > numberOfImportLines && numberOfImportLines >= 0) { break; } } } } catch (Exception ex) { ExceptionMethods.HandleException(ex); } return(fileRows); }
/// <summary> /// Handles the Click event of the btnOK control. /// Checks for correct shape name. /// </summary> /// <param name="sender"> /// The source of the event. /// </param> /// <param name="e"> /// The <see cref="System.EventArgs"/> instance containing the event data. /// </param> private void BtnOkClick(object sender, EventArgs e) { this.ShapeName = this.ShapeName.Trim(); var sb = new StringBuilder(); bool changed = false; for (int i = 0; i < this.ShapeName.Length; i++) { if (char.IsLetterOrDigit(this.ShapeName[i])) { sb.Append(this.ShapeName[i]); } else { changed = true; } } this.ShapeName = sb.ToString(); if (changed) { 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); return; } if (this.ShapeName == string.Empty) { InformationDialog.Show( "Empty shape name", "Please enter at least one character for the shape name", false, MessageBoxIcon.Information); return; } if (IOHelpers.IsNumeric(this.ShapeName[0])) { InformationDialog.Show( "Invalid shape name", "Please do not use a number for the first character of the shape name.", false, MessageBoxIcon.Information); return; } var aois = Document.ActiveDocument.DocDataSet.AOIs.Where(o => o.ShapeName == this.ShapeName && o.TrialID == this.trialID); // OgamaDataSet.AOIsDataTable aoisTable = Document.ActiveDocument.DocDataSet.AOIsAdapter.GetDataByTrialIDAndShapeName(this.trialID, this.ShapeName); if (aois.Any()) { string message = "The area of interest: " + Environment.NewLine + this.ShapeName + " already exists." + Environment.NewLine + "Please select another name."; ExceptionMethods.ProcessMessage("Shape exists", message); return; } this.DialogResult = DialogResult.OK; this.Close(); }
/// <summary> /// Generate the list of fixations under the current /// parsing conditions. /// </summary> /// <param name="numberOfImportLines"> /// An <see cref="int"/> /// with the max number of lines to import. /// Set it to -1 to use all lines. /// </param> /// <remarks> /// This is the heart of the class. If something does not work as expected, /// first have a look here. /// </remarks> private static bool GenerateOgamaFixationDataList(int numberOfImportLines) { // Retrieve existing slideshow trials (to check matching filenames for // correct trial ID numbering List <Trial> trials = Document.ActiveDocument.ExperimentSettings.SlideShow.Trials; List <string> trialNames = Document.ActiveDocument.ExperimentSettings.SlideShow.GetTrialNames(); // Clear existing values FixationDataList.Clear(); detectionSetting.ImageDictionary.Clear(); // Use the decimal separator specified. NumberFormatInfo nfi = CultureInfo.GetCultureInfo("en-US").NumberFormat; if (asciiSetting.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 < asciiSetting.ColumnHeaders.Count; i++) { columnsImportNum.Add(asciiSetting.ColumnHeaders[i], i); } // Get the assigned titles of the import columns for Ogamas columns string strSubjectNameImportColumn = asciiSetting.ColumnAssignments["SubjectName"]; string strTrialSequenceImportColumn = asciiSetting.ColumnAssignments["TrialSequence"]; string strTrialIDImportColumn = asciiSetting.ColumnAssignments["TrialID"]; string strTrialImageImportColumn = asciiSetting.ColumnAssignments["TrialImage"]; string strCountInTrialImportColumn = asciiSetting.ColumnAssignments["CountInTrial"]; string strStartTimeImportColumn = asciiSetting.ColumnAssignments["StartTime"]; string strEndTimeImportColumn = asciiSetting.ColumnAssignments["EndTime"]; string strLengthImportColumn = asciiSetting.ColumnAssignments["Length"]; string strPosXImportColumn = asciiSetting.ColumnAssignments["PosX"]; string strPosYImportColumn = asciiSetting.ColumnAssignments["PosY"]; // Convert the names into column counters. int numSubjectImportColumn = strSubjectNameImportColumn == string.Empty ? -1 : columnsImportNum[strSubjectNameImportColumn]; int numTrialSequenceImportColumn = strTrialSequenceImportColumn == string.Empty ? -1 : columnsImportNum[strTrialSequenceImportColumn]; int numTrialIDImportColumn = strTrialIDImportColumn == string.Empty ? -1 : columnsImportNum[strTrialIDImportColumn]; int numTrialImageImportColumn = strTrialImageImportColumn == string.Empty ? -1 : columnsImportNum[strTrialImageImportColumn]; int numCountInTrialImportColumn = strCountInTrialImportColumn == string.Empty ? -1 : columnsImportNum[strCountInTrialImportColumn]; int numStartTimeImportColumn = strStartTimeImportColumn == string.Empty ? -1 : columnsImportNum[strStartTimeImportColumn]; int numEndTimeImportColumn = strEndTimeImportColumn == string.Empty ? -1 : columnsImportNum[strEndTimeImportColumn]; int numLengthImportColumn = strLengthImportColumn == string.Empty ? -1 : columnsImportNum[strLengthImportColumn]; int numPosXImportColumn = strPosXImportColumn == string.Empty ? -1 : columnsImportNum[strPosXImportColumn]; int numPosYImportColumn = strPosYImportColumn == string.Empty ? -1 : columnsImportNum[strPosYImportColumn]; // Create a list of starting times from the list of the trial dialog // if this mode is selected. if (detectionSetting.TrialImportMode == TrialSequenceImportModes.UseAssignmentTable) { // If first given trial start time does not start with zero, // add a "zero trial" for the very first samples if (detectionSetting.TrialSequenceToStarttimeAssignments.Count == 0) { // In this trial import modes an empty TrialIDToStarttimeAssignments // List is not allowed. return(false); } } else { detectionSetting.TrialSequenceToTrialIDAssignments.Clear(); detectionSetting.TrialSequenceToStarttimeAssignments.Clear(); } int counter = 0; int countInTrialCounter = 1; int columncount = 0; int trialCounter = 0; int lastTrialSequence = 0; int currentTrialSequence = 0; int lengthConverterErrorCounter = 0; bool isLastTrial = false; SortedList <int, long> trial2Time = detectionSetting.TrialSequenceToStarttimeAssignments; if (trial2Time.Count > 0) { currentTrialSequence = trial2Time.Keys[0]; } // Begin reading File try { // Open file using (var importReader = new StreamReader(asciiSetting.Filename)) { // Clear old entries except parses from table if (detectionSetting.StimuliImportMode != StimuliImportModes.UseAssignmentTable) { detectionSetting.ImageDictionary.Clear(); detectionSetting.TrialIDToImageAssignments.Clear(); } // Read every line of ImportFile string line; while ((line = importReader.ReadLine()) != null) { // ignore empty lines if (line.Trim() == string.Empty) { continue; } // Ignore Quotes if applicable if (asciiSetting.IgnoreQuotes && line.Trim().Substring(0, asciiSetting.IgnoreQuotationString.Length) == asciiSetting.IgnoreQuotationString) { continue; } // Check for trial detection specifications switch (detectionSetting.TrialImportMode) { case TrialSequenceImportModes.UseMSGLines: // Check for MSG lines containing the trigger string if applicable if (line.Contains(detectionSetting.TrialTriggerString)) { trialCounter++; currentTrialSequence = trialCounter; } break; case TrialSequenceImportModes.UseAssignmentTable: case TrialSequenceImportModes.UseImportColumn: // No trial counting needed break; } // Ignore lines that do not have the "use only" quotation // string if (asciiSetting.UseQuotes && !line.Contains(asciiSetting.UseQuotationString)) { continue; } // ignore lines with ignore trigger if (asciiSetting.IgnoreTriggerStringLines && line.Contains(asciiSetting.IgnoreTriggerString)) { continue; } // Use only numeric starting lines if applicable if (asciiSetting.IgnoreNotNumeralLines && !IOHelpers.IsNumeric(line[0])) { continue; } // Split Tab separated line items string[] items = line.Split(asciiSetting.ColumnSeparatorCharacter); // Set columncount in first valid line if (counter == 0) { columncount = items.Length; } // Skip small lines if applicable if (asciiSetting.IgnoreSmallLines && columncount != items.Length) { continue; } // Skip first line if filled with column titles if (asciiSetting.ColumnTitlesAtFirstRow && counter == 0) { counter++; continue; } // Create Ogama columns placeholder var newFixationData = new FixationData(); // Calculate time value double timeInFileTime = Convert.ToDouble(items[numStartTimeImportColumn], nfi); long timeInMs = Convert.ToInt64(timeInFileTime * detectionSetting.TimeFactor); // Write subject name value newFixationData.SubjectName = numSubjectImportColumn != -1 ? items[numSubjectImportColumn] : detectionSetting.SubjectName; // Write Trial Sequence switch (detectionSetting.TrialImportMode) { case TrialSequenceImportModes.UseMSGLines: break; case TrialSequenceImportModes.UseAssignmentTable: if (!isLastTrial && timeInMs + asciiSetting.StartTime >= trial2Time.Values[trialCounter]) { trialCounter++; if (trialCounter >= trial2Time.Count) { isLastTrial = true; } } currentTrialSequence = trial2Time.Keys[trialCounter - 1]; break; case TrialSequenceImportModes.UseImportColumn: if (numTrialSequenceImportColumn != -1) { currentTrialSequence = Convert.ToInt32(items[numTrialSequenceImportColumn]); } break; } newFixationData.TrialSequence = currentTrialSequence; if (currentTrialSequence != lastTrialSequence) { countInTrialCounter = 1; lastTrialSequence = currentTrialSequence; } else { countInTrialCounter++; } // Write count in trial if (numCountInTrialImportColumn != -1) { newFixationData.CountInTrial = IOHelpers.IsNumeric(items[numCountInTrialImportColumn]) ? Convert.ToInt32(items[numCountInTrialImportColumn], nfi) : counter; } else { newFixationData.CountInTrial = countInTrialCounter; } // Get trial start time from database long currentTrialStarttime = 0; try { var matchingTrial = Document.ActiveDocument.DocDataSet.TrialsAdapter.GetDataBySubjectAndSequence( newFixationData.SubjectName, newFixationData.TrialSequence); currentTrialStarttime = matchingTrial[0].TrialStartTime; } catch (Exception) { var message = string.Format( "There is no trial for this fixation data in the experiment. (Subject: {0}, TrialSequence: {1}, not found)" + Environment.NewLine + "Before importing fixations, ensure that the subject and trials are already imported into the database e.g. via raw data import." + Environment.NewLine + "The fixation import assistant will now close.", newFixationData.SubjectName, newFixationData.TrialSequence); ExceptionMethods.ProcessMessage("Subjects entry is missing", message); return(false); } // Save starttime if (counter == 0 || (asciiSetting.ColumnTitlesAtFirstRow && counter == 1)) { asciiSetting.StartTime = currentTrialStarttime; if (timeInMs > 0) { asciiSetting.StartTime = timeInMs; } } // Write trialID to detection settings. if (numTrialIDImportColumn != -1) { int?columnTrialID = Convert.ToInt32(items[numTrialIDImportColumn]); if (!detectionSetting.TrialSequenceToTrialIDAssignments.ContainsKey(currentTrialSequence)) { detectionSetting.TrialSequenceToTrialIDAssignments.Add(currentTrialSequence, columnTrialID.Value); } } // Write TrialID if (numTrialIDImportColumn != -1) { newFixationData.TrialID = IOHelpers.IsNumeric(items[numTrialIDImportColumn]) ? Convert.ToInt32(items[numTrialIDImportColumn], nfi) : currentTrialSequence; } else { newFixationData.TrialID = currentTrialSequence; } // Save time value newFixationData.StartTime = timeInMs - currentTrialStarttime - asciiSetting.StartTime; // If starttimes are already relative to trial beginning if (newFixationData.StartTime < 0) { newFixationData.StartTime = timeInMs - asciiSetting.StartTime; } long endtime = 0; // Read ending time if (numEndTimeImportColumn != -1) { // Calculate time value double endtimeInFileTime = IOHelpers.IsNumeric(items[numEndTimeImportColumn]) ? Convert.ToDouble(items[numEndTimeImportColumn], nfi) : 0; endtime = Convert.ToInt64(endtimeInFileTime * detectionSetting.TimeFactor); } // Write fixation duration if (numLengthImportColumn != -1) { newFixationData.Length = IOHelpers.IsNumeric(items[numLengthImportColumn]) ? Convert.ToInt32(items[numLengthImportColumn], nfi) : 0; } // If no length column is specified or import failed // try to calculate from starting and ending time if (newFixationData.Length == 0) { newFixationData.Length = (int)(endtime - asciiSetting.StartTime - newFixationData.StartTime); } // Look for errors. if (newFixationData.Length == 0) { lengthConverterErrorCounter++; continue; } // Write fixation positions if (numPosXImportColumn != -1) { newFixationData.PosX = IOHelpers.IsNumeric(items[numPosXImportColumn]) ? Convert.ToSingle(items[numPosXImportColumn], nfi) : 0; } if (numPosYImportColumn != -1) { newFixationData.PosY = IOHelpers.IsNumeric(items[numPosYImportColumn]) ? Convert.ToSingle(items[numPosYImportColumn], nfi) : 0; } // Add the parsed raw data row to the list. FixationDataList.Add(newFixationData); // Increase counter counter++; // Cancel import, if only a part for preview should be imported. if (counter > numberOfImportLines && numberOfImportLines >= 0) { break; } } // reached end of file } // Show parsing errors. if (lengthConverterErrorCounter > 0) { var message = new StringBuilder(); message.Append(lengthConverterErrorCounter); message.Append(" fixation durations could not be parsed."); message.Append("These fixations are omitted from import."); ExceptionMethods.ProcessErrorMessage(message.ToString()); } } catch (Exception ex) { ExceptionMethods.HandleException(ex); } return(true); }