public DateTimeRereadFromFiles(FileDatabase database, Window owner) { this.InitializeComponent(); Utilities.TryFitWindowInWorkingArea(this); this.database = database; this.Owner = owner; }
public DateCorrectAmbiguous(FileDatabase database, Window owner) { this.InitializeComponent(); this.ambiguousDatesList = new List<AmbiguousDate>(); this.database = database; this.displayingPreview = false; this.Owner = owner; // set callbacks in code behind to avoid invoking callbacks when the dialog is created this.OriginalDate.Checked += this.DateBox_Checked; this.SwappedDate.Checked += this.DateBox_Checked; // find the ambiguous dates in the current selection if (this.FindAllAmbiguousDatesInSelectedImages() == true) { this.Abort = false; } else { this.Abort = true; } // Start displaying from the first ambiguous date. this.ambiguousDatesListIndex = 0; }
public DataEntryHandler(FileDatabase fileDatabase) { this.disposed = false; this.ImageCache = new ImageCache(fileDatabase); this.FileDatabase = fileDatabase; this.IsProgrammaticControlUpdate = false; }
public AdvancedImageSetOptions(FileDatabase database, Window owner) { this.InitializeComponent(); this.Owner = owner; this.database = database; this.currentImageSetTimeZone = database.ImageSet.GetTimeZone(); this.TimeZones.SelectTimeZone(this.currentImageSetTimeZone); }
public ImageCache(FileDatabase fileDatabase) : base(fileDatabase) { this.CurrentDifferenceState = ImageDifference.Unaltered; this.differenceBitmapCache = new Dictionary<ImageDifference, BitmapSource>(); this.mostRecentlyUsedIDs = new MostRecentlyUsedList<long>(Constant.Images.BitmapCacheSize); this.prefetechesByID = new ConcurrentDictionary<long, Task>(); this.unalteredBitmapsByID = new ConcurrentDictionary<long, BitmapSource>(); }
public DarkImagesThreshold(FileDatabase database, int currentImageIndex, CarnassialUserRegistrySettings state, Window owner) { this.InitializeComponent(); this.Owner = owner; this.database = database; this.imageEnumerator = new FileTableEnumerator(database, currentImageIndex); this.darkPixelThreshold = state.DarkPixelThreshold; this.darkPixelRatio = state.DarkPixelRatioThreshold; this.darkPixelRatioFound = 0; this.disposed = false; this.isColor = false; this.updateImageQualityForAllSelectedImagesStarted = false; this.stop = false; this.userSettings = state; }
public DateTimeFixedCorrection(FileDatabase fileDatabase, ImageRow fileToDisplay, Window owner) { this.InitializeComponent(); this.displayingPreview = false; this.fileDatabase = fileDatabase; this.fileToDisplay = fileToDisplay; this.Owner = owner; // get the image filename and display it this.FileName.Content = fileToDisplay.FileName; this.FileName.ToolTip = this.FileName.Content; // configure datetime picker this.initialDateTime = fileToDisplay.GetDateTime(); this.OriginalDate.Content = DateTimeHandler.ToDisplayDateTimeString(this.initialDateTime); this.DateTimePicker.Value = this.initialDateTime; this.DateTimePicker.ValueChanged += this.DateTimePicker_ValueChanged; }
public DateTimeSetTimeZone(FileDatabase fileDatabase, ImageRow fileToDisplay, Window owner) { this.InitializeComponent(); this.displayingPreview = false; this.fileDatabase = fileDatabase; this.fileToDisplay = fileToDisplay; this.Owner = owner; // get the file's current time DateTimeOffset currentDateTime = fileToDisplay.GetDateTime(); this.OriginalDate.Content = DateTimeHandler.ToDisplayDateTimeUtcOffsetString(currentDateTime); // get the filename and display it this.FileName.Content = fileToDisplay.FileName; // configure timezone picker this.TimeZones.SelectTimeZone(this.fileDatabase.ImageSet.GetTimeZone()); this.TimeZones.SelectionChanged += this.TimeZones_SelectionChanged; }
public void CreateControls(FileDatabase database, DataEntryHandler dataEntryPropagator) { // Depending on how the user interacts with the file import process image set loading can be aborted after controls are generated and then // another image set loaded. Any existing controls therefore need to be cleared. this.ControlGrid.Children.Clear(); this.Controls.Clear(); this.ControlsByDataLabel.Clear(); DataEntryDateTime dateTimeControl = null; DataEntryUtcOffset utcOffsetControl = null; List<DataEntryControl> visibleControls = new List<DataEntryControl>(); foreach (ControlRow control in database.Controls) { // no point in generating a control if it doesn't render in the UX if (control.Visible == false) { continue; } if (control.Type == Constant.DatabaseColumn.DateTime) { dateTimeControl = new DataEntryDateTime(control, this); visibleControls.Add(dateTimeControl); } else if (control.Type == Constant.DatabaseColumn.File || control.Type == Constant.DatabaseColumn.RelativePath || control.Type == Constant.Control.Note) { // standard controls rendering as notes aren't editable by the user List<string> autocompletions = null; bool readOnly = control.Type != Constant.Control.Note; if (readOnly == false) { autocompletions = new List<string>(database.GetDistinctValuesInFileDataColumn(control.DataLabel)); } DataEntryNote noteControl = new DataEntryNote(control, autocompletions, this); noteControl.ContentReadOnly = readOnly; visibleControls.Add(noteControl); } else if (control.Type == Constant.Control.Flag || control.Type == Constant.DatabaseColumn.DeleteFlag) { DataEntryFlag flagControl = new DataEntryFlag(control, this); visibleControls.Add(flagControl); } else if (control.Type == Constant.Control.Counter) { DataEntryCounter counterControl = new DataEntryCounter(control, this); visibleControls.Add(counterControl); } else if (control.Type == Constant.Control.FixedChoice || control.Type == Constant.DatabaseColumn.ImageQuality) { DataEntryChoice choiceControl = new DataEntryChoice(control, this); visibleControls.Add(choiceControl); } else if (control.Type == Constant.DatabaseColumn.UtcOffset) { utcOffsetControl = new DataEntryUtcOffset(control, this); visibleControls.Add(utcOffsetControl); } else { Debug.Fail(String.Format("Unhandled control type {0}.", control.Type)); continue; } } if ((dateTimeControl != null) && (utcOffsetControl != null)) { dateTimeControl.ShowUtcOffset(); visibleControls.Remove(utcOffsetControl); } foreach (DataEntryControl control in visibleControls) { this.ControlGrid.Children.Add(control.Container); this.Controls.Add(control); this.ControlsByDataLabel.Add(control.DataLabel, control); } dataEntryPropagator.SetDataEntryCallbacks(this.ControlsByDataLabel); }
private async Task CheckDifferenceResult(ImageDifferenceResult result, ImageCache cache, FileDatabase fileDatabase) { BitmapSource currentBitmap = cache.GetCurrentImage(); switch (result) { case ImageDifferenceResult.CurrentImageNotAvailable: case ImageDifferenceResult.NextImageNotAvailable: case ImageDifferenceResult.PreviousImageNotAvailable: if (cache.CurrentDifferenceState == ImageDifference.Unaltered) { Assert.IsNotNull(currentBitmap); } else { Assert.IsNull(currentBitmap); } break; case ImageDifferenceResult.NotCalculable: bool expectNullBitmap = false; int previousNextImageRow = -1; int otherImageRowForCombined = -1; switch (cache.CurrentDifferenceState) { // as a default assume images are matched and expect differences to be calculable if the necessary images are available case ImageDifference.Combined: expectNullBitmap = (cache.CurrentRow == 0) || (cache.CurrentRow == fileDatabase.CurrentlySelectedFileCount - 1); previousNextImageRow = cache.CurrentRow - 1; otherImageRowForCombined = cache.CurrentRow + 1; break; case ImageDifference.Next: expectNullBitmap = cache.CurrentRow == fileDatabase.CurrentlySelectedFileCount - 1; previousNextImageRow = cache.CurrentRow + 1; break; case ImageDifference.Previous: expectNullBitmap = cache.CurrentRow == 0; previousNextImageRow = cache.CurrentRow - 1; break; case ImageDifference.Unaltered: // result should be NotCalculable on Unaltered expectNullBitmap = true; return; } // check if the image to diff against is matched if (fileDatabase.IsFileRowInRange(previousNextImageRow)) { WriteableBitmap unalteredBitmap = (await cache.Current.LoadBitmapAsync(fileDatabase.FolderPath)).AsWriteable(); ImageRow previousNextImage = fileDatabase.Files[previousNextImageRow]; WriteableBitmap previousNextBitmap = (await previousNextImage.LoadBitmapAsync(fileDatabase.FolderPath)).AsWriteable(); bool mismatched = WriteableBitmapExtensions.BitmapsMismatchedOrNot24BitRgb(unalteredBitmap, previousNextBitmap); if (fileDatabase.IsFileRowInRange(otherImageRowForCombined)) { ImageRow otherImageForCombined = fileDatabase.Files[otherImageRowForCombined]; WriteableBitmap otherBitmapForCombined = (await otherImageForCombined.LoadBitmapAsync(fileDatabase.FolderPath)).AsWriteable(); mismatched |= WriteableBitmapExtensions.BitmapsMismatchedOrNot24BitRgb(unalteredBitmap, otherBitmapForCombined); } expectNullBitmap |= mismatched; } if (expectNullBitmap) { Assert.IsNull(currentBitmap, "Expected a null bitmap for difference result {0} and state {1}.", result, cache.CurrentDifferenceState); } else { Assert.IsNotNull(currentBitmap, "Expected a bitmap for difference result {0} and state {1}.", result, cache.CurrentDifferenceState); } break; case ImageDifferenceResult.Success: Assert.IsNotNull(currentBitmap); break; default: throw new NotSupportedException(String.Format("Unhandled result {0}.", result)); } }
public DateTimeLinearCorrection(FileDatabase fileDatabase, Window owner) { this.InitializeComponent(); this.Abort = false; this.Owner = owner; this.displayingPreview = false; this.earliestFileDateTimeUncorrected = DateTime.MaxValue.ToUniversalTime(); this.latestFileDateTimeUncorrected = DateTime.MinValue.ToUniversalTime(); this.fileDatabase = fileDatabase; this.earliestFile = null; this.latestFile = null; bool foundEarliest = false; bool foundLatest = false; foreach (ImageRow file in fileDatabase.Files) { DateTimeOffset fileDateTime = file.GetDateTime(); if (fileDateTime >= this.latestFileDateTimeUncorrected) { this.latestFile = file; this.latestFileDateTimeUncorrected = fileDateTime; foundLatest = true; } if (fileDateTime <= this.earliestFileDateTimeUncorrected) { this.earliestFile = file; this.earliestFileDateTimeUncorrected = fileDateTime; foundEarliest = true; } } if ((foundEarliest == false) || (foundLatest == false)) { this.Abort = true; return; } // configure earliest and latest images // Images proper are loaded in Window_Loaded(). this.EarliestImageFileName.Content = this.earliestFile.FileName; this.EarliestImageFileName.ToolTip = this.EarliestImageFileName.Content; this.LatestImageFileName.Content = this.latestFile.FileName; this.LatestImageFileName.ToolTip = this.LatestImageFileName.Content; // configure interval this.ClockLastCorrect.Maximum = this.earliestFileDateTimeUncorrected; this.ClockLastCorrect.Value = this.earliestFileDateTimeUncorrected; this.ClockLastCorrect.ValueChanged += this.Interval_ValueChanged; this.ClockDriftMeasured.Minimum = this.latestFileDateTimeUncorrected; this.ClockDriftMeasured.Value = this.latestFileDateTimeUncorrected; this.ClockDriftMeasured.ValueChanged += this.Interval_ValueChanged; // configure adjustment this.ClockDrift.Value = this.ClockDrift.Value; this.ClockDrift.ValueChanged += this.ClockDrift_ValueChanged; // show image times this.RefreshImageTimes(); }
protected Dictionary<string, string> LoadMetadata(FileDatabase fileDatabase, FileExpectations fileExpectation) { string filePath = Path.Combine(this.WorkingDirectory, fileExpectation.RelativePath, fileExpectation.FileName); Dictionary<string, string> metadata = Utilities.LoadMetadata(filePath); Assert.IsTrue(metadata.Count > 40, "Expected at least 40 metadata fields to be retrieved from {0}", filePath); // example information returned from ExifTool // field name Bushnell Reconyx // --- fields of likely interest for image analysis --- // Create Date 2016.02.24 04:59:46 [Bushnell only] // Date/Time Original 2016.02.24 04:59:46 2015.01.28 11:17:34 [but located in Makernote rather than the standard EXIF field!] // Modify Date 2016.02.24 04:59:46 [Bushnell only] // --- fields possibly of interest interest for image analysis --- // Exposure Time 0 1/84 // Shutter Speed 0 1/84 // Software BS683BWYx05209 [Bushnell only] // Firmware Version [Reconyx only] 3.3.0 // Trigger Mode [Reconyx only] Motion Detection // Sequence [Reconyx only] 1 of 5 // Ambient Temperature [Reconyx only] 0 C // Serial Number [Reconyx only] H500DE01120343 // Infrared Illuminator [Reconyx only] Off // User Label [Reconyx only] CCPF DS02 // --- fields of little interest (Bushnell often uses placeholder values which don't change) --- // ExifTool Version Number 10.14 10.14 // File Name BushnellTrophyHD-119677C-20160224-056.JPG Reconyx-HC500-20150128-201.JPG // Directory Carnassial/UnitTests/bin/Debug Carnassial/UnitTests/bin/Debug/CarnivoreTestImages // File Size 731 kB 336 kB // File Modification Date/Time <file time from last build> <file time from last build> // File Access Date/Time <file time from last build> <file time from last build> // File Creation Date/Time <file time from last build> <file time from last build> // File Permissions rw-rw-rw- rw-rw-rw- // File Type JPEG JPEG // File Type Extension jpg jpg // MIME Type image/jpeg image/jpeg // Exif Byte Order Little-endian(Intel, II) Little-endian(Intel, II) // Image Description M2E6L0-0R350B362 [Bushnell only] // Make [blank] [Bushnell only] // Camera Model Name [blank] [Bushnell only] // Orientation Horizontal(normal) [Bushnell only] // X Resolution 96 72 // Y Resolution 96 72 // Resolution Unit inches inches // Y Cb Cr Positioning Co-sited Co-sited // Copyright Copyright 2002 [Bushnell only] // F Number 2.8 [Bushnell only] // Exposure Program Aperture-priority AE [Bushnell only] // ISO 100 50 // Exif Version 0210 0220 // Components Configuration Y, Cb, Cr, - Y, Cb, Cr, - // Compressed Bits Per Pixel 0.7419992711 [Bushnell only] // Shutter Speed Value 1 [Bushnell only] // Aperture Value 2.6 [Bushnell only] // Exposure Compensation +2 [Bushnell only] // Max Aperture Value 2.6 [Bushnell only] // Metering Mode Average [Bushnell only] // Light Source Daylight [Bushnell only] // Flash No Flash [Bushnell only] // Warning [minor]Unrecognized MakerNotes [Bushnell only] // Flashpix Version 0100 0100 // Color Space sRGB sRGB // Exif Image Width 3264 2048 // Exif Image Height 2448 1536 // Related Sound File RelatedSound [Bushnell only] // Interoperability Index R98 - DCF basic file(sRGB) [Bushnell only] // Interoperability Version 0100 [Bushnell only] // Exposure Index 1 [Bushnell only] // Sensing Method One-chip color area [Bushnell only] // File Source Digital Camera [Bushnell only] // Scene Type Directly photographed [Bushnell only] // Compression JPEG(old - style) [Bushnell only] // Thumbnail Offset 1312 [Bushnell only] // Thumbnail Length 5768 [Bushnell only] // Image Width 3264 2048 // Image Height 2448 1536 // Encoding Process Baseline DCT, Huffman coding Baseline DCT, Huffman coding // Bits Per Sample 8 8 // Color Components 3 3 // Y Cb Cr Sub Sampling YCbCr4:2:2 (2 1) YCbCr4:2:2 (2 1) // Aperture 2.8 [Bushnell only] // Image Size 3264x2448 2048x1536 // Megapixels 8.0 3.1 // Thumbnail Image <binary data> [Bushnell only] // Ambient Temperature Fahrenheit [Reconyx only] 31 F // Battery Voltage [Reconyx only] 8.65 V // Contrast [Reconyx only] 142 // Brightness [Reconyx only] 238 // Event Number [Reconyx only] 39 // Firmware Date [Reconyx only] 2011:01:10 // Maker Note Version [Reconyx only] 0xf101 // Moon Phase [Reconyx only] First Quarter // Motion Sensitivity [Reconyx only] 100 // Sharpness [Reconyx only] 64 // Saturation [Reconyx only] 144 return metadata; }
protected List<FileExpectations> PopulateDefaultDatabase(FileDatabase fileDatabase, bool excludeSubfolderFiles) { TimeZoneInfo imageSetTimeZone = fileDatabase.ImageSet.GetTimeZone(); // files in same folder as .tdb and .ddb DateTimeAdjustment martenDateTimeAdjustment; ImageRow martenImage = this.CreateFile(fileDatabase, imageSetTimeZone, TestConstant.FileExpectation.InfraredMarten, out martenDateTimeAdjustment); Assert.IsTrue(martenDateTimeAdjustment.HasFlag(DateTimeAdjustment.MetadataDate) && martenDateTimeAdjustment.HasFlag(DateTimeAdjustment.MetadataTime)); DateTimeAdjustment bobcatDatetimeAdjustment; ImageRow bobcatImage = this.CreateFile(fileDatabase, imageSetTimeZone, TestConstant.FileExpectation.DaylightBobcat, out bobcatDatetimeAdjustment); Assert.IsTrue(bobcatDatetimeAdjustment.HasFlag(DateTimeAdjustment.MetadataDate) && bobcatDatetimeAdjustment.HasFlag(DateTimeAdjustment.MetadataTime)); fileDatabase.AddFiles(new List<ImageRow>() { martenImage, bobcatImage }, null); fileDatabase.SelectFiles(FileSelection.All); FileTableEnumerator fileEnumerator = new FileTableEnumerator(fileDatabase); Assert.IsTrue(fileEnumerator.TryMoveToFile(0)); Assert.IsTrue(fileEnumerator.MoveNext()); ColumnTuplesWithWhere bobcatUpdate = new ColumnTuplesWithWhere(); bobcatUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.Choice0, "choice b")); bobcatUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.Counter0, 1.ToString())); bobcatUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.FlagNotVisible, true)); bobcatUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.Note3, "bobcat")); bobcatUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.NoteNotVisible, "adult")); bobcatUpdate.SetWhere(fileEnumerator.Current.ID); fileDatabase.UpdateFiles(new List<ColumnTuplesWithWhere>() { bobcatUpdate }); long martenImageID = fileDatabase.Files[0].ID; fileDatabase.UpdateFile(martenImageID, TestConstant.DefaultDatabaseColumn.Choice0, "choice b"); fileDatabase.UpdateFile(martenImageID, TestConstant.DefaultDatabaseColumn.Counter0, 1.ToString()); fileDatabase.UpdateFile(martenImageID, TestConstant.DefaultDatabaseColumn.FlagNotVisible, Boolean.TrueString); fileDatabase.UpdateFile(martenImageID, TestConstant.DefaultDatabaseColumn.Note3, "American marten"); fileDatabase.UpdateFile(martenImageID, TestConstant.DefaultDatabaseColumn.NoteNotVisible, "adult"); // generate expectations List<FileExpectations> fileExpectations = new List<FileExpectations>() { new FileExpectations(TestConstant.FileExpectation.InfraredMarten), new FileExpectations(TestConstant.FileExpectation.DaylightBobcat), }; // files in subfolder if (excludeSubfolderFiles == false) { DateTimeAdjustment martenPairDateTimeAdjustment; ImageRow martenPairImage = this.CreateFile(fileDatabase, imageSetTimeZone, TestConstant.FileExpectation.DaylightMartenPair, out martenPairDateTimeAdjustment); Assert.IsTrue(martenPairDateTimeAdjustment.HasFlag(DateTimeAdjustment.MetadataDate) && martenPairDateTimeAdjustment.HasFlag(DateTimeAdjustment.MetadataTime)); DateTimeAdjustment coyoteDatetimeAdjustment; ImageRow coyoteImage = this.CreateFile(fileDatabase, imageSetTimeZone, TestConstant.FileExpectation.DaylightCoyote, out coyoteDatetimeAdjustment); Assert.IsTrue(coyoteDatetimeAdjustment.HasFlag(DateTimeAdjustment.MetadataDate) && coyoteDatetimeAdjustment.HasFlag(DateTimeAdjustment.MetadataTime)); fileDatabase.AddFiles(new List<ImageRow>() { martenPairImage, coyoteImage }, null); fileDatabase.SelectFiles(FileSelection.All); ColumnTuplesWithWhere coyoteImageUpdate = new ColumnTuplesWithWhere(); coyoteImageUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.Note3, "coyote")); coyoteImageUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.NoteNotVisible, "adult")); coyoteImageUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.NoteWithCustomDataLabel, String.Empty)); coyoteImageUpdate.Columns.Add(new ColumnTuple(TestConstant.DefaultDatabaseColumn.Note0, "escaped field, because a comma is present")); coyoteImageUpdate.SetWhere(fileEnumerator.Current.ID); fileDatabase.UpdateFiles(new List<ColumnTuplesWithWhere>() { coyoteImageUpdate }); long martenPairImageID = fileDatabase.Files[3].ID; fileDatabase.UpdateFile(martenPairImageID, TestConstant.DefaultDatabaseColumn.Note3, "American marten"); fileDatabase.UpdateFile(martenPairImageID, TestConstant.DefaultDatabaseColumn.NoteNotVisible, "adult"); fileDatabase.UpdateFile(martenPairImageID, TestConstant.DefaultDatabaseColumn.NoteWithCustomDataLabel, String.Empty); fileDatabase.UpdateFile(martenPairImageID, TestConstant.DefaultDatabaseColumn.Note0, "escaped field due to presence of \",\""); fileExpectations.Add(new FileExpectations(TestConstant.FileExpectation.DaylightMartenPair)); fileExpectations.Add(new FileExpectations(TestConstant.FileExpectation.DaylightCoyote)); } // pull the file data table again so the updates are visible to .csv export fileDatabase.SelectFiles(FileSelection.All); // complete setting expectations for (int fileIndex = 0; fileIndex < fileDatabase.Files.RowCount; ++fileIndex) { FileExpectations fileExpectation = fileExpectations[fileIndex]; fileExpectation.ID = fileIndex + 1; } return fileExpectations; }
private void VerifyDefaultImageSet(FileDatabase fileDatabase) { // InitialFolderName - current directory case occurs when the test creates a new file database, UnitTests case when the default .ddb is cloned Assert.IsTrue(fileDatabase.ImageSet.FileSelection == FileSelection.All); Assert.IsTrue((fileDatabase.ImageSet.InitialFolderName == Path.GetFileName(Environment.CurrentDirectory)) || (fileDatabase.ImageSet.InitialFolderName == "UnitTests")); Assert.IsTrue(fileDatabase.ImageSet.MostRecentFileID == Constant.Database.DefaultFileID); Assert.IsTrue(fileDatabase.ImageSet.Log == Constant.Database.ImageSetDefaultLog); Assert.IsFalse(fileDatabase.ImageSet.Options.HasFlag(ImageSetOptions.Magnifier)); Assert.IsTrue(fileDatabase.ImageSet.TimeZone == TimeZoneInfo.Local.Id); }
public ImageRow GetFileData(FileDatabase fileDatabase) { string imageFilePath; if (String.IsNullOrEmpty(this.RelativePath)) { imageFilePath = Path.Combine(fileDatabase.FolderPath, this.FileName); } else { imageFilePath = Path.Combine(fileDatabase.FolderPath, this.RelativePath, this.FileName); } TimeZoneInfo imageSetTimeZone = fileDatabase.ImageSet.GetTimeZone(); ImageRow imageProperties; fileDatabase.GetOrCreateFile(new FileInfo(imageFilePath), imageSetTimeZone, out imageProperties); // imageProperties.Date is defaulted by constructor // imageProperties.DateTime is defaulted by constructor // imageProperties.FileName is set by constructor // imageProperties.ID is set when images are refreshed after being added to the database // imageProperties.ImageQuality is defaulted by constructor // imageProperties.ImageTaken is set by constructor // imageProperties.InitialRootFolderName is set by constructor // imageProperties.RelativePath is set by constructor // imageProperties.Time is defaulted by constructor return imageProperties; }
/// <summary> /// Ask the user if he/she wants to delete one or more files and (depending on whether deleteData is set) the data associated with those files. /// Other parameters indicate various specifics of how the deletion was specified, which also determines what is displayed in the interface: /// </summary> public DeleteFiles(FileDatabase database, List<ImageRow> filesToDelete, bool deleteFileAndData, bool deleteCurrentFileOnly, Window owner) { this.InitializeComponent(); this.deleteFileAndData = deleteFileAndData; this.fileDatabase = database; this.filesToDelete = filesToDelete; this.Owner = owner; this.ThumbnailList.ItemsSource = this.filesToDelete; this.ThumbnailList.View = this.GetFileGridView(); if (this.deleteFileAndData) { this.OkButton.IsEnabled = false; } else { this.OkButton.IsEnabled = true; this.Confirm.Visibility = Visibility.Collapsed; } // construct the dialog's text based on the state of the flags if (deleteCurrentFileOnly) { string imageOrVideo = filesToDelete[0].IsVideo ? "video" : "image"; if (deleteFileAndData == false) { // Case 1: Delete the current image, but not its data. this.Message.Title = String.Format("Delete the current {0} but not its data?", imageOrVideo); this.Message.What = String.Format("Deletes the current {0} (shown below) but not its data.", imageOrVideo); this.Message.Result = String.Format("\u2022 The deleted {0} will be backed up in a sub-folder named {1}.{2}", imageOrVideo, Constant.File.DeletedFilesFolder, Environment.NewLine); this.Message.Result += String.Format("\u2022 A placeholder {0} will be shown when you try to view a deleted {0}.", imageOrVideo); this.Message.Hint = String.Format("\u2022 Restore the deleted {0} by manually moving it back to its original location, or{1}", imageOrVideo, Environment.NewLine); this.Message.Hint += String.Format("\u2022 Permanently delete the {0} by deleting it from the {1} folder.", imageOrVideo, Constant.File.DeletedFilesFolder); } else { // Case 2: Delete the current image and its data this.Message.Title = String.Format("Delete the current {0} and its data", imageOrVideo); this.Message.What = String.Format("Deletes the current {0} (shown below) and the data associated with that {0}.", imageOrVideo); this.Message.Result = String.Format("\u2022 The deleted {0} will be backed up in a sub-folder named {1}.{2}", imageOrVideo, Constant.File.DeletedFilesFolder, Environment.NewLine); this.Message.Result += String.Format("\u2022 However, the data associated with that {0} will be permanently deleted.", imageOrVideo); this.Message.Hint = String.Format("You can permanently delete the {0} by deleting it from the {1} folder.", imageOrVideo, Constant.File.DeletedFilesFolder); } } else { int numberOfFilesToDelete = this.filesToDelete.Count; this.Message.Title = "Delete " + numberOfFilesToDelete.ToString() + " images and videos marked for deletion in this selection?"; this.Message.Result = String.Empty; if (numberOfFilesToDelete > Constant.Images.LargeNumberOfDeletedImages) { this.Message.Result += "Deleting " + numberOfFilesToDelete.ToString() + " files will take a few moments. Please be patient." + Environment.NewLine; } this.Message.Result += String.Format("\u2022 The deleted files will be backed up in a sub-folder named {0}.{1}", Constant.File.DeletedFilesFolder, Environment.NewLine); if (deleteFileAndData == false) { // Case 3: Delete files which the delete flag set but not their data this.Message.What = "Deletes " + numberOfFilesToDelete.ToString() + " images and videos marked for deletion (shown below) in this selection, but not the data entered for them."; this.Message.Result += "\u2022 A placeholder image will be shown when you view a deleted file."; this.Message.Hint = "\u2022 Restore deleted files by manually copying or moving them back to their original location, or" + Environment.NewLine; this.Message.Hint += String.Format("\u2022 Permanently delete the files by deleting them from the {0} folder", Constant.File.DeletedFilesFolder); } else { // Case 4: Delete files which have the delete flag set and their data this.Message.Title = "Delete " + numberOfFilesToDelete.ToString() + " images and videos marked for deletion"; this.Message.What = "Deletes images and videos marked for deletion (shown below), along with the data entered for them."; this.Message.Result += "\u2022 The data for these files will be permanently deleted."; this.Message.Hint = String.Format("You can permanently delete the files by deleting the {0} folder.", Constant.File.DeletedFilesFolder); } } this.Title = this.Message.Title; }
/// <summary> /// Creates a data row from the specified FileExpectation. Verifies the file isn't already in the database and does not add it to the database. /// </summary> protected ImageRow CreateFile(FileDatabase fileDatabase, TimeZoneInfo imageSetTimeZone, FileExpectations fileExpectation, out DateTimeAdjustment dateTimeAdjustment) { FileInfo fileInfo = new FileInfo(Path.Combine(this.WorkingDirectory, fileExpectation.RelativePath, fileExpectation.FileName)); ImageRow file; Assert.IsFalse(fileDatabase.GetOrCreateFile(fileInfo, imageSetTimeZone, out file)); dateTimeAdjustment = file.TryReadDateTimeOriginalFromMetadata(fileDatabase.FolderPath, imageSetTimeZone); return file; }
public static bool TryCreateOrOpen(string filePath, TemplateDatabase templateDatabase, bool orderFilesByDate, CustomSelectionOperator customSelectionTermCombiningOperator, out FileDatabase fileDatabase) { // check for an existing database before instantiating the databse as SQL wrapper instantiation creates the database file bool populateDatabase = !File.Exists(filePath); fileDatabase = new FileDatabase(filePath); if (populateDatabase) { // initialize the database if it's newly created fileDatabase.OnDatabaseCreated(templateDatabase); } else { // if it's an existing database check if it needs updating to current structure and load data tables if (fileDatabase.OnExistingDatabaseOpened(templateDatabase) == false) { return false; } } // ensure all tables have been loaded from the database if (fileDatabase.ImageSet == null) { fileDatabase.GetImageSet(); } if (fileDatabase.Markers == null) { fileDatabase.GetMarkers(); } fileDatabase.CustomSelection = new CustomSelection(fileDatabase.Controls, customSelectionTermCombiningOperator); fileDatabase.OrderFilesByDateTime = orderFilesByDate; fileDatabase.PopulateDataLabelMaps(); return true; }
private void VerifyDefaultMarkerTableContent(FileDatabase fileDatabase, int filesExpected) { DataTable markers = fileDatabase.Markers.ExtractDataTable(); List<string> expectedColumns = new List<string>() { Constant.DatabaseColumn.ID }; foreach (ControlRow control in fileDatabase.Controls) { if (control.Type == Constant.Control.Counter) { expectedColumns.Add(control.DataLabel); } } Assert.IsTrue(markers.Columns.Count == expectedColumns.Count); for (int column = 0; column < expectedColumns.Count; ++column) { Assert.IsTrue(expectedColumns[column] == markers.Columns[column].ColumnName, "Expected column named '{0}' but found '{1}'.", expectedColumns[column], markers.Columns[column].ColumnName); } if (expectedColumns.Count == TestConstant.DefaultMarkerColumns.Count) { for (int column = 0; column < expectedColumns.Count; ++column) { Assert.IsTrue(expectedColumns[column] == TestConstant.DefaultMarkerColumns[column], "Expected column named '{0}' but found '{1}'.", expectedColumns[column], TestConstant.DefaultMarkerColumns[column]); } } // marker rows aren't populated if no counters are present in the database if (expectedColumns.Count == 1) { Assert.IsTrue(fileDatabase.Markers.RowCount == 0); } else { Assert.IsTrue(fileDatabase.Markers.RowCount == filesExpected); } }
private void VerifyFiles(FileDatabase fileDatabase, List<FileExpectations> imageExpectations, TimeZoneInfo initialImageSetTimeZone, int initialImageCount, TimeZoneInfo secondImageSetTimeZone) { for (int image = 0; image < imageExpectations.Count; ++image) { TimeZoneInfo expectedTimeZone = image >= initialImageCount ? secondImageSetTimeZone : initialImageSetTimeZone; FileExpectations imageExpectation = imageExpectations[image]; imageExpectation.Verify(fileDatabase.Files[image], expectedTimeZone); } }
protected List<FileExpectations> PopulateDefaultDatabase(FileDatabase fileDatabase) { return this.PopulateDefaultDatabase(fileDatabase, false); }