Skip to content

Commit 74b4532

Browse files
committed
Release v1.5.0
2 parents 97b4675 + 7224fb4 commit 74b4532

28 files changed

+886
-34
lines changed

Hourglass.Bundle/Bundle.wxs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
33
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
4-
<Bundle Name="Hourglass" Version="1.4.0.0" Manufacturer="Chris Dziemborowicz" UpgradeCode="f1d002c9-cfc9-40fb-84af-96e7aec26e0b" IconSourceFile="$(var.Hourglass.ProjectDir)Resources\AppIcon.ico">
4+
<Bundle Name="Hourglass" Version="1.5.0.0" Manufacturer="Chris Dziemborowicz" UpgradeCode="f1d002c9-cfc9-40fb-84af-96e7aec26e0b" IconSourceFile="$(var.Hourglass.ProjectDir)Resources\AppIcon.ico">
55
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
66
<bal:WixStandardBootstrapperApplication LicenseFile="MIT.rtf" LogoFile="Logo.png"/>
77
</BootstrapperApplicationRef>
@@ -10,4 +10,4 @@
1010
<MsiPackage Id="HourglassSetup" SourceFile="$(var.Hourglass.Setup.TargetPath)"/>
1111
</Chain>
1212
</Bundle>
13-
</Wix>
13+
</Wix>

Hourglass.Setup/Product.wxs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
33
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
4-
<Product Id="*" Name="Hourglass" Language="1033" Version="1.4.0.0" Manufacturer="Chris Dziemborowicz" UpgradeCode="172d3713-8820-4374-8195-3e2374e7724f">
4+
<Product Id="*" Name="Hourglass" Language="1033" Version="1.5.0.0" Manufacturer="Chris Dziemborowicz" UpgradeCode="172d3713-8820-4374-8195-3e2374e7724f">
55
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine"/>
66

77
<Icon Id="AppIcon.exe" SourceFile="$(var.Hourglass.ProjectDir)Resources\AppIcon.ico"/>
@@ -37,4 +37,4 @@
3737
<ComponentRef Id="ApplicationShortcutFolderComponent"/>
3838
</Feature>
3939
</Product>
40-
</Wix>
40+
</Wix>

Hourglass.Test/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/bin/
22
/obj/
3+
StyleCop.Cache

Hourglass.Test/Properties/AssemblyInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
[assembly: AssemblyCulture("")]
1818
[assembly: ComVisible(false)]
1919
[assembly: Guid("002a4be7-7323-4bf9-ab08-5fc8978d9eb0")]
20-
[assembly: AssemblyVersion("1.4.0.0")]
21-
[assembly: AssemblyFileVersion("1.4.0.0")]
20+
[assembly: AssemblyVersion("1.5.0.0")]
21+
[assembly: AssemblyFileVersion("1.5.0.0")]

Hourglass/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/bin/
22
/obj/
3+
StyleCop.Cache

Hourglass/App.config

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
</startup>
1111
<userSettings>
1212
<Hourglass.Properties.Settings>
13+
<setting name="OpenSavedTimersOnStartup" serializeAs="String">
14+
<value>False</value>
15+
</setting>
1316
<setting name="ShowInNotificationArea" serializeAs="String">
1417
<value>False</value>
1518
</setting>

Hourglass/AppEntry.cs

+60-11
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
namespace Hourglass
88
{
99
using System;
10+
using System.Linq;
1011
using System.Windows;
1112

1213
using Hourglass.Extensions;
1314
using Hourglass.Managers;
1415
using Hourglass.Properties;
16+
using Hourglass.Timing;
1517
using Hourglass.Windows;
1618

1719
using Microsoft.VisualBasic.ApplicationServices;
@@ -69,11 +71,13 @@ protected override bool OnStartup(StartupEventArgs e)
6971

7072
SetGlobalSettingsFromArguments(arguments);
7173

72-
TimerWindow window = GetTimerWindowFromArguments(arguments);
73-
7474
this.app = new App();
75+
this.app.Startup += (sender, args) =>
76+
{
77+
ShowTimerWindowsForArguments(arguments);
78+
};
7579
this.app.Exit += AppExit;
76-
this.app.Run(window);
80+
this.app.Run();
7781

7882
return false;
7983
}
@@ -94,26 +98,70 @@ protected override void OnStartupNextInstance(StartupNextInstanceEventArgs e)
9498

9599
SetGlobalSettingsFromArguments(arguments);
96100

97-
TimerWindow window = GetTimerWindowFromArguments(arguments);
98-
window.Show();
101+
ShowTimerWindowsForArguments(arguments);
102+
}
99103

