// Whenever a shortcut selection is done (other than a custom selection), // set the custom selection search terms to mirror that. public void SetSearchTermsFromSelection(FileSelectionEnum selection, string relativePath) { // Don't do anything if the selection was a custom selection // Note that FileSelectonENum.Folders is set elsewhere (in MenuItemSelectFOlder_Click) so we don't have to do it here. if (this.SearchTerms == null) { // This shouldn't happen, but just in case treat it as a no-op return; } // The various selections dictate what kinds of search terms to set and use. switch (selection) { case FileSelectionEnum.Custom: // If its a custom selection we use the existing settings // so nothing should be reset return; case FileSelectionEnum.All: // Clearing all use fields is the same as selecting All Files this.ClearCustomSearchUses(); break; case FileSelectionEnum.Folders: // Set and only use the relative path as a search term // Note that we do a return here, so we don't reset the relative path to the constrained root (if the arguments are specified) this.ClearCustomSearchUses(); this.SetAndUseRelativePathSearchTerm(relativePath); return; case FileSelectionEnum.Corrupted: case FileSelectionEnum.Missing: case FileSelectionEnum.Ok: case FileSelectionEnum.Dark: // Set and only use the chosen ImageQuality as a search term this.ClearCustomSearchUses(); this.SetAndUseImageQualitySearchTerm(selection); break; case FileSelectionEnum.MarkedForDeletion: // Set and only use the DeleteFlag as true as a search term this.ClearCustomSearchUses(); this.SetAndUseDeleteFlagSearchTerm(); break; default: // Shouldn't get here, but just in case it makes it a no-op return; } Arguments arguments = Util.GlobalReferences.MainWindow.Arguments; // For all other special cases, we also set the relative path if we are contrained to a relative path if (arguments != null && arguments.ConstrainToRelativePath) { this.SetAndUseRelativePathSearchTerm(arguments.RelativePath); } ; }
// Whenever a shortcut selection is done (other than a custom selection), // set the custom selection search terms to mirror that. public void SetCustomSearchFromSelection(FileSelectionEnum selection, string relativePath) { // Don't do anything if the selection was a custom selection // Note that FileSelectonENum.Folders is set elsewhere (in MenuItemSelectFOlder_Click) so we don't have to do it here. if (this.SearchTerms == null || selection == FileSelectionEnum.Custom) { return; } // Find the relevant search term, set its use flag to true, and set its database value to whatever we are going to select on. SearchTerm searchTerm; switch (selection) { case FileSelectionEnum.All: // Clearing all use fields is the same as selecting All Files this.ClearCustomSearchUses(); return; case FileSelectionEnum.Corrupted: case FileSelectionEnum.Missing: case FileSelectionEnum.Ok: case FileSelectionEnum.Dark: this.ClearCustomSearchUses(); // Set the use field for Image Quality, and its value to one of the three possibilities searchTerm = this.SearchTerms.First(term => term.DataLabel == Constant.DatabaseColumn.ImageQuality); if (selection == FileSelectionEnum.Ok) { searchTerm.DatabaseValue = Constant.ImageQuality.Ok; } else if (selection == FileSelectionEnum.Dark) { searchTerm.DatabaseValue = Constant.ImageQuality.Dark; } else { // Shouldn't really get here but just in case return; } searchTerm.UseForSearching = true; break; case FileSelectionEnum.MarkedForDeletion: this.ClearCustomSearchUses(); // Set the use field for DeleteFlag, and its value to true searchTerm = this.SearchTerms.First(term => term.DataLabel == Constant.DatabaseColumn.DeleteFlag); searchTerm.DatabaseValue = Constant.BooleanValue.True; searchTerm.UseForSearching = true; break; case FileSelectionEnum.Folders: this.SetRelativePathSearchTerm(relativePath); break; default: break; } }
private async Task FilesSelectAndShowAsync(FileSelectionEnum selection) { long fileID = Constant.DatabaseValues.DefaultFileID; if (this.DataHandler != null && this.DataHandler.ImageCache != null && this.DataHandler.ImageCache.Current != null) { fileID = this.DataHandler.ImageCache.Current.ID; } await this.FilesSelectAndShowAsync(fileID, selection).ConfigureAwait(true); }
public ImageQuality(ImageRow image) { // Check the arguments for null ThrowIf.IsNullArgument(image, nameof(image)); this.Bitmap = null; this.DarkPixelRatioFound = 0; this.FileName = image.File; this.IsColor = false; this.OldImageQuality = image.ImageQuality; this.NewImageQuality = null; }
// Set and use the ImageQuality search term public void SetAndUseImageQualitySearchTerm(FileSelectionEnum selection) { // Set the use field for Image Quality, and its value to one of the three possibilities SearchTerm searchTerm = this.SearchTerms.First(term => term.DataLabel == Constant.DatabaseColumn.ImageQuality); if (selection == FileSelectionEnum.Ok) { searchTerm.DatabaseValue = Constant.ImageQuality.Ok; } else if (selection == FileSelectionEnum.Dark) { searchTerm.DatabaseValue = Constant.ImageQuality.Dark; } else { // Shouldn't really get here but just in case, this ignores the search term. return; } searchTerm.UseForSearching = true; searchTerm.Operator = Constant.SearchTermOperator.Equal; searchTerm.UseForSearching = true; }
// PEFORMANCE FILES SELECT AND SHOW CALLED TOO OFTEN, GIVEN THAT IT IS A SLOW OPERATION private async Task FilesSelectAndShowAsync(long imageID, FileSelectionEnum selection) { // change selection // if the data grid is bound the file database automatically updates its contents on SelectFiles() if (this.DataHandler == null) { TracePrint.PrintMessage("FilesSelectAndShow() should not be reachable with a null data handler. Is a menu item wrongly enabled?");; } if (this.DataHandler.FileDatabase == null) { TracePrint.PrintMessage("FilesSelectAndShow() should not be reachable with a null database. Is a menu item wrongly enabled?"); } // Select the files according to the given selection // Note that our check for missing actually checks to see if the file exists, // which is why its a different operation // PEFORMANCE - TWO SLOW OPERATIONS: FilesSelectAndShow invoking this.dataHandler.FileDatabase.SelectFile / .SelectMissingFilesFromCurrentlySelectedFiles Mouse.OverrideCursor = Cursors.Wait; if (selection == FileSelectionEnum.Missing) { // PERFORMANCE this can be slow if there are many files, as it checks every single file in the current database selection to see if it exists // However, it is not a mainstream operation so can be considered a lower priority place for optimization bool anyFilesMissing = this.DataHandler.FileDatabase.SelectMissingFilesFromCurrentlySelectedFiles(); if (anyFilesMissing == false) { // No files were missing. Inform the user, and don't change anything. Mouse.OverrideCursor = null; Dialogs.FileSelectionNoFilesAreMissingDialog(this); return; } } else { // If its a folder selection, record it so we can save it later in the image set table this.DataHandler.FileDatabase.ImageSet.SelectedFolder = selection == FileSelectionEnum.Folders ? this.DataHandler.FileDatabase.GetSelectedFolder() : String.Empty; // PERFORMANCE Select Files is a very slow operation as it runs a query over all files and returns everything it finds as datatables stored in memory. this.BusyCancelIndicator.EnableForSelection(true); await this.DataHandler.FileDatabase.SelectFilesAsync(selection).ConfigureAwait(true); this.BusyCancelIndicator.EnableForSelection(false); this.DataHandler.FileDatabase.BindToDataGrid(); } Mouse.OverrideCursor = null; if ((this.DataHandler.FileDatabase.CountAllCurrentlySelectedFiles < 1) && (selection != FileSelectionEnum.All)) { // Tell the user that we are resetting the selection to all files Dialogs.FileSelectionResettngSelectionToAllFilesDialog(this, selection); this.StatusBar.SetMessage("Resetting selection to All files."); selection = FileSelectionEnum.All; // PEFORMANCE: The standard select files operation in FilesSelectAndShow this.BusyCancelIndicator.EnableForSelection(true); await this.DataHandler.FileDatabase.SelectFilesAsync(selection).ConfigureAwait(true); this.BusyCancelIndicator.EnableForSelection(false); this.DataHandler.FileDatabase.BindToDataGrid(); } // Change the selection to reflect what the user selected. Update the menu state accordingly // Set the checked status of the radio button menu items to the selection. string status; switch (selection) { case FileSelectionEnum.All: status = "All files"; break; case FileSelectionEnum.Custom: status = "Custom selection"; break; case FileSelectionEnum.Dark: status = "Dark files"; break; case FileSelectionEnum.MarkedForDeletion: status = "Files marked for deletion"; break; case FileSelectionEnum.Folders: status = "Files in a specific folder"; break; case FileSelectionEnum.Missing: status = "Missing files"; break; case FileSelectionEnum.Ok: status = "Non-dark files"; break; default: throw new NotSupportedException(String.Format("Unhandled file selection {0}.", selection)); } // Show feedback of the status description in both the status bar and the data entry control panel title this.StatusBar.SetView(status); this.DataEntryControlPanel.Title = "Data entry for " + status; // Reset the Episodes, as it may change based on the current selection Episodes.Reset(); // Display the specified file or, if it's no longer selected, the next closest one // FileShow() handles empty image sets, so those don't need to be checked for here. // After a selection changes, set the slider to represent the index and the count of the current selection this.FileNavigatorSlider_EnableOrDisableValueChangedCallback(false); this.FileNavigatorSlider.Maximum = this.DataHandler.FileDatabase.CountAllCurrentlySelectedFiles; // Reset the slider to the size of images in this set if (this.FileNavigatorSlider.Maximum <= 50) { this.FileNavigatorSlider.IsSnapToTickEnabled = true; this.FileNavigatorSlider.TickFrequency = 1.0; } else { this.FileNavigatorSlider.IsSnapToTickEnabled = false; this.FileNavigatorSlider.TickFrequency = 0.02 * this.FileNavigatorSlider.Maximum; } // Reset the ThumbnailGrid selection after every change in the selection if (this.IsDisplayingMultipleImagesInOverview()) { this.MarkableCanvas.ThumbnailGrid.SelectInitialCellOnly(); } this.DataEntryControls.AutocompletionPopulateAllNotesWithFileTableValues(this.DataHandler.FileDatabase); // Always force an update after a selection this.FileShow(this.DataHandler.FileDatabase.GetFileOrNextFileIndex(imageID), true); // Update the status bar accordingly this.StatusBar.SetCurrentFile(this.DataHandler.ImageCache.CurrentRow + 1); // We add 1 because its a 0-based list this.StatusBar.SetCount(this.DataHandler.FileDatabase.CountAllCurrentlySelectedFiles); this.FileNavigatorSlider_EnableOrDisableValueChangedCallback(true); this.DataHandler.FileDatabase.ImageSet.FileSelection = selection; // Remember the current selection }
/// <summary> /// When folder loading has completed add callbacks, prepare the UI, set up the image set, and show the image. /// </summary> private async Task OnFolderLoadingCompleteAsync(bool filesJustAdded) { this.ShowSortFeedback(true); // Show the image, hide the load button, and make the feedback panels visible this.ImageSetPane.IsActive = true; this.FileNavigatorSlider_EnableOrDisableValueChangedCallback(false); this.MarkableCanvas.Focus(); // We start with this having the focus so it can interpret keyboard shortcuts if needed. // Adjust the visibility of the CopyPreviousValuesButton. Copyable controls will preview/highlight as one enters the CopyPreviousValuesButton this.CopyPreviousValuesButton.Visibility = Visibility.Visible; this.DataEntryControlPanel.IsVisible = true; // Show the File Player this.FilePlayer.Visibility = Visibility.Visible; // Set whether detections actually exist at this point. GlobalReferences.DetectionsExists = this.State.UseDetections && this.DataHandler.FileDatabase.DetectionsExists(); // Sets the default bounding box threshold, either by using a default or reading it from the detection database table (if it exists) this.State.BoundingBoxDisplayThresholdResetToValueInDataBase(); // Get the QuickPasteXML from the database and populate the QuickPaste datastructure with it string xml = this.DataHandler.FileDatabase.ImageSet.QuickPasteXML; this.quickPasteEntries = QuickPasteOperations.QuickPasteEntriesFromXML(this.DataHandler.FileDatabase, xml); // if this is completion of an existing .ddb open, set the current selection and the image index to the ones from the previous session with the image set // also if this is completion of import to a new .ddb long mostRecentFileID = this.DataHandler.FileDatabase.ImageSet.MostRecentFileID; FileSelectionEnum fileSelection = this.DataHandler.FileDatabase.ImageSet.FileSelection; if (fileSelection == FileSelectionEnum.Folders) { // Compose a custom search term for the relative path // which sets and only usse the relative path as a search term this.DataHandler.FileDatabase.CustomSelection.ClearCustomSearchUses(); this.DataHandler.FileDatabase.CustomSelection.SetAndUseRelativePathSearchTerm(this.DataHandler.FileDatabase.ImageSet.SelectedFolder); } if (filesJustAdded && (this.DataHandler.ImageCache.CurrentRow != Constant.DatabaseValues.InvalidRow && this.DataHandler.ImageCache.CurrentRow != Constant.DatabaseValues.InvalidRow)) { // if this is completion of an add to an existing image set stay on the image, ideally, shown before the import if (this.DataHandler.ImageCache.Current != null) { mostRecentFileID = this.DataHandler.ImageCache.Current.ID; } // This is heavier weight than desirable, but it's a one off. this.DataHandler.ImageCache.TryInvalidate(mostRecentFileID); } // PERFORMANCE - Initial but necessary Selection done in OnFolderLoadingComplete invoking this.FilesSelectAndShow to display selected image set // PROGRESSBAR - Display a progress bar on this (and all other) calls to FilesSelectAndShow after a delay of (say) .5 seconds. await this.FilesSelectAndShowAsync(mostRecentFileID, fileSelection).ConfigureAwait(true); // match UX availability to file availability this.EnableOrDisableMenusAndControls(); // Reset the folder list used to construct the Select Folders menu this.MenuItemSelectByFolder_ResetFolderList(); // Trigger updates to the datagrid pane, if its visible to the user. if (this.DataGridPane.IsVisible) { this.DataGridPane_IsActiveChanged(null, null); } // We have to do this again, to ensure that we have switched to the ImageSetPane this.ImageSetPane.IsActive = true; }