Skip to content

Commit 216cab9

Browse files
committed
Release v1.2.0
2 parents 1e475f7 + 9b042cf commit 216cab9

File tree

16 files changed

+203
-12
lines changed

16 files changed

+203
-12
lines changed

Hourglass.Bundle/Bundle.wxs

+1-1
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.1.0.0" Manufacturer="Chris Dziemborowicz" UpgradeCode="f1d002c9-cfc9-40fb-84af-96e7aec26e0b" IconSourceFile="$(var.Hourglass.ProjectDir)Resources\AppIcon.ico">
4+
<Bundle Name="Hourglass" Version="1.2.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>

Hourglass.Setup/Product.wxs

+1-1
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.1.0.0" Manufacturer="Chris Dziemborowicz" UpgradeCode="172d3713-8820-4374-8195-3e2374e7724f">
4+
<Product Id="*" Name="Hourglass" Language="1033" Version="1.2.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"/>

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.1.0.0")]
21-
[assembly: AssemblyFileVersion("1.1.0.0")]
20+
[assembly: AssemblyVersion("1.2.0.0")]
21+
[assembly: AssemblyFileVersion("1.2.0.0")]

Hourglass/CommandLineArguments.cs

+21
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ public static string Usage
7676
/// </summary>
7777
public bool IsFullScreen { get; private set; }
7878

