Esempio n. 1
0
        /// <summary> Propagate the current value of this control forward from this point across the current set of filtered images </summary>
        /// <param name="key"></param>
        public void Forward(string key, bool checkForZero)
        {
            string valueToCopy = this.dbData.RowGetValueFromDataLabel(key);
            valueToCopy = valueToCopy.Trim();

            int number_images_affected = this.dbData.dataTable.Rows.Count - this.dbData.CurrentRow - 1;

            if (number_images_affected == 0)
            {
                // Nothing to propagate. Note that we shouldn't really see this, as the menu shouldn't be highlit if we are on the last image
                // But just in case...
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.IconType = MessageBoxImage.Exclamation;
                dlgMB.ButtonType = MessageBoxButton.OK;

                dlgMB.MessageTitle = "Nothing to copy forward.";
                dlgMB.MessageReason = "As you are  on the last image, there are no other images after this.";
                dlgMB.ShowDialog();
                return;
            }
            if (this.CopyForward(valueToCopy, number_images_affected.ToString(), checkForZero) != true) return;

            // Update. Note that we start on the next row, as we are copying from the current row.
            this.dbData.RowsUpdateFromRowToRowFilteredView(key, valueToCopy, this.dbData.CurrentRow + 1, this.dbData.ImageCount - 1);
        }
        /// <summary>
        /// Export all the database data associated with the filtered view to the CSV file indicated in the file path so that spreadsheet applications (like Excel) can display it.
        /// </summary>
        /// <param name="db"></param>
        /// <param name="filepath"></param>
        public static void ExportDataAsCSV(DBData db, string filepath)
        {
            TextWriter tw = new StreamWriter(filepath, false);
            try
            {
                // Write the header as defined by the data labels in the template file
                // If the data label is an empty string, we use the label instead.
                string header = "";
                string label;
                string datalabel;
                List<string> datalabels = new List<string>();
                for (int i = 0; i < db.templateTable.Rows.Count; i++)
                {
                    label = (string)db.templateTable.Rows[i][Constants.LABEL];
                    datalabel = (string)db.templateTable.Rows[i][Constants.DATALABEL];
                    header += addColumn(getLabel(label, datalabel));

                    // get a list of datalabels so we can add columns in the order that matches the current template table order
                    if (Constants.ID != datalabel) datalabels.Add(datalabel);
                }
                tw.WriteLine(header);
                // For each row in the data table, write out the columns in the same order as the
                // data labels in the template file
                for (int i = 0; i < db.dataTable.Rows.Count; i++)
                {
                    string row = "";
                    foreach (string dataLabel in datalabels)
                    {
                        row += addColumn((string)db.dataTable.Rows[i][dataLabel]);
                    }
                    tw.WriteLine(row);
                }
            }
            catch
            {
                // Can't write the spreadsheet file
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.IconType = MessageBoxImage.Error;
                dlgMB.ButtonType = MessageBoxButton.OK;

                dlgMB.MessageTitle = "Can't write the spreadsheet file.";
                dlgMB.MessageProblem = "The following file can't be written: " + filepath + ".";
                dlgMB.MessageReason = "You may already have it open in Excel or another  application.";
                dlgMB.MessageSolution = "If the file is open in another application, close it and try again.";
                dlgMB.ShowDialog();
            }
            tw.Close();
        }
Esempio n. 3
0
        // Ask the user to confirm value propagation from the last value
        private bool? PropagateFromLastValue(String text, string number_images_affected)
        {
            text = text.Trim();
            DlgMessageBox dlgMB = new DlgMessageBox();
            dlgMB.IconType = MessageBoxImage.Question;
            dlgMB.ButtonType = MessageBoxButton.YesNo;
            dlgMB.MessageTitle = "Please confirm 'Propagate to Here' for this field.";

            dlgMB.MessageProblem = "The 'Propagate to Here' operation is not undoable, and can overwrite existing values.";
            dlgMB.MessageReason = "\u2022 The last non-empty value \u00AB" + text + "\u00BB was seen " + number_images_affected + " images back." + Environment.NewLine;
            dlgMB.MessageReason += "\u2022 That field's value will be copied across all images between that image and this one in this filtered image set";
            dlgMB.MessageResult = "If you select yes: " + Environment.NewLine;
            dlgMB.MessageResult = "\u2022 " + number_images_affected + " images will be affected.";
            return dlgMB.ShowDialog();
        }
Esempio n. 4
0
        // Ask the user to confirm value propagation from the last value
        private bool? CopyForward(String text, string number, bool checkForZero)
        {
            text = text.Trim();

            DlgMessageBox dlgMB = new DlgMessageBox();
            dlgMB.IconType = MessageBoxImage.Question;
            dlgMB.ButtonType = MessageBoxButton.YesNo;
            dlgMB.MessageTitle = "Please confirm 'Copy Forward' for this field.";

            dlgMB.MessageProblem = "The Copy Forward operation is not undoable, and can overwrite existing values.";
            dlgMB.MessageResult = "If you select yes, this operation will:" + Environment.NewLine;
            if (!checkForZero && text.Equals(""))
            {
                dlgMB.MessageResult += "\u2022 copy the (empty) value \u00AB" + text + "\u00BB in this field from here to the last image of your filtered images.";
            }
            else {
                dlgMB.MessageResult += "\u2022 copy the value \u00AB" + text + "\u00BB in this field from here to the last image of your filtered images.";
            }
            dlgMB.MessageResult += Environment.NewLine + "\u2022 over-write any existing data values in those fields";
            dlgMB.MessageResult += Environment.NewLine + "\u2022 will affect " + number + " images.";
            return (dlgMB.ShowDialog());
        }
Esempio n. 5
0
        // Ask the user to confirm value propagation
        private bool? CopyCurrentValueToAll(String text, string number, bool checkForZero)
        {
            text = text.Trim();

            DlgMessageBox dlgMB = new DlgMessageBox();
            dlgMB.IconType = MessageBoxImage.Question;
            dlgMB.ButtonType = MessageBoxButton.YesNo;
            dlgMB.MessageTitle = "Please confirm 'Copy to All' for this field.";

            dlgMB.MessageProblem = "The Copy to All operation is not undoable, and can overwrite existing values.";
            dlgMB.MessageResult = "If you select yes, this operation will:" + Environment.NewLine;
            if (!checkForZero && text.Equals(""))
            {
                dlgMB.MessageResult += "\u2022 clear this field across all " + number + " of your filtered images.";
            }
            else {
                dlgMB.MessageResult += "\u2022  set this field to \u00AB" + text + "\u00BB across all " + number + " of your filtered images.";
            }
            dlgMB.MessageResult += Environment.NewLine + "\u2022 over-write any existing data values in those fields";
            return (dlgMB.ShowDialog());
        }
