├── btc qr.png
├── quansheng.ico
├── WiringMod2.png
├── WiringOverview2.png
├── WiringSchematic.png
├── QuanshengDock
├── smeter.png
├── quansheng.ico
├── UI
│ ├── ButtonBorder.cs
│ ├── VFOPreset.xaml
│ ├── DcsMenu.cs
│ ├── CtcssMenu.cs
│ ├── Indicator.cs
│ ├── SMeter.cs
│ ├── TextPrompt.xaml.cs
│ ├── TextPrompt.xaml
│ ├── Preset.cs
│ ├── LCD.cs
│ ├── RotaryEncoder.cs
│ ├── MenuActions.cs
│ └── Potentiometer.cs
├── App.xaml
├── AssemblyInfo.cs
├── General
│ ├── SavedList.cs
│ ├── SavedDictionary.cs
│ ├── Radio.cs
│ └── ColorBrush.cs
├── QuanshengDock.csproj
├── User
│ └── UserFolder.cs
├── App.xaml.cs
├── Serial
│ └── Packet.cs
├── ClassExtensions.cs
├── RepeaterBook
│ ├── BookContext.cs
│ ├── RepeaterBookBrowser.xaml.cs
│ ├── Repeater.cs
│ └── RepeaterBookBrowser.xaml
├── Audio
│ ├── AudioDevices.cs
│ ├── VOX.cs
│ ├── QDNH.cs
│ └── Sound.cs
├── ExtendedVFO
│ ├── GPIO.cs
│ ├── Messenger.xaml
│ ├── FixAM.cs
│ ├── Defines.cs
│ ├── Scanner.xaml.cs
│ ├── Messenger.xaml.cs
│ └── ScanList.cs
├── Channels
│ ├── CopiedChannel.cs
│ ├── Conversions.cs
│ ├── ChannelEditor.xaml.cs
│ └── ChannelEditor.xaml
├── Settings
│ └── SettingsWindow.xaml.cs
└── View
│ └── ViewModel.cs
├── QuanshengDock.sln
├── .gitattributes
├── README.md
└── .gitignore
/btc qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicsure/QuanshengDock/HEAD/btc qr.png
--------------------------------------------------------------------------------
/quansheng.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicsure/QuanshengDock/HEAD/quansheng.ico
--------------------------------------------------------------------------------
/WiringMod2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicsure/QuanshengDock/HEAD/WiringMod2.png
--------------------------------------------------------------------------------
/WiringOverview2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicsure/QuanshengDock/HEAD/WiringOverview2.png
--------------------------------------------------------------------------------
/WiringSchematic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicsure/QuanshengDock/HEAD/WiringSchematic.png
--------------------------------------------------------------------------------
/QuanshengDock/smeter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicsure/QuanshengDock/HEAD/QuanshengDock/smeter.png
--------------------------------------------------------------------------------
/QuanshengDock/quansheng.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicsure/QuanshengDock/HEAD/QuanshengDock/quansheng.ico
--------------------------------------------------------------------------------
/QuanshengDock/UI/ButtonBorder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows.Controls;
7 |
8 | namespace QuanshengDock.UI
9 | {
10 | // code by -nicsure- 2024
11 | // https://www.youtube.com/nicsure
12 |
13 | public class ButtonBorder : Border
14 | {
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/QuanshengDock/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/QuanshengDock/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/QuanshengDock/General/SavedList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Text.RegularExpressions;
7 | using System.Threading.Tasks;
8 |
9 | namespace QuanshengDock.General
10 | {
11 | public class SavedList : List
12 | {
13 | public string BackingFile { get; set; }
14 |
15 | public SavedList(string backingFile)
16 | {
17 | BackingFile = backingFile;
18 | try
19 | {
20 | string[] lines = File.ReadAllLines(backingFile);
21 | foreach(string line in lines)
22 | Add(Regex.Unescape(line));
23 | }
24 | catch { }
25 | }
26 |
27 | public void Save()
28 | {
29 | try
30 | {
31 | File.WriteAllLines(BackingFile, this.Select(l => $"{Regex.Escape(l)}").ToArray());
32 | }
33 | catch { }
34 | }
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/QuanshengDock/QuanshengDock.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net6.0-windows
6 | enable
7 | true
8 | True
9 | quansheng.ico
10 | true
11 | AnyCPU;x64
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/QuanshengDock/User/UserFolder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace QuanshengDock.User
9 | {
10 | // code by -nicsure- 2024
11 | // https://www.youtube.com/nicsure
12 |
13 | public static class UserFolder
14 | {
15 | private const string scanLogDir = "scanlogs";
16 |
17 | static UserFolder()
18 | {
19 | string logdir = Path.Combine(Instance.Name, scanLogDir);
20 | if (!Directory.Exists(Instance.Name))
21 | Directory.CreateDirectory(Instance.Name);
22 | if (!Directory.Exists(logdir))
23 | Directory.CreateDirectory(logdir);
24 | }
25 |
26 | public static string File(string file)
27 | {
28 | return Path.Combine(Instance.Name, file);
29 | }
30 |
31 | public static string LogFile(string file)
32 | {
33 | return Path.Combine(Instance.Name, scanLogDir, file);
34 | }
35 |
36 | public static string Dir => Instance.Name;
37 | }
38 |
39 | public static class Instance
40 | {
41 | private static string name = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "QuanshengDock");
42 | public static string Name
43 | {
44 | get => name;
45 | set => name = value;
46 | }
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/QuanshengDock/General/SavedDictionary.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Text.RegularExpressions;
7 | using System.Threading.Tasks;
8 | using System.Windows.Input;
9 |
10 | namespace QuanshengDock.General
11 | {
12 | // code by -nicsure- 2024
13 | // https://www.youtube.com/nicsure
14 |
15 | public class SavedDictionary : Dictionary
16 | {
17 | public string BackingFile { get; set; }
18 | public SavedDictionary(string backingFile)
19 | {
20 | BackingFile = backingFile;
21 | try
22 | {
23 | string[] lines = File.ReadAllLines(backingFile);
24 | for (int i = 0; i < (lines.Length & 0x7ffffffe); i += 2)
25 | {
26 | string key = Regex.Unescape(lines[i]);
27 | string value = Regex.Unescape(lines[i + 1]);
28 | this[key] = value;
29 | }
30 | }
31 | catch { }
32 | }
33 |
34 | public void Save()
35 | {
36 | try
37 | {
38 | File.WriteAllLines(BackingFile, this.Select(kp => $"{Regex.Escape(kp.Key)}\r\n{Regex.Escape(kp.Value)}").ToArray());
39 | }
40 | catch { }
41 | }
42 |
43 | public string GetValue(string key, string? def = null) => ContainsKey(key) ? this[key] : (def ?? string.Empty);
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/QuanshengDock/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using QuanshengDock.User;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Configuration;
5 | using System.Data;
6 | using System.Globalization;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Windows;
10 |
11 | namespace QuanshengDock
12 | {
13 | ///
14 | /// Interaction logic for App.xaml
15 | ///
16 | public partial class App : Application
17 | {
18 | protected override void OnStartup(StartupEventArgs e)
19 | {
20 | if (e.Args.Length > 0)
21 | Instance.Name = e.Args[0];
22 | CultureInfo customCulture = new("en-US");
23 | CultureInfo.DefaultThreadCurrentCulture = customCulture;
24 | CultureInfo.DefaultThreadCurrentUICulture = customCulture;
25 | System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;
26 | base.OnStartup(e);
27 | AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
28 | }
29 |
30 | private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
31 | {
32 | Exception exception = e.ExceptionObject as Exception ?? new("Unknown Exception Event");
33 | if (exception != null)
34 | {
35 | MessageBox.Show($"An unhandled exception {exception} occurred:\n\n{exception.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/QuanshengDock/Serial/Packet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace QuanshengDock.Serial
8 | {
9 | // code by -nicsure- 2024
10 | // https://www.youtube.com/nicsure
11 |
12 | public static class Packet
13 | {
14 | public const ushort Hello = 0x514;
15 | public const ushort GetRssi = 0x527;
16 | public const ushort KeyPress = 0x801;
17 | public const ushort GetScreen = 0x803;
18 | public const ushort Scan = 0x808;
19 | public const ushort ScanAdjust = 0x809;
20 | public const ushort ScanReply = 0x908;
21 | public const ushort WriteRegisters = 0x850;
22 | public const ushort ReadRegisters = 0x851;
23 | public const ushort RegisterInfo = 0x951;
24 | public const ushort WriteGPIO = 0x860;
25 | public const ushort ReadGPIO = 0x861;
26 | public const ushort GPIOInfo = 0x961;
27 | public const ushort GPIOPulse = 0x862;
28 | public const ushort EnterHardwareMode = 0x0870;
29 | public const ushort ExitHardwareMode = 0x0871;
30 | public const ushort SetReportReg = 0x0872;
31 | public const ushort ImHere = 0x515;
32 | public const ushort RssiInfo = 0x528;
33 | public const ushort WriteEeprom = 0x51D;
34 | public const ushort WriteEepromReply = 0x51E;
35 | public const ushort ReadEeprom = 0x51B;
36 | public const ushort ReadEepromReply = 0x51C;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/QuanshengDock.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.5.33627.172
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuanshengDock", "QuanshengDock\QuanshengDock.csproj", "{EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Release|Any CPU = Release|Any CPU
13 | Release|x64 = Release|x64
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}.Debug|x64.ActiveCfg = Debug|x64
19 | {EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}.Debug|x64.Build.0 = Debug|x64
20 | {EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}.Release|x64.ActiveCfg = Release|x64
23 | {EAEC23C4-D9E8-4FBD-8330-2F6A2130A4D0}.Release|x64.Build.0 = Release|x64
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {230BE291-8530-4324-96E7-00F2B8E64BE9}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/QuanshengDock/ClassExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace QuanshengDock
8 | {
9 | public static class ClassExtensions
10 | {
11 | public static byte Byte(this ushort s, int byteIndex) => (byte)((s >> (byteIndex * 8)) & 0xff);
12 | public static byte Byte(this short s, int byteIndex) => (byte)((s >> (byteIndex * 8)) & 0xff);
13 | public static byte Byte(this int s, int byteIndex) => (byte)((s >> (byteIndex * 8)) & 0xff);
14 | public static byte Byte(this uint s, int byteIndex) => (byte)((s >> (byteIndex * 8)) & 0xff);
15 | public static double ToDouble(this string s) => double.TryParse(s, out double d) ? d : 0;
16 | public static float Clamp(this float value, float min, float max) => Math.Max(min, Math.Min(value, max));
17 | public static double Clamp(this double value, double min, double max) => Math.Max(min, Math.Min(value, max));
18 | public static int Clamp(this int value, int min, int max) => value < min ? min : value > max ? max : value;
19 |
20 |
21 | public static bool DoubleParse(this string s, out double d)
22 | {
23 | if(!double.TryParse(s, out d))
24 | {
25 | if(!double.TryParse(s.Replace(",", "."), out d))
26 | {
27 | if (!double.TryParse(s.Replace(".", ","), out d))
28 | {
29 | return false;
30 | }
31 | }
32 | }
33 | return true;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/QuanshengDock/RepeaterBook/BookContext.cs:
--------------------------------------------------------------------------------
1 | using QuanshengDock.View;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace QuanshengDock.RepeaterBook
10 | {
11 | public class BookContext
12 | {
13 | public static BookContext Instance { get; } = new();
14 |
15 | public ViewModel