Exemplo n.º 1
0
        /// <summary>
        /// Loads the screenshots.
        /// </summary>
        public void Load(ImageFormatCollection imageFormatCollection, ScreenCollection screenCollection, RegionCollection regionCollection)
        {
            try
            {
                _mutexWriteFile.WaitOne();

                Log.Write("Loading screenshots from screenshots.xml");

                Stopwatch stopwatch = new Stopwatch();

                stopwatch.Start();

                if (_screenshotList == null)
                {
                    _screenshotList = new List <Screenshot>();
                    Log.Write("Initialized screenshot list");
                }

                if (_slideList == null)
                {
                    _slideList = new List <Slide>();
                    Log.Write("Initialized slide list");
                }

                if (_slideNameList == null)
                {
                    _slideNameList = new List <string>();
                    Log.Write("Initialized slide name list");
                }

                if (_screenshotList != null && Directory.Exists(FileSystem.ApplicationFolder) && !File.Exists(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile))
                {
                    Log.Write("Could not find \"" + FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile + "\" so creating it");

                    XmlWriterSettings xSettings = new XmlWriterSettings
                    {
                        Indent           = true,
                        CloseOutput      = true,
                        CheckCharacters  = true,
                        Encoding         = Encoding.UTF8,
                        NewLineChars     = Environment.NewLine,
                        IndentChars      = XML_FILE_INDENT_CHARS,
                        NewLineHandling  = NewLineHandling.Entitize,
                        ConformanceLevel = ConformanceLevel.Document
                    };

                    using (XmlWriter xWriter = XmlWriter.Create(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile, xSettings))
                    {
                        xWriter.WriteStartDocument();
                        xWriter.WriteStartElement(XML_FILE_ROOT_NODE);
                        xWriter.WriteAttributeString("app", "version", XML_FILE_ROOT_NODE, Settings.ApplicationVersion);
                        xWriter.WriteAttributeString("app", "codename", XML_FILE_ROOT_NODE, Settings.ApplicationCodename);
                        xWriter.WriteStartElement(XML_FILE_SCREENSHOTS_NODE);

                        xWriter.WriteEndElement();
                        xWriter.WriteEndElement();
                        xWriter.WriteEndDocument();

                        xWriter.Flush();
                        xWriter.Close();
                    }

                    Log.Write("Created \"" + FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile + "\"");
                }

                if (_screenshotList != null && Directory.Exists(FileSystem.ApplicationFolder) && File.Exists(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile))
                {
                    xDoc = new XmlDocument();

                    lock (xDoc)
                    {
                        xDoc.Load(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile);

                        AppVersion  = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value;
                        AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value;

                        Log.Write("Getting screenshots from screenshots.xml using XPath query \"" + SCREENSHOT_XPATH + "\"");

                        XmlNodeList xScreeshots = xDoc.SelectNodes(SCREENSHOT_XPATH);

                        if (xScreeshots != null)
                        {
                            Log.Write("Loading each screenshot from screenshots.xml");

                            foreach (XmlNode xScreenshot in xScreeshots)
                            {
                                Screenshot screenshot = new Screenshot();
                                screenshot.Slide = new Slide();

                                XmlNodeReader xReader = new XmlNodeReader(xScreenshot);

                                while (xReader.Read())
                                {
                                    if (xReader.IsStartElement())
                                    {
                                        switch (xReader.Name)
                                        {
                                        case SCREENSHOT_VIEWID:
                                            xReader.Read();
                                            screenshot.ViewId = Guid.Parse(xReader.Value);
                                            break;

                                        case SCREENSHOT_DATE:
                                            xReader.Read();
                                            screenshot.Date       = xReader.Value;
                                            screenshot.Slide.Date = xReader.Value;
                                            break;

                                        case SCREENSHOT_TIME:
                                            xReader.Read();
                                            screenshot.Time = xReader.Value;
                                            break;

                                        case SCREENSHOT_PATH:
                                            xReader.Read();
                                            screenshot.Path = xReader.Value;
                                            break;

                                        case SCREENSHOT_FORMAT:
                                            xReader.Read();
                                            screenshot.Format = imageFormatCollection.GetByName(xReader.Value);
                                            break;

                                        // 2.1 used "screen" for its definition of each display/monitor whereas 2.2 uses "component".
                                        // Active Window is now represented by 0 rather than 5.
                                        case SCREENSHOT_SCREEN:
                                            if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion) &&
                                                Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion))
                                            {
                                                xReader.Read();

                                                screenshot.Screen = Convert.ToInt32(xReader.Value);

                                                screenshot.Component = screenshot.Screen == 5 ? 0 : screenshot.Screen;
                                            }

                                            break;

                                        // We still want to support "component" since this was introduced in version 2.2 as the new representation for "screen".
                                        case SCREENSHOT_COMPONENT:
                                            xReader.Read();
                                            screenshot.Component = Convert.ToInt32(xReader.Value);

                                            if (screenshot.Component == -1)
                                            {
                                                screenshot.ScreenshotType = ScreenshotType.Region;
                                            }
                                            else if (screenshot.Component == 0)
                                            {
                                                screenshot.ScreenshotType = ScreenshotType.ActiveWindow;
                                            }
                                            else
                                            {
                                                screenshot.ScreenshotType = ScreenshotType.Screen;
                                            }

                                            break;

                                        case SCREENSHOT_SLIDENAME:
                                            xReader.Read();
                                            screenshot.Slide.Name = xReader.Value;
                                            break;

                                        case SCREENSHOT_SLIDEVALUE:
                                            xReader.Read();
                                            screenshot.Slide.Value = xReader.Value;
                                            break;

                                        case SCREENSHOT_WINDOW_TITLE:
                                            xReader.Read();
                                            screenshot.WindowTitle = xReader.Value;
                                            break;

                                        case SCREENSHOT_PROCESS_NAME:
                                            xReader.Read();
                                            screenshot.ProcessName = xReader.Value;
                                            break;

                                        case SCREENSHOT_LABEL:
                                            xReader.Read();
                                            screenshot.Label = xReader.Value;
                                            break;
                                        }
                                    }
                                }

                                xReader.Close();

                                if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion))
                                {
                                    if (Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion))
                                    {
                                        // We need to associate the screenshot's view ID with the component's view ID
                                        // because this special ID value is used for figuring out what screenshot image to display.
                                        screenshot.ViewId = screenCollection.GetByComponent(screenshot.Component).ViewId;

                                        string windowTitle = "*Screenshot imported from an old version of Auto Screen Capture*";

                                        Regex rgxOldSlidename = new Regex(@"^(?<Date>\d{4}-\d{2}-\d{2}) (?<Time>(?<Hour>\d{2})-(?<Minute>\d{2})-(?<Second>\d{2})-(?<Millisecond>\d{3}))");

                                        string hour        = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Hour"].Value;
                                        string minute      = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Minute"].Value;
                                        string second      = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Second"].Value;
                                        string millisecond = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Millisecond"].Value;

                                        screenshot.Date = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Date"].Value;
                                        screenshot.Time = hour + ":" + minute + ":" + second + "." + millisecond;

                                        screenshot.Slide.Name  = "{date=" + screenshot.Date + "}{time=" + screenshot.Time + "}";
                                        screenshot.Slide.Value = screenshot.Time + " [" + windowTitle + "]";

                                        screenshot.WindowTitle = windowTitle;
                                    }

                                    // Remove all the existing XML child nodes from the old XML screenshot.
                                    xScreenshot.RemoveAll();

                                    // Prepare the new XML child nodes for the old XML screenshot ...

                                    XmlElement xViewId = xDoc.CreateElement(SCREENSHOT_VIEWID);
                                    xViewId.InnerText = screenshot.ViewId.ToString();

                                    XmlElement xDate = xDoc.CreateElement(SCREENSHOT_DATE);
                                    xDate.InnerText = screenshot.Date;

                                    XmlElement xTime = xDoc.CreateElement(SCREENSHOT_TIME);
                                    xTime.InnerText = screenshot.Time;

                                    XmlElement xPath = xDoc.CreateElement(SCREENSHOT_PATH);
                                    xPath.InnerText = screenshot.Path;

                                    XmlElement xFormat = xDoc.CreateElement(SCREENSHOT_FORMAT);
                                    xFormat.InnerText = screenshot.Format.Name;

                                    XmlElement xComponent = xDoc.CreateElement(SCREENSHOT_COMPONENT);
                                    xComponent.InnerText = screenshot.Component.ToString();

                                    XmlElement xSlidename = xDoc.CreateElement(SCREENSHOT_SLIDENAME);
                                    xSlidename.InnerText = screenshot.Slide.Name;

                                    XmlElement xSlidevalue = xDoc.CreateElement(SCREENSHOT_SLIDEVALUE);
                                    xSlidevalue.InnerText = screenshot.Slide.Value;

                                    XmlElement xWindowTitle = xDoc.CreateElement(SCREENSHOT_WINDOW_TITLE);
                                    xWindowTitle.InnerText = screenshot.WindowTitle;

                                    XmlElement xProcessName = xDoc.CreateElement(SCREENSHOT_PROCESS_NAME);
                                    xProcessName.InnerText = screenshot.ProcessName;

                                    XmlElement xLabel = xDoc.CreateElement(SCREENSHOT_LABEL);
                                    xLabel.InnerText = screenshot.Label;

                                    // Create the new XML child nodes for the old XML screenshot so that it's now in the format of the new XML screenshot.
                                    xScreenshot.AppendChild(xViewId);
                                    xScreenshot.AppendChild(xDate);
                                    xScreenshot.AppendChild(xTime);
                                    xScreenshot.AppendChild(xPath);
                                    xScreenshot.AppendChild(xFormat);
                                    xScreenshot.AppendChild(xComponent);
                                    xScreenshot.AppendChild(xSlidename);
                                    xScreenshot.AppendChild(xSlidevalue);
                                    xScreenshot.AppendChild(xWindowTitle);
                                    xScreenshot.AppendChild(xProcessName);
                                    xScreenshot.AppendChild(xLabel);
                                }

                                if (!string.IsNullOrEmpty(screenshot.Date) &&
                                    !string.IsNullOrEmpty(screenshot.Time) &&
                                    !string.IsNullOrEmpty(screenshot.Path) &&
                                    screenshot.Format != null &&
                                    !string.IsNullOrEmpty(screenshot.Slide.Name) &&
                                    !string.IsNullOrEmpty(screenshot.Slide.Value) &&
                                    !string.IsNullOrEmpty(screenshot.WindowTitle))
                                {
                                    screenshot.Saved = true;
                                    Add(screenshot);
                                }
                            }
                        }
                        else
                        {
                            Log.Write("WARNING: Unable to load screenshots from screenshots.xml");
                        }

                        if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion))
                        {
                            Log.Write("Old application version discovered when loading screenshots.xml");

                            // We'll have to create the app:version and app:codename attributes for screenshots.xml if we're upgrading from "Clara".
                            if (Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion))
                            {
                                XmlAttribute attributeVersion  = xDoc.CreateAttribute("app", "version", "autoscreen");
                                XmlAttribute attributeCodename = xDoc.CreateAttribute("app", "codename", "autoscreen");

                                attributeVersion.Value  = Settings.ApplicationVersion;
                                attributeCodename.Value = Settings.ApplicationCodename;

                                xDoc.SelectSingleNode("/" + XML_FILE_ROOT_NODE).Attributes.Append(attributeVersion);
                                xDoc.SelectSingleNode("/" + XML_FILE_ROOT_NODE).Attributes.Append(attributeCodename);
                            }

                            // Apply the latest version and codename if the version of Auto Screen Capture is older than this version.
                            xDoc.SelectSingleNode("/" + XML_FILE_ROOT_NODE).Attributes["app:version"].Value  = Settings.ApplicationVersion;
                            xDoc.SelectSingleNode("/" + XML_FILE_ROOT_NODE).Attributes["app:codename"].Value = Settings.ApplicationCodename;

                            xDoc.Save(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile);

                            Log.Write("Upgraded screenshots.xml");
                        }
                    }
                }

                stopwatch.Stop();

                Log.Write("It took " + stopwatch.ElapsedMilliseconds + " milliseconds to load " + _screenshotList.Count + " screenshots");
            }
            catch (Exception ex)
            {
                Log.Write("ScreenshotCollection::Load", ex);
            }
            finally
            {
                _mutexWriteFile.ReleaseMutex();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Loads the screenshots.
        /// </summary>
        public static void Load(ImageFormatCollection imageFormatCollection, ScreenCollection screenCollection, RegionCollection regionCollection)
        {
            if (Directory.Exists(FileSystem.ApplicationFolder) &&
                File.Exists(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile))
            {
                xDoc = new XmlDocument();
                xDoc.Load(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile);

                AppVersion  = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value;
                AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value;

                XmlNodeList xScreeshots = xDoc.SelectNodes(SCREENSHOT_XPATH);

                foreach (XmlNode xScreenshot in xScreeshots)
                {
                    Screenshot screenshot = new Screenshot();
                    screenshot.Slide = new Slide();

                    XmlNodeReader xReader = new XmlNodeReader(xScreenshot);

                    while (xReader.Read())
                    {
                        if (xReader.IsStartElement())
                        {
                            switch (xReader.Name)
                            {
                            case SCREENSHOT_VIEWID:
                                xReader.Read();
                                screenshot.ViewId = Guid.Parse(xReader.Value);
                                break;

                            case SCREENSHOT_DATE:
                                xReader.Read();
                                screenshot.Date = xReader.Value;
                                break;

                            case SCREENSHOT_TIME:
                                xReader.Read();
                                screenshot.Time = xReader.Value;
                                break;

                            case SCREENSHOT_PATH:
                                xReader.Read();
                                screenshot.Path = xReader.Value;
                                break;

                            case SCREENSHOT_FORMAT:
                                xReader.Read();
                                screenshot.Format = imageFormatCollection.GetByName(xReader.Value);
                                break;

                            // 2.1 used "screen" for its definition of each display/monitor whereas 2.2 uses "component".
                            // Active Window is now represented by 0 rather than 5.
                            case SCREENSHOT_SCREEN:
                                if (Settings.VersionManager.IsOldAppVersion(AppVersion, AppCodename) &&
                                    Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null)
                                {
                                    xReader.Read();

                                    screenshot.Screen = Convert.ToInt32(xReader.Value);

                                    screenshot.Component = screenshot.Screen == 5 ? 0 : screenshot.Screen;
                                }
                                break;

                            // We still want to support "component" since this was introduced in version 2.2 as the new representation for "screen".
                            case SCREENSHOT_COMPONENT:
                                xReader.Read();
                                screenshot.Component = Convert.ToInt32(xReader.Value);

                                if (screenshot.Component == -1)
                                {
                                    screenshot.ScreenshotType = ScreenshotType.Region;
                                }
                                else if (screenshot.Component == 0)
                                {
                                    screenshot.ScreenshotType = ScreenshotType.ActiveWindow;
                                }
                                else
                                {
                                    screenshot.ScreenshotType = ScreenshotType.Screen;
                                }
                                break;

                            case SCREENSHOT_SLIDENAME:
                                xReader.Read();
                                screenshot.Slide.Name = xReader.Value;
                                break;

                            case SCREENSHOT_SLIDEVALUE:
                                xReader.Read();
                                screenshot.Slide.Value = xReader.Value;
                                break;

                            case SCREENSHOT_WINDOW_TITLE:
                                xReader.Read();
                                screenshot.WindowTitle = xReader.Value;
                                break;

                            case SCREENSHOT_LABEL:
                                xReader.Read();
                                screenshot.Label = xReader.Value;
                                break;
                            }
                        }
                    }

                    xReader.Close();

                    if (Settings.VersionManager.IsOldAppVersion(AppVersion, AppCodename))
                    {
                        if (Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null)
                        {
                            // We need to associate the screenshot's view ID with the component's view ID
                            // because this special ID value is used for figuring out what screenshot image to display.
                            screenshot.ViewId = screenCollection.GetByComponent(screenshot.Component).ViewId;

                            string windowTitle = "*Screenshot imported from an old version of Auto Screen Capture*";

                            Regex rgxOldSlidename =
                                new Regex(
                                    @"^(?<Date>\d{4}-\d{2}-\d{2}) (?<Time>(?<Hour>\d{2})-(?<Minute>\d{2})-(?<Second>\d{2})-(?<Millisecond>\d{3}))");

                            string hour        = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Hour"].Value;
                            string minute      = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Minute"].Value;
                            string second      = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Second"].Value;
                            string millisecond = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Millisecond"]
                                                 .Value;

                            screenshot.Date = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Date"].Value;
                            screenshot.Time = hour + ":" + minute + ":" + second + "." + millisecond;

                            screenshot.Slide.Name  = "{date=" + screenshot.Date + "}{time=" + screenshot.Time + "}";
                            screenshot.Slide.Value = screenshot.Time + " [" + windowTitle + "]";

                            screenshot.WindowTitle = windowTitle;
                        }
                    }

                    if (!string.IsNullOrEmpty(screenshot.Date) &&
                        !string.IsNullOrEmpty(screenshot.Time) &&
                        !string.IsNullOrEmpty(screenshot.Path) &&
                        screenshot.Format != null &&
                        !string.IsNullOrEmpty(screenshot.Slide.Name) &&
                        !string.IsNullOrEmpty(screenshot.Slide.Value))
                    {
                        Add(screenshot, screenCollection, regionCollection);
                    }
                }

                // Write out the upgraded screenshots (if any were found).
                if (Settings.VersionManager.IsOldAppVersion(AppVersion, AppCodename))
                {
                    Save();
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Loads the screenshots taken on a particular day from the screenshots.xml file.
        /// </summary>
        /// <param name="date">The date to load screenshots from.</param>
        public int LoadXmlFileAndAddScreenshots(string date)
        {
            try
            {
                _mutexWriteFile.WaitOne();

                XmlNodeList xScreenshots = null;

                if (string.IsNullOrEmpty(date))
                {
                    return(1);
                }

                if (xDoc != null)
                {
                    lock (xDoc)
                    {
                        AppVersion  = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value;
                        AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value;

                        Log.WriteDebugMessage("Loading screenshots taken on " + date + " from \"" + FileSystem.ScreenshotsFile + "\" using XPath query \"" + SCREENSHOT_XPATH + "[date='" + date + "']" + "\"");
                        xScreenshots = xDoc.SelectNodes(SCREENSHOT_XPATH + "[date='" + date + "']");

                        if (xScreenshots != null)
                        {
                            Log.WriteMessage("Loading " + xScreenshots.Count + " screenshots taken on " + date);

                            int screenshotsLoadLimit = Convert.ToInt32(Settings.Application.GetByKey("ScreenshotsLoadLimit", DefaultSettings.ScreenshotsLoadLimit).Value);

                            if (xScreenshots.Count >= screenshotsLoadLimit)
                            {
                                HelpTip.Message = "Cannot load screenshots taken on " + date + " as the number of screenshots being loaded (" + xScreenshots.Count + ") exceeds the allowed load limit (" + screenshotsLoadLimit + ")";

                                Log.WriteDebugMessage("Cannot load screenshots. The number of screenshots to be loaded (" + xScreenshots.Count + ") exceeded the number allowed set by ScreenshotsLoadLimit (" + screenshotsLoadLimit + ")");

                                return(2);
                            }

                            foreach (XmlNode xScreenshot in xScreenshots)
                            {
                                Screenshot screenshot = new Screenshot();
                                screenshot.Slide = new Slide();

                                XmlNodeReader xReader = new XmlNodeReader(xScreenshot);

                                while (xReader.Read())
                                {
                                    if (xReader.IsStartElement() && !xReader.IsEmptyElement)
                                    {
                                        switch (xReader.Name)
                                        {
                                        case SCREENSHOT_VIEWID:
                                            xReader.Read();
                                            screenshot.ViewId = Guid.Parse(xReader.Value);
                                            break;

                                        case SCREENSHOT_DATE:
                                            xReader.Read();
                                            screenshot.Date       = xReader.Value;
                                            screenshot.Slide.Date = xReader.Value;
                                            break;

                                        case SCREENSHOT_TIME:
                                            xReader.Read();
                                            screenshot.Time = xReader.Value;
                                            break;

                                        case SCREENSHOT_PATH:
                                            xReader.Read();
                                            screenshot.Path = xReader.Value;
                                            break;

                                        case SCREENSHOT_FORMAT:
                                            xReader.Read();
                                            screenshot.Format = _imageFormatCollection.GetByName(xReader.Value);
                                            break;

                                        // 2.1 used "screen" for its definition of each display/monitor whereas 2.2 uses "component".
                                        // Active Window is now represented by 0 rather than 5.
                                        case SCREENSHOT_SCREEN:
                                            if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion) &&
                                                Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion))
                                            {
                                                xReader.Read();

                                                screenshot.Screen = Convert.ToInt32(xReader.Value);

                                                screenshot.Component = screenshot.Screen == 5 ? 0 : screenshot.Screen;
                                            }
                                            break;

                                        // We still want to support "component" since this was introduced in version 2.2 as the new representation for "screen".
                                        case SCREENSHOT_COMPONENT:
                                            xReader.Read();
                                            screenshot.Component = Convert.ToInt32(xReader.Value);

                                            if (screenshot.Component == -1)
                                            {
                                                screenshot.ScreenshotType = ScreenshotType.Region;
                                            }
                                            else if (screenshot.Component == 0)
                                            {
                                                screenshot.ScreenshotType = ScreenshotType.ActiveWindow;
                                            }
                                            else
                                            {
                                                screenshot.ScreenshotType = ScreenshotType.Screen;
                                            }
                                            break;

                                        case SCREENSHOT_SLIDENAME:
                                            xReader.Read();
                                            screenshot.Slide.Name = xReader.Value;
                                            break;

                                        case SCREENSHOT_SLIDEVALUE:
                                            xReader.Read();
                                            screenshot.Slide.Value = xReader.Value;
                                            break;

                                        case SCREENSHOT_WINDOW_TITLE:
                                            xReader.Read();
                                            screenshot.WindowTitle = xReader.Value;
                                            break;

                                        case SCREENSHOT_PROCESS_NAME:
                                            xReader.Read();
                                            screenshot.ProcessName = xReader.Value;
                                            break;

                                        case SCREENSHOT_LABEL:
                                            xReader.Read();
                                            screenshot.Label = xReader.Value;
                                            break;
                                        }
                                    }
                                }

                                xReader.Close();

                                if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion))
                                {
                                    if (Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion))
                                    {
                                        // We need to associate the screenshot's view ID with the component's view ID
                                        // because this special ID value is used for figuring out what screenshot image to display.
                                        screenshot.ViewId = _screenCollection.GetByComponent(screenshot.Component).ViewId;

                                        string windowTitle = "*Screenshot imported from an old version of " + Settings.ApplicationName + "*";

                                        Regex rgxOldSlidename = new Regex(@"^(?<Date>\d{4}-\d{2}-\d{2}) (?<Time>(?<Hour>\d{2})-(?<Minute>\d{2})-(?<Second>\d{2})-(?<Millisecond>\d{3}))");

                                        string hour        = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Hour"].Value;
                                        string minute      = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Minute"].Value;
                                        string second      = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Second"].Value;
                                        string millisecond = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Millisecond"].Value;

                                        screenshot.Date = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Date"].Value;
                                        screenshot.Time = hour + ":" + minute + ":" + second + "." + millisecond;

                                        screenshot.Slide.Name  = "{date=" + screenshot.Date + "}{time=" + screenshot.Time + "}";
                                        screenshot.Slide.Value = screenshot.Time + " [" + windowTitle + "]";

                                        screenshot.WindowTitle = windowTitle;
                                    }

                                    // Remove all the existing XML child nodes from the old XML screenshot.
                                    xScreenshot.RemoveAll();

                                    // Prepare the new XML child nodes for the old XML screenshot ...

                                    XmlElement xViewId = xDoc.CreateElement(SCREENSHOT_VIEWID);
                                    xViewId.InnerText = screenshot.ViewId.ToString();

                                    XmlElement xDate = xDoc.CreateElement(SCREENSHOT_DATE);
                                    xDate.InnerText = screenshot.Date;

                                    XmlElement xTime = xDoc.CreateElement(SCREENSHOT_TIME);
                                    xTime.InnerText = screenshot.Time;

                                    XmlElement xPath = xDoc.CreateElement(SCREENSHOT_PATH);
                                    xPath.InnerText = screenshot.Path;

                                    XmlElement xFormat = xDoc.CreateElement(SCREENSHOT_FORMAT);
                                    xFormat.InnerText = screenshot.Format.Name;

                                    XmlElement xComponent = xDoc.CreateElement(SCREENSHOT_COMPONENT);
                                    xComponent.InnerText = screenshot.Component.ToString();

                                    XmlElement xSlidename = xDoc.CreateElement(SCREENSHOT_SLIDENAME);
                                    xSlidename.InnerText = screenshot.Slide.Name;

                                    XmlElement xSlidevalue = xDoc.CreateElement(SCREENSHOT_SLIDEVALUE);
                                    xSlidevalue.InnerText = screenshot.Slide.Value;

                                    XmlElement xWindowTitle = xDoc.CreateElement(SCREENSHOT_WINDOW_TITLE);
                                    xWindowTitle.InnerText = screenshot.WindowTitle;

                                    XmlElement xProcessName = xDoc.CreateElement(SCREENSHOT_PROCESS_NAME);
                                    xProcessName.InnerText = screenshot.ProcessName;

                                    XmlElement xLabel = xDoc.CreateElement(SCREENSHOT_LABEL);
                                    xLabel.InnerText = screenshot.Label;

                                    // Create the new XML child nodes for the old XML screenshot so that it's now in the format of the new XML screenshot.
                                    xScreenshot.AppendChild(xViewId);
                                    xScreenshot.AppendChild(xDate);
                                    xScreenshot.AppendChild(xTime);
                                    xScreenshot.AppendChild(xPath);
                                    xScreenshot.AppendChild(xFormat);
                                    xScreenshot.AppendChild(xComponent);
                                    xScreenshot.AppendChild(xSlidename);
                                    xScreenshot.AppendChild(xSlidevalue);
                                    xScreenshot.AppendChild(xWindowTitle);
                                    xScreenshot.AppendChild(xProcessName);
                                    xScreenshot.AppendChild(xLabel);
                                }

                                if (!string.IsNullOrEmpty(screenshot.Date) &&
                                    !string.IsNullOrEmpty(screenshot.Time) &&
                                    !string.IsNullOrEmpty(screenshot.Path) &&
                                    screenshot.Format != null &&
                                    !string.IsNullOrEmpty(screenshot.Slide.Name) &&
                                    !string.IsNullOrEmpty(screenshot.Slide.Value) &&
                                    !string.IsNullOrEmpty(screenshot.WindowTitle))
                                {
                                    // Since we're loading existing screenshots from the XML document each screenshot needs to be flagged as being "Saved"
                                    // because they were already saved to the file before loading them. The "Saved" flag should only be used when we're
                                    // saving new screenshots to avoid saving the entire screenshots collection.
                                    //
                                    // In other words, any screenshot flagged with a "Saved" value of "true" will be treated as if it is already in the file.
                                    // A screenshot flagged with a "Saved" value of "false" will be treated as a new screenshot that should be saved to the file.
                                    screenshot.Saved = true;

                                    Add(screenshot);
                                }
                            }
                        }
                        else
                        {
                            Log.WriteDebugMessage("WARNING: Unable to load screenshots taken on " + date + " from \"" + FileSystem.ScreenshotsFile + "\"");
                        }
                    }
                }

                return(0);
            }
            catch (Exception ex)
            {
                Log.WriteExceptionMessage("ScreenshotCollection::LoadXmlFileAndAddScreenshots", ex);

                return(-1);
            }
            finally
            {
                _mutexWriteFile.ReleaseMutex();
            }
        }