79+
/// <summary>
80+
/// Gets a value indicating whether to prompt the user before closing the timer window if the timer is running.
81+
/// </summary>
82+
public bool PromptOnExit { get; private set; }
83+
7984
/// <summary>
8085
/// Gets a value indicating whether an icon for the app should be visible in the notification area of the
8186
/// taskbar.
@@ -183,6 +188,7 @@ public TimerOptions GetTimerOptions()
183188
{
184189
Title = this.Title,
185190
AlwaysOnTop = this.AlwaysOnTop,
191+
PromptOnExit = this.PromptOnExit,
186192
LoopTimer = this.LoopTimer,
187193
PopUpWhenExpired = this.PopUpWhenExpired,
188194
CloseWhenExpired = this.CloseWhenExpired,
@@ -224,6 +230,7 @@ private static CommandLineArguments GetArgumentsFromMostRecentOptions()
224230
Title = null,
225231
AlwaysOnTop = options.AlwaysOnTop,
226232
IsFullScreen = windowSize.IsFullScreen,
233+
PromptOnExit = options.PromptOnExit,
227234
ShowInNotificationArea = Settings.Default.ShowInNotificationArea,
228235
LoopTimer = options.LoopTimer,
229236
PopUpWhenExpired = options.PopUpWhenExpired,
@@ -254,6 +261,7 @@ private static CommandLineArguments GetArgumentsFromFactoryDefaults()
254261
Title = defaultOptions.Title,
255262
AlwaysOnTop = defaultOptions.AlwaysOnTop,
256263
IsFullScreen = defaultOptions.WindowSize.IsFullScreen,
264+
PromptOnExit = defaultOptions.PromptOnExit,
257265
ShowInNotificationArea = false,
258266
LoopTimer = defaultOptions.LoopTimer,
259267
PopUpWhenExpired = defaultOptions.PopUpWhenExpired,
@@ -334,6 +342,19 @@ private static CommandLineArguments GetCommandLineArguments(IEnumerable<string>
334342
argumentsBasedOnFactoryDefaults.IsFullScreen = isFullScreen;
335343
break;
336344

345+
case "--prompt-on-exit":
346+
case "-o":
347+
ThrowIfDuplicateSwitch(specifiedSwitches, "--prompt-on-exit");
348+
349+
bool promptOnExit = GetBoolValue(
350+
arg,
351+
remainingArgs,
352+
argumentsBasedOnMostRecentOptions.PromptOnExit);
353+
354+
argumentsBasedOnMostRecentOptions.PromptOnExit = promptOnExit;
355+
argumentsBasedOnFactoryDefaults.PromptOnExit = promptOnExit;
356+
break;
357+
337358
case "--show-in-notification-area":
338359
case "-n":
339360
ThrowIfDuplicateSwitch(specifiedSwitches, "--show-in-notification-area");

Hourglass/Managers/TimerStartManager.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ public IList<TimerStart> TimerStarts
4848
}
4949

5050
/// <summary>
51-
/// Gets the most recent <see cref="TimerStart"/>, or <c>null</c> if there are no <see cref="TimerStart"/>
52-
/// objects in <see cref="TimerStarts"/>.
51+
/// Gets the most recent <see cref="TimerStart"/>, or the default <see cref="TimerStart"/> if there are no <see
52+
/// cref="TimerStart"/> objects in <see cref="TimerStarts"/>.
5353
/// </summary>
5454
public TimerStart LastTimerStart
5555
{
56-
get { return this.timerStarts.FirstOrDefault(e => e.IsCurrent); }
56+
get { return this.timerStarts.FirstOrDefault(e => e.IsCurrent) ?? TimerStart.Default; }
5757
}
5858

5959
/// <summary>

Hourglass/Properties/App.manifest

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
3-
<assemblyIdentity version="1.1.0.0" name="Hourglass"/>
3+
<assemblyIdentity version="1.2.0.0" name="Hourglass"/>
44
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
55
<security>
66
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">

Hourglass/Properties/AssemblyInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
[assembly: AssemblyCopyright("Copyright © 2015 Chris Dziemborowicz")]
1818
[assembly: AssemblyTrademark("")]
1919
[assembly: AssemblyCulture("")]
20-
[assembly: AssemblyVersion("1.1.0.0")]
21-
[assembly: AssemblyFileVersion("1.1.0.0")]
20+
[assembly: AssemblyVersion("1.2.0.0")]
21+
[assembly: AssemblyFileVersion("1.2.0.0")]
2222
[assembly: NeutralResourcesLanguageAttribute("en-US")]
2323
[assembly: Guid("83DBAA61-6193-4288-BBB7-BEAEC33FE321")]
2424
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

Hourglass/Properties/Resources.Designer.cs

+37-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Hourglass/Properties/Resources.resx

+17-1
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ $</value>
725725
<comment>A format string for a regular expression that matches a time only, where {0} is the time pattern</comment>
726726
</data>
727727
<data name="TimerStartTokenUseDateTimeParserPattern" xml:space="preserve">
728-
<value>^\s*(un)?till?\s*</value>
728+
<value>^\s*((un)?till?|@)\s*</value>
729729
<comment>A regular expression that indicates a preference for matching a date and/or time, rather than a time span, when parsing a timer start token</comment>
730730
</data>
731731
<data name="TimeSpanExtensionsUnitSeparator" xml:space="preserve">
@@ -1085,4 +1085,20 @@ $</value>
10851085
<value>{0} ago</value>
10861086
<comment>A format string for the string representation of the time since the timer expired</comment>
10871087
</data>
1088+
<data name="TimerStartDefault" xml:space="preserve">
1089+
<value>5 minutes</value>
1090+
<comment>The default value for a timer displayed if the user has never started a timer before</comment>
1091+
</data>
1092+
<data name="ContextMenuPromptOnExitMenuItem" xml:space="preserve">
1093+
<value>Pro_mpt on exit</value>
1094+
<comment>The text for the prompt on exit menu item, where the character following the optional underscore (_) is the access key</comment>
1095+
</data>
1096+
<data name="MessageBoxTitle" xml:space="preserve">
1097+
<value>Hourglass</value>
1098+
<comment>The caption used for any message boxes</comment>
1099+
</data>
1100+
<data name="TimerWindowCloseMessageBoxText" xml:space="preserve">
1101+
<value>Are you sure you want to close this timer window?</value>
1102+
<comment>The message displayed when the user closes a timer window while a timer is running</comment>
1103+
</data>
10881104
</root>

Hourglass/Resources/Usage.txt

+7
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ Options:
4747
Default value last
4848
Alias -f
4949

50+
--prompt-on-exit on|off|last
51+
Displays a prompt before closing the timer window.
52+
53+
Required no
54+
Default value last
55+
Alias -o
56+
5057
--show-in-notification-area on|off|last
5158
Shows an icon for the app in the notification area (system tray).
5259

Hourglass/Serialization/TimerOptionsInfo.cs

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ public class TimerOptionsInfo
2323
/// </summary>
2424
public bool AlwaysOnTop { get; set; }
2525

26+
/// <summary>
27+
/// Gets or sets a value indicating whether to prompt the user before closing the timer window if the timer is
28+
/// running.
29+
/// </summary>
30+
public bool PromptOnExit { get; set; }
31+
2632
/// <summary>
2733
/// Gets or sets a value indicating whether to loop the timer continuously.
2834
/// </summary>

Hourglass/Timing/TimerOptions.cs

+32
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ public class TimerOptions : INotifyPropertyChanged
3030
/// </summary>
3131
private bool alwaysOnTop;
3232

33+
/// <summary>
34+
/// A value indicating whether to prompt the user before closing the timer window if the timer is running.
35+
/// </summary>
36+
private bool promptOnExit;
37+
3338
/// <summary>
3439
/// A value indicating whether to loop the timer continuously.
3540
/// </summary>
@@ -78,6 +83,7 @@ public TimerOptions()
7883
{
7984
this.title = string.Empty;
8085
this.alwaysOnTop = false;
86+
this.promptOnExit = true;
8187
this.loopTimer = false;
8288
this.popUpWhenExpired = true;
8389
this.closeWhenExpired = false;
@@ -167,6 +173,29 @@ public bool AlwaysOnTop
167173
}
168174
}
169175