Esempio n. 6
0
        // Checks for updates by comparing the current version number with a version stored on the Timelapse website in an xml file.
        public static void GetAndParseVersion(Window win, bool showNoUpdatesMessage)
        {
            Version newVersion = null;  // if a newVersion variable, we will store the version info from xml file
            string url = ""; // THE URL where the new version is located
            string changes = ""; // A list of changes held in the xml file
            XmlTextReader reader = null;
            try
            {
                // provide the XmlTextReader with the URL of   our xml document

                reader = new XmlTextReader(Constants.URL_CONTAINING_LATEST_VERSION_INFO);
                reader.MoveToContent(); // simply (and easily) skip the junk at the beginning

                // internal - as the XmlTextReader moves only forward, we save current xml element name in elementName variable.
                // When we parse a  text node, we refer to elementName to check what was the node name
                string elementName = "";
                // we check if the xml starts with a proper "ourfancyapp" element node
                if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == Constants.APPLICATION_NAME))
                {
                    while (reader.Read())
                    {
                        // when we find an element node, we remember its name
                        if (reader.NodeType == XmlNodeType.Element)
                            elementName = reader.Name;
                        else
                        {
                            // for text nodes...
                            if ((reader.NodeType == XmlNodeType.Text) && (reader.HasValue))
                            {
                                // we check what the name of the node was
                                switch (elementName)
                                {
                                    case "version":
                                        // we keep the version info in xxx.xxx.xxx.xxx format as the Version class does the  parsing for us
                                        newVersion = new Version(reader.Value);
                                        break;
                                    case "url":
                                        url = reader.Value;
                                        break;
                                    case "changes":
                                        changes = reader.Value;
                                        break;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                return;
            }
            finally
            {
                if (reader != null) reader.Close();
            }

             // get the running version
             Version curVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

            // compare the versions
             if (curVersion.CompareTo(newVersion) < 0)
             {
                // ask the user if he would like to download the new version
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.MessageTitle = "A new version of Timelapse available.";
                dlgMB.MessageProblem = "You a running an old version of Timelapse: version " + curVersion.ToString();
                dlgMB.MessageReason = "A new version of Timelapse is available: version " + newVersion.ToString();
                dlgMB.MessageSolution = "Select 'Yes' to go to the Timelapse website and download it.";
                dlgMB.MessageResult = "The new version will contain these changes and more:" ;
                dlgMB.MessageResult += changes;
                dlgMB.MessageHint = "\u2022 We recommend downloading the latest version." + Environment.NewLine;
                dlgMB.MessageHint += "\u2022 To see all changes, go to http://saul.cpsc.ucalgary.ca/timelapse. Select 'Version history' from the side bar.";
                dlgMB.IconType = MessageBoxImage.Exclamation;
                dlgMB.ButtonType = MessageBoxButton.YesNo;
                bool? msg_result = dlgMB.ShowDialog();

                // Set the filter to show all images and a valid image
                if (msg_result == true)
                {
                        // navigate the default web browser to our app homepage (the url comes from the xml content)
                        System.Diagnostics.Process.Start(url);
                }
             }
             else if (showNoUpdatesMessage)
             {
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.MessageTitle = "No updates to Timelapse are available.";
                dlgMB.MessageReason = "You a running the latest version of Timelapse, version: " + curVersion.ToString();
                dlgMB.IconType = MessageBoxImage.Information;
                dlgMB.ButtonType = MessageBoxButton.OK;
                bool? msg_result = dlgMB.ShowDialog();
             }
        }
Esempio n. 7
0
 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
     string executable_folder = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
     if (!File.Exists(System.IO.Path.Combine(executable_folder, "System.Data.SQLite.dll")))
     {
         DlgMessageBox dlgMB = new DlgMessageBox();
         dlgMB.MessageTitle = "Timelapse needs to be in its original downloaded folder";
         dlgMB.MessageProblem = "The Timelapse Programs won't run properly as it was not correctly installed.";
         dlgMB.MessageReason = "When you downloaded Timelapse, it was in a folder with several other files and folders it needs. You probably dragged Timelapse out of that folder.";
         dlgMB.MessageSolution = "Put the Timelapse programs back in its original folder, or download it again.";
         dlgMB.MessageHint = "If you want to access these programs from elsewhere, create a shortcut to it." + Environment.NewLine;
         dlgMB.MessageHint += "1. From its original folder, right-click the Timelapse program icon  and select 'Create Shortcut' from the menu." + Environment.NewLine;
         dlgMB.MessageHint += "2. Drag the shortcut icon to the location of your choice.";
         dlgMB.IconType = MessageBoxImage.Error;
         dlgMB.ShowDialog();
         Application.Current.Shutdown();
     }
     else
     {
         CheckForUpdate.GetAndParseVersion(this, false);
     }
     // FOR MY DEBUGGING ONLY: THIS STARTS THE SYSTEM WITH THE LOAD MENU ITEM SELECTED loadImagesFromSources();  //OPENS THE MENU AUTOMATICALLY
 }
Esempio n. 8
0
        private bool SetImageFilterAndIndex(int index, int filter)
        {
            // Change the filter to reflect what the user selected. Update the menu state accordingly
            // Set the checked status of the radio button menu items to the filter.

            if (filter == (int)Constants.ImageQualityFilters.All)           // All images
            {
                this.dbData.GetImagesAll();
                StatusBarUpdate.View(this.statusBar, "all images.");
                MenuItemViewSetSelected((int)Constants.ImageQualityFilters.All);
                if (null != this.dlgDataView)
                {
                    this.dlgDataView.RefreshDataTable();  // If its displayed, update the window that shows the filtered view data base
                }
            }
            else if (filter == (int)Constants.ImageQualityFilters.Ok) // Light images
            {
                if (this.dbData.GetImagesAllButDarkAndCorrupted())
                {
                    StatusBarUpdate.View(this.statusBar, "light images.");
                    MenuItemViewSetSelected((int)Constants.ImageQualityFilters.Ok);
                    if (null != this.dlgDataView)
                    {
                        this.dlgDataView.RefreshDataTable();  // If its displayed, update the window that shows the filtered view data base
                    }
                }
                else
                {
                    // It really should never get here, as the menu option for filtering by light images will be disabled if there aren't any.
                    // Still,...
                    StatusBarUpdate.Message(this.statusBar, "no light images to display.");
                    DlgMessageBox dlgMB = new DlgMessageBox();
                    dlgMB.MessageTitle = "Light filter selected, but no images are marked as light.";
                    dlgMB.MessageProblem = "None of the images in this image set are light images, so nothing can be shown.";
                    dlgMB.MessageReason = "None of the images have their 'ImageQuality' field  set to OK.";
                    dlgMB.MessageResult = "The filter will not be applied.";
                    dlgMB.MessageHint = "If you have images that you think should be marked as 'light', set its ImageQUality field to OK.";
                    dlgMB.IconType = MessageBoxImage.Information;
                    dlgMB.ButtonType = MessageBoxButton.OK;
                    dlgMB.ShowDialog();

                    if (this.state.imageFilter == (int)Constants.ImageQualityFilters.Ok)
                        return SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All);
                    MenuItemViewSetSelected(this.state.imageFilter);
                    return false;
                }
            }
            else if (filter == (int)Constants.ImageQualityFilters.Corrupted) // Corrupted images
            {
                if (this.dbData.GetImagesCorrupted())
                {
                    StatusBarUpdate.View(this.statusBar, "corrupted images.");
                    MenuItemViewSetSelected((int)Constants.ImageQualityFilters.Corrupted);
                    if (null != this.dlgDataView)
                    {
                        this.dlgDataView.RefreshDataTable();  // If its displaye, update the window that shows the filtered view data base
                    }
                }
                else
                {
                    // It really should never get here, as the menu option for filtering by corrupted images will be disabled if there aren't any.
                    // Still,...
                    StatusBarUpdate.Message(this.statusBar, "no corrupted images to display.");
                    DlgMessageBox dlgMB = new DlgMessageBox();
                    dlgMB.MessageTitle = "Corrupted filter selected, but no images are marked as corrupted.";
                    dlgMB.MessageProblem = "None of the images in this image set are corrupted images, so nothing can be shown.";
                    dlgMB.MessageReason = "None of the images have their 'ImageQuality' field  set to Corrupted.";
                    dlgMB.MessageResult = "The filter will not be applied.";
                    dlgMB.MessageHint = "If you have images that you think should be marked as 'Corrupted', set its ImageQUality field to Corrupted.";
                    dlgMB.IconType = MessageBoxImage.Information;
                    dlgMB.ButtonType = MessageBoxButton.OK;
                    dlgMB.ShowDialog();

                    if (this.state.imageFilter == (int)Constants.ImageQualityFilters.Corrupted)
                        return SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All);
                    MenuItemViewSetSelected(this.state.imageFilter);
                    return false;
                }
            }
            else if (filter == (int)Constants.ImageQualityFilters.Dark) // Dark images
            {
                if (this.dbData.GetImagesDark())
                {
                    StatusBarUpdate.View(this.statusBar, "dark images.");
                    MenuItemViewSetSelected((int)Constants.ImageQualityFilters.Dark);
                    if (null != this.dlgDataView)
                    {
                        this.dlgDataView.RefreshDataTable();  // If its displayed, update the window that shows the filtered view data base
                    }
                }
                else
                {
                    // It really should never get here, as the menu option for filtering by dark images will be disabled if there aren't any.
                    // Still,...
                    StatusBarUpdate.Message(this.statusBar, "no dark images to display.");
                    DlgMessageBox dlgMB = new DlgMessageBox();
                    dlgMB.MessageTitle = "Dark filter selected, but no images are marked as dark.";
                    dlgMB.MessageProblem = "None of the images in this image set are dark images, so nothing can be shown.";
                    dlgMB.MessageReason = "None of the images have their 'ImageQuality' field  set to Dark.";
                    dlgMB.MessageResult = "The filter will not be applied.";
                    dlgMB.MessageHint = "If you have images that you think should be marked as 'Dark', set its ImageQUality field to Dark.";
                    dlgMB.IconType = MessageBoxImage.Information;
                    dlgMB.ButtonType = MessageBoxButton.OK;
                    dlgMB.ShowDialog();
                    if (this.state.imageFilter == (int)Constants.ImageQualityFilters.Dark)
                        return SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All);
                    MenuItemViewSetSelected(this.state.imageFilter);
                    return false;
                }
            }
            else if (filter == (int)Constants.ImageQualityFilters.Missing) // Missing images
            {
                if (this.dbData.GetImagesMissing())
                {
                    StatusBarUpdate.View(this.statusBar, "missing images.");
                    MenuItemViewSetSelected((int)Constants.ImageQualityFilters.Missing);
                    if (null != this.dlgDataView)
                    {
                        this.dlgDataView.RefreshDataTable();  // If its displayed, update the window that shows the filtered view data base
                    }
                }
                else
                {
                    // It really should never get here, as the menu option for filtering by missing images will be disabled if there aren't any.
                    // Still,...
                    StatusBarUpdate.Message(this.statusBar, "no missing images to display.");
                    DlgMessageBox dlgMB = new DlgMessageBox();
                    dlgMB.MessageTitle = "Missing filter selected, but no images are marked as missing.";
                    dlgMB.MessageProblem = "None of the images in this image set are missing images, so nothing can be shown.";
                    dlgMB.MessageReason = "None of the images have their 'ImageQuality' field  set to Missing.";
                    dlgMB.MessageResult = "The filter will not be applied.";
                    dlgMB.MessageHint = "If you have images that you think should be marked as 'Missing', set its ImageQUality field to Missing.";
                    dlgMB.IconType = MessageBoxImage.Information;
                    dlgMB.ButtonType = MessageBoxButton.OK;
                    dlgMB.ShowDialog();
                    if (this.state.imageFilter == (int)Constants.ImageQualityFilters.Missing)
                        return SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All);
                    MenuItemViewSetSelected(this.state.imageFilter);
                    return false;
                }
            }
            else if (filter == (int)Constants.ImageQualityFilters.MarkedForDeletion) // Images marked for deletion
            {
                if (this.dbData.GetImagesMarkedForDeletion())
                {
                    StatusBarUpdate.View(this.statusBar, "images marked for deletion.");
                    MenuItemViewSetSelected((int)Constants.ImageQualityFilters.MarkedForDeletion);
                    if (null != this.dlgDataView)
                    {
                        dlgDataView.RefreshDataTable();
                        this.MenuItemViewFilteredDatabaseContents_Click(null, null); //Regenerate the DataView if needed
                    }
                }
                else
                {
                    // It really should never get here, as the menu option for filtering by images marked for deletion will be disabled if there aren't any.
                    // Still,...
                    StatusBarUpdate.Message(this.statusBar, "No images marked for deletion to display.");
                    DlgMessageBox dlgMB = new DlgMessageBox();
                    dlgMB.MessageTitle = "Delete filter selected, but no images are marked for deletion";
                    dlgMB.MessageProblem = "None of the images in this image set are marked for deletion, so nothing can be shown.";
                    dlgMB.MessageReason = "None of the images have their 'Delete?' field checkmarked.";
                    dlgMB.MessageResult = "The filter will not be applied.";
                    dlgMB.MessageHint = "If you have images that you think should be marked for deletion, checkmark its Delete? field.";
                    dlgMB.IconType = MessageBoxImage.Information;
                    dlgMB.ButtonType = MessageBoxButton.OK;
                    dlgMB.ShowDialog();

                    if (this.state.imageFilter == (int)Constants.ImageQualityFilters.MarkedForDeletion)
                        return SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All);
                    MenuItemViewSetSelected(this.state.imageFilter);
                    return false;
                }
            }
            else if (filter == (int)Constants.ImageQualityFilters.Custom) // Custom Filter
            {
                if (this.customfilter.QueryResultCount != 0)
                {
                    StatusBarUpdate.View(this.statusBar, "images matching your custom filter.");
                    MenuItemViewSetSelected((int)Constants.ImageQualityFilters.Custom);
                    if (null != this.dlgDataView)
                    {
                        this.dlgDataView.RefreshDataTable();  // If its displayed, update the window that shows the filtered view data base
                    }
                }
                else
                {
                    // It really should never get here, as the dialog for filtering images shouldn't allow it, but...
                    // Still,...
                    StatusBarUpdate.Message(this.statusBar, "no images to display.");
                    DlgMessageBox dlgMB = new DlgMessageBox();
                    dlgMB.MessageTitle = "Custom filter selected, but no images match the specified search.";
                    dlgMB.MessageProblem = "None of the images in this image set match the specified search, so nothing can be shown.";
                    dlgMB.MessageResult = "The filter will not be applied.";
                    dlgMB.MessageHint = "Try to create another custom filter.";
                    dlgMB.IconType = MessageBoxImage.Information;
                    dlgMB.ButtonType = MessageBoxButton.OK;
                    dlgMB.ShowDialog();
                    if (this.state.imageFilter == (int)Constants.ImageQualityFilters.Missing)
                        return SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All);
                    MenuItemViewSetSelected(this.state.imageFilter);
                    return false;
                }
            }

            // Go to the first row.
            // We may want to change this to try to go to last saved image, if its in this filtered view.
            this.dbData.ToDataRowIndex (index);

            // After a filter change, set the slider to represent the index and the count of the current filter
            this.sldrImageNavigatorEnableCallback(false);
            this.sldrImageNavigator.Maximum = this.dbData.ImageCount - 1;  // Reset the slider to the size of images in this set
            this.sldrImageNavigator.Value = this.dbData.CurrentRow;

            // Update the status bar accordingly
            StatusBarUpdate.CurrentImageNumber(statusBar, this.dbData.CurrentRow + 1);  // We add 1 because its a 0-based list
            StatusBarUpdate.TotalCount(statusBar, this.dbData.ImageCount);
            showImage(this.dbData.CurrentRow);
            this.sldrImageNavigatorEnableCallback(true);
            this.state.imageFilter = filter;    // Remember the current filter
            return true;
        }
