diff --git a/FAQ.md b/FAQ.md
index 7b46b10..2d38b7b 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -22,6 +22,7 @@ The original **Hourglass** FAQ can be found [here](https://chris.dziemborowicz.c
- [How do I save a timer?](#how-do-i-save-a-timer)
- [How do I clear saved timers?](#how-do-i-clear-saved-timers)
- [How do I set a title for a timer?](#how-do-i-set-a-title-for-a-timer)
+- [How do I set a time for a timer?](#how-do-i-set-a-time-for-a-timer)
- [How do I change what is displayed in the timer window title?](#how-do-i-change-what-is-displayed-in-the-timer-window-title)
- [How do I change the timer window color theme?](#how-do-i-change-the-timer-window-color-theme)
- [Is there a dark color theme available?](#is-there-a-dark-color-theme-available)
@@ -291,7 +292,13 @@ And you can set the **Hourglass** to automatically open saved timers when it sta
## How do I save a timer?
-A not expired yet timer is saved automatically when closed. See also [How do I resume a timer that I accidentally closed?](#how-do-i-resume-a-timer-that-i-accidentally-closed)
+A not expired yet timer is saved automatically when closed if **Save timer on closing** option in the **Advanced options** submenu is checked.
+You can change it in the close confirmation dialog shown if the **Prompt on close** in the timer window options menu is checked.
+
+See also [How do I resume a timer that I accidentally closed?](#how-do-i-resume-a-timer-that-i-accidentally-closed)
+
+> [!IMPORTANT]
+> All the not expired yet timers are always saved on exit.
## How do I clear saved timers?
@@ -299,10 +306,14 @@ A not expired yet timer is saved automatically when closed. See also [How do I r
## How do I set a title for a timer?
-Click in the text field that says **Click to enter title**, enter a title and press `Enter`.
+Click in the text field that says **Click to enter title** or press `F2`, enter a title and press `Enter`.
To clear a title that you entered, click the title text field, delete the title text and press `Enter`.
+## How do I set a time for a timer?
+
+Click in the time field or press `F4`, enter a time and press `Enter` to accept the new time or `Esc` to revert it back. In case of an error the red border will blink for a some time.
+
## How do I change what is displayed in the timer window title?
By default, the timer window title displays the application name **Hourglass**. You can change it to display the time left, the time elapsed or the timer title instead.
diff --git a/Hourglass/App.config b/Hourglass/App.config
index 703ed03..9c5b410 100644
--- a/Hourglass/App.config
+++ b/Hourglass/App.config
@@ -34,6 +34,9 @@
False
+
+ True
+
diff --git a/Hourglass/AppEntry.cs b/Hourglass/AppEntry.cs
index 93f59e5..2fd5420 100644
--- a/Hourglass/AppEntry.cs
+++ b/Hourglass/AppEntry.cs
@@ -203,6 +203,7 @@ private static void SetGlobalSettingsFromArguments(CommandLineArguments argument
{
Settings.Default.ShowInNotificationArea = arguments.ShowInNotificationArea;
Settings.Default.OpenSavedTimersOnStartup = arguments.OpenSavedTimers;
+ Settings.Default.SaveTimerOnClosing = arguments.SaveTimerOnClosing;
Settings.Default.Prefer24HourTime = arguments.Prefer24HourTime;
Settings.Default.ActivateNextWindow = arguments.ActivateNextWindow;
Settings.Default.OrderByTitleFirst = arguments.OrderByTitleFirst;
diff --git a/Hourglass/CommandLineArguments.cs b/Hourglass/CommandLineArguments.cs
index a01b34d..d38952e 100644
--- a/Hourglass/CommandLineArguments.cs
+++ b/Hourglass/CommandLineArguments.cs
@@ -163,6 +163,11 @@ public static string Usage
///
public bool OpenSavedTimers { get; private set; }
+ ///
+ /// Gets a value indicating whether a timer should be saved on closing.
+ ///
+ public bool SaveTimerOnClosing { get; private set; }
+
///
/// Gets a value indicating whether to prefer interpreting time of day values as 24-hour time.
///
@@ -332,6 +337,7 @@ private static CommandLineArguments GetArgumentsFromMostRecentOptions()
Sound = options.Sound,
LoopSound = options.LoopSound,
OpenSavedTimers = Settings.Default.OpenSavedTimersOnStartup,
+ SaveTimerOnClosing = Settings.Default.SaveTimerOnClosing,
Prefer24HourTime = Settings.Default.Prefer24HourTime,
ActivateNextWindow = Settings.Default.ActivateNextWindow,
OrderByTitleFirst = Settings.Default.OrderByTitleFirst,
@@ -377,6 +383,7 @@ private static CommandLineArguments GetArgumentsFromFactoryDefaults()
Sound = defaultOptions.Sound,
LoopSound = defaultOptions.LoopSound,
OpenSavedTimers = false,
+ SaveTimerOnClosing = true,
Prefer24HourTime = false,
ActivateNextWindow = true,
OrderByTitleFirst = false,
@@ -717,6 +724,20 @@ private static CommandLineArguments GetCommandLineArguments(IEnumerable
argumentsBasedOnFactoryDefaults.OpenSavedTimers = openSavedTimers;
break;
+ case "--save-timer-on-closing":
+ case "-sc":
+ case "/sc":
+ ThrowIfDuplicateSwitch(specifiedSwitches, "--save-timer-on-closing");
+
+ bool saveTimerOnClosing = GetBoolValue(
+ arg,
+ remainingArgs,
+ argumentsBasedOnMostRecentOptions.SaveTimerOnClosing);
+
+ argumentsBasedOnMostRecentOptions.SaveTimerOnClosing = saveTimerOnClosing;
+ argumentsBasedOnFactoryDefaults.SaveTimerOnClosing = saveTimerOnClosing;
+ break;
+
case "--prefer-24h-time":
case "-j":
case "/j":
diff --git a/Hourglass/Managers/TimerManager.cs b/Hourglass/Managers/TimerManager.cs
index 8c5049c..29c8769 100644
--- a/Hourglass/Managers/TimerManager.cs
+++ b/Hourglass/Managers/TimerManager.cs
@@ -61,7 +61,7 @@ public bool SilentMode
/// .
///
#pragma warning disable S2365
- public IReadOnlyCollection ResumableTimers => _timers.Where(static t => t.State != TimerState.Stopped && !IsBoundToWindow(t)).ToArray();
+ public IReadOnlyCollection ResumableTimers => _timers.Where(static t => t is { ShouldBeSaved: true, State: not TimerState.Stopped } && !IsBoundToWindow(t)).ToArray();
#pragma warning restore S2365
///
@@ -87,7 +87,7 @@ public override void Initialize()
public override void Persist()
{
Settings.Default.Timers = _timers
- .Where(static t => t.State != TimerState.Stopped && t.State != TimerState.Expired)
+ .Where(static t => t is { ShouldBeSaved: true, State: not TimerState.Stopped and not TimerState.Expired })
.Where(static t => !t.Options.LockInterface)
.Take(MaxSavedTimers)
.ToList();
diff --git a/Hourglass/Properties/Resources.Designer.cs b/Hourglass/Properties/Resources.Designer.cs
index 0004581..1cf6416 100644
--- a/Hourglass/Properties/Resources.Designer.cs
+++ b/Hourglass/Properties/Resources.Designer.cs
@@ -583,6 +583,15 @@ public static string ContextMenuSavedTimersMenuItem {
}
}
+ ///
+ /// Looks up a localized string similar to Sa_ve timer on closing.
+ ///
+ public static string ContextMenuSaveTimerOnClosingMenuItem {
+ get {
+ return ResourceManager.GetString("ContextMenuSaveTimerOnClosingMenuItem", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to _Show elapsed time instead of time left.
///
@@ -1633,6 +1642,15 @@ public static string RelativeDateTokenTomorrowPattern {
}
}
+ ///
+ /// Looks up a localized string similar to &Save this timer.
+ ///
+ public static string SaveTimerTaskDialogText {
+ get {
+ return ResourceManager.GetString("SaveTimerTaskDialogText", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Lo_ud beep.
///
diff --git a/Hourglass/Properties/Resources.resx b/Hourglass/Properties/Resources.resx
index 4742aef..b80516d 100644
--- a/Hourglass/Properties/Resources.resx
+++ b/Hourglass/Properties/Resources.resx
@@ -1093,6 +1093,10 @@ $
&Close
Close task dialog command
+
+ Sa&ve this timer
+ Save this timer task dialog text
+
Mi&nimize
Minimize task dialog command
@@ -1128,6 +1132,10 @@ $
_Open saved timers on startup
The text for the open saved timers on startup menu item, where the character following the optional underscore (_) is the access key
+
+ Sa_ve timer on closing
+ The text for the save timer on closing menu item, where the character following the optional underscore (_) is the access key
+
_Show elapsed time instead of time left
The text for the show elapsed time menu item, where the character following the optional underscore (_) is the access key
diff --git a/Hourglass/Properties/Settings.Designer.cs b/Hourglass/Properties/Settings.Designer.cs
index 08b021a..2768f14 100644
--- a/Hourglass/Properties/Settings.Designer.cs
+++ b/Hourglass/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace Hourglass.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.12.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.13.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -173,5 +173,17 @@ public bool OrderByTitleFirst {
this["OrderByTitleFirst"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool SaveTimerOnClosing {
+ get {
+ return ((bool)(this["SaveTimerOnClosing"]));
+ }
+ set {
+ this["SaveTimerOnClosing"] = value;
+ }
+ }
}
}
diff --git a/Hourglass/Properties/Settings.settings b/Hourglass/Properties/Settings.settings
index 99a9e45..8d174b4 100644
--- a/Hourglass/Properties/Settings.settings
+++ b/Hourglass/Properties/Settings.settings
@@ -41,5 +41,8 @@
False
+
+ True
+
\ No newline at end of file
diff --git a/Hourglass/Resources/Usage.txt b/Hourglass/Resources/Usage.txt
index df947ea..e3af4c4 100644
--- a/Hourglass/Resources/Usage.txt
+++ b/Hourglass/Resources/Usage.txt
@@ -246,6 +246,13 @@ Options:
Default value last
Alias -v, /v
+ --save-timer-on-closing on|off|last
+ Saves the timer on closing.
+
+ Required no
+ Default value last
+ Alias -sc, /sc
+
--prefer-24h-time on|off|last
When the input used to start the timer contains a time of day that does
not explicitly specify "am" or "pm", prefer interpreting the input as a
@@ -351,6 +358,7 @@ Options:
--sound -s normal beep
--loop-sound -r off
--open-saved-timers -v off
+ --save-timer-on-closing -sc on
--prefer-24h-time -j off
--window-title -i app
--window-state -w normal
diff --git a/Hourglass/Timing/TimerBase.cs b/Hourglass/Timing/TimerBase.cs
index 504a3f9..73c6692 100644
--- a/Hourglass/Timing/TimerBase.cs
+++ b/Hourglass/Timing/TimerBase.cs
@@ -137,6 +137,11 @@ protected TimerBase(TimerInfo timerInfo)
///
public TimerState State { get; private set; } = TimerState.Stopped;
+ ///
+ /// Gets or sets value indicating whether this timer should be saved on closing.
+ ///
+ public bool ShouldBeSaved { get; set; } = true;
+
///
/// Gets the that this timer was started if the is or , or null otherwise.
diff --git a/Hourglass/Windows/ContextMenu.cs b/Hourglass/Windows/ContextMenu.cs
index b24ec17..3113b1a 100644
--- a/Hourglass/Windows/ContextMenu.cs
+++ b/Hourglass/Windows/ContextMenu.cs
@@ -173,6 +173,11 @@ public sealed class ContextMenu : System.Windows.Controls.ContextMenu
///
private MenuItem _openSavedTimersOnStartupMenuItem = null!;
+ ///
+ /// The "Save timer on closing" .
+ ///
+ private MenuItem _saveTimerOnClosingMenuItem = null!;
+
///
/// The "Display time in the digital clock format" .
///
@@ -431,6 +436,9 @@ private void UpdateMenuFromOptions()
// Open saved timers on startup
_openSavedTimersOnStartupMenuItem.IsChecked = Settings.Default.OpenSavedTimersOnStartup;
+ // Save timer on closing
+ _saveTimerOnClosingMenuItem.IsChecked = Settings.Default.SaveTimerOnClosing;
+
// Prefer 24-hour time when parsing
_prefer24HourTimeMenuItem.IsChecked = Settings.Default.Prefer24HourTime;
@@ -536,6 +544,9 @@ private void UpdateOptionsFromMenu()
// Open saved timers on startup
Settings.Default.OpenSavedTimersOnStartup = _openSavedTimersOnStartupMenuItem.IsChecked;
+ // Save timer on closing
+ Settings.Default.SaveTimerOnClosing = _saveTimerOnClosingMenuItem.IsChecked;
+
// Prefer 24-hour time when parsing
Settings.Default.Prefer24HourTime = _prefer24HourTimeMenuItem.IsChecked;
@@ -923,6 +934,14 @@ private void BuildMenu()
_openSavedTimersOnStartupMenuItem.Click += CheckableMenuItemClick;
advancedOptionsMenuItem.Items.Add(_openSavedTimersOnStartupMenuItem);
+ // Save timer on closing
+ _saveTimerOnClosingMenuItem = new CheckableMenuItem
+ {
+ Header = Properties.Resources.ContextMenuSaveTimerOnClosingMenuItem
+ };
+ _saveTimerOnClosingMenuItem.Click += CheckableMenuItemClick;
+ advancedOptionsMenuItem.Items.Add(_saveTimerOnClosingMenuItem);
+
// Prefer 24-hour time when parsing
_prefer24HourTimeMenuItem = new CheckableMenuItem
{
diff --git a/Hourglass/Windows/TimerWindow.xaml.cs b/Hourglass/Windows/TimerWindow.xaml.cs
index 9d5046c..cecd1fd 100644
--- a/Hourglass/Windows/TimerWindow.xaml.cs
+++ b/Hourglass/Windows/TimerWindow.xaml.cs
@@ -18,6 +18,8 @@ namespace Hourglass.Windows;
using System.Windows.Media.Animation;
using System.Windows.Shell;
+using KPreisser.UI;
+
using Extensions;
using Managers;
using Properties;
@@ -2078,15 +2080,22 @@ private void ConfirmClose()
{
BringToFrontAndActivate();
+ var saveTimerOnClosingTaskDialogCheckBox = new TaskDialogCheckBox(Properties.Resources.SaveTimerTaskDialogText)
+ {
+ Checked = Settings.Default.SaveTimerOnClosing
+ };
+
MessageBoxResult result = this.ShowTaskDialog(
Properties.Resources.TimerWindowCloseTaskDialogInstruction,
Properties.Resources.CloseWindowCloseTaskDialogCommand,
- Properties.Resources.MinimizeWindowCloseTaskDialogCommand);
+ Properties.Resources.MinimizeWindowCloseTaskDialogCommand,
+ saveTimerOnClosingTaskDialogCheckBox);
switch (result)
{
case MessageBoxResult.Yes:
ForceClose = true;
+ Timer.ShouldBeSaved = saveTimerOnClosingTaskDialogCheckBox.Checked;
Close();
return;
case MessageBoxResult.No:
diff --git a/README.md b/README.md
index cdfa324..692b63a 100644
--- a/README.md
+++ b/README.md
@@ -71,6 +71,7 @@ ngen-Hourglass.bat uninstall
- New option `--pause-after-loop-timer`, `-pl`, `/pl`
- New option `--order-by-title`, `-ot`, `/ot`
- Renamed option `--prompt-on-exit` to `--prompt-on-close`
+- New option `--save-timer-on-closing`, `-sc`, `/sc`
See [command-line usage](https://github.com/i2van/hourglass/blob/develop/Hourglass/Resources/Usage.txt) for details.
@@ -105,6 +106,8 @@ See [command-line usage](https://github.com/i2van/hourglass/blob/develop/Hourgla
- The `Esc` shortcut minimizes the timer window.
- The `F11` shortcut makes the timer window full screen and back.
- The `Ctrl`+`N` shortcut creates a new timer window.
+- The `F2` shortcut edits a timer window title.
+- The `F4` shortcut edits a timer window time.
#### Context Menu
@@ -117,6 +120,7 @@ See [command-line usage](https://github.com/i2van/hourglass/blob/develop/Hourgla
- The **Advanced options** / **Show trigger time** timer window context menu option shows the trigger time in the timer window and in the notification area context menu. The command-line option is `--show-trigger-time`, `-st`, `/st`
- The **Advanced options** / **Activate next window when minimized or closed** timer window context menu option enables the next timer window activation when the current timer window is minimized or closed. The command-line option is `--activate-next`, `-an`, `/an`
- The **Advanced options** / **Order timers by title first then by time left** timer window context menu option orders the timers by the title first then by the time left. The command-line option is `--order-by-title`, `-ot`, `/ot`
+- The **Advanced options** / **Save timer on closing** timer window context menu option enables timer window save on closing. The command-line option is `--save-timer-on-closing`, `-sc`, `/sc`
- The **Pause all** timer window context menu command pauses all the running timers. Command-line command is `pause`
- The **Resume all** timer window context menu command resumes all the paused timers. Command-line command is `resume`
- The **Pause after each loop** timer window context menu command pauses the loop timer when it expires. Command-line command is `--pause-after-loop-timer`, `-pl`, `/pl`