// Delete callback manages all deletion menu choices where: // - the current image or all images marked for deletion are deleted // - the data associated with those images may be delted. // - deleted images are moved to a backup folder. private async void MenuItemDeleteFiles_Click(object sender, RoutedEventArgs e) { MenuItem menuItem = sender as MenuItem; // This callback is invoked by DeleteImage (which deletes the current image) and DeleteImages (which deletes the images marked by the deletion flag) // Thus we need to use two different methods to construct a table containing all the images marked for deletion List <ImageRow> filesToDelete; bool deleteCurrentImageOnly; bool deleteFilesAndData; if (menuItem.Name.Equals(this.MenuItemDeleteFiles.Name) || menuItem.Name.Equals(this.MenuItemDeleteFilesAndData.Name)) { deleteCurrentImageOnly = false; deleteFilesAndData = menuItem.Name.Equals(this.MenuItemDeleteFilesAndData.Name); // get list of all images marked for deletion in the current seletion using (FileTable filetable = this.DataHandler.FileDatabase.SelectFilesMarkedForDeletion()) { filesToDelete = filetable.ToList(); } for (int index = filesToDelete.Count - 1; index >= 0; index--) { if (this.DataHandler.FileDatabase.FileTable.Find(filesToDelete[index].ID) == null) { filesToDelete.Remove(filesToDelete[index]); } } } else { // Delete current image case. Get the ID of the current image and construct a datatable that contains that image's datarow deleteCurrentImageOnly = true; deleteFilesAndData = menuItem.Name.Equals(this.MenuItemDeleteCurrentFileAndData.Name); filesToDelete = new List <ImageRow>(); if (this.DataHandler.ImageCache.Current != null) { filesToDelete.Add(this.DataHandler.ImageCache.Current); } } // If no images are selected for deletion. Warn the user. // Note that this should never happen, as the invoking menu item should be disabled (and thus not selectable) // if there aren't any images to delete. Still,... if (filesToDelete == null || filesToDelete.Count < 1) { Dialogs.MenuEditNoFilesMarkedForDeletionDialog(this); return; } long currentFileID = this.DataHandler.ImageCache.Current.ID; DeleteImages deleteImagesDialog = new DeleteImages(this, this.DataHandler.FileDatabase, this.DataHandler.ImageCache, filesToDelete, deleteFilesAndData, deleteCurrentImageOnly); bool? result = deleteImagesDialog.ShowDialog(); if (result == true) { // Delete the files Mouse.OverrideCursor = Cursors.Wait; // Reload the file datatable. await this.FilesSelectAndShowAsync(currentFileID, this.DataHandler.FileDatabase.ImageSet.FileSelection).ConfigureAwait(true); if (deleteFilesAndData) { // Find and show the image closest to the last one shown if (this.DataHandler.FileDatabase.CountAllCurrentlySelectedFiles > 0) { int nextImageRow = this.DataHandler.FileDatabase.GetFileOrNextFileIndex(currentFileID); this.FileShow(nextImageRow); } else { // No images left, so disable everything this.EnableOrDisableMenusAndControls(); } } else { // display the updated properties on the current image, or the closest one to it. int nextImageRow = this.DataHandler.FileDatabase.FindClosestImageRow(currentFileID); this.FileShow(nextImageRow); } Mouse.OverrideCursor = null; } }
// Delete callback manages all deletion menu choices where: // - the current image or all images marked for deletion are deleted // - the data associated with those images may be delted. // - deleted images are moved to a backup folder. private async void MenuItemDeleteFiles_Click(object sender, RoutedEventArgs e) { MenuItem menuItem = sender as MenuItem; // This callback is invoked by DeleteImage (which deletes the current image) and DeleteImages (which deletes the images marked by the deletion flag) // Thus we need to use two different methods to construct a table containing all the images marked for deletion List <ImageRow> filesToDelete; bool deleteCurrentImageOnly; bool deleteFiles; bool deleteData; if (menuItem.Name.Equals(this.MenuItemDeleteFiles.Name) || menuItem.Name.Equals(this.MenuItemDeleteFilesAndData.Name) || menuItem.Name.Equals(this.MenuItemDeleteFilesData.Name)) { deleteCurrentImageOnly = false; deleteFiles = false == menuItem.Name.Equals(this.MenuItemDeleteFilesData.Name); // this is the only condition where we don't delete the file deleteData = false == menuItem.Name.Equals(this.MenuItemDeleteFiles.Name); // this is the only condition where we don't delete the data // get list of all images marked for deletion in the current seletion using (FileTable filetable = this.DataHandler.FileDatabase.SelectFilesMarkedForDeletion()) { filesToDelete = filetable.ToList(); } for (int index = filesToDelete.Count - 1; index >= 0; index--) { if (this.DataHandler.FileDatabase.FileTable.Find(filesToDelete[index].ID) == null) { filesToDelete.Remove(filesToDelete[index]); } } } else { // Delete current image case. Get the ID of the current image and construct a datatable that contains that image's datarow deleteCurrentImageOnly = true; deleteFiles = false == menuItem.Name.Equals(this.MenuItemDeleteCurrentData.Name); // this is the only condition where we don't delete the current file deleteData = false == menuItem.Name.Equals(this.MenuItemDeleteCurrentFile.Name); // this is the only condition where we don't delete the current data filesToDelete = new List <ImageRow>(); if (this.DataHandler.ImageCache.Current != null) { filesToDelete.Add(this.DataHandler.ImageCache.Current); } } // If no images are selected for deletion. Warn the user. // Note that this should never happen, as the invoking menu item should be disabled (and thus not selectable) // if there aren't any images to delete. Still,... if (filesToDelete == null || filesToDelete.Count < 1) { Dialogs.MenuEditNoFilesMarkedForDeletionDialog(this); return; } // if we delete data records, we can sometimes get in the situation (particularly if we delete a duplicate) where the next fileID displayed is not the closest to the existing position. // To resolve this, we get the closest non-deleted file ID before we do the deletion and then try to display that file. long currentFileID = this.DataHandler.ImageCache.Current.ID; if (deleteData == true) { //foreach (ImageRow ir in filesToDelete) //{ // System.Diagnostics.Debug.Print(ir.ID.ToString()); //} // if we delete the data for the current image only but not the file , we can sometimes get in the situation (particularly if we delete a duplicate) where the next fileID displayed is not the closest to the existing position. // To resolve this, we get the closest non-deleted file ID before we do the deletion. int fileIndex = this.DataHandler.ImageCache.CurrentRow; bool allDone = false; for (int nextFileIndex = fileIndex; nextFileIndex < this.DataHandler.FileDatabase.FileTable.Count(); nextFileIndex++) { // Check if is a deleted file. if (this.DataHandler.FileDatabase.IsFileRowInRange(nextFileIndex)) { // System.Diagnostics.Debug.Print("-->" + this.DataHandler.FileDatabase.FileTable[nextFileIndex].ID.ToString()); if (false == filesToDelete.Any(file => file.ID == this.DataHandler.FileDatabase.FileTable[nextFileIndex].ID)) { // Its not a deleted file, so we have a valid next file to display! currentFileID = this.DataHandler.FileDatabase.FileTable[nextFileIndex].ID; allDone = true; break; } } } if (allDone == false) { for (int prevFileIndex = fileIndex; prevFileIndex >= 0; prevFileIndex--) { // Check if is a deleted file. if (this.DataHandler.FileDatabase.IsFileRowInRange(prevFileIndex)) { if (false == filesToDelete.Any(file => file.ID == this.DataHandler.FileDatabase.FileTable[prevFileIndex].ID)) { // Its not a deleted file, so we have a valid next file to display! currentFileID = this.DataHandler.FileDatabase.FileTable[prevFileIndex].ID; allDone = true; break; } } } } } // Delete the files DeleteImages deleteImagesDialog = new DeleteImages(this, this.DataHandler.FileDatabase, this.DataHandler.ImageCache, filesToDelete, deleteFiles, deleteData, deleteCurrentImageOnly); bool? result = deleteImagesDialog.ShowDialog(); if (result == true) { Mouse.OverrideCursor = Cursors.Wait; // Reload the file datatable. await this.FilesSelectAndShowAsync(currentFileID, this.DataHandler.FileDatabase.ImageSet.FileSelection).ConfigureAwait(true); if (deleteData) { // Find and show the image closest to the last one shown if (this.DataHandler.FileDatabase.CountAllCurrentlySelectedFiles > 0) { int nextImageRow = this.DataHandler.FileDatabase.GetFileOrNextFileIndex(currentFileID); this.FileShow(nextImageRow); } else { // No images left, so disable everything this.EnableOrDisableMenusAndControls(); } } else { // display the updated properties on the current image, or the closest one to it. int nextImageRow = this.DataHandler.FileDatabase.FindClosestImageRow(currentFileID); this.FileShow(nextImageRow); } Mouse.OverrideCursor = null; } }