Esempio n. 9
0
        // Load  all the jpg images found in the folder
        Boolean LoadDByScanningImageFolder()
        {
            DateTimeHandler dateTimeHandler = new DateTimeHandler();
            FileInfo fileInfo;
            ProgressState progressState = new ProgressState();
            ImageProperties imgprop;  // Collect the image properties for for the 2nd pass...
            List<ImageProperties> imgprop_list = new List<ImageProperties>();
            Dictionary<String, String> dataline = new Dictionary<String, String>();   // Populate the data for the image
            Dictionary<String, String> markerline = new Dictionary<String, String>(); // Populate the markers database, where each key column corresponds to each key counter in the datatable
            int index = 0;
            string datalabel = "";
            bool ambiguous_daymonth_order = false;

            this.imageFilePaths = new DirectoryInfo(this.dbData.FolderPath).GetFiles("*.jpg");
            int count = imageFilePaths.Length;
            if (count == 0) return false;

            // Create the database and its table before we can load any data into it
            // Open a connection to the template DB
            bool result = this.dbData.CreateDB(template);

            // We generate the data user interface controls from the template description after the database has been created from the template
            myControls.GenerateControls(dbData);
            MenuItemControlsInSeparateWindow_Click(this.MenuItemControlsInSeparateWindow, null);  //this.ControlsInMainWindow();

            this.dbData.CreateTables();
            this.dbData.CreateLookupTables();

            // We want to show previews of the frames to the user as they are individually loaded
            // Because WPF uses a scene graph, we have to do this by a background worker, as this forces the update
            var bgw = new BackgroundWorker() { WorkerReportsProgress = true };
            bgw.DoWork += (ow, ea) =>
            {   // this runs on the background thread; its written as an anonymous delegate
                //We need to invoke this to allow updates on the UI
                this.Dispatcher.Invoke(new Action(() =>
                {;
                    // First, change the UI
                    this.helpControl.Visibility = System.Windows.Visibility.Collapsed;
                    Feedback(null, 0, "Examining images...");
                }));

                // First pass: Examine images to extract its basic properties
                BitmapSource bmap;
                BitmapSource corruptedbmp = BitmapFrame.Create(new Uri("pack://application:,,/Resources/corrupted.jpg"));;
                for (int i = 0; i < count; i++)
                {
                    fileInfo = imageFilePaths[i];
                     bmap = null;

                    imgprop = new ImageProperties();
                    imgprop.Name = fileInfo.Name;
                    imgprop.Folder = Utilities.GetFolderNameFromFolderPath(this.FolderPath);
                    try
                    {
                        // Create the bitmap and determine its ImageQuality
                        bmap = BitmapFrame.Create(new Uri(fileInfo.FullName), BitmapCreateOptions.None, BitmapCacheOption.None);

                        bool dark = PixelBitmap.IsDark(bmap, this.darkPixelThreshold, this.darkPixelRatioThreshold);  //
                        imgprop.ImageQuality = (dark) ? (int)Constants.ImageQualityFilters.Dark : (int)Constants.ImageQualityFilters.Ok;
                    }
                    catch
                    {
                        bmap = corruptedbmp;
                        imgprop.ImageQuality = (int) Constants.ImageQualityFilters.Corrupted;
                    }

                    // Get the data from the metadata
                    BitmapMetadata meta = (BitmapMetadata) bmap.Metadata;
                    imgprop.DateMetadata = meta.DateTaken;
                    // For some reason, different versions of Windows treat creation time and modification time differently,
                    // giving inconsisten values. So I just check both and take the lesser of the two.
                    DateTime time1 = File.GetCreationTime(fileInfo.FullName);
                    DateTime time2 = File.GetLastWriteTime(fileInfo.FullName);
                    imgprop.DateFileCreation = (DateTime.Compare (time1, time2) < 0) ? time1 : time2;
                    //string time3 = (meta.DateTaken == null) ? "null" : meta.DateTaken.ToString();

                    //Debug.Print(fileInfo.Name + " " + time1.ToString() + " " + time2.ToString() + " " + time3);
                    imgprop.ID = index + 1; // its plus 1 as the Database IDs start at 1 rather than 0
                    imgprop_list.Add (imgprop);

                    index++;
                    int progress = Convert.ToInt32(Convert.ToDouble(index) / Convert.ToDouble(count) * 100);

                    if (index == 1 || (index % 1 == 0) )
                    {
                        progressState.Message = String.Format ("{0}/{1}: Examining {2}", i, count, imgprop.Name);
                        progressState.Bmap = bmap;
                        bgw.ReportProgress(progress, progressState);
                    }
                    else
                    {
                        progressState.Bmap = null;
                    }
                }

                // Second pass: Determine dates ... This can be pretty quick, so we don't really need to give any feedback on it.
                progressState.Message = "Second pass";
                progressState.Bmap = null;
                bgw.ReportProgress(0, progressState);
                ambiguous_daymonth_order = DateTimeHandler.VerifyAndUpdateDates(imgprop_list);

                // Third pass: Update database
                // TODO This is pretty slow... a good place to make it more efficient by adding multiple values in one shot

                // We need to get a list of which columns are counters vs notes or fixed coices,
                // as we will shortly have to initialize them to some defaults
                List<string> CounterList = new List<string>();
                List<string> Notes_and_FixedChoicesList = new List<string>();
                List<string> FlagsList = new List<string>();
                for (int i = 0; i < this.dbData.dataTable.Columns.Count; i++)
                {
                    datalabel = this.dbData.dataTable.Columns[i].ColumnName;
                    string type = (string)this.dbData.TypeFromKey[datalabel];
                    if (null == type) continue; // Column must be the ID, which we skip over as its not a key.
                    if (type.Equals(Constants.COUNTER)) CounterList.Add(datalabel);
                    else if (type.Equals(Constants.NOTE) || type.Equals(Constants.FIXEDCHOICE)) Notes_and_FixedChoicesList.Add(datalabel);
                    else if (type.Equals(Constants.FLAG)) FlagsList.Add(datalabel);
                }

                // Create a dataline from the image properties, add it to a list of data lines,
                // then do a multiple insert of the list of datalines to the database
                List <Dictionary<string, string>> dataline_list ; //= new List <Dictionary<string, string>> ();
                List<Dictionary<string, string>> markerline_list ; //= new List<Dictionary<string, string>>();
                //for (int i = 0; i < imgprop_list.Count; i++)

                const int interval = 100;
                for (int j = 0; j < imgprop_list.Count; j++)
                {
                    // Create a dataline from the image properties, add it to a list of data lines,
                    // then do a multiple insert of the list of datalines to the database
                    dataline_list = new List<Dictionary<string, string>>();
                    markerline_list = new List<Dictionary<string, string>>();
                    for (int i = j; ( (i < (j + interval)) && (i < imgprop_list.Count) ); i++)
                    {

                        // THE PROBLEM IS THAT WE ARE NOT ADDING THESE VALUES IN THE SAME ORDER AS THE TABLE
                        // THEY MUST BE IN THE SAME ORDER IE, AS IN THE COLUMNS. This case statement just fills up
                        // the dataline in the same order as the template table.
                        // It assumes that the key is always the first column
                        dataline = new Dictionary<string, string>();
                        markerline = new Dictionary<string, string>();
                      //dataline.Add(Constants.ID, "NULL");     // Add the ID. Its Null to force autoincrement
                      //  markerline.Add(Constants.ID, (i+1).ToString());
                        for (int col = 0; col < dbData.dataTable.Columns.Count; col++) // Fill up each column in order
                        {
                            string col_datalabel = dbData.dataTable.Columns[col].ColumnName;
                            string type = (string) dbData.TypeFromKey [col_datalabel];
                            if (null == type) continue; // a null will be returned from the ID, as we don't add it to the typefromkey hash.
                            switch (type)
                            {
                                case Constants.FILE: // Add The File name
                                    datalabel = (string)this.dbData.DataLabelFromType[Constants.FILE];
                                    dataline.Add(datalabel, imgprop_list[i].Name);
                                    break;
                                case Constants.FOLDER: // Add The Folder name
                                    datalabel = (string)this.dbData.DataLabelFromType[Constants.FOLDER];
                                    dataline.Add(datalabel, imgprop_list[i].Folder);
                                    break;
                                case Constants.DATE:
                                    // Add the date
                                    datalabel = (string)this.dbData.DataLabelFromType[Constants.DATE];
                                    dataline.Add(datalabel, imgprop_list[i].FinalDate);
                                    break;
                                case Constants.TIME:
                                    // Add the time
                                    datalabel = (string)this.dbData.DataLabelFromType[Constants.TIME];
                                    dataline.Add(datalabel, imgprop_list[i].FinalTime);
                                    break;
                                case Constants.IMAGEQUALITY: // Add the Image Quality
                                    datalabel = (string)this.dbData.DataLabelFromType[Constants.IMAGEQUALITY];
                                    string str = Constants.IMAGEQUALITY_OK;
                                    if (imgprop_list[i].ImageQuality == (int)Constants.ImageQualityFilters.Dark) str = Constants.IMAGEQUALITY_DARK;
                                    else if (imgprop_list[i].ImageQuality == (int)Constants.ImageQualityFilters.Corrupted) str = Constants.IMAGEQUALITY_CORRUPTED;
                                    dataline.Add(datalabel, str);
                                    break;
                                case Constants.DELETEFLAG: // Add the Delete flag
                                    datalabel = (string)this.dbData.DataLabelFromType[Constants.DELETEFLAG];
                                    dataline.Add(datalabel, this.dbData.TemplateGetDefault(datalabel)); // Default as specified in the template file, which should be "false"
                                    break;
                                case Constants.NOTE:        // Find and then Add the Note or Fixed Choice
                                case Constants.FIXEDCHOICE:
                                    // Now initialize notes, counters, and fixed choices to the defaults
                                    foreach (string tkey in Notes_and_FixedChoicesList)
                                    {
                                        if (col_datalabel.Equals (tkey))
                                            dataline.Add(tkey, this.dbData.TemplateGetDefault(tkey) ); // Default as specified in the template file

                                    }
                                    break;
                                case Constants.FLAG:
                                    // Now initialize flags to the defaults
                                    foreach (string tkey in FlagsList)
                                    {
                                        if (col_datalabel.Equals(tkey))
                                            dataline.Add(tkey, this.dbData.TemplateGetDefault(tkey)); // Default as specified in the template file

                                    }
                                    break;
                                case Constants.COUNTER:
                                     foreach (string tkey in CounterList)
                                     {
                                        if (col_datalabel.Equals(tkey))
                                        {
                                            dataline.Add(tkey, this.dbData.TemplateGetDefault(tkey)); // Default as specified in the template file
                                            markerline.Add(tkey, "");        // TODO ASSUMES THAT MARKER LIST IS IN SAME ORDER AS COUNTERS. THIS MAY NOT BE CORRECT ONCE WE SWITCH ROWS, SO SHOULD DO THIS SEPARATELY
                                        }
                                     }
                                    break;

                                default:
                                    Debug.Print("Shouldn't ever reach here!");
                                    break;
                            }
                        }
                        dataline_list.Add(dataline);
                        if (markerline.Count > 0)
                            markerline_list.Add(markerline);
                        index = i;

                    }
                    this.dbData.InsertMultipleRows(Constants.TABLEDATA, dataline_list);
                    this.dbData.InsertMultipleRows(Constants.TABLEMARKERS, markerline_list);
                    j = j + interval - 1;
                    // Get the bitmap again to show it
                    if (imgprop_list[index].ImageQuality == (int)Constants.ImageQualityFilters.Corrupted)
                        bmap = corruptedbmp;
                    else
                        bmap = BitmapFrame.Create(new Uri(System.IO.Path.Combine(this.dbData.FolderPath, imgprop_list[index].Name)), BitmapCreateOptions.None, BitmapCacheOption.None);

                    // Show progress. Since its slow, we may as well do it every update
                    int progress2 = Convert.ToInt32(Convert.ToDouble(index) / Convert.ToDouble(count) * 100);
                    progressState.Message = String.Format("{0}/{1}: Adding {2}", index, count, imgprop_list[index].Name);
                    progressState.Bmap = bmap;
                    bgw.ReportProgress(progress2, progressState);
                }
                // this.dbData.AddNewRow(dataline);
                // this.dbData.AddNewRow(markerline, Constants.TABLEMARKERS);
            };
            bgw.ProgressChanged += (o, ea) =>
            {   // this gets called on the UI thread
                ProgressState progstate = (ProgressState)ea.UserState;
                Feedback (progressState.Bmap, ea.ProgressPercentage, progressState.Message);
                this.feedbackCtl.Visibility = System.Windows.Visibility.Visible;
            };
            bgw.RunWorkerCompleted += (o, ea) =>
            {

                // this.dbData.GetImagesAll(); // Now load up the data table
                // Get rid of the feedback panel, and show the main interface
                this.feedbackCtl.Visibility = Visibility.Collapsed;
                this.feedbackCtl.ShowImage = null;

                this.markableCanvas.Visibility = Visibility.Visible;

                // Finally warn the user if there are any ambiguous dates in terms of day/month or month/day order
                if (ambiguous_daymonth_order)
                {
                    DlgMessageBox dlgMB = new DlgMessageBox ();
                    dlgMB.MessageTitle = "Timelapse was unsure about the month / day order of your image's dates";
                    dlgMB.MessageProblem = "Timelapse is extracting the dates from your images. However, it cannot tell if the dates are in day/month order, or month/day order.";
                    dlgMB.MessageReason = "Image date formats can be ambiguous. For example, is 2015/03/05 March 5 or May 3?";
                    dlgMB.MessageSolution = "If Timelapse gets it wrong, you can correct the dates by choosing" + Environment.NewLine;
                    dlgMB.MessageSolution += "\u2022 Edit Menu -> Dates -> Swap Day and Month.";
                    dlgMB.MessageHint = "If you are unsure about the correct date, try the following." + Environment.NewLine;
                    dlgMB.MessageHint += "\u2022 If your camera prints the date on the image, check that." + Environment.NewLine;
                    dlgMB.MessageHint += "\u2022 Look at the images to see what season it is (e.g., winter vs. summer)." + Environment.NewLine;
                    dlgMB.MessageHint += "\u2022 Examine the creation date of the image file." + Environment.NewLine;
                    dlgMB.MessageHint += "\u2022 Check your own records.";
                    dlgMB.ButtonType = MessageBoxButton.OK;
                    dlgMB.IconType = MessageBoxImage.Information;
                    dlgMB.ShowDialog();
                }
                LoadComplete(true);
                // If we want to import old data from the ImageData.xml file, we can do it here...
                // Check to see if there is an ImageData.xml file in here. If there is, ask the user
                // if we want to load the data from that...
                if (File.Exists(System.IO.Path.Combine(this.FolderPath, Constants.XMLDATAFILENAME)))
                {
                    DlgImportImageDataXMLFile dlg = new DlgImportImageDataXMLFile();
                    dlg.Owner = this;
                    bool? result3 = dlg.ShowDialog();
                    if (result3 == true)
                    {
                        ImageDataXML.Read(System.IO.Path.Combine(this.FolderPath, Constants.XMLDATAFILENAME), dbData.templateTable, dbData);
                        SetImageFilterAndIndex(this.dbData.State_Row, this.dbData.State_Filter); // to regenerate the controls and markers for this image
                    }
                }
            };
            bgw.RunWorkerAsync();
            return true;
        }
