203 lines
7.1 KiB
C#
203 lines
7.1 KiB
C#
using System;
|
||
using System.Windows;
|
||
using System.Windows.Controls;
|
||
using System.Windows.Input;
|
||
using Microsoft.Win32;
|
||
using QoSManager.Models;
|
||
using QoSManager.Services;
|
||
using QoSManager.Views;
|
||
|
||
namespace QoSManager.Views
|
||
{
|
||
public partial class PolicyEditWindow : Window
|
||
{
|
||
public PolicyEditWindow()
|
||
{
|
||
InitializeComponent();
|
||
ContentRendered += PolicyEditWindow_ContentRendered;
|
||
InitializeEventHandlers();
|
||
}
|
||
|
||
private void PolicyEditWindow_ContentRendered(object sender, EventArgs e)
|
||
{
|
||
ContentRendered -= PolicyEditWindow_ContentRendered;
|
||
CenterToOwnerOrScreen();
|
||
UpdateDscpConverter(); // Initialize converter display
|
||
}
|
||
|
||
private void InitializeEventHandlers()
|
||
{
|
||
CreateButton.Click += CreateButton_Click;
|
||
CancelButton.Click += CancelButton_Click;
|
||
BrowseButton.Click += BrowseButton_Click;
|
||
DSCPTextBox.PreviewTextInput += DSCPTextBox_PreviewTextInput;
|
||
DSCPTextBox.TextChanged += DSCPTextBox_TextChanged;
|
||
}
|
||
|
||
private void CenterToOwnerOrScreen()
|
||
{
|
||
if (Owner != null)
|
||
{
|
||
Left = Owner.Left + (Owner.Width - ActualWidth) / 2;
|
||
Top = Owner.Top + (Owner.Height - ActualHeight) / 2;
|
||
}
|
||
else
|
||
{
|
||
Left = SystemParameters.WorkArea.Left + (SystemParameters.WorkArea.Width - ActualWidth) / 2;
|
||
Top = SystemParameters.WorkArea.Top + (SystemParameters.WorkArea.Height - ActualHeight) / 2;
|
||
}
|
||
}
|
||
|
||
private void BrowseButton_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
var processSelectionWindow = new ProcessSelectionWindow();
|
||
processSelectionWindow.Owner = this;
|
||
|
||
if (processSelectionWindow.ShowDialog() == true)
|
||
{
|
||
ProcessTextBox.Text = processSelectionWindow.SelectedProcess;
|
||
}
|
||
}
|
||
|
||
private void CreateButton_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
if (ValidateInput())
|
||
{
|
||
DialogResult = true;
|
||
Close();
|
||
}
|
||
}
|
||
|
||
private void CancelButton_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
DialogResult = false;
|
||
Close();
|
||
}
|
||
|
||
private void DSCPTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||
{
|
||
UpdateDscpConverter();
|
||
}
|
||
|
||
private void UpdateDscpConverter()
|
||
{
|
||
// Check if TOS TextBlock control is initialized
|
||
if (TosValueTextBlock == null)
|
||
return;
|
||
|
||
if (int.TryParse(DSCPTextBox.Text, out int dscpValue) && dscpValue >= 1 && dscpValue <= 63)
|
||
{
|
||
// Update TOS value
|
||
string tosValue = DscpTosConverter.GetTosFromDscp(dscpValue);
|
||
TosValueTextBlock.Text = tosValue;
|
||
}
|
||
else
|
||
{
|
||
// Reset display for invalid input
|
||
TosValueTextBlock.Text = "Invalid";
|
||
}
|
||
}
|
||
|
||
private void DSCPTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||
{
|
||
// Only allow digits
|
||
if (!int.TryParse(e.Text, out _))
|
||
{
|
||
e.Handled = true;
|
||
return;
|
||
}
|
||
|
||
// Check if the new value would be within 1-63 range
|
||
string currentText = DSCPTextBox.Text ?? "";
|
||
string newText = currentText + e.Text;
|
||
|
||
if (int.TryParse(newText, out int value))
|
||
{
|
||
if (value < 1 || value > 63)
|
||
{
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private bool ValidateInput()
|
||
{
|
||
if (string.IsNullOrWhiteSpace(NameTextBox.Text))
|
||
{
|
||
CustomMessageBox.Show("Введите имя политики.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
NameTextBox.Focus();
|
||
return false;
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(ProcessTextBox.Text))
|
||
{
|
||
CustomMessageBox.Show("Укажите имя процесса.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
ProcessTextBox.Focus();
|
||
return false;
|
||
}
|
||
|
||
if (!int.TryParse(DSCPTextBox.Text, out int dscpValue) || dscpValue < 1 || dscpValue > 63)
|
||
{
|
||
CustomMessageBox.Show("Значение DSCP должно быть числом от 1 до 63.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
DSCPTextBox.Focus();
|
||
return false;
|
||
}
|
||
|
||
// В PowerShell одинарные кавычки экранируются внутри строки, а двоеточие и обратные слэши
|
||
// нужны для Windows-пути вроде C:\Program Files (x86)\...
|
||
var forbiddenNameChars = "\"\\()/#*[]";
|
||
var forbiddenInName = NameTextBox.Text.IndexOfAny(forbiddenNameChars.ToCharArray());
|
||
if (forbiddenInName != -1)
|
||
{
|
||
CustomMessageBox.Show($"Имя политики содержит запрещенный символ '{NameTextBox.Text[forbiddenInName]}'. New-NetQosPolicy не позволяет использовать символы: {forbiddenNameChars}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
NameTextBox.Focus();
|
||
return false;
|
||
}
|
||
|
||
var forbiddenProcessChars = "\"|&<>?*";
|
||
var forbiddenInProcess = ProcessTextBox.Text.IndexOfAny(forbiddenProcessChars.ToCharArray());
|
||
if (forbiddenInProcess != -1)
|
||
{
|
||
CustomMessageBox.Show($"Путь процесса содержит запрещенный символ '{ProcessTextBox.Text[forbiddenInProcess]}'. Для Windows-пути допустимы C:\\... и обратные слэши.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
ProcessTextBox.Focus();
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public QoSPolicy GetPolicy()
|
||
{
|
||
int dscpValue = 1;
|
||
if (int.TryParse(DSCPTextBox.Text, out int parsedValue))
|
||
{
|
||
dscpValue = parsedValue;
|
||
}
|
||
|
||
return new QoSPolicy
|
||
{
|
||
Name = NameTextBox.Text.Trim(),
|
||
Process = ProcessTextBox.Text.Trim(),
|
||
DSCP = dscpValue
|
||
};
|
||
}
|
||
|
||
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||
{
|
||
if (e.ChangedButton == MouseButton.Left)
|
||
{
|
||
DragMove();
|
||
}
|
||
}
|
||
|
||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
Close();
|
||
}
|
||
}
|
||
}
|