public void SetDateTimesAndOffset(DateTimeOffset dateTime) { foreach (SearchTerm dateTimeTerm in this.SearchTerms.Where(term => term.DataLabel == Constant.DatabaseColumn.DateTime)) { dateTimeTerm.SetDatabaseValue(dateTime); } SearchTerm utcOffsetTerm = this.SearchTerms.FirstOrDefault(term => term.DataLabel == Constant.DatabaseColumn.UtcOffset); if (utcOffsetTerm != null) { utcOffsetTerm.SetDatabaseValue(dateTime.Offset); } }
/// <summary> /// Create a CustomSelection, where we build a list of potential search terms based on the controls found in the sorted template table /// The search term will be used only if its 'UseForSearching' field is true /// </summary> public CustomSelection(DataTableBackedList <ControlRow> templateTable, CustomSelectionOperatorEnum termCombiningOperator) { // Check the arguments for null ThrowIf.IsNullArgument(templateTable, nameof(templateTable)); this.DetectionSelections = new Detection.DetectionSelections(); this.SearchTerms = new List <SearchTerm>(); this.TermCombiningOperator = termCombiningOperator; // skip hidden controls as they're not normally a part of the user experience // this is potentially problematic in corner cases; an option to show terms for all controls can be added if needed foreach (ControlRow control in templateTable) { // If you don't want a control to appear in the CustomSelection, add it here // The Folder is usually the same for all files in the image set and thus not useful for selection // date and time are redundant with DateTime string controlType = control.Type; if (controlType == Constant.DatabaseColumn.Date || controlType == Constant.DatabaseColumn.Folder || controlType == Constant.DatabaseColumn.Time) { continue; } // create search term for the control SearchTerm searchTerm = new SearchTerm { ControlType = controlType, DataLabel = control.DataLabel, DatabaseValue = control.DefaultValue, Operator = Constant.SearchTermOperator.Equal, Label = control.Label, List = control.GetChoices(true), UseForSearching = false }; if (searchTerm.List.Count > 0) { // Add the empty string to the beginning of the search list, which allows the option of searching for empty items searchTerm.List.Insert(0, String.Empty); } this.SearchTerms.Add(searchTerm); // Create a new search term for each row, where each row specifies a particular control and how it can be searched if (controlType == Constant.Control.Counter) { searchTerm.DatabaseValue = "0"; searchTerm.Operator = Constant.SearchTermOperator.GreaterThan; // Makes more sense that people will test for > as the default rather than counters } else if (controlType == Constant.DatabaseColumn.DateTime) { // the first time the CustomSelection dialog is popped Timelapse calls SetDateTime() to changes the default date time to the date time // of the current image searchTerm.DatabaseValue = DateTimeHandler.ToStringDatabaseDateTime(Constant.ControlDefault.DateTimeValue); searchTerm.Operator = Constant.SearchTermOperator.GreaterThanOrEqual; // support querying on a range of datetimes by giving the user two search terms, one configured for the start of the interval and one // for the end SearchTerm dateTimeLessThanOrEqual = new SearchTerm(searchTerm) { Operator = Constant.SearchTermOperator.LessThanOrEqual }; this.SearchTerms.Add(dateTimeLessThanOrEqual); } else if (controlType == Constant.Control.Flag) { searchTerm.DatabaseValue = Constant.BooleanValue.False; } else if (controlType == Constant.DatabaseColumn.UtcOffset) { // the first time it's popped CustomSelection dialog changes this default to the date time of the current image searchTerm.SetDatabaseValue(Constant.ControlDefault.DateTimeValue.Offset); } // else use default values above } }
/// <summary> /// Create a CustomSelection, where we build a list of potential search terms based on the controls found in the sorted template table /// The search term will be used only if its 'UseForSearching' field is true /// </summary> public CustomSelection(DataTableBackedList <ControlRow> templateTable, CustomSelectionOperatorEnum termCombiningOperator) { // Check the arguments for null ThrowIf.IsNullArgument(templateTable, nameof(templateTable)); this.DetectionSelections = new Detection.DetectionSelections(); this.SearchTerms = new List <SearchTerm>(); this.TermCombiningOperator = termCombiningOperator; // skip hidden controls as they're not normally a part of the user experience // this is potentially problematic in corner cases; perhaps add an option to show terms for all controls can be added if needed? foreach (ControlRow control in templateTable) { // If you don't want a control to appear in the CustomSelection, add it here // The Folder is usually the same for all files in the image set and thus not useful for selection // date and time are redundant with DateTime string controlType = control.Type; if (controlType == Constant.DatabaseColumn.Date || controlType == Constant.DatabaseColumn.Folder || controlType == Constant.DatabaseColumn.Time) { continue; } // create search term for the control SearchTerm searchTerm = new SearchTerm { ControlType = controlType, DataLabel = control.DataLabel, DatabaseValue = control.DefaultValue, Operator = Constant.SearchTermOperator.Equal, Label = control.Label, List = control.GetChoices(true), UseForSearching = false }; if (searchTerm.List.Count > 0) { // Add the empty string to the beginning of the search list, which allows the option of searching for empty items searchTerm.List.Insert(0, String.Empty); } this.SearchTerms.Add(searchTerm); // Create a new search term for each row, where each row specifies a particular control and how it can be searched if (controlType == Constant.Control.Counter) { searchTerm.DatabaseValue = "0"; searchTerm.Operator = Constant.SearchTermOperator.GreaterThan; // Makes more sense that people will test for > as the default rather than counters } else if (controlType == Constant.DatabaseColumn.DateTime) { // the first time the CustomSelection dialog is popped Timelapse calls SetDateTime() to changes the default date time to the date time // of the current image searchTerm.DatabaseValue = DateTimeHandler.ToStringDatabaseDateTime(Constant.ControlDefault.DateTimeValue); searchTerm.Operator = Constant.SearchTermOperator.GreaterThanOrEqual; // support querying on a range of datetimes by giving the user two search terms, one configured for the start of the interval and one // for the end SearchTerm dateTimeLessThanOrEqual = new SearchTerm(searchTerm) { Operator = Constant.SearchTermOperator.LessThanOrEqual }; this.SearchTerms.Add(dateTimeLessThanOrEqual); } else if (controlType == Constant.Control.Flag) { searchTerm.DatabaseValue = Constant.BooleanValue.False; } else if (controlType == Constant.DatabaseColumn.UtcOffset) { // the first time it's popped CustomSelection dialog changes this default to the date time of the current image searchTerm.SetDatabaseValue(Constant.ControlDefault.DateTimeValue.Offset); } // else use default values above } // The hacky mess below is simply to get the search terms in an ordered list, where: // - the standard visible search terms are at the beginning, in a specific order // - the remaining non-standard search terms follow, in the order specified in the template // Get the unordered standard search tersm IEnumerable <SearchTerm> unodrderedStandardSearchTerms = SearchTerms.Where( term => term.DataLabel == Constant.DatabaseColumn.File || term.DataLabel == Constant.DatabaseColumn.Folder || term.DataLabel == Constant.DatabaseColumn.RelativePath || term.DataLabel == Constant.DatabaseColumn.DateTime || term.DataLabel == Constant.DatabaseColumn.ImageQuality || term.DataLabel == Constant.DatabaseColumn.UtcOffset || term.DataLabel == Constant.DatabaseColumn.DeleteFlag); // Create a dictionary that will contain items in the correct order string secondDateTimeLabel = "2nd" + Constant.DatabaseColumn.DateTime; Dictionary <string, SearchTerm> dictOrderedTerms = new Dictionary <string, SearchTerm> { { Constant.DatabaseColumn.File, null }, { Constant.DatabaseColumn.Folder, null }, { Constant.DatabaseColumn.RelativePath, null }, { Constant.DatabaseColumn.DateTime, null }, { secondDateTimeLabel, null }, { Constant.DatabaseColumn.UtcOffset, null }, { Constant.DatabaseColumn.ImageQuality, null }, { Constant.DatabaseColumn.DeleteFlag, null } }; // Add the unordered search terms into the dictionary, which will put them in the correct order List <SearchTerm> orderedSearchTerms = new List <SearchTerm>(); foreach (SearchTerm searchTerm in unodrderedStandardSearchTerms) { if (dictOrderedTerms.ContainsKey(searchTerm.DataLabel)) { if (searchTerm.DataLabel == Constant.DatabaseColumn.DateTime && dictOrderedTerms[searchTerm.DataLabel] != null) { // We need to use the 2nd datetime label as there may be two DateTime entries (i.e. to allow a user to select a date range) dictOrderedTerms[secondDateTimeLabel] = searchTerm; } else { dictOrderedTerms[searchTerm.DataLabel] = searchTerm; } } } // Create a new ordered list of standard search terms based on the non-null (and correctly ordered) search terms in the dictionary List <SearchTerm> standardSearchTerms = new List <SearchTerm>(); foreach (KeyValuePair <string, SearchTerm> kvp in dictOrderedTerms) { if (kvp.Value != null) { standardSearchTerms.Add(kvp.Value); } } // Collect all the non-standard search terms which the user currently selected as UseForSearching IEnumerable <SearchTerm> nonStandardSearchTerms = SearchTerms.Except(unodrderedStandardSearchTerms).ToList(); // FInally, concat the two lists together to collect all the correctly ordered search terms into a single list SearchTerms = standardSearchTerms.Concat(nonStandardSearchTerms).ToList(); }