Esempio n. 10
0
        private void MenuItemRereadDatesfromImages_Click(object sender, RoutedEventArgs e)
        {
            // If we are not in the filter all view, or if its a corrupt image, tell the person. Selecting ok will shift the views..
            if (this.state.imageFilter != (int)Constants.ImageQualityFilters.All)
            {

                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.MessageTitle = "Re-read the dates from the images...";
                dlgMB.MessageProblem = "To re-read dates from the images, Timelapse must first be filtered to view All Images (normally set  in the Filter menu)";
                dlgMB.MessageSolution = "Select 'Ok' for Timelapse to set the filter to 'All Images'.";
                dlgMB.IconType = MessageBoxImage.Exclamation;
                dlgMB.ButtonType = MessageBoxButton.OKCancel;
                bool? msg_result = dlgMB.ShowDialog();

                // Set the filter to show all images and a valid image
                if (msg_result == true)
                {
                    SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All); // Set it to all images
                    int row = dbData.RowFindNextDisplayableImage(1); // Start at Row 1, as they are numbered from 1 onwards...
                    if (row >= 0) showImage(row);
                }
                else return;
            }
            DlgDateRereadDatesFromImages dlg = new DlgDateRereadDatesFromImages(this.dbData);
            dlg.Owner = this;
            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                this.showImage(dbData.CurrentRow);
            }
        }
