/// <summary>
        /// Checks whether there has been enough of a change in daylight setting to warrant a wallpaper change, and if there has been,
        /// returns the WBImage representing the new wallpaper to be changed to
        /// </summary>
        /// <returns>
        /// WBImage representing the new wallpaper, if there has been enough change in daylight setting to warrant a wallpaper change;
        /// null if there has not been enough change in daylight setting to warrant wallpaper change
        /// or there are no images in library
        /// </returns>
        private WBImage CheckforChange()
        {
            // Only update the wall if there is at least one image in library to work with; otherwise return null
            if (Library.LibraryList.Count > 0)
            {
                // First check for (and remove) any missing images
                Library.CheckMissing();

                DateTime now = DateTime.Now;

                // Find closest image to current time's daylight value
                CurrentDaylight = GetDaylightValue(now);
                WBImage checkImage = FindClosestImage(now);

                // If image is different from current, return it
                if (checkImage != _currentImage)
                {
                    return(checkImage);
                }
                // If new image is the same then no change will occur; return null
                else
                {
                    return(null);
                }
            }

            // If no images in library, just return null
            return(null);
        }
        /// <summary>
        /// Higher-level function for checking daylight + updating wallpaper if enough change has been
        /// detected; checks whether current wallpaper is different from the wallpaper that should be set at
        /// this time; if it is it sets that wallpaper
        /// Also updates the next update time and resets it to blank if one cannot be found
        /// </summary>
        /// <returns>True if the current wallpaper was changed to another, false if not</returns>
        public bool CheckAndUpdate()
        {
            bool changed = false;

            // Check for change in wall
            WBImage image = CheckforChange();

            // If there is change, update the wall to the new one
            if (image != null)
            {
                SetWall(image, WallpaperStyle);
                changed = true;
            }

            // Find the next time when wallpaper will change
            _nextUpdateTime = FindNextUpdateTime();

            // Restart the timer if a valid next update time was found
            if (_nextUpdateTime != new DateTime())
            {
                _updateTimer.Interval = _nextUpdateTime.Subtract(DateTime.Now);
                _updateTimer.Start();
            }
            // Otherwise reset the timers (sets progress to blank, giving user 'wallpaper will not change'
            // message in the progress bar)
            else
            {
                ResetTimers();
            }

            return(changed);
        }
        /// <summary>
        /// Sets the wallpaper to the WBImage represented by the selection sent from the front-end
        /// (front-end sends a collection representing the selected front-end element, which is converted
        /// into the relevent WBImage)
        /// </summary>
        /// <param name="collection"></param>
        private void Set(object collection)
        {
            // Cast selected image and set it as wall
            System.Collections.IList items = (System.Collections.IList)collection;
            WBImage selectedImage          = (WBImage)items[0];

            SetWall(selectedImage, WallpaperStyle);
        }
        /// <summary>
        /// Models the next 24-hour day using the current settings and searches for the next time that
        /// a wallpaper change will occur; returns that time if it is found, returns a "blank" new DateTime()
        /// if no update will occur in 24 hours (i.e. will not occur at all with current settings);
        /// Also sets the front-end progress bar string to reflect that wallpaper will not change if this is
        /// the case
        /// </summary>
        /// <returns>
        /// DateTime representing time that next wallpaper update will occur if it is found,
        /// "blank" DateTime with value == new DateTime() == DateTime.Min if this time is not found (i.e.
        /// wallpaper will not update with the current settings
        /// </returns>
        private DateTime FindNextUpdateTime()
        {
            // Only do checks if there's at least 2 images in library; otherwise wallpaper will not change
            if (Library.LibraryList.Count > 1)
            {
                // Set last update time to now if it has not been set yet
                if (_lastUpdateTime == new DateTime())
                {
                    _lastUpdateTime = DateTime.Now;
                }

                // Get first check time
                DateTime nextCheckTime = _lastUpdateTime.AddMinutes(_checkInterval.TotalMinutes);

                // Continue looping until intervals have looped around back to the same time on the next day
                // I.e. the check time has the same date as the timer's start time, or the checktime has looped
                // over to the next day but is still before the timer's start time on that day
                // I.e. exits when check time passes the timer's start time but on the following day
                while (nextCheckTime.Date == _lastUpdateTime.Date ||
                       (nextCheckTime.Date == _lastUpdateTime.AddDays(1).Date &&
                        nextCheckTime.TimeOfDay.CompareTo(_lastUpdateTime.TimeOfDay) <= 0))
                {
                    // Next image that will be set as wall when brightness is checked

                    WBImage nextCheckImage = FindClosestImage(nextCheckTime);

                    // Return if the image will actually be different at this check time (i.e. it will actually
                    // update to a different wall when checked)
                    if (_currentImage != nextCheckImage)
                    {
                        return(nextCheckTime);
                    }
                    // Otherwise start the loop again, checking at the time after the next interval
                    else
                    {
                        nextCheckTime = nextCheckTime.AddMinutes(_checkInterval.TotalMinutes);
                    }
                }

                // If looped all the way around with no update, then there won't ever be any actual wall change
                // with the current library/automation settings
                // In this case, update progress report to reflect this and return a basic DateTime
                ProgressReport = "Wallpaper will not change with current settings";
                return(new DateTime());
            }
            // If < 2 images in library, wallpaper will not change
            else
            {
                ProgressReport = "Wallpaper will not change with current settings";
                return(new DateTime());
            }
        }
        /// <summary>
        /// Sets desktop wallpaper to given WBImage using given style (fill, fit, tiled, etc.)
        /// </summary>
        /// <param name="image">WBImage to be set as wallpaper</param>
        /// <param name="style">
        /// Wallpaper style to be used when setting:
        /// "Tiled", "Centered", "Stretched", "Fit", or "Fill"
        /// </param>
        private void SetWall(WBImage image, string style)
        {
            // Taken partly from https://stackoverflow.com/questions/1061678/change-desktop-wallpaper-using-code-in-net,
            // partly from https://stackoverflow.com/questions/19989906/how-to-set-wallpaper-style-fill-stretch-according-to-windows-version

            // Open registry key used to set wallpaper style
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);

            // Set appropriate values on key depending on wallpaper style choice
            if (style == "Tiled")
            {
                key.SetValue(@"WallpaperStyle", "0");
                key.SetValue(@"TileWallpaper", "1");
            }
            else if (style == "Centered")
            {
                key.SetValue(@"WallpaperStyle", "0");
                key.SetValue(@"TileWallpaper", "0");
            }
            else if (style == "Stretched")
            {
                key.SetValue(@"WallpaperStyle", "2");
                key.SetValue(@"TileWallpaper", "0");
            }
            else if (style == "Fit")
            {
                key.SetValue(@"WallpaperStyle", "6");
                key.SetValue(@"TileWallpaper", "0");
            }
            else if (style == "Fill")
            {
                key.SetValue(@"WallpaperStyle", "10");
                key.SetValue(@"TileWallpaper", "0");
            }

            // Set the wallpaper via system parameter
            SystemParametersInfo(SPI_SETDESKWALLPAPER,
                                 0,
                                 image.Path,
                                 SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);

            // Update current closest's thumb, background color, and front-end brightness value
            CurrentWallThumb      = image.Thumbnail;
            CurrentWallBack       = image.BackgroundColor;
            CurrentWallBrightness = image.AverageBrightness;
            CurrentWallFileName   = Path.GetFileName(image.Path);
            _currentImage         = image;

            _lastUpdateTime = DateTime.Now;
        }
