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;
        }
        private bool TryGetFile(int fileRow, out ImageRow file)
        {
            if (fileRow == this.CurrentRow)
            {
                file = this.Current;
                return true;
            }

            if (this.Database.IsFileRowInRange(fileRow) == false)
            {
                file = null;
                return false;
            }

            file = this.Database.Files[fileRow];
            return file.IsDisplayable();
        }
        private async Task<BitmapSource> TryGetBitmapAsync(ImageRow file, bool suppressPrefetch)
        {
            // locate the requested bitmap
            BitmapSource bitmap;
            if (this.unalteredBitmapsByID.TryGetValue(file.ID, out bitmap) == false)
            {
                Task prefetch;
                if (this.prefetechesByID.TryGetValue(file.ID, out prefetch))
                {
                    // bitmap retrieval's already in progress, so wait for it to complete
                    await prefetch;
                    bitmap = this.unalteredBitmapsByID[file.ID];
                }
                else
                {
                    // load the requested bitmap from disk as it isn't cached, doesn't have a prefetch running, and is needed right now by the caller
                    bitmap = await file.LoadBitmapAsync(this.Database.FolderPath);
                    this.CacheBitmap(file.ID, bitmap);
                }
            }

            // start prefetches of nearby bitmaps if requested
            if (suppressPrefetch == false)
            {
                // assuming a sequential forward scan order the next file is the most likely to be requested
                this.TryInitiateBitmapPrefetch(this.CurrentRow + 1);
            }
            return bitmap;
        }
        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();
        }
 public UndoRedoState(ImageRow file)
 {
     this.Type = UndoRedoType.FileValues;
     this.Values = file.AsDictionary();
 }
        public void Verify(ImageRow file, TimeZoneInfo timeZone)
        {
            // this.DarkPixelFraction isn't applicable
            Assert.IsTrue(file.DateTime.Kind == DateTimeKind.Utc);
            Assert.IsTrue(file.DeleteFlag == this.DeleteFlag);
            Assert.IsTrue(file.FileName == this.FileName, "{0}: Expected FileName '{1}' but found '{2}'.", this.FileName, this.FileName, file.FileName);
            Assert.IsTrue(file.ID == this.ID, "{0}: Expected ID '{1}' but found '{2}'.", this.FileName, this.ID, file.ID);
            Assert.IsTrue(file.ImageQuality == this.Quality, "{0}: Expected ImageQuality '{1}' but found '{2}'.", this.FileName, this.Quality, file.ImageQuality);
            // this.IsColor isn't applicable
            Assert.IsTrue(file.RelativePath == this.RelativePath, "{0}: Expected RelativePath '{1}' but found '{2}'.", this.FileName, this.RelativePath, file.RelativePath);
            // this.UserDefinedColumnsByDataLabel isn't current applicable

            // bypass checking of Date and Time properties if requested, for example if the camera didn't generate image taken metadata
            if (this.SkipDateTimeVerification == false)
            {
                DateTimeOffset imageDateTime = file.GetDateTime();
                DateTimeOffset expectedDateTime = this.ConvertDateTimeToTimeZone(timeZone);
                Assert.IsTrue(imageDateTime.UtcDateTime == expectedDateTime.UtcDateTime, "{0}: Expected date time '{1}' but found '{2}'.", this.FileName, DateTimeHandler.ToDatabaseDateTimeString(expectedDateTime), DateTimeHandler.ToDatabaseDateTimeString(imageDateTime.UtcDateTime));
                Assert.IsTrue(imageDateTime.Offset == expectedDateTime.Offset, "{0}: Expected date time offset '{1}' but found '{2}'.", this.FileName, expectedDateTime.Offset, imageDateTime.Offset);
                Assert.IsTrue(file.DateTime == expectedDateTime.UtcDateTime, "{0}: Expected DateTime '{1}' but found '{2}'.", this.FileName, DateTimeHandler.ToDatabaseDateTimeString(expectedDateTime), DateTimeHandler.ToDatabaseDateTimeString(file.DateTime));
                Assert.IsTrue(file.UtcOffset == expectedDateTime.Offset, "{0}: Expected UtcOffset '{1}' but found '{2}'.", this.FileName, expectedDateTime.Offset, file.UtcOffset);
            }
        }
        private bool TryGetFile(string relativePath, string fileName, out ImageRow file)
        {
            ColumnTuplesWithWhere fileQuery = new ColumnTuplesWithWhere();
            fileQuery.SetWhere(relativePath, fileName);
            List<ImageRow> files = this.Files.Select(fileQuery.Where);
            if (files.Count == 0)
            {
                file = null;
                return false;
            }
            if (files.Count == 1)
            {
                file = files[0];
                return true;
            }

            throw new ArgumentOutOfRangeException("relativePath, fileName", String.Format("{0} files match '{1}'.", files.Count, fileQuery.Where));
        }
        public void UpdateFiles(ImageRow valueSource, DataEntryControl control, int fromIndex, int toIndex)
        {
            if (fromIndex < 0)
            {
                throw new ArgumentOutOfRangeException("fromIndex");
            }
            if (toIndex < fromIndex || toIndex > this.CurrentlySelectedFileCount - 1)
            {
                throw new ArgumentOutOfRangeException("toIndex");
            }

            string value = valueSource.GetValueDatabaseString(control.DataLabel);
            List<ColumnTuplesWithWhere> imagesToUpdate = new List<ColumnTuplesWithWhere>();
            for (int index = fromIndex; index <= toIndex; index++)
            {
                // update data table
                ImageRow image = this.Files[index];
                image.SetValueFromDatabaseString(control.DataLabel, value);

                // update database
                List<ColumnTuple> columnToUpdate = new List<ColumnTuple>() { new ColumnTuple(control.DataLabel, value) };
                ColumnTuplesWithWhere imageUpdate = new ColumnTuplesWithWhere(columnToUpdate, image.ID);
                imagesToUpdate.Add(imageUpdate);
            }

            this.CreateBackupIfNeeded();
            this.Database.Update(Constant.DatabaseTable.FileData, imagesToUpdate);
        }
 // Set one property on all rows in the selection to a given value
 public void UpdateFiles(ImageRow valueSource, DataEntryControl control)
 {
     this.UpdateFiles(valueSource, control, 0, this.CurrentlySelectedFileCount - 1);
 }
        /// <summary>
        /// Get the row matching the specified image or create a new image.  The caller is responsible to add newly created images the database and data table.
        /// </summary>
        /// <returns>true if the image is already in the database</returns>
        public bool GetOrCreateFile(FileInfo fileInfo, TimeZoneInfo imageSetTimeZone, out ImageRow file)
        {
            // GetRelativePath() includes the image's file name; remove that from the relative path as it's stored separately
            // GetDirectoryName() returns String.Empty if there's no relative path; the SQL layer treats this inconsistently, resulting in
            // DataRows returning with RelativePath = String.Empty even if null is passed despite setting String.Empty as a column default
            // resulting in RelativePath = null.  As a result, String.IsNullOrEmpty() is the appropriate test for lack of a RelativePath.
            string relativePath = NativeMethods.GetRelativePath(this.FolderPath, fileInfo.FullName);
            relativePath = Path.GetDirectoryName(relativePath);

            if (this.TryGetFile(relativePath, fileInfo.Name, out file))
            {
                return true;
            }

            file = this.Files.NewRow(fileInfo);
            file.RelativePath = relativePath;
            Debug.Assert(File.Exists(file.GetFilePath(this.FolderPath)), "Failure in ImageRow formation.");
            file.SetDateTimeOffsetFromFileInfo(this.FolderPath, imageSetTimeZone);
            return false;
        }