disable controls by default until a codeplug is loaded; add confirmation dialog when resetting console settings; move console settings into the standard windows default pathing for user settings;

pull/1/head
Bryan Biedenkapp 11 months ago
parent 95e1964591
commit 3533d36d3c

@ -25,24 +25,29 @@
<Menu VerticalAlignment="Center" Height="25" Background="White" Grid.ColumnSpan="2">
<MenuItem Header="File">
<MenuItem Header="_Open Codeplug" Click="OpenCodeplug_Click"/>
<MenuItem Header="_Open Codeplug" Click="OpenCodeplug_Click" />
<Separator />
<MenuItem Header="_Exit" Click="Exit_Click" />
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="_Audio Settings" Click="AudioSettings_Click" />
<MenuItem Header="_Reset Settings" Click="ResetSettings_Click"/>
<MenuItem Header="_Reset Settings" Click="ResetSettings_Click" />
<Separator />
<MenuItem Header="_Enable Edit Mode" IsCheckable="True" Checked="ToggleEditMode_Click" Unchecked="ToggleEditMode_Click" />
<MenuItem Header="_Enable Edit Mode" IsCheckable="True" Checked="ToggleEditMode_Click" Unchecked="ToggleEditMode_Click" x:Name="menuEditMode" />
<Separator />
<MenuItem Header="_Select Widgets to Display" Click="SelectWidgets_Click"/>
<MenuItem Header="_Select Widgets to Display" Click="SelectWidgets_Click" />
<MenuItem Header="Alerts">
<MenuItem Header="Add Alert Tone" Click="AddAlertTone_Click"/>
<MenuItem Header="Add Alert Tone" Click="AddAlertTone_Click" />
</MenuItem>
</MenuItem>
<MenuItem Header="Page">
<MenuItem Header="_Page Subscriber" Click="P25Page_Click" />
<MenuItem Header="_QuickCall II" Click="ManualPage_Click" />
<MenuItem Header="Commands">
<MenuItem Header="_Page Subscriber" Click="PageRID_Click" x:Name="menuPageSubscriber" />
<MenuItem Header="Radio _Check Subscriber" Click="RadioCheckRID_Click" x:Name="menuRadioCheckSubscriber" />
<Separator />
<MenuItem Header="_Inhibit Subscriber" Click="InhibitRID_Click" x:Name="menuInhibitSubscriber" />
<MenuItem Header="_Uninhibit Subscriber" Click="UninhibitRID_Click" x:Name="menuUninhibitSubscriber" />
<Separator />
<MenuItem Header="_QuickCall II" Click="ManualPage_Click" x:Name="menuQuickCall2" />
</MenuItem>
</Menu>
@ -64,7 +69,7 @@
</Image>
<!-- Open Codeplug -->
<Button VerticalContentAlignment="Bottom" HorizontalAlignment="Left" Margin="238,0,0,0" VerticalAlignment="Center" Height="46" Width="45" x:Name="OpenCodeplug_Click2" Click="OpenCodeplug_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" Grid.Row="1" FontSize="10" FontFamily="Arial"
<Button VerticalContentAlignment="Bottom" HorizontalAlignment="Left" Margin="238,0,0,0" VerticalAlignment="Center" Height="46" Width="45" Click="OpenCodeplug_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" Grid.Row="1" FontSize="10" FontFamily="Arial"
ToolTip="Open Codeplug">
<Button.Resources>
<Style TargetType="{x:Type Border}">
@ -161,7 +166,7 @@
</Button>
<!-- Page Subscriber -->
<Button VerticalContentAlignment="Bottom" HorizontalAlignment="Left" Margin="510,0,0,0" VerticalAlignment="Center" Height="46" Width="44" Click="P25Page_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" Grid.Row="1" FontSize="10" FontFamily="Arial"
<Button VerticalContentAlignment="Bottom" HorizontalAlignment="Left" Margin="510,0,0,0" VerticalAlignment="Center" Height="46" Width="44" x:Name="btnPageSub" Click="PageRID_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" Grid.Row="1" FontSize="10" FontFamily="Arial"
ToolTip="Page Subscriber">
<Button.Resources>
<Style TargetType="{x:Type Border}">
@ -178,7 +183,7 @@
</Button>
<!-- Clear Emergency (disabled) -->
<Button VerticalContentAlignment="Bottom" HorizontalAlignment="Left" Margin="559,0,0,0" VerticalAlignment="Center" Height="46" Width="45" Click="ClearEmergency_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" Grid.Row="1" FontSize="10" FontFamily="Arial"
<Button VerticalContentAlignment="Bottom" HorizontalAlignment="Left" Margin="559,0,0,0" VerticalAlignment="Center" Height="46" Width="45" x:Name="btnClearEmergency" Click="ClearEmergency_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" Grid.Row="1" FontSize="10" FontFamily="Arial"
ToolTip="Clear Emergency" Visibility="Hidden">
<Button.Resources>
<Style TargetType="{x:Type Border}">
@ -196,7 +201,7 @@
</Button>
<!-- Select/Unselect All -->
<Button VerticalContentAlignment="Center" HorizontalAlignment="Left" Margin="609,0,0,0" VerticalAlignment="Center" Height="46" Click="SelectAll_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" FontSize="10" FontFamily="Arial" Grid.Row="1"
<Button VerticalContentAlignment="Center" HorizontalAlignment="Left" Margin="609,0,0,0" VerticalAlignment="Center" Height="46" x:Name="btnSelectAll" Click="SelectAll_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" FontSize="10" FontFamily="Arial" Grid.Row="1"
ToolTip="Select All/Unselect All">
<Button.Resources>
<Style TargetType="{x:Type Border}">
@ -213,7 +218,7 @@
</Button>
<!-- Encryption Key Information -->
<Button VerticalContentAlignment="Center" HorizontalAlignment="Left" Margin="656,0,0,0" VerticalAlignment="Center" Height="46" Width="44" Click="KeyStatus_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" FontSize="10" FontFamily="Arial" Grid.Row="1"
<Button VerticalContentAlignment="Center" HorizontalAlignment="Left" Margin="656,0,0,0" VerticalAlignment="Center" Height="46" Width="44" x:Name="btnKeyStatus" Click="KeyStatus_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" FontSize="10" FontFamily="Arial" Grid.Row="1"
ToolTip="Encryption Key Information">
<Button.Resources>
<Style TargetType="{x:Type Border}">
@ -230,7 +235,7 @@
</Button>
<!-- Call History -->
<Button VerticalContentAlignment="Center" HorizontalAlignment="Left" Margin="703,0,0,0" VerticalAlignment="Center" Height="46" Width="44" Click="CallHist_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" FontSize="10" FontFamily="Arial" Grid.Row="1"
<Button VerticalContentAlignment="Center" HorizontalAlignment="Left" Margin="703,0,0,0" VerticalAlignment="Center" Height="46" Width="44" x:Name="btnCallHistory" Click="CallHist_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" FontSize="10" FontFamily="Arial" Grid.Row="1"
ToolTip="Call History">
<Button.Resources>
<Style TargetType="{x:Type Border}">
@ -247,7 +252,7 @@
</Button>
<!-- Audio Settings -->
<Button VerticalContentAlignment="Bottom" VerticalAlignment="Center" Height="46" Click="AudioSettings_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" Grid.Row="1" FontSize="10" FontFamily="Arial"
<Button VerticalContentAlignment="Bottom" VerticalAlignment="Center" Height="46" x:Name="btnAudioSettings" Click="AudioSettings_Click" BorderBrush="#FFC1C1C1" BorderThickness="1,1,1,1" Grid.Row="1" FontSize="10" FontFamily="Arial"
ToolTip="Audio Settings" HorizontalAlignment="Left" Width="54" Margin="800,0,0,0">
<Button.Resources>
<Style TargetType="{x:Type Border}">