100-
if (window.WindowState != WindowState.Minimized)
104+
/// <summary>
105+
/// Shows a new timer window or windows for all saved timers, depending on whether the <see
106+
/// cref="CommandLineArguments"/> specify to open saved timers.
107+
/// </summary>
108+
/// <param name="arguments">Parsed command-line arguments.</param>
109+
private static void ShowTimerWindowsForArguments(CommandLineArguments arguments)
110+
{
111+
if (arguments.OpenSavedTimers && TimerManager.Instance.ResumableTimers.Any())
101112
{
102-
window.BringToFrontAndActivate();
113+
ShowSavedTimerWindows(arguments);
114+
115+
if (arguments.TimerStart != null)
116+
{
117+
ShowNewTimerWindow(arguments);
118+
}
119+
}
120+
else
121+
{
122+
ShowNewTimerWindow(arguments);
103123
}
104124
}
105125

106126
/// <summary>
107-
/// Returns a new instance of the <see cref="TimerWindow"/> class for the parsed command-line arguments.
127+
/// Shows a new timer window. The window will run the <see cref="TimerStart"/> specified in the <see
128+
/// cref="CommandLineArguments"/>, or it will display in input mode if there is no <see cref="TimerStart"/>.
108129
/// </summary>
109130
/// <param name="arguments">Parsed command-line arguments.</param>
110-
/// <returns>A <see cref="TimerWindow"/>.</returns>
111-
private static TimerWindow GetTimerWindowFromArguments(CommandLineArguments arguments)
131+
private static void ShowNewTimerWindow(CommandLineArguments arguments)
112132
{
113133
TimerWindow window = new TimerWindow(arguments.TimerStart);
114134
window.Options.Set(arguments.GetTimerOptions());
115135
window.Restore(arguments.GetWindowSize(), RestoreOptions.AllowMinimized);
116-
return window;
136+
window.Show();
137+
138+
if (window.WindowState != WindowState.Minimized)
139+
{
140+
window.BringToFrontAndActivate();
141+
}
142+
}
143+
144+
/// <summary>
145+
/// Shows windows for all saved timers.
146+
/// </summary>
147+
/// <param name="arguments">Parsed command-line arguments.</param>
148+
private static void ShowSavedTimerWindows(CommandLineArguments arguments)
149+
{
150+
foreach (Timer savedTimer in TimerManager.Instance.ResumableTimers)
151+
{
152+
TimerWindow window = new TimerWindow();
153+
154+
if (savedTimer.Options.WindowSize != null)
155+
{
156+
window.Restore(savedTimer.Options.WindowSize, RestoreOptions.AllowMinimized);
157+
}
158+
else
159+
{
160+
window.Restore(arguments.GetWindowSize(), RestoreOptions.AllowMinimized);
161+
}
162+
163+
window.Show(savedTimer);
164+
}
117165
}
118166