Esempio n. 11
0
        // Populate a data field from metadata (example metadata displayed from the currently selected image)
        private void MenuItemPopulateFieldFromMetaData_Click(object sender, RoutedEventArgs e)
        {
            // If we are not in the filter all view, or if its a corrupt image or deleted image, tell the person. Selecting ok will shift the filter..
            if (dbData.RowIsImageDisplayable() == false || this.state.imageFilter != (int)Constants.ImageQualityFilters.All)
            {
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.MessageTitle = "Populate a Data Field with Image Metadata of your Choosing...";
                dlgMB.MessageProblem = "To populate a data field with image metadata of your choosing, Timelapse must first" + Environment.NewLine;
                dlgMB.MessageProblem += "\u2022 be filtered to view All Images (normally set  in the Filter menu)" + Environment.NewLine;
                dlgMB.MessageProblem += "\u2022 be displaying a valid image";
                dlgMB.MessageSolution = "Select 'Ok' for Timelapse to do the above actions for you.";
                dlgMB.IconType = MessageBoxImage.Exclamation;
                dlgMB.ButtonType = MessageBoxButton.OKCancel;
                bool? msg_result = dlgMB.ShowDialog();

                // Set the filter to show all images and a valid image
                if (msg_result == true)
                {
                    SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All); // Set it to all images
                    int row = dbData.RowFindNextDisplayableImage(1); // Start at Row 1, as they are numbered from 1 onwards...
                    if (row >= 0) showImage(row);
                }
                else return;
            }

            DlgPopulateFieldWithMetadata dlg = new DlgPopulateFieldWithMetadata(this.dbData, this.dbData.RowGetValueFromType(Constants.FILE), this.FolderPath);
            dlg.Owner = this;
            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                this.showImage(dbData.CurrentRow);
                this.state.isContentChanged = true;
            }
        }