176+
/// <summary>
177+
/// Gets or sets a value indicating whether to prompt the user before closing the timer window if the timer is
178+
/// running.
179+
/// </summary>
180+
public bool PromptOnExit
181+
{
182+
get
183+
{
184+
return this.promptOnExit;
185+
}
186+
187+
set
188+
{
189+
if (this.promptOnExit == value)
190+
{
191+
return;
192+
}
193+
194+
this.promptOnExit = value;
195+
this.OnPropertyChanged("PromptOnExit");
196+
}
197+
}
198+
170199
/// <summary>
171200
/// Gets or sets a value indicating whether to loop the timer continuously.
172201
/// </summary>
@@ -364,6 +393,7 @@ public void Set(TimerOptions options)
364393

365394
this.title = options.title;
366395
this.alwaysOnTop = options.alwaysOnTop;
396+
this.promptOnExit = options.promptOnExit;
367397
this.loopTimer = options.loopTimer;
368398
this.popUpWhenExpired = options.popUpWhenExpired;
369399
this.closeWhenExpired = options.closeWhenExpired;
@@ -386,6 +416,7 @@ public void Set(TimerOptionsInfo info)
386416

387417
this.title = info.Title;
388418
this.alwaysOnTop = info.AlwaysOnTop;
419+
this.promptOnExit = info.PromptOnExit;
389420
this.loopTimer = info.LoopTimer;
390421
this.popUpWhenExpired = info.PopUpWhenExpired;
391422
this.closeWhenExpired = info.CloseWhenExpired;
@@ -405,6 +436,7 @@ public TimerOptionsInfo ToTimerOptionsInfo()
405436
{
406437
Title = this.title,
407438
AlwaysOnTop = this.alwaysOnTop,
439+
PromptOnExit = this.promptOnExit,
408440
LoopTimer = this.loopTimer,
409441
PopUpWhenExpired = this.popUpWhenExpired,
410442
CloseWhenExpired = this.closeWhenExpired,

Hourglass/Timing/TimerStart.cs

+9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Hourglass.Timing
99
using System;
1010

1111
using Hourglass.Parsing;
12+
using Hourglass.Properties;
1213
using Hourglass.Serialization;
1314

1415
/// <summary>
@@ -65,6 +66,14 @@ private TimerStart(TimerStartInfo timerStartInfo)
6566
this.timerStartToken = timerStartInfo.TimerStartToken;
6667
}
6768

69+
/// <summary>
70+
/// Gets the default <see cref="TimerStart"/> object.
71+
/// </summary>
72+
public static TimerStart Default
73+
{
74+
get { return TimerStart.FromString(Resources.TimerStartDefault); }
75+
}
76+
6877
/// <summary>
6978
/// Gets a value indicating whether the <see cref="TimerStart"/> can be used to start a timer now.
7079
/// </summary>

Hourglass/Windows/ContextMenu.cs

+17
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ public class ContextMenu : System.Windows.Controls.ContextMenu
5555
/// </summary>
5656
private MenuItem fullScreenMenuItem;
5757

58+
/// <summary>
59+
/// The "Prompt on exit" <see cref="MenuItem"/>.
60+
/// </summary>
61+
private MenuItem promptOnExitMenuItem;
62+
5863
/// <summary>
5964
/// The "Show in notification area" <see cref="MenuItem"/>.
6065
/// </summary>
@@ -255,6 +260,9 @@ private void UpdateMenuFromOptions()
255260
// Full screen
256261
this.fullScreenMenuItem.IsChecked = this.timerWindow.IsFullScreen;
257262

263+
// Prompt on exit
264+
this.promptOnExitMenuItem.IsChecked = this.timerWindow.Options.PromptOnExit;
265+
258266
// Show in notification area
259267
this.showInNotificationAreaMenuItem.IsChecked = Settings.Default.ShowInNotificationArea;
260268

@@ -311,6 +319,9 @@ private void UpdateOptionsFromMenu()
311319

312320
// Full screen
313321
this.timerWindow.IsFullScreen = this.fullScreenMenuItem.IsChecked;
322+
323+
// Prompt on exit
324+
this.timerWindow.Options.PromptOnExit = this.promptOnExitMenuItem.IsChecked;
314325

315326
// Show in notification area
316327
Settings.Default.ShowInNotificationArea = this.showInNotificationAreaMenuItem.IsChecked;
@@ -383,6 +394,12 @@ private void BuildMenu()
383394
this.fullScreenMenuItem.Click += this.CheckableMenuItemClick;
384395
this.Items.Add(this.fullScreenMenuItem);
385396

397+
this.promptOnExitMenuItem = new MenuItem();
398+
this.promptOnExitMenuItem.Header = Properties.Resources.ContextMenuPromptOnExitMenuItem;
399+
this.promptOnExitMenuItem.IsCheckable = true;
400+
this.promptOnExitMenuItem.Click += this.CheckableMenuItemClick;
401+
this.Items.Add(this.promptOnExitMenuItem);
402+
386403
this.showInNotificationAreaMenuItem = new MenuItem();
387404
this.showInNotificationAreaMenuItem.Header = Properties.Resources.ContextMenuShowInNotificationAreaMenuItem;
388405
this.showInNotificationAreaMenuItem.IsCheckable = true;

0 commit comments

Comments
 (0)