119167
/// <summary>
@@ -123,6 +171,7 @@ private static TimerWindow GetTimerWindowFromArguments(CommandLineArguments argu
123171
private static void SetGlobalSettingsFromArguments(CommandLineArguments arguments)
124172
{
125173
Settings.Default.ShowInNotificationArea = arguments.ShowInNotificationArea;
174+
Settings.Default.OpenSavedTimersOnStartup = arguments.OpenSavedTimers;
126175
}
127176

128177
/// <summary>

Hourglass/CommandLineArguments.cs

+114
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,22 @@ public static string Usage
8181
/// </summary>
8282
public bool PromptOnExit { get; private set; }
8383

84+
/// <summary>
85+
/// Gets a value indicating whether to keep the computer awake while the timer is running.
86+
/// </summary>
87+
public bool DoNotKeepComputerAwake { get; private set; }
88+
8489
/// <summary>
8590
/// Gets a value indicating whether an icon for the app should be visible in the notification area of the
8691
/// taskbar.
8792
/// </summary>
8893
public bool ShowInNotificationArea { get; private set; }
8994

95+
/// <summary>
96+
/// Gets a value indicating whether to show the time elapsed rather than the time left.
97+
/// </summary>
98+
public bool ShowTimeElapsed { get; private set; }
99+
90100
/// <summary>
91101
/// Gets a value indicating whether to loop the timer continuously.
92102
/// </summary>
@@ -103,6 +113,11 @@ public static string Usage
103113
/// </summary>
104114
public bool CloseWhenExpired { get; private set; }
105115

116+
/// <summary>
117+
/// Gets a value indicating whether Windows should be shut down when the timer expires.
118+
/// </summary>
119+
public bool ShutDownWhenExpired { get; private set; }
120+
106121
/// <summary>
107122
/// Gets the color of the timer progress bar.
108123
/// </summary>
@@ -119,6 +134,11 @@ public static string Usage
119134
/// </summary>
120135
public bool LoopSound { get; private set; }
121136

137+
/// <summary>
138+
/// Gets a value indicating whether all saved timers should be opened when the application starts.
139+
/// </summary>
140+
public bool OpenSavedTimers { get; private set; }
141+
122142
/// <summary>
123143
/// Gets a value that indicates whether the timer window is restored, minimized, or maximized.
124144
/// </summary>
@@ -189,9 +209,12 @@ public TimerOptions GetTimerOptions()
189209
Title = this.Title,
190210
AlwaysOnTop = this.AlwaysOnTop,
191211
PromptOnExit = this.PromptOnExit,
212+
DoNotKeepComputerAwake = this.DoNotKeepComputerAwake,
213+
ShowTimeElapsed = this.ShowTimeElapsed,
192214
LoopTimer = this.LoopTimer,
193215
PopUpWhenExpired = this.PopUpWhenExpired,
194216
CloseWhenExpired = this.CloseWhenExpired,
217+
ShutDownWhenExpired = this.ShutDownWhenExpired,
195218
Color = this.Color,
196219
Sound = this.Sound,
197220
LoopSound = this.LoopSound,
@@ -231,13 +254,17 @@ private static CommandLineArguments GetArgumentsFromMostRecentOptions()
231254
AlwaysOnTop = options.AlwaysOnTop,
232255
IsFullScreen = windowSize.IsFullScreen,
233256
PromptOnExit = options.PromptOnExit,
257+
DoNotKeepComputerAwake = options.DoNotKeepComputerAwake,
258+
ShowTimeElapsed = options.ShowTimeElapsed,
234259
ShowInNotificationArea = Settings.Default.ShowInNotificationArea,
235260
LoopTimer = options.LoopTimer,
236261
PopUpWhenExpired = options.PopUpWhenExpired,
237262
CloseWhenExpired = options.CloseWhenExpired,
263+
ShutDownWhenExpired = options.ShutDownWhenExpired,
238264
Color = options.Color,
239265
Sound = options.Sound,
240266
LoopSound = options.LoopSound,
267+
OpenSavedTimers = Settings.Default.OpenSavedTimersOnStartup,
241268
WindowState = windowSize.WindowState != WindowState.Minimized ? windowSize.WindowState : windowSize.RestoreWindowState,
242269
RestoreWindowState = windowSize.RestoreWindowState,
243270
WindowBounds = windowSize.RestoreBounds
@@ -262,13 +289,17 @@ private static CommandLineArguments GetArgumentsFromFactoryDefaults()
262289
AlwaysOnTop = defaultOptions.AlwaysOnTop,
263290
IsFullScreen = defaultOptions.WindowSize.IsFullScreen,
264291
PromptOnExit = defaultOptions.PromptOnExit,
292+
DoNotKeepComputerAwake = defaultOptions.DoNotKeepComputerAwake,
293+
ShowTimeElapsed = defaultOptions.ShowTimeElapsed,
265294
ShowInNotificationArea = false,
266295
LoopTimer = defaultOptions.LoopTimer,
267296
PopUpWhenExpired = defaultOptions.PopUpWhenExpired,
268297
CloseWhenExpired = defaultOptions.CloseWhenExpired,
298+
ShutDownWhenExpired = defaultOptions.ShutDownWhenExpired,
269299
Color = defaultOptions.Color,
270300
Sound = defaultOptions.Sound,
271301
LoopSound = defaultOptions.LoopSound,
302+
OpenSavedTimers = false,
272303
WindowState = defaultOptions.WindowSize.WindowState,
273304
RestoreWindowState = defaultOptions.WindowSize.RestoreWindowState,
274305
WindowBounds = defaultWindowBoundsWithLocation
@@ -355,6 +386,32 @@ private static CommandLineArguments GetCommandLineArguments(IEnumerable<string>
355386
argumentsBasedOnFactoryDefaults.PromptOnExit = promptOnExit;
356387
break;
357388

389+
case "--do-not-keep-awake":
390+
case "-k":
391+
ThrowIfDuplicateSwitch(specifiedSwitches, "--do-not-keep-awake");
392+
393+
bool doNotKeepComputerAwake = GetBoolValue(
394+
arg,
395+
remainingArgs,
396+
argumentsBasedOnMostRecentOptions.DoNotKeepComputerAwake);
397+
398+
argumentsBasedOnMostRecentOptions.DoNotKeepComputerAwake = doNotKeepComputerAwake;
399+
argumentsBasedOnFactoryDefaults.DoNotKeepComputerAwake = doNotKeepComputerAwake;
400+
break;
401+
402+
case "--show-time-elapsed":
403+
case "-u":
404+
ThrowIfDuplicateSwitch(specifiedSwitches, "--show-time-elapsed");
405+
406+
bool showTimeElapsed = GetBoolValue(
407+
arg,
408+
remainingArgs,
409+
argumentsBasedOnMostRecentOptions.ShowTimeElapsed);
410+
411+
argumentsBasedOnMostRecentOptions.ShowTimeElapsed = showTimeElapsed;
412+
argumentsBasedOnFactoryDefaults.ShowTimeElapsed = showTimeElapsed;
413+
break;
414+
358415
case "--show-in-notification-area":
359416
case "-n":
360417
ThrowIfDuplicateSwitch(specifiedSwitches, "--show-in-notification-area");
@@ -407,6 +464,18 @@ private static CommandLineArguments GetCommandLineArguments(IEnumerable<string>
407464
argumentsBasedOnFactoryDefaults.CloseWhenExpired = closeWhenExpired;
408465
break;
409466

467+
case "--shut-down-when-expired":
468+
case "-x":
469+
ThrowIfDuplicateSwitch(specifiedSwitches, "--shut-down-when-expired");
470+
471+
bool shutDownWhenExpired = GetBoolValue(
472+
arg,
473+
remainingArgs);
474+
475+
argumentsBasedOnMostRecentOptions.ShutDownWhenExpired = shutDownWhenExpired;
476+
argumentsBasedOnFactoryDefaults.ShutDownWhenExpired = shutDownWhenExpired;
477+
break;
478+
410479
case "--color":
411480
case "-c":
412481
ThrowIfDuplicateSwitch(specifiedSwitches, "--color");
@@ -446,6 +515,19 @@ private static CommandLineArguments GetCommandLineArguments(IEnumerable<string>
446515
argumentsBasedOnFactoryDefaults.LoopSound = loopSound;
447516
break;
448517

518+
case "--open-saved-timers":
519+
case "-v":
520+
ThrowIfDuplicateSwitch(specifiedSwitches, "--open-saved-timers");
521+
522+
bool openSavedTimers = GetBoolValue(
523+
arg,
524+
remainingArgs,
525+
argumentsBasedOnMostRecentOptions.OpenSavedTimers);
526+
527+
argumentsBasedOnMostRecentOptions.OpenSavedTimers = openSavedTimers;
528+
argumentsBasedOnFactoryDefaults.OpenSavedTimers = openSavedTimers;
529+
break;
530+
449531
case "--window-bounds":
450532
case "-b":
451533
ThrowIfDuplicateSwitch(specifiedSwitches, "--window-bounds");
@@ -556,6 +638,38 @@ private static string GetRequiredValue(string arg, Queue<string> remainingArgs)
556638
return value;
557639
}
558640

641+
/// <summary>
642+
/// Returns the next <see cref="bool"/> value in <paramref name="remainingArgs"/>, or throws an exception if
643+
/// <paramref name="remainingArgs"/> is empty or the next argument is not "on" or "off".
644+
/// </summary>
645+
/// <param name="arg">The name of the argument for which the value is to be returned.</param>
646+
/// <param name="remainingArgs">The unparsed arguments.</param>
647+
/// <returns>The next <see cref="bool"/> value in <paramref name="remainingArgs"/>.</returns>
648+
/// <exception cref="ParseException">If <paramref name="remainingArgs"/> is empty or the next argument is not
649+
/// "on" or "off".</exception>
650+
private static bool GetBoolValue(string arg, Queue<string> remainingArgs)
651+
{
652+
string value = GetRequiredValue(arg, remainingArgs);
653+
654+
switch (value)
655+
{
656+
case "on":
657+
return true;
658+
659+
case "off":
660+
return false;
661+
662+
default:
663+
string message = string.Format(
664+
Resources.ResourceManager.GetEffectiveProvider(),
665+
Resources.CommandLineArgumentsParseExceptionInvalidValueForSwitchFormatString,
666+
arg,
667+
value);
668+
669+
throw new ParseException(message);
670+
}
671+
}
672+
559673
/// <summary>
560674
/// Returns the next <see cref="bool"/> value in <paramref name="remainingArgs"/>, or throws an exception if
561675
/// <paramref name="remainingArgs"/> is empty or the next argument is not "on", "off", or "last".

0 commit comments

Comments
 (0)