Esempio n. 12
0
        private void MenuItemOptionsDarkImagesThreshold_Click(object sender, RoutedEventArgs e)
        {
            // If we are not in the filter all view, or if its a corrupt image, tell the person. Selecting ok will shift the views..
            if (this.state.imageFilter != (int)Constants.ImageQualityFilters.All)
            {
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.MessageTitle = "Customize the threshold for determining dark images...";
                dlgMB.MessageProblem = "To customize the threshold for determining dark images, Timelapse must first be  filtered to view All Images (normally set  in the Filter menu).";
                dlgMB.MessageSolution = "Select 'Ok' for Timelapse to set the filter to 'All Images'.";
                dlgMB.IconType = MessageBoxImage.Exclamation;
                dlgMB.ButtonType = MessageBoxButton.OKCancel;
                bool? msg_result = dlgMB.ShowDialog();

                // Set the filter to show all images and a valid image
                if (msg_result == true)
                {
                    SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All); // Set it to all images
                    int row = dbData.RowFindNextDisplayableImage(1); // Start at Row 1, as they are numbered from 1 onwards...
                    if (row >= 0) showImage(row);
                }
                else return;
            }
            DlgOptionsDarkImagesThreshold dlg = new DlgOptionsDarkImagesThreshold(this.dbData, this.darkPixelThreshold, this.darkPixelRatioThreshold) ;
            dlg.Owner = this;
            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                this.state.isContentChanged = true;
            }
        }
