Files
Planification/native-host/bin/tray.ps1
T

197 lines
7.3 KiB
PowerShell

# Planification - icone barre des taches (best-effort, optionnel) // 2026.1.4 - QRO
# Developpe par Quentin Rouiller (QRO) - DGNSI, Canton de Vaud.
# Licence MIT - voir le fichier LICENSE.
#
# Indique que le helper de sync est installe. Clic / menu -> fenetre du journal
# (aspect application : journal colore par niveau, auto-rafraichi, bouton
# "Tout afficher"). Lance par tray.vbs (fenetre masquee), au login.
$ErrorActionPreference = 'SilentlyContinue'
# Instance unique.
$mutex = New-Object System.Threading.Mutex($false, 'Local\PlanificationTraySingleton')
if (-not $mutex.WaitOne(0)) { exit }
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# tray.ps1 vit dans <install>\bin -> racine = parent ; assets et log a la racine.
$root = if ($PSScriptRoot) { Split-Path -Parent $PSScriptRoot } else { Join-Path $env:LOCALAPPDATA 'Planification' }
$logFile = Join-Path $root 'activity.log'
$iconPng = Join-Path (Join-Path $root 'assets') 'icon.png'
function Get-TrayIcon {
try {
if (Test-Path -LiteralPath $iconPng) {
$bmp = New-Object System.Drawing.Bitmap($iconPng)
return [System.Drawing.Icon]::FromHandle($bmp.GetHicon())
}
} catch {}
return [System.Drawing.SystemIcons]::Information
}
$script:logForm = $null
$script:logRtb = $null
$script:logChk = $null
$script:logSig = ''
$colInfo = [System.Drawing.Color]::FromArgb(40, 70, 120)
$colDebug = [System.Drawing.Color]::FromArgb(150, 150, 150)
$colErr = [System.Drawing.Color]::FromArgb(200, 40, 40)
$colTs = [System.Drawing.Color]::FromArgb(120, 120, 120)
function Update-LogText {
if (-not $script:logRtb -or $script:logRtb.IsDisposed) { return }
$lines = @()
if (Test-Path -LiteralPath $logFile) {
try {
$all = Get-Content -LiteralPath $logFile -Encoding UTF8 -ErrorAction SilentlyContinue
if ($all) {
if ($script:logChk -and -not $script:logChk.Checked) {
$all = $all | Where-Object { $_ -notmatch '\[DEBUG\]' }
}
$lines = @($all | Select-Object -Last 500)
}
} catch {}
}
$sig = ($lines -join "`n")
if ($sig -eq $script:logSig) { return }
$script:logSig = $sig
$rtb = $script:logRtb
$rtb.SuspendLayout()
$rtb.Clear()
if ($lines.Count -eq 0) {
$rtb.SelectionColor = $colDebug
$rtb.AppendText("(aucune activite de synchronisation pour le moment)")
} else {
foreach ($line in $lines) {
$col = $colInfo
if ($line -match '\[ERREUR\]') { $col = $colErr }
elseif ($line -match '\[DEBUG\]') { $col = $colDebug }
if ($line -match '^(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2})(.*)$') {
$rtb.SelectionStart = $rtb.TextLength; $rtb.SelectionColor = $colTs
$rtb.AppendText($Matches[1])
$rtb.SelectionStart = $rtb.TextLength; $rtb.SelectionColor = $col
$rtb.AppendText($Matches[2] + "`n")
} else {
$rtb.SelectionStart = $rtb.TextLength; $rtb.SelectionColor = $col
$rtb.AppendText($line + "`n")
}
}
}
$rtb.ResumeLayout()
$rtb.SelectionStart = $rtb.TextLength; $rtb.ScrollToCaret()
}
function Show-LogWindow {
if ($script:logForm -and -not $script:logForm.IsDisposed) {
$script:logForm.WindowState = 'Normal'; $script:logForm.Activate(); return
}
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Planification - journal de synchronisation'
$form.Size = New-Object System.Drawing.Size(760, 540)
$form.StartPosition = 'CenterScreen'
$form.BackColor = [System.Drawing.Color]::FromArgb(245, 246, 248)
try { $form.Icon = Get-TrayIcon } catch {}
# 1) zone de texte (Fill) ajoutee en premier
$rtb = New-Object System.Windows.Forms.RichTextBox
$rtb.Dock = 'Fill'
$rtb.ReadOnly = $true
$rtb.BorderStyle = 'None'
$rtb.BackColor = [System.Drawing.Color]::White
$rtb.Font = New-Object System.Drawing.Font('Consolas', 9.5)
$rtb.DetectUrls = $false
$form.Controls.Add($rtb)
# 2) barre d'outils claire avec le BOUTON bascule "Tout afficher" bien visible
$bar = New-Object System.Windows.Forms.Panel
$bar.Dock = 'Top'; $bar.Height = 40
$bar.BackColor = [System.Drawing.Color]::FromArgb(238, 240, 243)
$chk = New-Object System.Windows.Forms.CheckBox
$chk.Appearance = 'Button'
$chk.Text = 'Tout afficher (mode detaille)'
$chk.TextAlign = 'MiddleCenter'
$chk.AutoSize = $false
$chk.Size = New-Object System.Drawing.Size(200, 28)
$chk.Location = New-Object System.Drawing.Point(10, 6)
$chk.FlatStyle = 'System'
$chk.add_CheckedChanged({ $script:logSig = '~'; Update-LogText })
$bar.Controls.Add($chk)
$hint = New-Object System.Windows.Forms.Label
$hint.Text = 'Par defaut : l''essentiel. Activez pour voir tout le detail technique.'
$hint.ForeColor = [System.Drawing.Color]::FromArgb(90, 90, 90)
$hint.AutoSize = $true
$hint.Location = New-Object System.Drawing.Point(220, 12)
$bar.Controls.Add($hint)
$form.Controls.Add($bar)
# 3) bandeau titre (bleu) ajoute en dernier -> tout en haut
$hdrBar = New-Object System.Windows.Forms.Panel
$hdrBar.Dock = 'Top'; $hdrBar.Height = 32
$hdrBar.BackColor = [System.Drawing.Color]::FromArgb(40, 70, 120)
$hdr = New-Object System.Windows.Forms.Label
$hdr.Text = 'Activite de synchronisation - Planification'
$hdr.ForeColor = [System.Drawing.Color]::White
$hdr.Font = New-Object System.Drawing.Font('Segoe UI', 10, [System.Drawing.FontStyle]::Bold)
$hdr.AutoSize = $true
$hdr.Location = New-Object System.Drawing.Point(10, 7)
$hdrBar.Controls.Add($hdr)
$form.Controls.Add($hdrBar)
$script:logForm = $form
$script:logRtb = $rtb
$script:logChk = $chk
$script:logSig = ''
Update-LogText
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 2000
$timer.add_Tick({ Update-LogText })
$timer.Start()
$form.add_FormClosed({ $timer.Stop(); $timer.Dispose() })
$form.Show(); $form.Activate()
}
$ni = New-Object System.Windows.Forms.NotifyIcon
$ni.Icon = Get-TrayIcon
$ni.Text = 'Planification - synchronisation active'
$ni.Visible = $true
$menu = New-Object System.Windows.Forms.ContextMenuStrip
$miLog = $menu.Items.Add('Voir le journal de synchronisation')
$miLog.add_Click({ Show-LogWindow })
$miQuit = $menu.Items.Add('Quitter')
$miQuit.add_Click({ $ni.Visible = $false; $ni.Dispose(); [System.Windows.Forms.Application]::Exit() })
$ni.ContextMenuStrip = $menu
$ni.add_MouseClick({ param($s, $e) if ($e.Button -eq [System.Windows.Forms.MouseButtons]::Left) { Show-LogWindow } })
# v2026.1.7 - auto-extinction apres 2 h SANS activite de synchronisation. On se
# base sur la date de derniere ecriture du journal (le host y ecrit a chaque
# operation). Le navigateur relancera le host a la prochaine activite, qui
# relancera ce tray. -> "de base eteint, s'active a l'usage, se ferme au repos".
$IDLE_LIMIT_MIN = 120
$idleTimer = New-Object System.Windows.Forms.Timer
$idleTimer.Interval = 300000 # verifie toutes les 5 min
$idleTimer.add_Tick({
try {
$age = $null
if (Test-Path -LiteralPath $logFile) {
$age = ((Get-Date) - (Get-Item -LiteralPath $logFile).LastWriteTime).TotalMinutes
}
# Pas de journal, ou journal inactif depuis >= 2 h -> on s'eteint.
if (($null -eq $age) -or ($age -ge $IDLE_LIMIT_MIN)) {
$ni.Visible = $false; $ni.Dispose()
[System.Windows.Forms.Application]::Exit()
}
} catch {}
})
$idleTimer.Start()
[System.Windows.Forms.Application]::EnableVisualStyles()
[System.Windows.Forms.Application]::Run()
$idleTimer.Stop()
$ni.Dispose()