Esempio n. 6
0
 /// <summary>
 /// Adds given WBImage at given filePath to the library if it is not already in library
 /// </summary>
 /// <param name="image"></param>
 /// <param name="filePath"></param>
 private void AddImage(WBImage image)
 {
     // Give user message and don't add this image if it is already in library
     if (LibraryList.Any(checkImage => checkImage.Path.Equals(image.Path)))
     {
         _notifier.ShowInformation(string.Format("{0} was not added since it is already in the library",
                                                 Path.GetFileName(image.Path)));
     }
     // Otherwise add the image to the library
     else
     {
         LibraryList.Add(image);
     }
 }
        /// <summary>
        /// Returns image in library with brightness value closest to the daylight value at given DateTime time
        /// with current manager settings; returns null if no images in library to work with
        /// </summary>
        /// <param name="time">DateTime to be used to compare daylight value with library images' brightness
        /// values</param>
        /// <returns>
        /// WBImage in library with brightness value closest to the daylight value at given
        /// DateTime time using current manager settings;
        /// null if no images in library
        /// </returns>
        private WBImage FindClosestImage(DateTime time)
        {
            // Only search for closest if there are images in the library
            if (Library.LibraryList.Count > 0)
            {
                // Get current daylight value
                double daylightAtTime = GetDaylightValue(time);
                // Find (enabled) image with brightness value closest to current daylight value
                WBImage closestImage =
                    Library.LibraryList.Aggregate((x, y) =>
                                                  (Math.Abs(x.AverageBrightness - daylightAtTime)
                                                   < Math.Abs(y.AverageBrightness - daylightAtTime) ||
                                                   !y.IsEnabled) &&
                                                  x.IsEnabled
                                                           ? x : y);
                return(closestImage);
            }

            // Return null if no images in library
            else
            {
                return(null);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Generalized function working with both adding files and adding folders; adds image files from
        /// given filePaths list to the library
        /// </summary>
        /// <param name="sender">BackgroundWorker running the task</param>
        /// <param name="filePaths">List of filepaths for image files to be added to library</param>
        private void AddWork(object sender, List <string> filePaths)
        {
            // For keeping track of progress
            int numFiles = filePaths.Count;
            int progress;

            // Create the WBImage object for each image file and add it to library
            for (int i = 0; i < filePaths.Count; i++)
            {
                // If user cancelled then exit loop and return before adding next file
                if (_worker.CancellationPending == true)
                {
                    return;
                }

                // Get stream, path, and filename for current file
                string filePath = filePaths[i];
                string fileName = Path.GetFileName(filePath);

                // Create progress string to be shown in progress bar
                string progressString = string.Format("{0}|{1}|{2}",
                                                      fileName,
                                                      i + 1,
                                                      numFiles);

                // Get current progress as percentage of total files
                progress = Convert.ToInt32((double)i / numFiles * 100);

                // Report progress and current file being worked on
                (sender as BackgroundWorker).ReportProgress(progress, progressString);

                // Try to add current file to the library
                try
                {
                    // Create the bitmap in the scope of the background worker (this is the performance intensive
                    // task for this whole process)
                    using (Bitmap bitmap = new Bitmap(File.Open(filePaths[i], FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
                    {
                        // Create the WBImage for this file and add it to the results list (in the main thread
                        // so that it doesn't get upset that UI-relevant objects were created in the background thread)
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            WBImage image = new WBImage(bitmap, filePath);
                            AddImage(image);
                        });
                    }
                }
                // If file fails to open, notify user
                catch (IOException)
                {
                    // Show failure toast notif
                    _notifier.ShowError(string.Format("Failed to add {0} to library; file corrupted or in use by another program",
                                                      fileName));
                }
                // FIXME: find a way to overcome this horrific memory allocation conundrum!
                // If memory allocation for Bitmap fails, notify user that image file is too big
                catch (OutOfMemoryException)
                {
                    // Show failure toast notif
                    _notifier.ShowError(string.Format("Failed to add {0} to library; image file is too big!",
                                                      fileName));
                }
            }
        }