diff --git a/LICENSE b/LICENSE index 4dc896a..fa36f6e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 Jeff Hicks +Copyright (c) 2018-2019 Jeff Hicks Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/PSCalendar.psd1 b/PSCalendar.psd1 index 5fcebb5..c7b96df 100644 --- a/PSCalendar.psd1 +++ b/PSCalendar.psd1 @@ -7,7 +7,7 @@ RootModule = 'PSCalendar.psm1' # Version number of this module. -ModuleVersion = '1.4.0' +ModuleVersion = '1.5.0' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/README.md b/README.md index 3111af5..3591299 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ PS C:\> Show-GuiCalendar 12/2018 2/2019 -highlight 12/24/18,12/25/18,12/31/18,1/ The calendar form is transparent. But you should be able to click on it to drag it around your screen. You can also use the + and - keys to increase or decrease the calendar's opacity. Be aware that if you close the PowerShell session that launched the calendar, the calendar too will close. - *last updated 1 October 2018* + *last updated 10 January 2019* diff --git a/calendar-functions.ps1 b/calendar-functions.ps1 index 45a1c84..5c6ae44 100644 --- a/calendar-functions.ps1 +++ b/calendar-functions.ps1 @@ -32,15 +32,15 @@ Function Get-Calendar { [Parameter(Mandatory, HelpMessage = "Enter an ending date for the month like 2/1/2019", ParameterSetName = "span")] [ValidateNotNullOrEmpty()] - [ValidateScript({ - if ($_ -ge $Start) { - $True - } - else { - Throw "The end date ($_) must be later than the start date ($start)" - $False - } - })] + [ValidateScript( { + if ($_ -ge $Start) { + $True + } + else { + Throw "The end date ($_) must be later than the start date ($start)" + $False + } + })] [DateTime]$End, [ValidateNotNullorEmpty()] @@ -108,7 +108,7 @@ Function Get-Calendar { #highlight a specific date if ($highlightDates -ne (Get-Date).date.toString() ) { - $highlightDates+= (Get-Date).date.toString() + $highlightDates += (Get-Date).date.toString() } $compareDate = New-Object DateTime $currentDay.Year, @@ -195,11 +195,18 @@ Function Show-Calendar { [Parameter(HelpMessage = "Specify a color for the days of the week heading.")] [ValidateNotNullOrEmpty()] - [consolecolor]$DayColor = "Cyan" + [consolecolor]$DayColor = "Cyan", + [System.Management.Automation.Host.Coordinates]$Position ) Write-Verbose "Starting $($myinvocation.mycommand)" + if ($position) { + #save current cursor location + $here = $host.ui.RawUI.CursorPosition + $PSBoundParameters.remove("Position") | out-Null + } + #add default values if not bound $params = "Month", "Year", "HighlightDate" foreach ($param in $params) { @@ -209,7 +216,7 @@ Function Show-Calendar { } #remove color parameters if specified - "HighlightColor","TitleColor","DayColor" | foreach-object { + "HighlightColor", "TitleColor", "DayColor" | foreach-object { if ($PSBoundParameters.Containskey($_)) { $PSBoundParameters.Remove($_) | Out-Null } @@ -227,20 +234,29 @@ Function Show-Calendar { foreach ($line in $calarray) { if ($line -match "\d{4}") { #write the line with the month and year + if ($position) { + $host.ui.RawUI.CursorPosition = $Position + } write-Host $line -ForegroundColor $TitleColor } elseif ($line -match "\w{3}|-{3}") { #write the day names and underlines + if ($Position) { + $Position.y++ + $host.ui.RawUI.CursorPosition = $Position + } Write-Host $line -ForegroundColor $DayColor } elseif ($line -match "\*") { #break apart lines with asterisks $week = $line - - $m.Matches($week).Value| foreach-object { + if ($position) { + $Position.y++ + $host.ui.RawUI.CursorPosition = $Position + } + $m.Matches($week).Value | foreach-object { $day = "$_" - if ($day -match "\*") { write-host "$($day.replace('*','').padleft(3," ")) " -NoNewline -ForegroundColor $HighlightColor } @@ -248,13 +264,24 @@ Function Show-Calendar { write-host "$($day.PadLeft(3," ")) " -nonewline } } + write-host "" } else { + if ($Position) { + $Position.y++ + $host.ui.RawUI.CursorPosition = $Position + } Write-host $line } } #foreach line in calarray + if ($Position) { + #set cursor position back + $here.y++ + $host.ui.RawUI.CursorPosition = $here + } + Write-Verbose "Ending $($myinvocation.mycommand)" } #end Show-Calendar @@ -272,15 +299,15 @@ Function Show-GuiCalendar { [Parameter(Position = 2, HelpMessage = "Enter the last month to display by date, like 3/1/2019. You cannot display more than 3 months.")] [ValidateNotNullOrEmpty()] - [ValidateScript({ - if ($_ -ge $Start) { - $True - } - else { - Throw "The end date ($_) must be later than the start date ($start)" - $False - } - })] + [ValidateScript( { + if ($_ -ge $Start) { + $True + } + else { + Throw "The end date ($_) must be later than the start date ($start)" + $False + } + })] [datetime]$End = [datetime]::new([datetime]::now.year, [datetime]::now.month, 1), [Parameter(HelpMessage = "Enter an array of dates to highlight like 12/25/2019.")] @@ -325,21 +352,21 @@ Function Show-GuiCalendar { Add-Type -AssemblyName PresentationFramework -ErrorAction Stop Add-Type –assemblyName PresentationCore -ErrorAction Stop Add-Type –assemblyName WindowsBase -ErrorAction Stop - } + } Catch { - Write-Warning "Failed to load a required type library. $($_.exception.message)" - #bail out - Return - } + Write-Warning "Failed to load a required type library. $($_.exception.message)" + #bail out + Return + } - $myParams=@{ - Months = $months - Height = (200 * $months.count) - Title = "My Calendar" + $myParams = @{ + Months = $months + Height = (200 * $months.count) + Title = "My Calendar" HighlightDate = $HighlightDate - Font = $Font - FontStyle = $FontStyle - FontWeight = $FontWeight + Font = $Font + FontStyle = $FontStyle + FontWeight = $FontWeight } Write-Verbose "Using these parameters" @@ -353,126 +380,126 @@ Function Show-GuiCalendar { Write-Verbose "Defining runspace script" $psCmd = [PowerShell]::Create().AddScript( { - Param ( - [datetime[]]$HighlightDate, - [string]$Font, - [string]$FontStyle, - [string]$FontWeight, - [int]$Height, - [string]$Title, - [datetime[]]$Months - ) - - #create a window form. - $form = New-Object System.Windows.Window - - $form.AllowsTransparency = $True - $form.WindowStyle = "none" - #the title won't be shown when window style is set to none - $form.Title = $Title - $form.Height = $height - $form.Width = 200 - - $bg = new-object System.Windows.Media.SolidColorBrush - - $form.Background = $bg - #color is set for development purposes. It won't be seen normally. - $form.Background.Color = "green" - $form.background.Opacity = 0 - $form.ShowInTaskbar = $False - $form.Add_Loaded({ - $form.Topmost = $True - $form.Activate() - }) + Param ( + [datetime[]]$HighlightDate, + [string]$Font, + [string]$FontStyle, + [string]$FontWeight, + [int]$Height, + [string]$Title, + [datetime[]]$Months + ) + + #create a window form. + $form = New-Object System.Windows.Window + + $form.AllowsTransparency = $True + $form.WindowStyle = "none" + #the title won't be shown when window style is set to none + $form.Title = $Title + $form.Height = $height + $form.Width = 200 + + $bg = new-object System.Windows.Media.SolidColorBrush + + $form.Background = $bg + #color is set for development purposes. It won't be seen normally. + $form.Background.Color = "green" + $form.background.Opacity = 0 + $form.ShowInTaskbar = $False + $form.Add_Loaded( { + $form.Topmost = $True + $form.Activate() + }) - $form.Add_MouseLeftButtonDown( {$form.DragMove()}) + $form.Add_MouseLeftButtonDown( {$form.DragMove()}) - #add event handlers to adjust opacity by using the +/- keys - $form.add_KeyDown( { + #add event handlers to adjust opacity by using the +/- keys + $form.add_KeyDown( { - switch ($_.key) { - {'Add', 'OemPlus' -contains $_} { - foreach ($cal in $myCals) { - If ($cal.Opacity -lt 1) { - $cal.Opacity = $cal.opacity + .1 - $cal.UpdateLayout() + switch ($_.key) { + {'Add', 'OemPlus' -contains $_} { + foreach ($cal in $myCals) { + If ($cal.Opacity -lt 1) { + $cal.Opacity = $cal.opacity + .1 + $cal.UpdateLayout() + } + } } - } - } - {'Subtract', 'OemMinus' -contains $_} { - foreach ($cal in $myCals) { - If ($cal.Opacity -gt .2) { - $cal.Opacity = $cal.Opacity - .1 - $cal.UpdateLayout() + {'Subtract', 'OemMinus' -contains $_} { + foreach ($cal in $myCals) { + If ($cal.Opacity -gt .2) { + $cal.Opacity = $cal.Opacity - .1 + $cal.UpdateLayout() + } + } } - } } - } - }) - - $stack = $stack = New-object System.Windows.Controls.StackPanel - $stack.Width = $form.Width - $stack.Height = $form.Height - $stack.HorizontalAlignment = "center" - $stack.VerticalAlignment = "top" - - #create an array to store calendars so that opacity can be - #set for multiple calendars in unison - $myCals = @() - foreach ($month in $months) { - $cal = New-Object System.Windows.Controls.Calendar - $cal.DisplayMode = "Month" - - $cal.Opacity = 1 - $cal.FontFamily = $font - $cal.FontSize = 24 - $cal.FontWeight = $FontWeight - $cal.FontStyle = $fontStyle - - $cal.DisplayDateStart = $month - - $cal.HorizontalAlignment = "center" - $cal.VerticalAlignment = "top" - - $cal.SelectionMode = "multipleRange" - if ($highlightdate) { - foreach ($d in $HighlightDate) { - if ($d.month -eq $month.Month) { - $cal.SelectedDates.add($d) + }) + + $stack = $stack = New-object System.Windows.Controls.StackPanel + $stack.Width = $form.Width + $stack.Height = $form.Height + $stack.HorizontalAlignment = "center" + $stack.VerticalAlignment = "top" + + #create an array to store calendars so that opacity can be + #set for multiple calendars in unison + $myCals = @() + foreach ($month in $months) { + $cal = New-Object System.Windows.Controls.Calendar + $cal.DisplayMode = "Month" + + $cal.Opacity = 1 + $cal.FontFamily = $font + $cal.FontSize = 24 + $cal.FontWeight = $FontWeight + $cal.FontStyle = $fontStyle + + $cal.DisplayDateStart = $month + + $cal.HorizontalAlignment = "center" + $cal.VerticalAlignment = "top" + + $cal.SelectionMode = "multipleRange" + if ($highlightdate) { + foreach ($d in $HighlightDate) { + if ($d.month -eq $month.Month) { + $cal.SelectedDates.add($d) + } } } - } - $cal.add_DisplayDateChanged( { - # add the selected days for the currently displayed month - $cal | out-string | write-host - [datetime]$month = $cal.Displaydate - if ($highlightdate) { - foreach ($d in $HighlightDate) { - if ($d.month -eq $month.Month) { - $cal.SelectedDates.add($d) + $cal.add_DisplayDateChanged( { + # add the selected days for the currently displayed month + $cal | out-string | write-host + [datetime]$month = $cal.Displaydate + if ($highlightdate) { + foreach ($d in $HighlightDate) { + if ($d.month -eq $month.Month) { + $cal.SelectedDates.add($d) + } } } - } - $cal.UpdateLayout() - }) + $cal.UpdateLayout() + }) - $stack.addchild($cal) - $myCals+=$cal - } + $stack.addchild($cal) + $myCals += $cal + } - $btn = New-Object System.Windows.Controls.Button - $btn.Content = "_Close" - $btn.Width = 75 - $btn.VerticalAlignment = "Bottom" - $btn.HorizontalAlignment = "Center" - $btn.Opacity = 1 - $btn.Add_click( {$form.close()}) + $btn = New-Object System.Windows.Controls.Button + $btn.Content = "_Close" + $btn.Width = 75 + $btn.VerticalAlignment = "Bottom" + $btn.HorizontalAlignment = "Center" + $btn.Opacity = 1 + $btn.Add_click( {$form.close()}) - $stack.AddChild($btn) + $stack.AddChild($btn) - $form.AddChild($stack) - $form.ShowDialog() | out-null + $form.AddChild($stack) + $form.ShowDialog() | out-null }) diff --git a/changelog.md b/changelog.md index 30a9f96..fa43419 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Change Log for PSCalendar +## v1.5.0 + ++ Modified `Show-Calendar` to allow you to specify a position in the console. ++ Help updates ++ Updated `README.md` ++ Minor changes to the Pester test + ## v1.4.0 + Added parameters to `Show-Calendar` to let user specify colors. (Issue #4) diff --git a/docs/Show-Calendar.md b/docs/Show-Calendar.md index 7df6e1b..8f7aab0 100644 --- a/docs/Show-Calendar.md +++ b/docs/Show-Calendar.md @@ -14,8 +14,9 @@ Display a colorized calendar month in the console. ## SYNTAX ```yaml -Show-Calendar [[-Month] ] [-Year ] [-HighlightDate ] [-HighlightColor ] - [] +Show-Calendar [[-Month] ] [[-Year] ] [-HighlightDate ] + [-HighlightColor ] [-TitleColor ] [-DayColor ] + [-Position ] [] ``` ## DESCRIPTION @@ -40,6 +41,14 @@ PS C:\> Show-Calendar -Month February -Year 2019 -HighlightDate 2/22/19 -Highlig Display February 2019 and highlight the 22nd in red. +### Example 3 + +```powershell +PS C:\> Show-Calendar -Position ([system.management.automation.host.coordinates]::new(75,1)) +``` + +Display the calendar at a specified X,Y position in the console. This parameter will probably not work in the PowerShell ISE. + ## PARAMETERS ### -Month @@ -107,10 +116,57 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -DayColor + +Specify a color for the days of the week heading. + +```yaml +Type: ConsoleColor +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Position + +Enter a System.Management.Automation.Host.Coordinates object to specify a location for the calendar. This may not work properly in all hosts and you might need some trial and error to figure out a position that works for you. + +```yaml +Type: Coordinates +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -TitleColor + +Specify a color for the days of the month heading. + +```yaml +Type: ConsoleColor +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. -For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -118,7 +174,7 @@ For more information, see about_CommonParameters (http://go.microsoft.com/fwlink ## OUTPUTS -### None +### None. This command writes to the PowerShell hosting application. ## NOTES diff --git a/docs/Show-GuiCalendar.md b/docs/Show-GuiCalendar.md index 2e6617c..ecf1b40 100644 --- a/docs/Show-GuiCalendar.md +++ b/docs/Show-GuiCalendar.md @@ -22,7 +22,7 @@ Show-GuiCalendar [[-Start] ] [[-End] ] [-HighlightDate Green + + DayColor + + Specify a color for the days of the week heading. + + ConsoleColor + + ConsoleColor + + + None + + + Position + + Enter a System.Management.Automation.Host.Coordinates object to specify a location for the calendar. This may not work properly in all hosts and you might need some trial and error to figure out a position that works for you. + + Coordinates + + Coordinates + + + None + + + TitleColor + + Specify a color for the days of the month heading. + + ConsoleColor + + ConsoleColor + + + None + @@ -392,6 +428,42 @@ Sun Mon Tue Wed Thu Fri Sat Green + + DayColor + + Specify a color for the days of the week heading. + + ConsoleColor + + ConsoleColor + + + None + + + Position + + Enter a System.Management.Automation.Host.Coordinates object to specify a location for the calendar. This may not work properly in all hosts and you might need some trial and error to figure out a position that works for you. + + Coordinates + + Coordinates + + + None + + + TitleColor + + Specify a color for the days of the month heading. + + ConsoleColor + + ConsoleColor + + + None + @@ -406,7 +478,7 @@ Sun Mon Tue Wed Thu Fri Sat - None + None. This command writes to the PowerShell hosting application. @@ -434,6 +506,13 @@ Sun Mon Tue Wed Thu Fri Sat Display February 2019 and highlight the 22nd in red. + + -------------------------- Example 3 -------------------------- + PS C:\> Show-Calendar -Position ([system.management.automation.host.coordinates]::new(75,1)) + + Display the calendar at a specified X,Y position in the console. This parameter will probably not work in the PowerShell ISE. + + @@ -457,7 +536,7 @@ Sun Mon Tue Wed Thu Fri Sat If you are running Windows PowerShell, you can display a graphical calendar. You can specify up to 3 months. There are also parameters to fine tune the calendar style. The calendar form is transparent. But you should be able to click on it to drag it around your screen. You can also use the + and - keys to increase or decrease the calendar's opacity. You may have to click on a calendar before making any adjustments. - This command launches the calendar in a separate runspace so that it doesn't block your prompt. However, if you close the PowerShell session that launched a graphical calendar, the calender will also automatically close. + This command launches the calendar in a separate runspace so that it doesn't block your prompt. However, if you close the PowerShell session that launched a graphical calendar, the calendar will also automatically close. diff --git a/test/PSCalendar.Tests.ps1 b/test/PSCalendar.Tests.ps1 index e242068..4200f4a 100644 --- a/test/PSCalendar.Tests.ps1 +++ b/test/PSCalendar.Tests.ps1 @@ -1,10 +1,14 @@ #these tests are acceptance tests and validate that the module has the #settings I intend and that the commands work as expected. +#remove any existing versions of the module $moduleName = (Get-Item -path $PSScriptRoot).Parent.Name $ModuleManifestName = "$modulename.psd1" $ModuleManifestPath = "$PSScriptRoot\..\$ModuleManifestName" +If (Get-Module $moduleName) { + remove-module $moduleName +} import-module $ModuleManifestPath -Force Describe $ModuleName { @@ -127,15 +131,15 @@ InModuleScope $moduleName { $ModuleManifestPath = "$PSScriptRoot\..\$ModuleManifestName" #use a runspace to avoid displaying the Write-Host output $ps = [powershell]::Create() - $ps.AddScript({ - param([string]$Name) + $ps.AddScript( { + param([string]$Name) - Import-Module -Name $Name - Show-Calendar + Import-Module -Name $Name + Show-Calendar - },$True) | out-null + }, $True) | out-null - $ps.AddParameter("Name",$ModuleManifestPath) | Out-Null + $ps.AddParameter("Name", $ModuleManifestPath) | Out-Null $r = $ps.Invoke() @@ -151,19 +155,19 @@ InModuleScope $moduleName { #test with a new set of values $ps = [powershell]::Create() - $ps.AddScript({ - param([string]$Name) + $ps.AddScript( { + param([string]$Name) - Import-Module -Name $Name - Show-Calendar + Import-Module -Name $Name + Show-Calendar - },$True) | out-null + }, $True) | out-null $h = @{ - Name = $mod + Name = $mod Month = "foo" - } - $ps.AddParameters($h) + } + $ps.AddParameters($h) $r = $ps.Invoke() It "Should fail with a bad month name" { $ps.streams.error | Should Not BeNullOrEmpty @@ -186,3 +190,5 @@ InModuleScope $moduleName { } } -tag command } + +Write-Host "You will need to manually kill and graphical calendars that were spawned from the test." -ForegroundColor yellow \ No newline at end of file