Esempio n. 13
0
        /// <summary> 
        /// Export the current image to the folder selected by the user via a folder browser dialog.
        /// and provide feedback in the status bar if done.
        /// </summary>
        private void MenuItemExportThisImage_Click(object sender, RoutedEventArgs e)
        {
            if (!this.dbData.RowIsImageDisplayable())
            {
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.IconType = MessageBoxImage.Error;
                dlgMB.ButtonType = MessageBoxButton.OK;

                dlgMB.MessageTitle = "Can't export this image!";
                dlgMB.MessageProblem = "We can't export the currently displayed image.";
                dlgMB.MessageReason = "It is likely a corrupted or missing image.";
                dlgMB.MessageSolution = "Make sure you have navigated to, and are displaying, a valid image before you try to export it.";
                dlgMB.ShowDialog();
                return;
            }
            //Get the file name of the current image
            string sourceFile = this.dbData.RowGetValueFromType(Constants.FILE);

            // Set up a Folder Browser with some instructions
            var dialog = new System.Windows.Forms.SaveFileDialog();
            dialog.Title = "Export a copy of the currently displayed image";
            dialog.Filter = "JPeg Image|*.jpg";
            dialog.FileName = sourceFile;
            dialog.OverwritePrompt = true;

            // Display the Folder Browser dialog
            System.Windows.Forms.DialogResult result = dialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                // Set the source and destination file names, including the complete path
                string sourceFileName = System.IO.Path.Combine(this.FolderPath, sourceFile);
                string destFileName = dialog.FileName;

                // Try to copy the source file to the destination, overwriting the destination file if it already exists.
                // And giving some feedback about its success (or failure)
                try
                {
                    System.IO.File.Copy(sourceFileName, destFileName, true);
                    StatusBarUpdate.Message(this.statusBar, sourceFile + " copied to " + destFileName);
                }
                catch
                {
                    StatusBarUpdate.Message(this.statusBar, "Copy failed for some reason!");
                }
            }
        }
Esempio n. 14
0
        /// <summary> Delete all images marked for deletion, and optionally the data associated with those images.
        /// Deleted images are actually moved to a backup folder.</summary>
        private void MenuItemDeleteImages_Click(object sender, RoutedEventArgs e)
        {
            int filter = this.state.imageFilter;
            int currentrow = this.dbData.CurrentRow;
            MenuItem mi = sender as MenuItem;

            DataTable deletedTable = this.dbData.GetDataTableOfImagesMarkedForDeletion();
            if (null==deletedTable)
            {
                // It really should never get here, as this menu will be disabled if there aren't any images to delete.
                // Still,...
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.MessageTitle = "No images are marked for deletion";
                dlgMB.MessageProblem = "You are trying to delete images marked for deletion, but none of the images have their 'Delete?' field checkmarked.";
                dlgMB.MessageHint = "If you have images that you think should be deleted, checkmark its Delete? field.";
                dlgMB.IconType = MessageBoxImage.Information;
                dlgMB.ButtonType = MessageBoxButton.OK;
                dlgMB.ShowDialog();
                return;
            }
            DlgDeleteImages dlg;
            if (mi.Name.Equals ("MenuItemDeleteImages"))
                dlg = new DlgDeleteImages(this.dbData, deletedTable, this.FolderPath, false);   // don't delete data
            else
                dlg = new DlgDeleteImages(this.dbData, deletedTable, this.FolderPath, true);   // delete data
            dlg.Owner = this;

            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                this.SetImageFilterAndIndex(currentrow, filter);
                this.showImage(this.dbData.CurrentRow, false);
            }
        }
Esempio n. 15
0
        /// <summary> Correct for daylight savings time</summary>
        private void MenuItemCorrectDaylightSavings_Click(object sender, RoutedEventArgs e)
        {
            // If we are not in the filter all view, or if its a corrupt image, tell the person. Selecting ok will shift the views..
            if (dbData.RowIsImageDisplayable() == false || this.state.imageFilter != (int)Constants.ImageQualityFilters.All)
            {
                if (this.state.imageFilter != (int)Constants.ImageQualityFilters.All)
                {
                    DlgMessageBox dlgMB = new DlgMessageBox();
                    dlgMB.MessageTitle = "Can't correct for daylight savings time...";
                    dlgMB.MessageProblem = "To correct for daylight savings time:" + Environment.NewLine;
                    dlgMB.MessageProblem += "\u2022 Timelapse must first be filtered to view All Images (normally set  in the Filter menu)" + Environment.NewLine;
                    dlgMB.MessageProblem += "\u2022 The displayed image should also be the one at the daylight savings time threshold.";
                    dlgMB.MessageSolution = "Select 'Ok' for Timelapse to set the filter to 'All Images', and try again.";
                    dlgMB.MessageHint = "For this correction to work properly, you should navigate and display the image that is at the daylight savings time threshold.";
                    dlgMB.IconType = MessageBoxImage.Exclamation;
                    dlgMB.ButtonType = MessageBoxButton.OKCancel;
                    bool? msg_result = dlgMB.ShowDialog();

                    // Set the filter to show all images and then go to the first image
                    if (msg_result == true)
                    {
                        SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All); // Set it to all images
                        showImage(0);
                    }
                }
                else // Just a corrupted image
                {
                    DlgMessageBox dlgMB = new DlgMessageBox();
                    dlgMB.MessageTitle = "Can't correct for daylight savings time...";
                    dlgMB.MessageProblem = "This is a corrupted image.  ";
                    dlgMB.MessageSolution = "To correct for daylight savings time, you need to:" + Environment.NewLine;
                    dlgMB.MessageSolution += "\u2022 be displaying  an image with a valid date ";
                    dlgMB.MessageSolution += "\u2022 where that image should be the one at the daylight savings time threshold.";
                    dlgMB.IconType = MessageBoxImage.Exclamation;
                    dlgMB.ButtonType = MessageBoxButton.OK;
                    bool? msg_result = dlgMB.ShowDialog();
                }
                return;
            }

            DlgDateTimeChangeCorrection dlg = new DlgDateTimeChangeCorrection(this.dbData);
            dlg.Owner = this;
            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                this.showImage(dbData.CurrentRow);
            }
        }
