From 29a951a8c0621851d0d09562bf7ba56ccdec4524 Mon Sep 17 00:00:00 2001 From: Timothy Johnson Date: Sat, 20 Apr 2019 23:07:05 -0400 Subject: [PATCH] Further improvements to error handling during theme load/import --- README.md | 4 ++++ src/AboutDialog.Designer.cs | 1 + src/AboutDialog.cs | 26 +++++++++++++++++++++++--- src/App.config | 9 +++------ src/ProgressDialog.cs | 10 ++++++---- src/ThemeDialog.Designer.cs | 23 +++++------------------ src/ThemeDialog.cs | 20 +++++--------------- src/ThemeLoader.cs | 24 ++++++++++++++++++------ src/ThemeManager.cs | 29 +++++++++++++++++++---------- src/WallpaperChangeScheduler.cs | 7 +++---- src/WinDynamicDesktop.csproj | 3 +-- src/app.manifest | 4 +--- 12 files changed, 89 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 7aa927b..5c7ac88 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,10 @@ This is a commonly requested feature to mimic the behavior of macOS and many Lin You are not limited to the Mojave themes that come preinstalled with the app. Custom themes created by the community can be downloaded [here](https://github.com/t1m0thyj/WinDynamicDesktop/wiki/Community-created-themes). You can also create your own theme that uses whatever wallpaper images you want, by following the instructions in [this tutorial](https://github.com/t1m0thyj/WinDynamicDesktop/wiki/Creating-custom-themes). +### Can I translate the app into my language? + +Yes, translations are welcome. For instructions on how to create them and where to submit them, see [here](https://github.com/t1m0thyj/WDD-locale). + ### How can I hide the tray icon? If you want to run the app silently with no icon in the system tray, you can do this by editing the `settings.conf` file which is in the same folder as the EXE. Change the setting `"hideTrayIcon":false` to `"hideTrayIcon":true` (or add it if it doesn't exist), then restart the app. diff --git a/src/AboutDialog.Designer.cs b/src/AboutDialog.Designer.cs index c073664..d4d1243 100644 --- a/src/AboutDialog.Designer.cs +++ b/src/AboutDialog.Designer.cs @@ -112,6 +112,7 @@ private void InitializeComponent() // // donateButton // + this.donateButton.AutoSize = true; this.donateButton.Location = new System.Drawing.Point(80, 97); this.donateButton.Name = "donateButton"; this.donateButton.Size = new System.Drawing.Size(64, 23); diff --git a/src/AboutDialog.cs b/src/AboutDialog.cs index 9623661..884473d 100644 --- a/src/AboutDialog.cs +++ b/src/AboutDialog.cs @@ -26,15 +26,35 @@ public AboutDialog() this.Font = SystemFonts.MessageBoxFont; this.nameLabel.Font = new Font(this.Font.Name, this.Font.Size * 1.2F, FontStyle.Bold); - int minWidth = TextRenderer.MeasureText(this.descriptionLabel.Text, this.Font).Width; - minWidth = minWidth + (this.descriptionLabel.Width - minWidth) / 2 + - this.descriptionLabel.Location.X * 2; + int minWidth = TextRenderer.MeasureText(descriptionLabel.Text, this.Font).Width; + + if (this.descriptionLabel.Width < minWidth) + { + minWidth += descriptionLabel.Location.X * 2; + nameLabel.Width = minWidth; + copyrightLabel.Width = minWidth; + descriptionLabel.Width = minWidth; + websiteLabel.Width = minWidth; + } + + minWidth = minWidth + (descriptionLabel.Width - minWidth) / 2 + + descriptionLabel.Location.X * 2; if (this.Size.Width < minWidth) { this.Size = new Size(minWidth, this.Size.Height); this.CenterToScreen(); } + + minWidth = TextRenderer.MeasureText(creditsButton.Text, this.Font).Width + 10; + + if (this.creditsButton.Width < minWidth) + { + int oldWidth = creditsButton.Width; + creditsButton.Width = minWidth; + donateButton.Location = new Point(donateButton.Location.X + minWidth - oldWidth, + donateButton.Location.Y); + } } private void AboutDialog_Load(object sender, EventArgs e) diff --git a/src/App.config b/src/App.config index aac72e5..1394251 100644 --- a/src/App.config +++ b/src/App.config @@ -1,8 +1,8 @@ - - - + + + @@ -11,7 +11,4 @@ - - - diff --git a/src/ProgressDialog.cs b/src/ProgressDialog.cs index 5a6a970..bda40db 100644 --- a/src/ProgressDialog.cs +++ b/src/ProgressDialog.cs @@ -124,7 +124,8 @@ private void ImportNext() string themePath = importQueue.Peek(); this.Invoke(new Action(() => UpdateImportStatus(themePath))); ThemeConfig theme = ThemeManager.ImportTheme(themePath); - this.Invoke(new Action(() => ThemeLoader.HandleError(theme.themeId))); + this.Invoke(new Action(() => ThemeLoader.HandleError( + Path.GetFileNameWithoutExtension(themePath)))); if (theme != null) { @@ -132,7 +133,7 @@ private void ImportNext() { downloadQueue = new Queue( new List() { theme }); - DownloadNext(); // TODO Test if this works + DownloadNext(); // TODO Test this } ThemeManager.importedThemes.Add(theme); @@ -172,7 +173,7 @@ private void OnDownloadProgressChanged(object sender, DownloadProgressChangedEve { UpdateTotalPercentage(e.ProgressPercentage); - fileTransferSpeedLabel.Text = string.Format(_("{0} MB/s"), + fileTransferSpeedLabel.Text = string.Format(_("{0} MB/s"), (e.BytesReceived / 1024f / 1024f / stopwatch.Elapsed.TotalSeconds).ToString("0.#")); fileSizeProgressLabel.Text = string.Format(_("{0} MB of {1} MB"), @@ -211,7 +212,8 @@ await Task.Run(() => ThemeLoader.ExtractTheme(theme.themeId + "_images.zip", } else { - ThemeManager.DisableTheme(theme.themeId); // TODO Handle error here for failed download + ThemeLoader.HandleError(theme.themeId, string.Format( + _("Failed to download images for the '{0}' theme"), theme.themeId)); } } diff --git a/src/ThemeDialog.Designer.cs b/src/ThemeDialog.Designer.cs index 1a2986f..9fa7c49 100644 --- a/src/ThemeDialog.Designer.cs +++ b/src/ThemeDialog.Designer.cs @@ -36,7 +36,6 @@ private void InitializeComponent() this.imageNumberLabel = new System.Windows.Forms.Label(); this.nextButton = new System.Windows.Forms.Button(); this.lastButton = new System.Windows.Forms.Button(); - this.darkModeCheckbox = new System.Windows.Forms.CheckBox(); this.applyButton = new System.Windows.Forms.Button(); this.closeButton = new System.Windows.Forms.Button(); this.themeLinkLabel = new System.Windows.Forms.LinkLabel(); @@ -98,9 +97,9 @@ private void InitializeComponent() // // imageNumberLabel // - this.imageNumberLabel.Location = new System.Drawing.Point(111, 217); + this.imageNumberLabel.Location = new System.Drawing.Point(112, 217); this.imageNumberLabel.Name = "imageNumberLabel"; - this.imageNumberLabel.Size = new System.Drawing.Size(125, 13); + this.imageNumberLabel.Size = new System.Drawing.Size(123, 13); this.imageNumberLabel.TabIndex = 10; this.imageNumberLabel.Text = "label1"; this.imageNumberLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -125,18 +124,6 @@ private void InitializeComponent() this.lastButton.UseVisualStyleBackColor = true; this.lastButton.Click += new System.EventHandler(this.lastButton_Click); // - // darkModeCheckbox - // - this.darkModeCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.darkModeCheckbox.AutoSize = true; - this.darkModeCheckbox.Location = new System.Drawing.Point(353, 300); - this.darkModeCheckbox.Name = "darkModeCheckbox"; - this.darkModeCheckbox.Size = new System.Drawing.Size(79, 17); - this.darkModeCheckbox.TabIndex = 4; - this.darkModeCheckbox.Text = "Dark Mode"; - this.darkModeCheckbox.UseVisualStyleBackColor = true; - this.darkModeCheckbox.CheckedChanged += new System.EventHandler(this.darkModeCheckbox_CheckedChanged); - // // applyButton // this.applyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); @@ -162,8 +149,9 @@ private void InitializeComponent() // // themeLinkLabel // + this.themeLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.themeLinkLabel.AutoSize = true; - this.themeLinkLabel.Location = new System.Drawing.Point(136, 300); + this.themeLinkLabel.Location = new System.Drawing.Point(314, 300); this.themeLinkLabel.Name = "themeLinkLabel"; this.themeLinkLabel.Size = new System.Drawing.Size(118, 13); this.themeLinkLabel.TabIndex = 3; @@ -173,6 +161,7 @@ private void InitializeComponent() // // importButton // + this.importButton.AutoSize = true; this.importButton.Location = new System.Drawing.Point(15, 296); this.importButton.Name = "importButton"; this.importButton.Size = new System.Drawing.Size(107, 23); @@ -239,7 +228,6 @@ private void InitializeComponent() this.Controls.Add(this.importButton); this.Controls.Add(this.themeLinkLabel); this.Controls.Add(this.previewBox); - this.Controls.Add(this.darkModeCheckbox); this.Controls.Add(this.applyButton); this.Controls.Add(this.closeButton); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; @@ -265,7 +253,6 @@ private void InitializeComponent() private System.Windows.Forms.Label imageNumberLabel; private System.Windows.Forms.Button nextButton; private System.Windows.Forms.Button lastButton; - private System.Windows.Forms.CheckBox darkModeCheckbox; private System.Windows.Forms.Button applyButton; private System.Windows.Forms.Button closeButton; private System.Windows.Forms.LinkLabel themeLinkLabel; diff --git a/src/ThemeDialog.cs b/src/ThemeDialog.cs index 20cde92..66bad6e 100644 --- a/src/ThemeDialog.cs +++ b/src/ThemeDialog.cs @@ -47,7 +47,7 @@ public ThemeDialog() public void ImportThemes(List themePaths) { - ProgressDialog importDialog = new ProgressDialog(); + ProgressDialog importDialog = new ProgressDialog() { Owner = this }; importDialog.FormClosing += OnImportDialogClosing; importDialog.Show(); importDialog.InitImport(themePaths); @@ -164,14 +164,9 @@ private string GetCreditsText() private List GetImageList(ThemeConfig theme) { List imageList = new List(); - - if (!darkModeCheckbox.Checked) - { - imageList.AddRange(theme.sunriseImageList); - imageList.AddRange(theme.dayImageList); - imageList.AddRange(theme.sunsetImageList); - } - + imageList.AddRange(theme.sunriseImageList); + imageList.AddRange(theme.dayImageList); + imageList.AddRange(theme.sunsetImageList); imageList.AddRange(theme.nightImageList); return imageList; } @@ -274,8 +269,6 @@ private void ThemeDialog_Load(object sender, EventArgs e) imageListView1.ContextMenuStrip = contextMenuStrip1; imageListView1.SetRenderer(new ThemeListViewRenderer()); - darkModeCheckbox.Checked = JsonConfig.settings.darkMode; - Size thumbnailSize = GetThumbnailSize(); imageListView1.ThumbnailSize = thumbnailSize; imageListView1.Items.Add(_("None"), ShrinkImage(windowsWallpaper, thumbnailSize.Width, @@ -337,8 +330,7 @@ private void imageListView1_SelectionChanged(object sender, EventArgs e) SolarData solarData = SunriseSunsetService.GetSolarData(DateTime.Today); ThemeConfig theme = ThemeManager.themeSettings[selectedIndex - 1]; imageNumber = GetImageList(theme).IndexOf( - AppContext.wpEngine.GetImageData(solarData, theme, - darkModeCheckbox.Checked).Item1) + 1; + AppContext.wpEngine.GetImageData(solarData, theme).Item1) + 1; } creditsLabel.Text = GetCreditsText(); @@ -413,8 +405,6 @@ private void applyButton_Click(object sender, EventArgs e) } JsonConfig.settings.themeName = ThemeManager.currentTheme?.themeId; - JsonConfig.settings.darkMode = darkModeCheckbox.Checked; - MainMenu.darkModeItem.Checked = JsonConfig.settings.darkMode; if (selectedIndex == 0) { diff --git a/src/ThemeLoader.cs b/src/ThemeLoader.cs index 073703b..79a478d 100644 --- a/src/ThemeLoader.cs +++ b/src/ThemeLoader.cs @@ -72,8 +72,19 @@ public static void HandleError(string themeId) TaskbarProgress.SetState(taskbarHandle, TaskbarProgress.TaskbarStates.Error); } - MessageBox.Show(string.Format(_("Failed to load '{0}' theme:\n{1}"), themeId, - errorMsg), _("Error"), MessageBoxButtons.OK, MessageBoxIcon.Warning); + if (!ThemeManager.importMode) + { + DialogResult result = MessageBox.Show(string.Format(_("Failed to load '{0}' " + + "theme:\n{1}\n\nDo you want to disable this theme to prevent the error from " + + "happening again?"), themeId, errorMsg), _("Error"), MessageBoxButtons.YesNo, + MessageBoxIcon.Warning); + ThemeManager.DisableTheme(themeId, result == DialogResult.Yes); + } + else + { + MessageBox.Show(string.Format(_("Failed to import '{0}' theme:\n{1}"), themeId, + errorMsg), _("Error"), MessageBoxButtons.OK, MessageBoxIcon.Warning); + } if (taskbarHandle != IntPtr.Zero) { @@ -81,11 +92,12 @@ public static void HandleError(string themeId) } errorMsg = null; + } - if (!ThemeManager.importMode) - { - ThemeManager.DisableTheme(themeId); - } + public static void HandleError(string themeId, string errorText) + { + errorMsg = errorText; + HandleError(themeId); } public static bool PromptDialog(string dialogText) diff --git a/src/ThemeManager.cs b/src/ThemeManager.cs index 69634bd..4f3b413 100644 --- a/src/ThemeManager.cs +++ b/src/ThemeManager.cs @@ -73,19 +73,16 @@ public static string GetThemeName(ThemeConfig theme) return theme.displayName ?? theme.themeId.Replace('_', ' '); } - public static void DisableTheme(string themeId) + public static void DisableTheme(string themeId, bool permanent) { themeSettings.RemoveAll(t => t.themeId == themeId); - if (currentTheme.themeId == themeId) + if (currentTheme != null && (currentTheme.themeId == themeId)) { currentTheme = null; } - bool shouldDisable = ThemeLoader.PromptDialog(_("The '{0}' theme could not be " + - "loaded. Do you want to disable it to prevent this error from happening again?")); - - if (shouldDisable) + if (permanent) { Directory.Move(Path.Combine("themes", themeId), Path.Combine("themes", "." + themeId)); @@ -109,17 +106,22 @@ public static ThemeConfig ImportTheme(string importPath) } Directory.CreateDirectory(Path.Combine("themes", themeId)); + bool shouldContinue = true; + ThemeConfig theme = null; if (Path.GetExtension(importPath) != ".json") { - ThemeLoader.ExtractTheme(importPath, themeId); + shouldContinue = ThemeLoader.ExtractTheme(importPath, themeId); } else { File.Copy(importPath, Path.Combine("themes", themeId, "theme.json"), true); } - ThemeConfig theme = ThemeLoader.TryLoad(themeId); + if (shouldContinue) + { + theme = ThemeLoader.TryLoad(themeId); + } if (theme == null) { @@ -198,14 +200,21 @@ private static void DownloadMissingImages() LaunchSequence.NextStep(); return; } + + foreach (ThemeConfig theme in + missingThemes.Where(theme => string.IsNullOrEmpty(theme.imagesZipUri))) + { + missingThemes.Remove(theme); + ThemeLoader.HandleError(theme.themeId, + string.Format(_("Failed to find images for the '{0}' theme"), theme.themeId)); + } downloadDialog = new ProgressDialog(); downloadDialog.FormClosed += OnDownloadDialogClosed; downloadDialog.Show(); MainMenu.themeItem.Enabled = false; - downloadDialog.InitDownload(missingThemes.FindAll( - theme => !string.IsNullOrEmpty(theme.imagesZipUri))); // TODO Handle error if null or empty and missing images + downloadDialog.InitDownload(missingThemes); } private static void OnDownloadDialogClosed(object sender, EventArgs e) diff --git a/src/WallpaperChangeScheduler.cs b/src/WallpaperChangeScheduler.cs index dd87f37..31ed41a 100644 --- a/src/WallpaperChangeScheduler.cs +++ b/src/WallpaperChangeScheduler.cs @@ -58,8 +58,7 @@ public void RunScheduler(bool forceImageUpdate = false) lastImagePath = null; } - Tuple imageData = GetImageData(data, ThemeManager.currentTheme, - JsonConfig.settings.darkMode); + Tuple imageData = GetImageData(data, ThemeManager.currentTheme); SetWallpaper(imageData.Item1); nextImageUpdateTime = new DateTime(imageData.Item2); } @@ -109,13 +108,13 @@ private DaySegment GetCurrentDaySegment(SolarData data) } } - public Tuple GetImageData(SolarData data, ThemeConfig theme, bool darkMode) + public Tuple GetImageData(SolarData data, ThemeConfig theme) { int[] imageList; DateTime segmentStart; DateTime segmentEnd; - if (!darkMode) + if (!JsonConfig.settings.darkMode) { switch (GetCurrentDaySegment(data)) { diff --git a/src/WinDynamicDesktop.csproj b/src/WinDynamicDesktop.csproj index a146853..9e66d8c 100644 --- a/src/WinDynamicDesktop.csproj +++ b/src/WinDynamicDesktop.csproj @@ -10,12 +10,11 @@ WinExe WinDynamicDesktop WinDynamicDesktop - v4.7.2 + v4.6.1 512 true - AnyCPU diff --git a/src/app.manifest b/src/app.manifest index 4fe2ad9..94e4345 100644 --- a/src/app.manifest +++ b/src/app.manifest @@ -40,7 +40,7 @@ - + @@ -49,13 +49,11 @@ DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. --> -