diff --git a/Source/NETworkManager.Localization/Resources/Strings.Designer.cs b/Source/NETworkManager.Localization/Resources/Strings.Designer.cs index 3cf04e06e4..8df05e8a07 100644 --- a/Source/NETworkManager.Localization/Resources/Strings.Designer.cs +++ b/Source/NETworkManager.Localization/Resources/Strings.Designer.cs @@ -1898,7 +1898,34 @@ public static string CloseGroup { return ResourceManager.GetString("CloseGroup", resourceCulture); } } - + + /// + /// Looks up a localized string similar to Start group. + /// + public static string StartGroup { + get { + return ResourceManager.GetString("StartGroup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Group actions. + /// + public static string GroupActions { + get { + return ResourceManager.GetString("GroupActions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pause group. + /// + public static string PauseGroup { + get { + return ResourceManager.GetString("PauseGroup", resourceCulture); + } + } + /// /// Looks up a localized string similar to Closing in {0} seconds.... /// diff --git a/Source/NETworkManager.Localization/Resources/Strings.resx b/Source/NETworkManager.Localization/Resources/Strings.resx index 9c69a5b26d..5533818793 100644 --- a/Source/NETworkManager.Localization/Resources/Strings.resx +++ b/Source/NETworkManager.Localization/Resources/Strings.resx @@ -3892,6 +3892,15 @@ Try again in a few seconds. Close group + + Start group + + + Group actions + + + Pause group + Run command... (Ctrl+Shift+P) diff --git a/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs b/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs index f50cf2cafe..a25bf063a8 100644 --- a/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs +++ b/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs @@ -239,6 +239,28 @@ private void CloseGroupAction(object group) RemoveGroup(group.ToString()); } + /// + /// Gets the command to start every host in a group that is not currently running. + /// + public ICommand StartGroupCommand => new RelayCommand(StartGroupAction); + + private void StartGroupAction(object group) + { + foreach (var host in Hosts.Where(host => host.Group.Equals(group.ToString()) && !host.IsRunning)) + host.Start(); + } + + /// + /// Gets the command to pause every host in a group that is currently running. + /// + public ICommand PauseGroupCommand => new RelayCommand(PauseGroupAction); + + private void PauseGroupAction(object group) + { + foreach (var host in Hosts.Where(host => host.Group.Equals(group.ToString()) && host.IsRunning)) + host.Stop(); + } + #endregion #region Methods diff --git a/Source/NETworkManager/Views/PingMonitorHostView.xaml b/Source/NETworkManager/Views/PingMonitorHostView.xaml index 46ddaa631e..048c2fe6c1 100644 --- a/Source/NETworkManager/Views/PingMonitorHostView.xaml +++ b/Source/NETworkManager/Views/PingMonitorHostView.xaml @@ -26,6 +26,10 @@ + + @@ -196,8 +200,8 @@ + Visibility="{Binding Path=Hosts.Count, Converter={StaticResource ResourceKey=IntNotZeroToVisibilityCollapsedConverter}}" + Background="Transparent"> @@ -216,91 +220,154 @@ + - + Orientation="Horizontal" + VerticalAlignment="Center"> + - + - - + + - + Style="{StaticResource ResourceKey=DefaultTextBlock}" + Foreground="{DynamicResource ResourceKey=MahApps.Brushes.Gray5}" + Margin="6,0,6,0" /> + - + - - + + + Style="{StaticResource ResourceKey=DefaultTextBlock}" + Foreground="{DynamicResource ResourceKey=MahApps.Brushes.Gray5}" + Margin="6,0,6,0" + Visibility="{Binding ElementName=PausedText, Path=Visibility}" /> + Style="{StaticResource ResourceKey=DefaultTextBlock}" + Foreground="{DynamicResource ResourceKey=MahApps.Brushes.Gray5}"> - + - - + + - + - + - @@ -337,8 +404,8 @@ Focusable="False" Style="{StaticResource ResourceKey=VerticalGridSplitter}" /> + ProfileItemTemplate="{StaticResource ResourceKey=PingMonitorProfileItemTemplate}" + ProfileContextMenuExtraItems="{StaticResource ResourceKey=PingMonitorProfileContextMenuExtraItems}" + RunProfileCommand="{Binding Path=PingProfileCommand}" /> \ No newline at end of file diff --git a/Source/NETworkManager/Views/PingMonitorHostView.xaml.cs b/Source/NETworkManager/Views/PingMonitorHostView.xaml.cs index 14ef172187..42366d6a88 100644 --- a/Source/NETworkManager/Views/PingMonitorHostView.xaml.cs +++ b/Source/NETworkManager/Views/PingMonitorHostView.xaml.cs @@ -1,3 +1,5 @@ +using System.Windows; +using System.Windows.Controls; using NETworkManager.ViewModels; namespace NETworkManager.Views; @@ -27,4 +29,17 @@ public void OnViewVisible() { _viewModel.OnViewVisible(); } + + /// + /// Opens the group actions context menu on a normal click (not just right-click), so it + /// works the same way for mouse, touch and keyboard activation. PlacementTarget is set + /// explicitly since it isn't populated automatically when opening the menu this way, and + /// the menu items rely on it to reach the group name (see Button.Tag in the XAML). + /// + private void GroupActionsButton_Click(object sender, RoutedEventArgs e) + { + var button = (Button)sender; + button.ContextMenu.PlacementTarget = button; + button.ContextMenu.IsOpen = true; + } } diff --git a/Website/docs/application/ping-monitor.md b/Website/docs/application/ping-monitor.md index 6391f00de4..03e953395f 100644 --- a/Website/docs/application/ping-monitor.md +++ b/Website/docs/application/ping-monitor.md @@ -52,6 +52,18 @@ You can interact with the chart to inspect past results: When you zoom or pan, the chart leaves live mode and stops scrolling. A **Live** button then appears in the top-right corner of the chart — click it to return to live mode and resume auto-scrolling. +### Groups + +Hosts are grouped by their profile group (or **Hosts** if none is set). Each group header shows a live count of hosts that are up, down and paused (**Paused** is only shown while at least one host in the group is paused). + +Click/tap the **⋮** icon on the right of a group header to open its action menu: + +| Action | Description | +|--------|-------------| +| **Start** | Starts every host in the group that isn't currently running | +| **Pause** | Pauses every host in the group that's currently running | +| **Close** | Stops and removes every host in the group | + ### Context menu Right-click a monitored host (anywhere except the chart) to open the context menu: diff --git a/Website/docs/changelog/next-release.md b/Website/docs/changelog/next-release.md index beeb7c68ab..33e29c9986 100644 --- a/Website/docs/changelog/next-release.md +++ b/Website/docs/changelog/next-release.md @@ -54,7 +54,8 @@ Release date: **xx.xx.2026** **Ping Monitor** -- Added a live count of hosts up/down (and paused, if any) per group, next to the group's close button. [#3572](https://github.com/BornToBeRoot/NETworkManager/pull/3572) +- Added a live count of hosts up/down (and paused, if any) to each group header. [#3572](https://github.com/BornToBeRoot/NETworkManager/pull/3572) +- Added **Start** and **Pause** actions to each group header (next to the existing **Close**), to start every paused host in the group or pause every running one at once. Click/tap the **⋮** icon to open the group's action menu. [#3575](https://github.com/BornToBeRoot/NETworkManager/pull/3575) - Reworked each monitored host's card: the collapsed quick info now shows labeled values (`Received: X · Lost: Y · Packet loss: Z%`) instead of unlabeled numbers, the expanded view shows only the latency chart (with more room, since Hostname/IP address are already visible in the header) and the last status change time moved to a tooltip on the connectivity icon. The **Status change** field was also renamed to **Last status change**. [#3572](https://github.com/BornToBeRoot/NETworkManager/pull/3572) - Host input now accepts newline-separated hosts (one per line, e.g. a column pasted from Excel), converted automatically to the semicolon-separated form. [#3568](https://github.com/BornToBeRoot/NETworkManager/pull/3568) - Host input now supports shorthand IPv4 ranges like `192.168.0.1-100`, in addition to the existing `192.168.0.0-192.168.0.100` and `192.168.[0-100].1` range formats. [#3568](https://github.com/BornToBeRoot/NETworkManager/pull/3568)