Esempio n. 16
0
        // Load the code template and then the images from either the database (if it exists) or the actual images (if it doesn't exist)
        private void loadImagesFromSources()
        {
            // First, select a template file which should reside with  the image set, otherwise abort loading (which means the user can try again later)
            // Also pass it the last image folder / template file viewed, which will be shown in the file dialog
            string tpath = persist.ReadLastImageFolderPath();       // the last path opened by the user is stored in the registry
            string filename = persist.ReadLastImageTemplateName();  // the template filname opened by the user is stored in the registry

            tpath = Utilities.GetTemplateFileFromUser(tpath, filename);  // Returns the path and the file name
            if (tpath == null) return;
            // Parse the returned file path to get just the filename and the path to the folder.
            filename = System.IO.Path.GetFileName(tpath);
            if (filename.Equals ("")) filename = Constants.DBTEMPLATEFILENAME;
            persist.WriteLastImageTemplateName(filename);  // We should really do this on exit as well, but I didn't feel like storing it

            tpath = System.IO.Path.GetDirectoryName(tpath);

            if ("" == tpath || null == tpath) return;

            this.FolderPath = tpath;        // We keep the path in two places for convenience of referencing them
            this.dbData.FolderPath = tpath;

            // Create the template to the Timelapse Template database
            this.template = new Template();

            if (!template.Open(this.FolderPath, filename)) return;

            // We now have the template file. Load the TemplateTable from that file, which makes it data accessible through its table
            template.LoadTemplateTable();

            // Find the .ddb file in the image set folder. If a single .ddb file is found, use that one
            // If there are multiple .ddb files, ask the use to choose one and use that
            // However, if the user cancels that choice, just abort.
            // If there are no .ddb files, then just create the standard one.
            switch (this.dbData.FindFile())
            {
                case 0: // An existing .ddb file is available
                    if (this.LoadImagesFromDB(template) == true)
                    {
                        if (state.immediateExit) return;
                        LoadComplete(false);
                    }
                    break;
                case 1: // User cancelled the process of choosing between .ddb files
                    if (state.immediateExit) return;
                    break;
                case 2: // There are no existing .ddb files
                default:
                    if (LoadDByScanningImageFolder() == false)
                    {
                        DlgMessageBox dlgMB = new DlgMessageBox();

                        dlgMB.MessageTitle = "No Images Found in the Image Set Folder";
                        dlgMB.MessageProblem = "There doesn't seem to be any JPG images in your chosen image folder:";
                        dlgMB.MessageProblem += Environment.NewLine + "\u2022 " + this.FolderPath + Environment.NewLine;
                        dlgMB.MessageReason = "\u2022 The folder has no JPG files in it (image files ending in '.jpg'), or" + Environment.NewLine;
                        dlgMB.MessageReason += "\u2022 You may has selected the wrong folder, i.e., a folder other than the one containing the images.";
                        dlgMB.MessageSolution = "\u2022 Check that the chosen folder actually contains JPG images (i.e., a 'jpg' suffix), or" + Environment.NewLine;
                        dlgMB.MessageSolution += "\u2022 Choose another folder.";
                        dlgMB.IconType = MessageBoxImage.Error;
                        dlgMB.ButtonType = MessageBoxButton.OK;
                        dlgMB.ShowDialog();
                        return;
                    }
                    break;
            }
            state.isContentChanged = false; // We've altered some content

            // For persistance: set a flag if We've opened the same image folder we worked with in the last session.
            // If its different, saved the new folder path
            this.ImageFolderReopened = (tpath == this.FolderPath) ? true : false;
        }
Esempio n. 17
0
        /// <summary>
        ///  Copy the last non-empty value  in this control preceding this image up to the current image
        ///  
        /// </summary>
        /// <param name="mainWindow"></param>
        /// <param name="control"></param>
        public string FromLastValue(string key, bool checkForZero, bool isflag)
        {
            string valueToCopy = (checkForZero) ? "0" : "";

            int row = -1;
            for (int i = dbData.CurrentRow - 1; i >=0; i--) // Search for the row with some value in it, starting from the previous row
            {
                valueToCopy = (string) dbData.dataTable.Rows[i][key];
                valueToCopy = valueToCopy.Trim();
                if ( valueToCopy.Length  > 0 )
                {
                    if ( (checkForZero && !valueToCopy.Equals("0"))             // Skip over non-zero values for counters
                        || (isflag     && !valueToCopy.ToLower().Equals("false")) // Skip over false values for flags
                        || (!checkForZero && !isflag)) {
                        row = i;    //We found a non-empty value
                        break;
                    }
                }
            }
            if (row < 0)
            {
                // Nothing to propagate. Note that we shouldn't see this, as the menu item should be deactivated if this is the case.
                // But just in case.
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.IconType = MessageBoxImage.Exclamation;
                dlgMB.ButtonType = MessageBoxButton.OK;

                dlgMB.MessageTitle = "Nothing to Propagate to Here.";
                dlgMB.MessageReason = "None of the earlier images have anything in this field, so there are no values to propagate.";
                dlgMB.ShowDialog();
                return (string) dbData.dataTable.Rows[dbData.CurrentRow][key]; // No change, so return the current value
            }
            int number_images_affected = this.dbData.CurrentRow - row;
            if (this.PropagateFromLastValue(valueToCopy, (number_images_affected).ToString()) != true)
            {
                return (string)dbData.dataTable.Rows[dbData.CurrentRow][key]; // No change, so return the current value
            };

            // Update. Note that we start on the next row, as we are copying from the current row.
            this.dbData.RowsUpdateFromRowToRowFilteredView(key, valueToCopy, row+1, this.dbData.CurrentRow);
            return (valueToCopy);
        }
Esempio n. 18
0
        /// <summary> Swap the day / month fields if possible </summary>
        private void MenuItemSwapDayMonth_Click(object sender, RoutedEventArgs e)
        {
            // If we are not in the filter all view, or if its a corrupt image, tell the person. Selecting ok will shift the views..
            if (dbData.RowIsImageDisplayable() == false || this.state.imageFilter != (int)Constants.ImageQualityFilters.All)
            {
                DlgMessageBox dlgMB = new DlgMessageBox();
                dlgMB.MessageTitle = "Swap the day / month...";
                dlgMB.MessageProblem = "To swap the day / month, Timelapse must first:" + Environment.NewLine;
                dlgMB.MessageProblem += "\u2022 be filtered to view All Images (normally set  in the Filter menu)" + Environment.NewLine;
                dlgMB.MessageProblem += "\u2022 preferably be displaying a valid image";
                dlgMB.MessageSolution = "Select 'Ok' for Timelapse to set the filter to 'All Images'.";
                dlgMB.IconType = MessageBoxImage.Exclamation;
                dlgMB.ButtonType = MessageBoxButton.OKCancel;
                bool? msg_result = dlgMB.ShowDialog();

                // Set the filter to show all images and a valid image
                if (msg_result == true)
                {
                    SetImageFilterAndIndex(0, (int)Constants.ImageQualityFilters.All); // Set it to all images
                    int row = dbData.RowFindNextDisplayableImage(1); // Start at Row 1, as they are numbered from 1 onwards...
                    if (row >= 0) showImage(row);
                }
                else return;
            }

            DlgDateSwapDayMonth dlg = new DlgDateSwapDayMonth(this.dbData);
            dlg.Owner = this;
            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                this.showImage(dbData.CurrentRow);
            }
        }