@ -37,7 +37,6 @@ using fnecore.P25;
using fnecore.P25.LC.TSBK;
using fnecore.P25.KMM;
namespace dvmconsole
{
/// <summary>
@ -118,7 +117,11 @@ namespace dvmconsole
public MainWindow()
{
InitializeComponent();
DisableControls();
settingsManager.LoadSettings();
selectedChannelsManager = new SelectedChannelsManager();
flashingManager = new FlashingBackgroundManager(null, ChannelsCanvas, null, this);
emergencyAlertPlayback = new WaveFilePlaybackManager(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Audio/emergency.wav"));
@ -140,6 +143,52 @@ namespace dvmconsole
Loaded += MainWindow_Loaded;
}
/// <summary>
/// Helper to enable form controls when settings and codeplug are loaded.
/// </summary>
private void EnableControls()
{
menuEditMode.IsEnabled = true;
menuPageSubscriber.IsEnabled = true;
menuRadioCheckSubscriber.IsEnabled = true;
menuInhibitSubscriber.IsEnabled = true;
menuUninhibitSubscriber.IsEnabled = true;
menuQuickCall2.IsEnabled = true;
btnGlobalPtt.IsEnabled = true;
btnAlert1.IsEnabled = true;
btnAlert2.IsEnabled = true;
btnAlert3.IsEnabled = true;
btnPageSub.IsEnabled = true;
btnSelectAll.IsEnabled = true;
btnKeyStatus.IsEnabled = true;
btnCallHistory.IsEnabled = true;
}
/// <summary>
/// Helper to disable form controls when settings load fails.
/// </summary>
private void DisableControls()
{
menuEditMode.IsEnabled = false;
menuPageSubscriber.IsEnabled = false;
menuRadioCheckSubscriber.IsEnabled = false;
menuInhibitSubscriber.IsEnabled = false;
menuUninhibitSubscriber.IsEnabled = false;
menuQuickCall2.IsEnabled = false;
btnGlobalPtt.IsEnabled = false;
btnAlert1.IsEnabled = false;
btnAlert2.IsEnabled = false;
btnAlert3.IsEnabled = false;
btnPageSub.IsEnabled = false;
btnSelectAll.IsEnabled = false;
btnKeyStatus.IsEnabled = false;
btnCallHistory.IsEnabled = false;
}
/// <summary>
///
/// </summary>
@ -169,8 +218,9 @@ namespace dvmconsole
/// <param name="e"></param>
private void ResetSettings_Click(object sender, RoutedEventArgs e)
{
if (File.Exists("UserSettings.json"))
File.Delete("UserSettings.json");
var confirmResult = MessageBox.Show("Are you sure to wish to reset console settings?", "Confirm Settings Reset", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (confirmResult == MessageBoxResult.Yes)
settingsManager.Reset();
}
/// <summary>
@ -189,11 +239,13 @@ namespace dvmconsole
var yaml = File.ReadAllText(filePath);
Codeplug = deserializer.Deserialize<Codeplug>(yaml);
EnableControls();
GenerateChannelWidgets();
}
catch (Exception ex)
{
MessageBox.Show($"Error loading codeplug: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
DisableControls();
}
}
@ -471,10 +523,12 @@ namespace dvmconsole
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void P25Page_Click(object sender, RoutedEventArgs e)
private void PageRID_Click(object sender, RoutedEventArgs e)
{
DigitalPageWindow pageWindow = new DigitalPageWindow(Codeplug.Systems);
pageWindow.Owner = this;
pageWindow.Title = "Page Subscriber";
if (pageWindow.ShowDialog() == true)
{
PeerSystem handler = fneSystemManager.GetFneSystem(pageWindow.RadioSystem.Name);
@ -495,6 +549,99 @@ namespace dvmconsole
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RadioCheckRID_Click(object sender, RoutedEventArgs e)
{
DigitalPageWindow pageWindow = new DigitalPageWindow(Codeplug.Systems);
pageWindow.Owner = this;
pageWindow.Title = "Radio Check Subscriber";
if (pageWindow.ShowDialog() == true)
{
PeerSystem handler = fneSystemManager.GetFneSystem(pageWindow.RadioSystem.Name);
IOSP_EXT_FNCT extFunc = new IOSP_EXT_FNCT((ushort)ExtendedFunction.CHECK, uint.Parse(pageWindow.RadioSystem.Rid), uint.Parse(pageWindow.DstId));
RemoteCallData callData = new RemoteCallData
{
SrcId = uint.Parse(pageWindow.RadioSystem.Rid),
DstId = uint.Parse(pageWindow.DstId),
LCO = P25Defines.TSBK_IOSP_EXT_FNCT
};
byte[] tsbk = new byte[P25Defines.P25_TSBK_LENGTH_BYTES];
extFunc.Encode(ref tsbk);
handler.SendP25TSBK(callData, tsbk);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void InhibitRID_Click(object sender, RoutedEventArgs e)
{
DigitalPageWindow pageWindow = new DigitalPageWindow(Codeplug.Systems);
pageWindow.Owner = this;
pageWindow.Title = "Inhibit Subscriber";
if (pageWindow.ShowDialog() == true)
{
PeerSystem handler = fneSystemManager.GetFneSystem(pageWindow.RadioSystem.Name);
IOSP_EXT_FNCT extFunc = new IOSP_EXT_FNCT((ushort)ExtendedFunction.INHIBIT, uint.Parse(pageWindow.RadioSystem.Rid), uint.Parse(pageWindow.DstId));
RemoteCallData callData = new RemoteCallData
{
SrcId = uint.Parse(pageWindow.RadioSystem.Rid),
DstId = uint.Parse(pageWindow.DstId),
LCO = P25Defines.TSBK_IOSP_EXT_FNCT
};
byte[] tsbk = new byte[P25Defines.P25_TSBK_LENGTH_BYTES];
extFunc.Encode(ref tsbk);
handler.SendP25TSBK(callData, tsbk);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UninhibitRID_Click(object sender, RoutedEventArgs e)
{
DigitalPageWindow pageWindow = new DigitalPageWindow(Codeplug.Systems);
pageWindow.Owner = this;
pageWindow.Title = "Uninhibit Subscriber";
if (pageWindow.ShowDialog() == true)
{
PeerSystem handler = fneSystemManager.GetFneSystem(pageWindow.RadioSystem.Name);
IOSP_EXT_FNCT extFunc = new IOSP_EXT_FNCT((ushort)ExtendedFunction.UNINHIBIT, uint.Parse(pageWindow.RadioSystem.Rid), uint.Parse(pageWindow.DstId));
RemoteCallData callData = new RemoteCallData
{
SrcId = uint.Parse(pageWindow.RadioSystem.Rid),
DstId = uint.Parse(pageWindow.DstId),
LCO = P25Defines.TSBK_IOSP_EXT_FNCT
};
byte[] tsbk = new byte[P25Defines.P25_TSBK_LENGTH_BYTES];
extFunc.Encode(ref tsbk);
handler.SendP25TSBK(callData, tsbk);
}
}
/// <summary>
///
/// </summary>
@ -504,6 +651,7 @@ namespace dvmconsole
{
QuickCallPage pageWindow = new QuickCallPage();
pageWindow.Owner = this;
if (pageWindow.ShowDialog() == true)
{
foreach (ChannelBox channel in selectedChannelsManager.GetSelectedChannels())
@ -1541,6 +1689,7 @@ namespace dvmconsole
private void KeyStatus_Click(object sender, RoutedEventArgs e)
{
KeyStatusWindow keyStatus = new KeyStatusWindow(Codeplug, this);
keyStatus.Owner = this;
keyStatus.Show();
}
@ -1799,6 +1948,7 @@ namespace dvmconsole
/// <param name="e"></param>
private void CallHist_Click(object sender, RoutedEventArgs e)
{
callHistoryWindow.Owner = this;
callHistoryWindow.Show();
}

@ -8,6 +8,7 @@
* @license AGPLv3 License (https://opensource.org/licenses/AGPL-3.0)
*
* Copyright (C) 2024-2025 Caleb, K4PHP
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
*
*/
@ -23,7 +24,13 @@ namespace dvmconsole
/// </summary>
public class SettingsManager
{
private const string SettingsFilePath = "UserSettings.json";
public static readonly string UserAppData = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
public static readonly string RootAppDataPath = "DVMProject" + Path.DirectorySeparatorChar + "dvmconsole";
public static readonly string UserAppDataPath = UserAppData + Path.DirectorySeparatorChar + RootAppDataPath;
private static readonly string SettingsFilePath = UserAppDataPath + Path.DirectorySeparatorChar + "UserSettings.json";
/*
** Properties
@ -75,9 +82,13 @@ namespace dvmconsole
/// <summary>
///
/// </summary>
public void LoadSettings()
public bool LoadSettings()
{
if (!File.Exists(SettingsFilePath)) return;
if (!Directory.Exists(UserAppDataPath))
Directory.CreateDirectory(UserAppDataPath);
if (!File.Exists(SettingsFilePath))
return false;
try
{
@ -95,14 +106,47 @@ namespace dvmconsole
AlertToneFilePaths = loadedSettings.AlertToneFilePaths ?? new List<string>();
AlertTonePositions = loadedSettings.AlertTonePositions ?? new Dictionary<string, ChannelPosition>();
ChannelOutputDevices = loadedSettings.ChannelOutputDevices ?? new Dictionary<string, int>();
return true;
}
return false;
}
catch (Exception ex)
{
Trace.WriteLine($"Error loading settings: {ex.Message}");
return false;
}
}
/// <summary>
///
/// </summary>
public void SaveSettings()
{
if (!Directory.Exists(UserAppDataPath))
Directory.CreateDirectory(UserAppDataPath);
try
{
var json = JsonConvert.SerializeObject(this, Formatting.Indented);
File.WriteAllText(SettingsFilePath, json);
}
catch (Exception ex)
{
Trace.WriteLine($"Error saving settings: {ex.Message}");
}
}
/// <summary>
///
/// </summary>
public void Reset()
{
if (File.Exists(SettingsFilePath))
File.Delete(SettingsFilePath);
}
/// <summary>
///
/// </summary>
@ -162,21 +206,5 @@ namespace dvmconsole
ChannelOutputDevices[channelName] = deviceIndex;
SaveSettings();
}
/// <summary>
///
/// </summary>
public void SaveSettings()
{
try
{
var json = JsonConvert.SerializeObject(this, Formatting.Indented);
File.WriteAllText(SettingsFilePath, json);
}
catch (Exception ex)
{
Trace.WriteLine($"Error saving settings: {ex.Message}");
}
}
} // public class SettingsManager
} // namespace dvmconsole

Loading…
Cancel
Save

Powered by TurnKey Linux.