mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
Compare commits
566 Commits
v0.3.1
...
v0.5.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48a93990e8 | ||
|
|
414ba25d61 | ||
|
|
f67f90e8b0 | ||
|
|
5751c70212 | ||
|
|
4e15c426a8 | ||
|
|
ceda189260 | ||
|
|
fce0ae33e7 | ||
|
|
fc5c6ef841 | ||
|
|
d0033578d5 | ||
|
|
670ec3a097 | ||
|
|
8bfb1d5470 | ||
|
|
46a916a945 | ||
|
|
459e77390a | ||
|
|
f4ab46b79d | ||
|
|
3c58e98788 | ||
|
|
36de81248c | ||
|
|
925353d515 | ||
|
|
7c32897321 | ||
|
|
cbeda19d27 | ||
|
|
8148ca48af | ||
|
|
adcb55ffbc | ||
|
|
1152b13220 | ||
|
|
166383e1ed | ||
|
|
0d5d1b20e3 | ||
|
|
77ea43f61a | ||
|
|
f988344222 | ||
|
|
60489e1fef | ||
|
|
ac8aa17a80 | ||
|
|
25a42126df | ||
|
|
1b90e0b50c | ||
|
|
7f5ad7eb20 | ||
|
|
0e6713b6e2 | ||
|
|
96d3996bec | ||
|
|
0fb148d31e | ||
|
|
cebca28b19 | ||
|
|
af8cc0255e | ||
|
|
775ae00861 | ||
|
|
1b80f5f1b3 | ||
|
|
f9a7bbeddf | ||
|
|
58a0264565 | ||
|
|
6d2af95e9a | ||
|
|
bf46b19dc9 | ||
|
|
7749fd10f1 | ||
|
|
90bc321aca | ||
|
|
bad4fae1b8 | ||
|
|
c3fc435fdc | ||
|
|
2ab0c78728 | ||
|
|
187989f6b8 | ||
|
|
3b83412bcb | ||
|
|
968ea458da | ||
|
|
a9f4fbbdd4 | ||
|
|
6b3b45e9af | ||
|
|
2355dfce07 | ||
|
|
0e8c9591e4 | ||
|
|
54e4771f36 | ||
|
|
b2eb245feb | ||
|
|
e826314d06 | ||
|
|
0eec2e7ab8 | ||
|
|
5e9c239ea3 | ||
|
|
1fd9b0fbcb | ||
|
|
8413343e76 | ||
|
|
2a0427c559 | ||
|
|
5d9d232585 | ||
|
|
f0f0329f9b | ||
|
|
2a45849e6d | ||
|
|
aa89079e28 | ||
|
|
31b9ee5910 | ||
|
|
6a54fe101c | ||
|
|
87b3d34024 | ||
|
|
b8bbe9264a | ||
|
|
0c7dd192b0 | ||
|
|
8b487d79e4 | ||
|
|
cb83a8e870 | ||
|
|
0bc11a07cf | ||
|
|
560cbad5d7 | ||
|
|
87e9bf8749 | ||
|
|
770f58c668 | ||
|
|
4b806ecfde | ||
|
|
7303e06943 | ||
|
|
846b249fb3 | ||
|
|
67f23494e2 | ||
|
|
d7efb627d7 | ||
|
|
08bc0b9963 | ||
|
|
d1ed46860c | ||
|
|
38f694d262 | ||
|
|
75ef3217ac | ||
|
|
2847dff64a | ||
|
|
f0d9ef99ea | ||
|
|
67702096d7 | ||
|
|
88f124af9d | ||
|
|
d34460c4e3 | ||
|
|
f4f3db7436 | ||
|
|
3ebfa90ca1 | ||
|
|
733fdd0d7a | ||
|
|
09893605eb | ||
|
|
57468ef932 | ||
|
|
c6afb1c133 | ||
|
|
05c0b51fde | ||
|
|
de8cfa24f9 | ||
|
|
fe714c69a7 | ||
|
|
ac219cf2ba | ||
|
|
77b1102100 | ||
|
|
5117e6cbe8 | ||
|
|
61c4e13c3e | ||
|
|
f1190b7be3 | ||
|
|
49e7087b9b | ||
|
|
c397b5a601 | ||
|
|
c809dcc609 | ||
|
|
7eec82deee | ||
|
|
b061db1189 | ||
|
|
8715dd2d6b | ||
|
|
63b0aaaa7f | ||
|
|
d20dd1af8c | ||
|
|
e1f32d3d0b | ||
|
|
eaa3433034 | ||
|
|
838016c89f | ||
|
|
030a88f5a3 | ||
|
|
de3ba5529a | ||
|
|
7962758e05 | ||
|
|
0f9d1c0792 | ||
|
|
48be38a2d8 | ||
|
|
207893e5a8 | ||
|
|
e07d6fa854 | ||
|
|
e26698d0d8 | ||
|
|
a8837c8e2a | ||
|
|
7395f02fb8 | ||
|
|
706ada2940 | ||
|
|
d957846ab0 | ||
|
|
bbe90ca74b | ||
|
|
96611fa2c2 | ||
|
|
c94edf05ef | ||
|
|
74adb6f30c | ||
|
|
421abe5768 | ||
|
|
1d003c561e | ||
|
|
b22177ee17 | ||
|
|
a1e8c761ef | ||
|
|
ad194d1bab | ||
|
|
2bb5082943 | ||
|
|
2c3648f8c2 | ||
|
|
3d816c3570 | ||
|
|
e1194d26bd | ||
|
|
8167e9e9f2 | ||
|
|
3b357c4d40 | ||
|
|
89cb54676d | ||
|
|
73c251ff4d | ||
|
|
0d51b39604 | ||
|
|
af0dbf1566 | ||
|
|
01146a5624 | ||
|
|
316cdb4068 | ||
|
|
91cae70fa1 | ||
|
|
2723926f83 | ||
|
|
2aff9ee817 | ||
|
|
c87e6553dc | ||
|
|
5d580544e7 | ||
|
|
08ea0e0f18 | ||
|
|
c8b441dbd4 | ||
|
|
1aa22789e5 | ||
|
|
cff5494db4 | ||
|
|
9bd6507342 | ||
|
|
379461e649 | ||
|
|
cc52ae5bd7 | ||
|
|
39f6d6c831 | ||
|
|
649258bd2b | ||
|
|
de9431f649 | ||
|
|
18f9e38090 | ||
|
|
2e37f1e687 | ||
|
|
5e8f2d0523 | ||
|
|
9fb6c33319 | ||
|
|
fdecac4230 | ||
|
|
85c27a6cca | ||
|
|
57f56d31a2 | ||
|
|
df25675d3f | ||
|
|
277a84702a | ||
|
|
c651296378 | ||
|
|
866d25e86a | ||
|
|
5e62f1b889 | ||
|
|
e9d524ad14 | ||
|
|
158c8b4b8a | ||
|
|
41df207bb9 | ||
|
|
692ffabe82 | ||
|
|
944ad5a571 | ||
|
|
5ca70d3940 | ||
|
|
904752e3dd | ||
|
|
cf61798466 | ||
|
|
fd72f459f9 | ||
|
|
1bc462b300 | ||
|
|
1c6f91f101 | ||
|
|
a7c28f066a | ||
|
|
604c8ab6e5 | ||
|
|
23a3ee39cc | ||
|
|
fa16db129b | ||
|
|
de249c448b | ||
|
|
e1bc56c500 | ||
|
|
d1d115d11f | ||
|
|
aca41b4f6e | ||
|
|
1e3ae996ac | ||
|
|
b3b2e74688 | ||
|
|
44237bec5c | ||
|
|
53b44f44e3 | ||
|
|
9af7a184ad | ||
|
|
9c8d87ec64 | ||
|
|
4c34968d28 | ||
|
|
2d71f5173a | ||
|
|
2e942113c6 | ||
|
|
e20540ccc6 | ||
|
|
8d7e0e9f46 | ||
|
|
cc5d94f58d | ||
|
|
26197e433c | ||
|
|
f54b4dfd0e | ||
|
|
085ba52294 | ||
|
|
b8c24680a5 | ||
|
|
c658582157 | ||
|
|
83e518d503 | ||
|
|
2163d0f822 | ||
|
|
34c920eede | ||
|
|
35b0b5ef9b | ||
|
|
08672c33bd | ||
|
|
e2651d6c7c | ||
|
|
851a4e12d2 | ||
|
|
b7c66ec844 | ||
|
|
7522a3a820 | ||
|
|
6a0402d1cf | ||
|
|
5309af84f7 | ||
|
|
8d8d77fa11 | ||
|
|
284cf07e97 | ||
|
|
16414c7585 | ||
|
|
70c9eed0bf | ||
|
|
f49b1fef17 | ||
|
|
3fe070987a | ||
|
|
00d5610213 | ||
|
|
d3c1a605df | ||
|
|
85df151a96 | ||
|
|
8915797aac | ||
|
|
03a5d71a95 | ||
|
|
4158d4ac10 | ||
|
|
f934676bd0 | ||
|
|
d5b802e794 | ||
|
|
139227e46d | ||
|
|
2394d51a51 | ||
|
|
d9fa2bea5b | ||
|
|
0cb360eeed | ||
|
|
ea472f873f | ||
|
|
8cbdbd527e | ||
|
|
ff0d893bd9 | ||
|
|
7b924d0486 | ||
|
|
712eb07f4b | ||
|
|
d5c3ecc7df | ||
|
|
c4bf089667 | ||
|
|
378b03e06e | ||
|
|
34235382fb | ||
|
|
c05aff0768 | ||
|
|
f0c3e0fd1a | ||
|
|
d601cbda0e | ||
|
|
2653dc6b38 | ||
|
|
48cbbfc656 | ||
|
|
d6892b9203 | ||
|
|
59f0844fcc | ||
|
|
43b285a50a | ||
|
|
4e92a6e350 | ||
|
|
25d387f3cf | ||
|
|
52e3d9d20d | ||
|
|
1e37a63d34 | ||
|
|
e51f485a2e | ||
|
|
9378254a38 | ||
|
|
4ab37735e8 | ||
|
|
85ca66f656 | ||
|
|
d716b0be1c | ||
|
|
70444c1337 | ||
|
|
d90e149021 | ||
|
|
7510664e00 | ||
|
|
5481fb7d4d | ||
|
|
3a39ae76ba | ||
|
|
08ea5ab7cb | ||
|
|
3fa7401a2b | ||
|
|
fce10960fb | ||
|
|
10b6a08624 | ||
|
|
5960343637 | ||
|
|
347a71f097 | ||
|
|
5b5a1431b4 | ||
|
|
efd811407e | ||
|
|
b67d4d92dc | ||
|
|
735fca16d6 | ||
|
|
72fe72c833 | ||
|
|
4a4d1d4b2e | ||
|
|
2ed7074c0d | ||
|
|
b5a895c266 | ||
|
|
b57d7b5c0e | ||
|
|
cb12d314d0 | ||
|
|
eb79d9e037 | ||
|
|
d95c78c0f1 | ||
|
|
aee5ece8d2 | ||
|
|
ba358a7d48 | ||
|
|
09b209496b | ||
|
|
cc209683bd | ||
|
|
2771c28dba | ||
|
|
d752917073 | ||
|
|
28bc02e172 | ||
|
|
0f6044d48b | ||
|
|
58ecb83e2c | ||
|
|
9e1de922e4 | ||
|
|
84d0b827d8 | ||
|
|
a17132be0d | ||
|
|
dae68515a5 | ||
|
|
0aaec8ff54 | ||
|
|
001883edc2 | ||
|
|
335fb51456 | ||
|
|
e94b6ae172 | ||
|
|
785125da4f | ||
|
|
81b8f5a423 | ||
|
|
bf186a7408 | ||
|
|
43fc326f93 | ||
|
|
7cdbb75b42 | ||
|
|
96a56cab68 | ||
|
|
29d4b36cf7 | ||
|
|
b15a3e59a0 | ||
|
|
9950e46e5a | ||
|
|
570321da3e | ||
|
|
bb0bcd3198 | ||
|
|
cb54850f99 | ||
|
|
5bb8c46bd5 | ||
|
|
2a3fd2c5a3 | ||
|
|
d712feb45a | ||
|
|
fbb24a4c05 | ||
|
|
3992f8178c | ||
|
|
8642def77e | ||
|
|
38e6de6cb2 | ||
|
|
994e78f42b | ||
|
|
b8a46af836 | ||
|
|
1c6d19959a | ||
|
|
50bc3088b7 | ||
|
|
09356848eb | ||
|
|
316bfb19c2 | ||
|
|
c045c8f16d | ||
|
|
8946d789ff | ||
|
|
19399d9138 | ||
|
|
9acdf22b91 | ||
|
|
f963d821a1 | ||
|
|
ade0cef50b | ||
|
|
2044c2a2de | ||
|
|
1c312a50b6 | ||
|
|
54f6bd09e2 | ||
|
|
5f8f2ec330 | ||
|
|
d7e018f66e | ||
|
|
c2a232fdee | ||
|
|
c5d2dcd0cf | ||
|
|
8e4e4129ca | ||
|
|
9176ca610f | ||
|
|
97b31e4d9b | ||
|
|
a3e5520d3e | ||
|
|
8c456972cc | ||
|
|
35d81ab31d | ||
|
|
b90b06e600 | ||
|
|
04144ca677 | ||
|
|
d3c7a50918 | ||
|
|
0fd29fa35a | ||
|
|
c00b173064 | ||
|
|
2718367259 | ||
|
|
3f0c13096a | ||
|
|
71ba4adbd7 | ||
|
|
3908e29a2e | ||
|
|
0c47efea03 | ||
|
|
5c0d97d942 | ||
|
|
61ae0d2d83 | ||
|
|
68f2a8da2c | ||
|
|
0d69f11e65 | ||
|
|
b3d5daea8b | ||
|
|
fe34623c4a | ||
|
|
353747cecc | ||
|
|
a8c649ef64 | ||
|
|
8cf50e629e | ||
|
|
20a8f2bb3c | ||
|
|
8c237be682 | ||
|
|
2d5271b849 | ||
|
|
609a1e86c7 | ||
|
|
821e719015 | ||
|
|
104c4f72be | ||
|
|
9e7fa7618d | ||
|
|
ee09520181 | ||
|
|
fa12b840db | ||
|
|
183d7d6d19 | ||
|
|
e2550869ce | ||
|
|
e88944e53d | ||
|
|
0051a1d381 | ||
|
|
f7a873dd0c | ||
|
|
ad560db5ea | ||
|
|
6f1ce79461 | ||
|
|
df1bc1031e | ||
|
|
a621a31aa9 | ||
|
|
19fa256c60 | ||
|
|
7a830077bd | ||
|
|
f4793f3cfd | ||
|
|
2cd3b73633 | ||
|
|
18f50485d3 | ||
|
|
b410cf0dfe | ||
|
|
1fdcb623a6 | ||
|
|
9dda1f95a1 | ||
|
|
a5c8552937 | ||
|
|
e4209c8e4f | ||
|
|
a898be265f | ||
|
|
c13315f731 | ||
|
|
341e740e77 | ||
|
|
cbc228d798 | ||
|
|
488b2e02ce | ||
|
|
e395d737f8 | ||
|
|
7a9f705517 | ||
|
|
dfaf506e23 | ||
|
|
81c9a352a8 | ||
|
|
e6937764c3 | ||
|
|
5bfc5bf456 | ||
|
|
ce83273393 | ||
|
|
95aa9f8803 | ||
|
|
e971ad4582 | ||
|
|
ff9395e4b9 | ||
|
|
d023da9ead | ||
|
|
60ffb18cd9 | ||
|
|
c36f6901af | ||
|
|
bfaacb309d | ||
|
|
c3b405a752 | ||
|
|
3619b480f8 | ||
|
|
830b2a2d34 | ||
|
|
78bb5ffe43 | ||
|
|
5dd1664844 | ||
|
|
8868c1f954 | ||
|
|
646bd78037 | ||
|
|
5af4cb8706 | ||
|
|
45a6c5a0b6 | ||
|
|
b563f2d11b | ||
|
|
148ddd0bd5 | ||
|
|
a0630102e6 | ||
|
|
3d1ac30646 | ||
|
|
dda37a1198 | ||
|
|
eaf7c7d11e | ||
|
|
80c5ad1bc8 | ||
|
|
956bf2d76a | ||
|
|
1406d5576a | ||
|
|
03e39f3343 | ||
|
|
28f351287c | ||
|
|
54227703a2 | ||
|
|
bb078de0a9 | ||
|
|
ec30cd6305 | ||
|
|
5a88ac0200 | ||
|
|
05eea44f7e | ||
|
|
030fc1617c | ||
|
|
594a77a9d0 | ||
|
|
c2fcc9e85d | ||
|
|
28da8b2fa4 | ||
|
|
1c06c4382f | ||
|
|
28cb9d9407 | ||
|
|
96d9d6f750 | ||
|
|
85691edacb | ||
|
|
f2f2c92afe | ||
|
|
fcd3c2fd46 | ||
|
|
e78d2339ff | ||
|
|
673c8a2423 | ||
|
|
5a03a0038c | ||
|
|
e7f7d27a1f | ||
|
|
0cf964fa98 | ||
|
|
b6f282a85a | ||
|
|
32ab0598e8 | ||
|
|
5ae3cb38e1 | ||
|
|
78205bb1bf | ||
|
|
3d9b38bef5 | ||
|
|
d5b377b1af | ||
|
|
a7a0c26b38 | ||
|
|
d4761be00a | ||
|
|
05fa5c25fd | ||
|
|
69e9bed2af | ||
|
|
d2e7f008c8 | ||
|
|
ddad4b6fb0 | ||
|
|
b65dd7e414 | ||
|
|
b076587f30 | ||
|
|
336669f1d5 | ||
|
|
46cf7f4193 | ||
|
|
e9aeb09011 | ||
|
|
236df8f3f4 | ||
|
|
667c50174d | ||
|
|
c7f00ea124 | ||
|
|
1759f4a804 | ||
|
|
3d9044802e | ||
|
|
42aec490bd | ||
|
|
c3f5c1c70e | ||
|
|
188a521770 | ||
|
|
6e352143d2 | ||
|
|
7391265949 | ||
|
|
26b97f09b7 | ||
|
|
1d2d9e8630 | ||
|
|
ee6aeafa84 | ||
|
|
47cc194415 | ||
|
|
9316599dec | ||
|
|
a1535c4157 | ||
|
|
b478068475 | ||
|
|
7286c978da | ||
|
|
628d514462 | ||
|
|
3478702845 | ||
|
|
695d622603 | ||
|
|
e8e47bfb40 | ||
|
|
c1a4425969 | ||
|
|
4fa1a1aa81 | ||
|
|
4e1f9bcf97 | ||
|
|
50bb96b14a | ||
|
|
51ea70f279 | ||
|
|
e15f271a54 | ||
|
|
605475c98b | ||
|
|
86248c511a | ||
|
|
b1e07f762c | ||
|
|
f2d1ac7e48 | ||
|
|
d114282e4b | ||
|
|
0fd20655fa | ||
|
|
181527f54c | ||
|
|
910587bad7 | ||
|
|
1dc9a7fb0e | ||
|
|
eef29d28da | ||
|
|
1c71a37755 | ||
|
|
318e6f3586 | ||
|
|
f38184fd83 | ||
|
|
d2085052f6 | ||
|
|
441b595325 | ||
|
|
57fab2b7ca | ||
|
|
bf65e10286 | ||
|
|
a3ecb339be | ||
|
|
910a08f7bb | ||
|
|
5a76f31dea | ||
|
|
1b42e64f50 | ||
|
|
1ddc0a33a5 | ||
|
|
a12aaf7cf3 | ||
|
|
b3e4bd6a9c | ||
|
|
5281679b7f | ||
|
|
a581da56a8 | ||
|
|
88580af436 | ||
|
|
64688a3c20 | ||
|
|
8be3399a6b | ||
|
|
0181926fe3 | ||
|
|
2c3be02939 | ||
|
|
a00ec42230 | ||
|
|
14a3532030 | ||
|
|
28340809ca | ||
|
|
f3d3a8187a | ||
|
|
8484e837b8 | ||
|
|
01b188ea25 | ||
|
|
3be65d5e9a | ||
|
|
c21f3fca23 | ||
|
|
99d81d247a | ||
|
|
27461df7f0 | ||
|
|
9983d2119d | ||
|
|
9e275b7d62 | ||
|
|
f461ed9cdb | ||
|
|
7c6b7494b8 | ||
|
|
ab31b40124 | ||
|
|
ac686f5f64 | ||
|
|
f7cd798f07 | ||
|
|
41d307cdad | ||
|
|
afae1654d5 | ||
|
|
ffc92a8f0e | ||
|
|
6d9e129087 | ||
|
|
0e1da8fb3b | ||
|
|
7d5371db4c | ||
|
|
131290fcd2 | ||
|
|
e2fe06638b | ||
|
|
17c16e16ee | ||
|
|
cd4eaedfcc | ||
|
|
fd748fec79 | ||
|
|
14b844f0bd | ||
|
|
99ef002d07 | ||
|
|
e868428c88 | ||
|
|
d2542d2560 | ||
|
|
9ca87299d5 |
34
.classpath
34
.classpath
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="lib" path="imports/commons-lang3-3.2.1.jar"/>
|
||||
<classpathentry kind="lib" path="imports/jide-oss-3.5.15.jar"/>
|
||||
<classpathentry kind="lib" path="imports/jsr80-1.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-linux-arm.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-linux-x86_64.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-linux-x86.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-osx-x86_64.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-osx-x86.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-windows-x86_64.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-windows-x86.jar"/>
|
||||
<classpathentry kind="lib" path="imports/miglayout-4.0-swing.jar"/>
|
||||
<classpathentry kind="lib" path="imports/usb-api-1.0.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/usb4java-1.2.0.jar"/>
|
||||
<classpathentry kind="lib" path="imports/usb4java-javax-1.2.0.jar"/>
|
||||
<classpathentry kind="lib" path="config"/>
|
||||
<classpathentry kind="lib" path="imports/JTransforms-3.0.jar" sourcepath="/home/denny/.m2/repository/com/github/wendykierp/JTransforms/3.0/JTransforms-3.0-sources.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-linux-ppc.jar"/>
|
||||
<classpathentry kind="lib" path="imports/JLargeArrays-1.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/slf4j-api-1.7.7.jar"/>
|
||||
<classpathentry kind="lib" path="imports/logback-classic-1.1.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/logback-core-1.1.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/commons-io-2.4.jar"/>
|
||||
<classpathentry kind="lib" path="imports/jmbe-interface-0.3.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/tablefilter-swing-5.2.1.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/home/denny/Downloads/tablefilter-swing-5.2.1-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -1,4 +0,0 @@
|
||||
[Dolphin]
|
||||
Timestamp=2015,9,8,20,39,49
|
||||
Version=3
|
||||
ViewMode=1
|
||||
34
.github/workflows/gradle.yml
vendored
Normal file
34
.github/workflows/gradle.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Java CI with Gradle
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'liberica'
|
||||
java-package: 'jdk+fx'
|
||||
- name: Build with Gradle
|
||||
uses: gradle/gradle-build-action@937999e9cc2425eddc7fd62d1053baf041147db7
|
||||
with:
|
||||
arguments: clean build
|
||||
35
.gitignore
vendored
35
.gitignore
vendored
@@ -1,6 +1,35 @@
|
||||
*.class
|
||||
### JetBrains template
|
||||
.idea/
|
||||
/classes*
|
||||
/product*
|
||||
/bin*
|
||||
out/
|
||||
.directory
|
||||
.settings
|
||||
.settings
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
*.iml
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
### Java template
|
||||
*.class
|
||||
*.log
|
||||
# Package Files #
|
||||
#*.jar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
### Gradle template
|
||||
.gradle
|
||||
/build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
9
.idea/codeStyleSettings.xml
generated
9
.idea/codeStyleSettings.xml
generated
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value />
|
||||
</option>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
|
||||
</component>
|
||||
</project>
|
||||
22
.idea/compiler.xml
generated
22
.idea/compiler.xml
generated
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/copyright/profiles_settings.xml
generated
9
.idea/copyright/profiles_settings.xml
generated
@@ -1,9 +0,0 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="sdrtrunk">
|
||||
<LanguageOptions name="__TEMPLATE__">
|
||||
<option name="addBlankAfter" value="false" />
|
||||
<option name="separateBefore" value="true" />
|
||||
<option name="separateAfter" value="true" />
|
||||
</LanguageOptions>
|
||||
</settings>
|
||||
</component>
|
||||
6
.idea/copyright/sdrtrunk.xml
generated
6
.idea/copyright/sdrtrunk.xml
generated
@@ -1,6 +0,0 @@
|
||||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="myName" value="sdrtrunk" />
|
||||
<option name="notice" value="sdrtrunk Copyright (C) 2014-&#36;today.year Dennis Sheirer This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/> " />
|
||||
</copyright>
|
||||
</component>
|
||||
11
.idea/dictionaries/denny.xml
generated
11
.idea/dictionaries/denny.xml
generated
@@ -2,20 +2,31 @@
|
||||
<dictionary name="denny">
|
||||
<words>
|
||||
<w>bahroo</w>
|
||||
<w>basebanded</w>
|
||||
<w>broadcastify</w>
|
||||
<w>correlator</w>
|
||||
<w>deinterleave</w>
|
||||
<w>descrambled</w>
|
||||
<w>dinf</w>
|
||||
<w>esnid</w>
|
||||
<w>fleetsync</w>
|
||||
<w>heterdyned</w>
|
||||
<w>heterodynes</w>
|
||||
<w>icecast</w>
|
||||
<w>ident</w>
|
||||
<w>nutall</w>
|
||||
<w>overflowable</w>
|
||||
<w>polyphase</w>
|
||||
<w>qpsk</w>
|
||||
<w>remez</w>
|
||||
<w>resampler</w>
|
||||
<w>samplerate</w>
|
||||
<w>sdrtrunk</w>
|
||||
<w>sheirer</w>
|
||||
<w>shoutcast</w>
|
||||
<w>streamable</w>
|
||||
<w>talkgroup</w>
|
||||
<w>talkgroups</w>
|
||||
<w>tgid</w>
|
||||
<w>ultravox</w>
|
||||
<w>wacn</w>
|
||||
|
||||
35
.idea/libraries/imports.xml
generated
35
.idea/libraries/imports.xml
generated
@@ -1,35 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="imports">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/imports/logback-classic-1.1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/usb-api-1.0.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-io-2.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-lang3-3.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/tablefilter-swing-5.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-x86.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/JLargeArrays-1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-ppc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-windows-x86.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-osx-x86.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/miglayout-4.0-swing.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-windows-x86_64.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/usb4java-1.2.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/jide-oss-3.5.15.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-x86_64.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/logback-core-1.1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/usb4java-javax-1.2.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/jsr80-1.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-arm.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-osx-x86_64.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/JTransforms-3.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/jmbe-interface-0.3.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/java-lame-3.98.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-codec-1.9.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-logging-1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/slf4j-api-1.7.21.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-aarch64.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,20 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="org.asynchttpclient:async-http-client:2.0.18" type="repository">
|
||||
<properties maven-id="org.asynchttpclient:async-http-client:2.0.18" />
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/imports/slf4j-api-1.7.21.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/javassist-3.20.0-GA.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/axis.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/jaxrpc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-discovery-0.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/activation-1.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/java-mail-1.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/wsdl4j-1.5.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/radioreference-14.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/mina-core-2.0.16.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/mina-http-2.0.16.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
42
.idea/misc.xml
generated
42
.idea/misc.xml
generated
@@ -1,44 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ClientPropertiesManager">
|
||||
<properties class="javax.swing.AbstractButton">
|
||||
<property name="hideActionText" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JComponent">
|
||||
<property name="html.disable" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JEditorPane">
|
||||
<property name="JEditorPane.w3cLengthUnits" class="java.lang.Boolean" />
|
||||
<property name="JEditorPane.honorDisplayProperties" class="java.lang.Boolean" />
|
||||
<property name="charset" class="java.lang.String" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JList">
|
||||
<property name="List.isFileList" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JPasswordField">
|
||||
<property name="JPasswordField.cutCopyAllowed" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JSlider">
|
||||
<property name="Slider.paintThumbArrowShape" class="java.lang.Boolean" />
|
||||
<property name="JSlider.isFilled" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JTable">
|
||||
<property name="Table.isFileList" class="java.lang.Boolean" />
|
||||
<property name="JTable.autoStartsEdit" class="java.lang.Boolean" />
|
||||
<property name="terminateEditOnFocusLost" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JToolBar">
|
||||
<property name="JToolBar.isRollover" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JTree">
|
||||
<property name="JTree.lineStyle" class="java.lang.String" />
|
||||
</properties>
|
||||
<properties class="javax.swing.text.JTextComponent">
|
||||
<property name="caretAspectRatio" class="java.lang.Double" />
|
||||
<property name="caretWidth" class="java.lang.Integer" />
|
||||
</properties>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="liberica-18.0.1-fx" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/sdrtrunk.iml" filepath="$PROJECT_DIR$/sdrtrunk.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
124
.idea/uiDesigner.xml
generated
124
.idea/uiDesigner.xml
generated
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
23
.project
23
.project
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>sdrtrunk</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,12 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
38
CHANGELOG
38
CHANGELOG
@@ -1,5 +1,39 @@
|
||||
0.4.0 20200404
|
||||
- Release includes embedded Java 14 & JavaFX 13 runtime
|
||||
- Adds Polyphase Channelizer with 2x channel oversampling and redesigned source management
|
||||
- Adds P25 Phase 2 decoder
|
||||
- Adds P25 radio identifier aliasing
|
||||
- JMBE library 1.0.4 with support for AMBE tone metadata
|
||||
- New JavaFX User Preferences dialog
|
||||
- HackRF tuner enhanced (sample rates and saturation issues)
|
||||
- Adds support for Airspy mini tuner
|
||||
- Redesigned audio sub-system that uses AudioSegments
|
||||
- USB tuner bus saturation management/monitoring
|
||||
- Bitstream (.bits) recording
|
||||
- MP3 Audio Recording
|
||||
- Numerous bug fixes
|
||||
|
||||
0.3.0-beta1 20170129
|
||||
0.3.4 20180418
|
||||
- New P25 C4FM decoder that uses Differential QPSK decoder instead of FM demodulation with 4FSK.
|
||||
- Adds channel auto-start and ordering capability with startup dialog allowing user to invoke or bypass channel
|
||||
auto-start. Provides user with more control over startup configuration.
|
||||
- Adds preferred tuner attribute to channel configuration allowing user to select a preferred tuner for the channel
|
||||
|
||||
0.3.3 20171225
|
||||
- Changes build system from ant to gradle. Thanks to: Roman Tsypuk https://github.com/tsypuk
|
||||
- Adds LIST and ID3 metadata to wav audio recordings
|
||||
|
||||
0.3.2 20171105
|
||||
- Resolves issue with tuner frequency adjustments that was causing channel processing
|
||||
to lockup and show persistent 'overflow' state in each channel status
|
||||
- Resolves issue with broadcastify 'mountpoint-in-use' error handling and updates
|
||||
memory usage logging
|
||||
- Resolves issue with Shoutcast 2 login error
|
||||
|
||||
0.3.1 20171009
|
||||
- Resolves Java 9 incompatibility issues
|
||||
|
||||
0.3.0 20170922
|
||||
- REQUIRES: Java 8 (or newer) for compatibility and eventual changeover to JavaFX
|
||||
- FEATURE: audio streaming - adds capability to stream to multiple remote broadcast
|
||||
servers (Broadcastify, Icecast v2.3 and v2.4+, and Shoutcast V1 and V2). Each
|
||||
@@ -34,7 +68,7 @@
|
||||
- Updated Baseband (I/Q) recording at 48 kHz
|
||||
- Added Airspy tuner support
|
||||
- New traffic channel pool manager for trunked call following
|
||||
- P25 Decoder for C4FM and LSM with trunked call following and audio
|
||||
- P25 Decoder for C4FM and LSM with trunked call following and audio
|
||||
decoding via the JMBE library
|
||||
- Updated MPT1327 decoder and trunked call following.
|
||||
- Updated spectral and waterfall display with zoom (2-64x) and pan and automatic
|
||||
|
||||
91
README.md
91
README.md
@@ -1,10 +1,93 @@
|
||||

|
||||
|
||||
# sdrtrunk
|
||||
A cross-platform java application for decoding, monitoring, recording and streaming trunked mobile and related radio protocols using Software Defined Radios (SDR).
|
||||
|
||||
* [Getting Started](https://github.com/DSheirer/sdrtrunk/wiki/GettingStarted)
|
||||
* [User's Manual Version 0.3.0](https://github.com/DSheirer/sdrtrunk/wiki/UserManual_Version0.3.0)
|
||||
* [Getting Started](https://github.com/DSheirer/sdrtrunk/wiki/GettingStarted_V0.3.0)
|
||||
* [User's Manual Version 0.3.0 and 0.4.0](https://github.com/DSheirer/sdrtrunk/wiki/UserManual_V0.3.0)
|
||||
* [Playlist Editor User Manual Version 0.5.0](https://github.com/DSheirer/sdrtrunk/wiki/Playlist-Editor)
|
||||
* [Download](https://github.com/DSheirer/sdrtrunk/releases)
|
||||
* [Support](https://groups.google.com/forum/#!forum/sdrtrunk)
|
||||
* [Support Group](https://groups.google.com/forum/#!forum/sdrtrunk)
|
||||
* [Discord Support Channel](https://discord.gg/HJQaKYE)
|
||||
|
||||

|
||||

|
||||
**Figure 1:** sdrtrunk **Version 0.3.0** Application Screenshot
|
||||
|
||||
# End User Instructions:
|
||||
|
||||
If you simply want to download and run the program, please follow these instructions.
|
||||
|
||||
## Download the latest sdrtrunk release for your operating system
|
||||
|
||||
All release versions of sdrtrunk are available from the [releases](https://github.com/DSheirer/sdrtrunk/releases) tab.
|
||||
|
||||
* **(alpha)** These versions are under development feature previews and likely to contain bugs and unexpected behavior.
|
||||
* **(beta)** These versions are currently being tested for bugs and functionality prior to final release.
|
||||
* **(final)** These versions have been tested and are the current release version.
|
||||
|
||||
## Unzip the release
|
||||
|
||||
Use 7-zip or any zip utility to unzip the release file
|
||||
|
||||
## Start the application
|
||||
|
||||
Once unzipped, open a command prompt to where you unzipped the release. Change to the **/bin** directory and use the launch script to start the application:
|
||||
* **Windows** sdr-trunk.bat
|
||||
* **Linux/OSX** ./sdr-trunk
|
||||
|
||||
## Optional - P25/DMR Audio
|
||||
If you're using sdrtrunk with a P25 or DMR radio system, you'll need to compile and include the [JMBE](https://github.com/DSheirer/sdrtrunk/wiki/JMBE) digital audio library.
|
||||
|
||||
In Version 0.5.0 and higher, the SDRTrunk application has support for building the JMBE library. On the menu, choose **View >> User Preferences** and then click the **Decoder >> JMBE Audio Library** tab.
|
||||
|
||||
For versions prior to Version 0.5.0, the [JMBE](https://github.com/DSheirer/sdrtrunk/wiki/JMBE) wiki page contains instructions for downloading the JMBE audio library source code and compiling the JMBE library. Once you have compiled the library, launch the sdrtrunk application. From the menu bar, choose **View >> Preferences**. In the **JMBE Audio Codec** section, update the path to where your compiled JMBE library is located. Any channels that are started after you set the path will be able to produce P25 audio.
|
||||
|
||||
## Minimum System Requirements
|
||||
* **Operating System:** Windows (~~32 or~~ 64-bit), Linux (~~32 or~~ 64-bit) or Mac/Linux (64-bit, 10.14 or higher)
|
||||
* **CPU:** 4-core
|
||||
* **RAM:** 8GB or more (preferred). Depending on usage, 4GB may be sufficient.
|
||||
|
||||
# Developer Instructions:
|
||||
|
||||
If you're interested in modifying and/or compiling the source code, please follow these instructions to use gradle to compile the code.
|
||||
|
||||
## Build the project
|
||||
sdrtrunk uses the gradle build system. This requires **OpenJDK 17** or higher installed on your local computer.
|
||||
|
||||
### OpenJDK
|
||||
There are many vendors producing OpenJDK distributions. A few that I use are:
|
||||
* [Azul Zulu OpenJDK](https://www.azul.com/downloads/?package=jdk)
|
||||
* [Bellsoft Liberica OpenJDK](https://bell-sw.com/pages/downloads/#/java-17-lts%20/%20current)
|
||||
* [SDKMAN](https://sdkman.io/) - Linux Only
|
||||
|
||||
Use the gradle wrapper to build the source code:
|
||||
|
||||
### Linux
|
||||
```
|
||||
./gradlew clean build
|
||||
```
|
||||
### Windows
|
||||
```
|
||||
gradlew.bat clean build
|
||||
```
|
||||
|
||||
The **/build/distributions** folder will contain the zip file of the compiled program. Unzip it and launch the program from the scripts in the **/bin** directory.
|
||||
|
||||
## Run the Application (from Gradle)
|
||||
|
||||
### Linux
|
||||
```
|
||||
./gradlew clean run
|
||||
```
|
||||
### Windows
|
||||
```
|
||||
gradlew.bat clean run
|
||||
```
|
||||
|
||||
|
||||
## Development
|
||||
All dependencies/versions are controlled from build.gradle.
|
||||
To change the new release version tag of artifact - change property:
|
||||
```
|
||||
version = '0.5.0'
|
||||
```
|
||||
|
||||
226
build.gradle
Normal file
226
build.gradle
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
plugins {
|
||||
id 'application'
|
||||
id 'java'
|
||||
id 'idea'
|
||||
id 'org.beryx.runtime' version '1.12.7'
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
version = '0.5.0-beta5'
|
||||
sourceCompatibility = '17'
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs 'src/main'
|
||||
test.java.srcDirs 'src/test'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
// JUnit Tests
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.assertj:assertj-core:3.8.0'
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
||||
testImplementation 'org.mockito:mockito-core:3.+'
|
||||
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
|
||||
|
||||
//Jitpack imports
|
||||
implementation 'com.github.dnault:libresample4j:master'
|
||||
implementation 'com.github.DSheirer.jmbe:jmbe-api:1.0.0'
|
||||
implementation 'com.github.nwaldispuehl:java-lame:v3.98.4'
|
||||
|
||||
//mavenCentral/jcenter imports
|
||||
implementation 'ch.qos.logback:logback-classic:1.2.3'
|
||||
implementation 'ch.qos.logback:logback-core:1.2.3'
|
||||
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.2'
|
||||
implementation 'com.fazecast:jSerialComm:2.5.0'
|
||||
implementation 'com.github.jiconfont:jiconfont-font_awesome:4.7.0.1'
|
||||
implementation 'com.github.jiconfont:jiconfont-javafx:1.0.0'
|
||||
implementation 'com.github.jiconfont:jiconfont-swing:1.0.1'
|
||||
implementation 'com.github.wendykierp:JTransforms:3.1'
|
||||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
implementation 'com.google.guava:guava:27.0.1-jre'
|
||||
implementation 'com.jidesoft:jide-oss:3.6.18'
|
||||
implementation 'com.miglayout:miglayout-swing:5.2'
|
||||
implementation 'com.mpatric:mp3agic:0.9.1'
|
||||
implementation 'commons-io:commons-io:2.7'
|
||||
implementation 'eu.hansolo:charts:1.0.5'
|
||||
implementation 'io.github.dsheirer:radio-reference-api:15.1.8'
|
||||
implementation 'javax.usb:usb-api:1.0.2'
|
||||
implementation 'net.coderazzi:tablefilter-swing:5.4.0'
|
||||
implementation 'org.apache.commons:commons-compress:1.20'
|
||||
implementation 'org.apache.commons:commons-lang3:3.8.1'
|
||||
implementation 'org.apache.commons:commons-math3:3.6.1'
|
||||
implementation 'org.apache.commons:commons-csv:1.9.0'
|
||||
implementation 'org.apache.mina:mina-core:2.1.3'
|
||||
implementation 'org.apache.mina:mina-http:2.1.3'
|
||||
implementation 'org.controlsfx:controlsfx:11.1.0'
|
||||
implementation 'org.rauschig:jarchivelib:1.0.0'
|
||||
implementation 'org.slf4j:slf4j-api:1.7.25'
|
||||
implementation 'org.usb4java:libusb4java:1.3.0'
|
||||
implementation 'org.usb4java:usb4java:1.3.0'
|
||||
implementation 'org.usb4java:usb4java-javax:1.3.0'
|
||||
implementation 'io.github.dsheirer:libusb4java-darwin-aarch64:1.3.1' //usb4java native lib for OSX M1 cpu
|
||||
implementation 'pl.edu.icm:JLargeArrays:1.6'
|
||||
}
|
||||
|
||||
/**
|
||||
* This is needed for the JDK17 vector API ... until it moves out of incubation
|
||||
*/
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs.add("--add-modules=jdk.incubator.vector") //Needed while Panama Vector API remains in incubator
|
||||
}
|
||||
|
||||
application {
|
||||
mainClassName = "io.github.dsheirer.gui.SDRTrunk"
|
||||
applicationDefaultJvmArgs =
|
||||
['--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED', //Needed for controls-fx.jar
|
||||
'--add-modules=jdk.incubator.vector', //Needed while Panama Vector API remains in incubator
|
||||
'--add-exports=java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED'] //Windows Swing - jide-oss library
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes (
|
||||
'Implementation-Title' : 'sdrtrunk project',
|
||||
'Implementation-Version' : archiveVersion,
|
||||
'Created-By' : "Gradle ${gradle.gradleVersion}",
|
||||
'Build-Timestamp' : new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()),
|
||||
'Build-JDK' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']}",
|
||||
'Build-OS' : "${System.properties['os.name']} (${System.properties['os.arch']} ${System.properties['os.version']}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
idea {
|
||||
module {
|
||||
downloadJavadoc = true
|
||||
downloadSources = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime target OS and CPU image names. We append version here so that version details are at end of zip filename.
|
||||
*/
|
||||
String targetLinuxAarch64 = 'linux-aarch64-v' + version
|
||||
String targetLinuxX86_64 = 'linux-x86_64-v' + version
|
||||
String targetOsxAarch64 = 'osx-aarch64-v' + version
|
||||
String targetOsxX86_64 = 'osx-x86_64-v' + version
|
||||
String targetWindowsX86_64 = 'windows-x86_64-v' + version
|
||||
|
||||
/**
|
||||
* Optional pre-downloaded Java Development Kit (JDK) for each target OS and CPU. These locations are hard-coded to the
|
||||
* author's development environment, but can be changed to your environment if you want to use this build pattern.
|
||||
*/
|
||||
String jdk_base = '/home/denny/java_jdks/'
|
||||
String jdk_linux_aarch64 = jdk_base + 'linux-arm64/jdk-18.0.1-full'
|
||||
String jdk_linux_x86_64 = jdk_base + 'linux-x64/jdk-18.0.1-full'
|
||||
String jdk_osx_x86_64 = jdk_base + 'osx-x64/jdk-18.0.1-full.jdk'
|
||||
String jdk_osx_aarch64 = jdk_base + 'osx-arm64/jdk-18.0.1-full.jdk'
|
||||
String jdk_windows_x86_64 = jdk_base + 'windows-x64/jdk-18.0.1-full'
|
||||
|
||||
boolean hasTargetJdks = file(jdk_linux_x86_64).exists() || file(jdk_linux_aarch64).exists() ||
|
||||
file(jdk_osx_x86_64).exists() || file(jdk_osx_aarch64).exists() || file(jdk_windows_x86_64).exists()
|
||||
|
||||
/**
|
||||
* Auto-download target JDKs. Defaults to false, or the user can override via the gradle command line by
|
||||
* including this option: '-PdownloadJdks=true'
|
||||
*/
|
||||
boolean downloadJdks = project.hasProperty('downloadJdks') ? project.getProperty('downloadJdks') : false
|
||||
|
||||
/**
|
||||
* Beryx Runtime plugin for creating OS and CPU targeted build(s) of the software.
|
||||
*
|
||||
* Option 1: Create a single target build using the locally installed JDK, or optionally create target builds for
|
||||
* all OS and CPU targets when pre-downloaded target JDKs are available (see 'jdk_*' properties above).
|
||||
*
|
||||
* >: gradle runtimeZip
|
||||
*
|
||||
* Option 2: Create all OS and CPU target builds by automatically downloading all JDKs needed to build the target images
|
||||
*
|
||||
* >: gradle runtimeZip -PdownloadJdks=true
|
||||
*/
|
||||
runtime {
|
||||
//Build by automatically downloading JDKs for the OS and CPU targets
|
||||
if(downloadJdks) {
|
||||
println("Building all runtime images")
|
||||
println("The [ > jre: ] build phase downloads several target JDKs and this may take a while ... please wait")
|
||||
targetPlatform(targetLinuxAarch64) {
|
||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-linux-aarch64-full.tar.gz")
|
||||
}
|
||||
targetPlatform(targetLinuxX86_64) {
|
||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-linux-amd64-full.tar.gz")
|
||||
}
|
||||
targetPlatform(targetOsxAarch64) {
|
||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-macos-aarch64-full.tar.gz")
|
||||
}
|
||||
targetPlatform(targetOsxX86_64) {
|
||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-macos-amd64-full.tar.gz")
|
||||
}
|
||||
targetPlatform(targetWindowsX86_64) {
|
||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-windows-amd64-full.zip")
|
||||
}
|
||||
}
|
||||
//Build using pre-downloaded JDKs
|
||||
else if(hasTargetJdks) {
|
||||
println("Building all runtime images using pre-downloaded JDKs")
|
||||
if(file(jdk_linux_aarch64).exists()) {
|
||||
targetPlatform(targetLinuxAarch64, jdk_linux_aarch64)
|
||||
}
|
||||
if(file(jdk_linux_x86_64).exists()) {
|
||||
targetPlatform(targetLinuxX86_64, jdk_linux_x86_64)
|
||||
}
|
||||
if(file(jdk_osx_aarch64).exists()) {
|
||||
targetPlatform(targetOsxAarch64, jdk_osx_aarch64)
|
||||
}
|
||||
if(file(jdk_osx_x86_64).exists()) {
|
||||
targetPlatform(targetOsxX86_64, jdk_osx_x86_64)
|
||||
}
|
||||
if(file(jdk_windows_x86_64).exists()) {
|
||||
targetPlatform(targetWindowsX86_64, jdk_windows_x86_64)
|
||||
}
|
||||
}
|
||||
//Build using locally installed JDK only
|
||||
else {
|
||||
println("Building a single runtime image using locally installed JDK")
|
||||
}
|
||||
|
||||
//Additional modules to include with auto-detected modules.
|
||||
modules = ['jdk.crypto.ec'] //jdk.crypto.ec needed for HTTPS connections (broadcastify calls & map tile server)
|
||||
|
||||
//Use auto-detected modules and 'add' any specified modules.
|
||||
additive = true
|
||||
|
||||
//Recommended options for reducing/shrinking runtime target image size
|
||||
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
|
||||
|
||||
//Runtime images have auto appended version in image zip name. Override to include version in single target image.
|
||||
imageZip = (hasTargetJdks | downloadJdks) ? file("$buildDir/image/sdr-trunk.zip") :
|
||||
file("$buildDir/image/sdr-trunk-" + version + ".zip")
|
||||
}
|
||||
142
build/build.xml
142
build/build.xml
@@ -1,142 +0,0 @@
|
||||
<project name="SDRTrunk" default="SDRTrunk" basedir=".">
|
||||
<description>
|
||||
Ant build script for SDRTrunk Decoder Application
|
||||
</description>
|
||||
|
||||
<!-- version properties -->
|
||||
<property name="major" value="0"/>
|
||||
<property name="minor" value="3"/>
|
||||
<property name="patch" value="1"/>
|
||||
<property name="release" value="final"/>
|
||||
<property name="filename" value="sdrtrunk_${major}.${minor}.${patch}${release}"/>
|
||||
|
||||
<!-- Build properties -->
|
||||
<property name="repo" location=".."/>
|
||||
<property name="source.code" location="${repo}/src"/>
|
||||
<property name="source.configs" location="${repo}/config"/>
|
||||
<property name="source.images" location="${repo}/images"/>
|
||||
<property name="source.libs" location="${repo}/imports"/>
|
||||
<property name="source.scripts" location="${repo}/scripts"/>
|
||||
|
||||
<property name="output" location="${repo}/product"/>
|
||||
<property name="output.classes" location="${repo}/classes"/>
|
||||
<property name="output.folder" location="${output}/sdrtrunk"/>
|
||||
<property name="output.config" location="${output.folder}/config"/>
|
||||
<property name="output.images" location="${output.folder}/images"/>
|
||||
<property name="output.libs" location="${output.folder}/libs"/>
|
||||
|
||||
<path id="classpath">
|
||||
<fileset dir="${source.libs}" includes="*.jar"/>
|
||||
</path>
|
||||
|
||||
<target name="init">
|
||||
<!-- Create the classes folder to contain the compiled java classes -->
|
||||
<mkdir dir="${output.classes}"/>
|
||||
|
||||
<!-- Create version file -->
|
||||
<echo message="${major}.${minor}.${patch}-${release}" file="${output.classes}/sdrtrunk-version"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="clean,init,compile-java-8,compile-java-9"
|
||||
description="Compile java classes" />
|
||||
|
||||
<target name="compile-java-8" depends="check-java-version" if="java.8" description="Compiles code with Java 8 arguments">
|
||||
<echo message="Compiling with Java 8 Options"/>
|
||||
<javac srcdir="${source.code}" destdir="${output.classes}" classpathref="classpath" includeantruntime="false"/>
|
||||
</target>
|
||||
|
||||
<target name="compile-java-9" depends="check-java-version" if="java.9" description="Compiles code with Java 9 arguments">
|
||||
<echo message="Compiling with Java 9 Options"/>
|
||||
<javac srcdir="${source.code}" destdir="${output.classes}" classpathref="classpath" includeantruntime="false">
|
||||
<compilerarg value="--add-modules"/>
|
||||
<compilerarg value="java.xml.bind"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="check-java-version" description="Determines if the compiler is Java 8 or 9">
|
||||
<condition property="java.8" value="true">
|
||||
<contains string="${java.version}" substring="1.8"/>
|
||||
</condition>
|
||||
<condition property="java.9" value="true">
|
||||
<equals arg1="${java.version}" arg2="9"/>
|
||||
</condition>
|
||||
<echo message="Java Version: ${java.version}"/>
|
||||
</target>
|
||||
|
||||
<target name="SDRTrunk" depends="compile" description="Create SDRTrunk application">
|
||||
<!-- Create the distribution directory -->
|
||||
<mkdir dir="${output.folder}"/>
|
||||
|
||||
<!-- Create jar file -->
|
||||
<jar jarfile="${output.folder}/sdrtrunk.jar" basedir="${output.classes}">
|
||||
<manifest>
|
||||
<attribute name="Title" value="sdrtrunk"/>
|
||||
<attribute name="Main-Class" value="gui.SDRTrunk"/>
|
||||
<attribute name="Version" value="${major}.${minor}.${patch}-${release}"/>
|
||||
</manifest>
|
||||
<fileset dir="${source.configs}">
|
||||
<exclude name="*.rules"/>
|
||||
</fileset>
|
||||
|
||||
<fileset dir="${repo}">
|
||||
<include name="LICENSE"/>
|
||||
</fileset>
|
||||
</jar>
|
||||
|
||||
<!-- Copy third-party libraries -->
|
||||
<mkdir dir="${output.libs}"/>
|
||||
<copy todir="${output.libs}">
|
||||
<fileset dir="${source.libs}" includes="*.jar"/>
|
||||
</copy>
|
||||
|
||||
<!-- Copy config files -->
|
||||
<mkdir dir="${output.config}"/>
|
||||
|
||||
<copy todir="${output.config}">
|
||||
<fileset dir="${source.configs}">
|
||||
<include name="*.rules"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Copy image files -->
|
||||
<mkdir dir="${output.images}"/>
|
||||
<copy todir="${output.images}">
|
||||
<fileset dir="${source.images}"/>
|
||||
</copy>
|
||||
|
||||
<!-- Copy license file -->
|
||||
<copy todir="${output.folder}">
|
||||
<fileset dir="${repo}">
|
||||
<include name="LICENSE"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Copy program scripts -->
|
||||
<copy todir="${output.folder}">
|
||||
<fileset dir="${source.scripts}"/>
|
||||
</copy>
|
||||
|
||||
|
||||
<!-- Bundle the files into .zip -->
|
||||
<zip destfile="${output}/${filename}.zip" basedir="${output}"/>
|
||||
|
||||
<!-- Remove linux start script before tar task -->
|
||||
<delete file="${output.folder}/run_sdrtrunk_linux.sh"/>
|
||||
|
||||
<!-- Bundle files into .tar.gz and copy/set permissions on linux start script -->
|
||||
<tar destfile="${output}/${filename}.tar.gz" compression="gzip">
|
||||
<tarfileset dir="${output.folder}" prefix="sdrtrunk"/>
|
||||
<tarfileset dir="${source.scripts}" prefix="sdrtrunk" filemode="777">
|
||||
<include name="run_sdrtrunk_linux.sh"/>
|
||||
</tarfileset>
|
||||
</tar>
|
||||
|
||||
<delete dir="${output.folder}"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" description="Clean previous build artifacts">
|
||||
<delete dir="${output.classes}"/>
|
||||
<delete dir="${output}"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -1,33 +0,0 @@
|
||||
<configuration>
|
||||
<timestamp key="appstart" datePattern="HHmmss"/>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${user.home}/SDRTrunk/logs/sdrtrunk_app.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- daily log rollover -->
|
||||
<fileNamePattern>${user.home}/SDRTrunk/logs/%d{yyyyMMdd}_sdrtrunk_app.log</fileNamePattern>
|
||||
<maxHistory>10</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%-25(%d{yyyyMMdd HHmmss.SSS} [%thread]) %-5level %logger{30} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-12(%d{HH:mm:ss.SSS}) %-5level %logger{25} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<!-- Apache Mina TCP/HTTP library -->
|
||||
<logger name="org.apache.mina" level="INFO" />
|
||||
|
||||
</configuration>
|
||||
16
copyright.template
Normal file
16
copyright.template
Normal file
@@ -0,0 +1,16 @@
|
||||
******************************************************************************
|
||||
Copyright (C) 2014-${today.year} Dennis Sheirer
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*****************************************************************************
|
||||
@@ -1,17 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
24
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
24
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# ******************************************************************************
|
||||
# Copyright (C) 2014-2022 Dennis Sheirer
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
# *****************************************************************************
|
||||
#
|
||||
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
183
gradlew
vendored
Executable file
183
gradlew
vendored
Executable file
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
100
gradlew.bat
vendored
Normal file
100
gradlew.bat
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,4 +0,0 @@
|
||||
[Dolphin]
|
||||
PreviewsShown=true
|
||||
Timestamp=2013,9,20,8,54,21
|
||||
Version=3
|
||||
@@ -1,4 +0,0 @@
|
||||
[Dolphin]
|
||||
Timestamp=2013,4,7,10,12,39
|
||||
Version=3
|
||||
ViewMode=1
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
imports/axis.jar
BIN
imports/axis.jar
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
java -version
|
||||
|
||||
# Test for java version 9
|
||||
JAVA_9=$(java -version 2>&1 | grep -i version | sed 's/.* "\([9]\).*/\1/')
|
||||
|
||||
if [ -z ${JAVA_9+x} ]; then
|
||||
echo Using Java 9 program options
|
||||
# Java 9 uses the G1 garbage collector by default and requires that we specify the
|
||||
# java.xml.bind package since it's been removed from the java se core library
|
||||
java -cp "*:libs/*" --add-modules java.xml.bind gui.SDRTrunk;
|
||||
else
|
||||
echo Using Java 8 program options
|
||||
java -XX:+UseG1GC -cp "*:libs/*" gui.SDRTrunk;
|
||||
fi
|
||||
@@ -1,25 +0,0 @@
|
||||
@echo off
|
||||
|
||||
java -version
|
||||
|
||||
SETLOCAL ENABLEDELAYEDEXPANSION
|
||||
|
||||
for /f "usebackq tokens=3" %%a in (`java -version 2^>^&1 ^| find "version"`) do (
|
||||
rem set b to the unquoted version string parsed from the java version command
|
||||
set b=%%~a
|
||||
|
||||
rem set c to the first character of the unquoted version string
|
||||
set c=!b:~0,1!
|
||||
|
||||
if !c! equ 9 (
|
||||
echo Using Java 9 options
|
||||
java -cp "SDRTrunk.jar;*;libs/*;config/*;images/*" --add-modules java.xml.bind gui.SDRTrunk
|
||||
) else (
|
||||
echo Using Java 8 options
|
||||
java -XX:+UseG1GC -cp "SDRTrunk.jar;*;libs/*;config/*;images/*" gui.SDRTrunk
|
||||
)
|
||||
)
|
||||
|
||||
ENDLOCAL
|
||||
|
||||
@echo on
|
||||
1023
sdr-trunk.ipr
Normal file
1023
sdr-trunk.ipr
Normal file
File diff suppressed because it is too large
Load Diff
25
sdrtrunk.iml
25
sdrtrunk.iml
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/images" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/config" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$" type="java-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="imports" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../jmbe/jmbe/library/jmbe-0.3.3.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="org.asynchttpclient:async-http-client:2.0.18" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
1
settings.gradle
Normal file
1
settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'sdr-trunk'
|
||||
@@ -1,4 +0,0 @@
|
||||
[Dolphin]
|
||||
Timestamp=2015,9,1,6,42,59
|
||||
Version=3
|
||||
ViewMode=1
|
||||
@@ -1,354 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import alias.action.AliasAction;
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import alias.id.nonrecordable.NonRecordable;
|
||||
import alias.id.priority.Priority;
|
||||
|
||||
@XmlSeeAlso( { AliasID.class, AliasAction.class } )
|
||||
@XmlRootElement( name = "alias" )
|
||||
public class Alias
|
||||
{
|
||||
private String mList;
|
||||
private String mGroup;
|
||||
private String mName;
|
||||
private int mColor;
|
||||
private String mIconName;
|
||||
private List<AliasID> mAliasIDs = new ArrayList<AliasID>();
|
||||
private List<AliasAction> mAliasActions = new ArrayList<AliasAction>();
|
||||
|
||||
public Alias()
|
||||
{
|
||||
}
|
||||
|
||||
public Alias( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
@XmlAttribute( name="name" )
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void setName( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
@XmlAttribute( name="list" )
|
||||
public String getList()
|
||||
{
|
||||
return mList;
|
||||
}
|
||||
|
||||
public void setList( String list )
|
||||
{
|
||||
mList = list;
|
||||
}
|
||||
|
||||
public boolean hasList()
|
||||
{
|
||||
return mList != null;
|
||||
}
|
||||
|
||||
@XmlAttribute( name="group" )
|
||||
public String getGroup()
|
||||
{
|
||||
return mGroup;
|
||||
}
|
||||
|
||||
public void setGroup( String group )
|
||||
{
|
||||
mGroup = group;
|
||||
}
|
||||
|
||||
public boolean hasGroup()
|
||||
{
|
||||
return mGroup != null;
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public int getColor()
|
||||
{
|
||||
return mColor;
|
||||
}
|
||||
|
||||
public void setColor( int color )
|
||||
{
|
||||
mColor = color;
|
||||
}
|
||||
|
||||
public Color getDisplayColor()
|
||||
{
|
||||
return new Color( getColor() );
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public String getIconName()
|
||||
{
|
||||
return mIconName;
|
||||
}
|
||||
|
||||
public void setIconName( String iconName )
|
||||
{
|
||||
mIconName = iconName;
|
||||
}
|
||||
|
||||
@XmlElement( name="id" )
|
||||
public List<AliasID> getId()
|
||||
{
|
||||
return mAliasIDs;
|
||||
}
|
||||
|
||||
public void setId( ArrayList<AliasID> id )
|
||||
{
|
||||
mAliasIDs = id;
|
||||
}
|
||||
|
||||
public void addAliasID( AliasID id )
|
||||
{
|
||||
mAliasIDs.add( id );
|
||||
}
|
||||
|
||||
public void removeAliasID( AliasID id )
|
||||
{
|
||||
mAliasIDs.remove( id );
|
||||
}
|
||||
|
||||
@XmlElement( name="action" )
|
||||
public List<AliasAction> getAction()
|
||||
{
|
||||
return mAliasActions;
|
||||
}
|
||||
|
||||
public void setAction( List<AliasAction> actions )
|
||||
{
|
||||
mAliasActions = actions;
|
||||
}
|
||||
|
||||
public void addAliasAction( AliasAction action )
|
||||
{
|
||||
mAliasActions.add( action );
|
||||
}
|
||||
|
||||
public void removeAliasAction( AliasAction action )
|
||||
{
|
||||
mAliasActions.remove( action );
|
||||
}
|
||||
|
||||
public boolean hasActions()
|
||||
{
|
||||
return !mAliasActions.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any validation/cleanup actions on this alias.
|
||||
*/
|
||||
public void validate()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Returns the priority level of this alias, if defined, or the default priority
|
||||
*/
|
||||
@XmlTransient
|
||||
public int getCallPriority()
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.getType() == AliasIDType.PRIORITY)
|
||||
{
|
||||
return ((Priority)id).getPriority();
|
||||
}
|
||||
}
|
||||
|
||||
return Priority.DEFAULT_PRIORITY;
|
||||
}
|
||||
|
||||
public boolean hasCallPriority()
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.getType() == AliasIDType.PRIORITY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or updates the call priority
|
||||
*/
|
||||
public void setCallPriority( int priority )
|
||||
{
|
||||
if( priority == Priority.DO_NOT_MONITOR ||
|
||||
( Priority.MIN_PRIORITY <= priority && priority <= Priority.MAX_PRIORITY ) )
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.getType() == AliasIDType.PRIORITY)
|
||||
{
|
||||
((Priority)id).setPriority( priority );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//If we don't find a priority id, create one
|
||||
Priority p = new Priority();
|
||||
p.setPriority( priority );
|
||||
addAliasID( p );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the alias for a non-recordable alias id. Default is true;
|
||||
*/
|
||||
@XmlTransient
|
||||
public boolean isRecordable()
|
||||
{
|
||||
for( AliasID id: getId() )
|
||||
{
|
||||
if( id.getType() == AliasIDType.NON_RECORDABLE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or removes the non-recordable alias ID for this alias.
|
||||
*/
|
||||
public void setRecordable( boolean recordable )
|
||||
{
|
||||
if( recordable )
|
||||
{
|
||||
AliasID toRemove = null;
|
||||
|
||||
for( AliasID id: getId() )
|
||||
{
|
||||
if( id.getType() == AliasIDType.NON_RECORDABLE)
|
||||
{
|
||||
toRemove = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( toRemove != null )
|
||||
{
|
||||
removeAliasID( toRemove );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( AliasID id: getId() )
|
||||
{
|
||||
if( id.getType() == AliasIDType.NON_RECORDABLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
addAliasID( new NonRecordable() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the alias for broadcast channel/streamable alias ids. Default is false;
|
||||
*/
|
||||
@XmlTransient
|
||||
public boolean isStreamable()
|
||||
{
|
||||
for( AliasID id: getId() )
|
||||
{
|
||||
if( id.getType() == AliasIDType.BROADCAST_CHANNEL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of broadcast channels specified for this alias.
|
||||
*/
|
||||
@XmlTransient
|
||||
public Set<BroadcastChannel> getBroadcastChannels()
|
||||
{
|
||||
Set<BroadcastChannel> broadcastChannels = new TreeSet<>();
|
||||
|
||||
for(AliasID id: getId())
|
||||
{
|
||||
if(id.getType() == AliasIDType.BROADCAST_CHANNEL)
|
||||
{
|
||||
broadcastChannels.add((BroadcastChannel)id);
|
||||
}
|
||||
}
|
||||
|
||||
return broadcastChannels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this alias contains a broadcast channel alias id with the channel name.
|
||||
*/
|
||||
public boolean hasBroadcastChannel(String channel)
|
||||
{
|
||||
if(channel == null || channel.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(AliasID id: getId())
|
||||
{
|
||||
if(id.getType() == AliasIDType.BROADCAST_CHANNEL &&
|
||||
((BroadcastChannel)id).getChannelName().contentEquals(channel))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,356 +0,0 @@
|
||||
package alias;
|
||||
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import com.jidesoft.swing.JideSplitPane;
|
||||
import gui.editor.Editor;
|
||||
import icon.IconManager;
|
||||
import net.coderazzi.filters.gui.AutoChoices;
|
||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AliasController extends JPanel
|
||||
implements ActionListener, ListSelectionListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
private JTable mAliasTable;
|
||||
private TableFilterHeader mTableFilterHeader;
|
||||
private AliasEditor mAliasEditor;
|
||||
private MultipleAliasEditor mMultipleAliasEditor;
|
||||
private JideSplitPane mSplitPane;
|
||||
|
||||
private static final String NEW_ALIAS = "New";
|
||||
private static final String COPY_ALIAS = "Copy";
|
||||
private static final String DELETE_ALIAS = "Delete";
|
||||
|
||||
private JButton mNewButton = new JButton(NEW_ALIAS);
|
||||
private JButton mCopyButton = new JButton(COPY_ALIAS);
|
||||
private JButton mDeleteButton = new JButton(DELETE_ALIAS);
|
||||
|
||||
private IconCellRenderer mIconCellRenderer;
|
||||
|
||||
public AliasController(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager)
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
|
||||
mAliasEditor = new AliasEditor(mAliasModel, broadcastModel, iconManager);
|
||||
mMultipleAliasEditor = new MultipleAliasEditor(mAliasModel, broadcastModel, iconManager);
|
||||
|
||||
mIconCellRenderer = new IconCellRenderer(iconManager);
|
||||
|
||||
init();
|
||||
|
||||
mAliasModel.addListener(mAliasEditor);
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout(new MigLayout("insets 0 0 0 0",
|
||||
"[grow,fill]",
|
||||
"[grow,fill]"));
|
||||
|
||||
//System Configuration View and Editor
|
||||
mAliasTable = new JTable(mAliasModel);
|
||||
mAliasTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
mAliasTable.getSelectionModel().addListSelectionListener(this);
|
||||
mAliasTable.setAutoCreateRowSorter(true);
|
||||
|
||||
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_COLOR)
|
||||
.setCellRenderer(new ColorCellRenderer());
|
||||
|
||||
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_ICON)
|
||||
.setCellRenderer(mIconCellRenderer);
|
||||
|
||||
mTableFilterHeader = new TableFilterHeader(mAliasTable, AutoChoices.ENABLED);
|
||||
mTableFilterHeader.setFilterOnUpdates(true);
|
||||
|
||||
JScrollPane tableScroller = new JScrollPane(mAliasTable);
|
||||
|
||||
JPanel buttonsPanel = new JPanel();
|
||||
|
||||
buttonsPanel.setLayout(
|
||||
new MigLayout("insets 0 0 0 0", "[grow,fill][grow,fill][grow,fill]", "[]"));
|
||||
|
||||
mNewButton.addActionListener(this);
|
||||
mNewButton.setToolTipText("Adds a new alias");
|
||||
buttonsPanel.add(mNewButton);
|
||||
|
||||
mCopyButton.addActionListener(this);
|
||||
mCopyButton.setEnabled(false);
|
||||
mCopyButton.setToolTipText("Creates a copy of the currently selected alias and adds it");
|
||||
buttonsPanel.add(mCopyButton);
|
||||
|
||||
mDeleteButton.addActionListener(this);
|
||||
mDeleteButton.setEnabled(false);
|
||||
mDeleteButton.setToolTipText("Deletes the currently selected alias");
|
||||
buttonsPanel.add(mDeleteButton);
|
||||
|
||||
JPanel listAndButtonsPanel = new JPanel();
|
||||
|
||||
listAndButtonsPanel.setLayout(
|
||||
new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill][]"));
|
||||
|
||||
listAndButtonsPanel.add(tableScroller, "wrap");
|
||||
listAndButtonsPanel.add(buttonsPanel);
|
||||
|
||||
mSplitPane = new JideSplitPane(JideSplitPane.HORIZONTAL_SPLIT);
|
||||
mSplitPane.setDividerSize(5);
|
||||
mSplitPane.setShowGripper(true);
|
||||
mSplitPane.add(listAndButtonsPanel);
|
||||
mSplitPane.add(mAliasEditor);
|
||||
|
||||
add(mSplitPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the editor argument as the currently visible alias editor
|
||||
*/
|
||||
private void setEditor(Editor<?> editor)
|
||||
{
|
||||
if(mSplitPane.getComponentCount() == 3)
|
||||
{
|
||||
Component component = mSplitPane.getComponent(2);
|
||||
|
||||
if(component instanceof Editor<?> && component != editor)
|
||||
{
|
||||
//Get current divider location so that we can reapply it after
|
||||
//changing out the editors, so that the interface doesn't move
|
||||
int location = mSplitPane.getDividerLocation(0);
|
||||
|
||||
((Editor<?>) component).setItem(null);
|
||||
|
||||
mSplitPane.remove(component);
|
||||
editor.setPreferredSize(new Dimension(100, 100));
|
||||
mSplitPane.add(editor);
|
||||
|
||||
mSplitPane.validate();
|
||||
mSplitPane.setDividerLocation(0, location);
|
||||
mSplitPane.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Alias getAlias(int selectedRow)
|
||||
{
|
||||
if(selectedRow >= 0)
|
||||
{
|
||||
int index = mAliasTable.convertRowIndexToModel(selectedRow);
|
||||
|
||||
return mAliasModel.getAliasAtIndex(index);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent event)
|
||||
{
|
||||
//Limits event firing to only when selection is complete
|
||||
if(!event.getValueIsAdjusting())
|
||||
{
|
||||
int[] selectedRows = mAliasTable.getSelectedRows();
|
||||
|
||||
if(selectedRows.length == 0)
|
||||
{
|
||||
mAliasEditor.setItem(null);
|
||||
mCopyButton.setEnabled(false);
|
||||
mDeleteButton.setEnabled(false);
|
||||
}
|
||||
else if(selectedRows.length == 1)
|
||||
{
|
||||
setEditor(mAliasEditor);
|
||||
|
||||
Alias selectedAlias = getAlias(selectedRows[0]);
|
||||
|
||||
mAliasEditor.setItem(selectedAlias);
|
||||
|
||||
if(selectedAlias != null)
|
||||
{
|
||||
mCopyButton.setEnabled(true);
|
||||
mDeleteButton.setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCopyButton.setEnabled(false);
|
||||
mDeleteButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setEditor(mMultipleAliasEditor);
|
||||
|
||||
mCopyButton.setEnabled(true);
|
||||
mDeleteButton.setEnabled(true);
|
||||
|
||||
List<Alias> selectedAliases = new ArrayList<Alias>();
|
||||
|
||||
for(int selectedRow : selectedRows)
|
||||
{
|
||||
Alias alias = getAlias(selectedRow);
|
||||
|
||||
selectedAliases.add(alias);
|
||||
}
|
||||
|
||||
mMultipleAliasEditor.setItem(selectedAliases);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the alias to the alias table/model and scrolls the view it
|
||||
*/
|
||||
private void addAlias(Alias alias)
|
||||
{
|
||||
//HACK: when inserting a row to the model, the JTable gets
|
||||
//notified and attempts to tell the coderazzi table filter
|
||||
//adaptive choices filter to refresh before the table filter is
|
||||
//notified of the row additions, causing an index out of bounds
|
||||
//exception. We turn off adaptive choices temporarily, add the
|
||||
//channel, and turn on adaptive choices again.
|
||||
mTableFilterHeader.setAdaptiveChoices(false);
|
||||
|
||||
int index = mAliasModel.addAlias(alias);
|
||||
|
||||
mTableFilterHeader.setAdaptiveChoices(true);
|
||||
|
||||
if(index >= 0)
|
||||
{
|
||||
int translatedIndex = mAliasTable.convertRowIndexToView(index);
|
||||
mAliasTable.setRowSelectionInterval(translatedIndex, translatedIndex);
|
||||
mAliasTable.scrollRectToVisible(
|
||||
new Rectangle(mAliasTable.getCellRect(translatedIndex, 0, true)));
|
||||
}
|
||||
}
|
||||
|
||||
private List<Alias> getSelectedAliases()
|
||||
{
|
||||
List<Alias> selected = new ArrayList<>();
|
||||
|
||||
int[] rows = mAliasTable.getSelectedRows();
|
||||
|
||||
for(int row : rows)
|
||||
{
|
||||
if(row >= 0)
|
||||
{
|
||||
Alias alias = mAliasModel.getAliasAtIndex(mAliasTable.convertRowIndexToModel(row));
|
||||
|
||||
if(alias != null)
|
||||
{
|
||||
selected.add(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to New, Copy and Delete Channel button invocations
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event)
|
||||
{
|
||||
switch(event.getActionCommand())
|
||||
{
|
||||
case NEW_ALIAS:
|
||||
addAlias(new Alias("New Alias"));
|
||||
break;
|
||||
case COPY_ALIAS:
|
||||
for(Alias alias : getSelectedAliases())
|
||||
{
|
||||
addAlias(AliasFactory.copyOf(alias));
|
||||
}
|
||||
break;
|
||||
case DELETE_ALIAS:
|
||||
List<Alias> toDelete = getSelectedAliases();
|
||||
|
||||
if(toDelete != null && !toDelete.isEmpty())
|
||||
{
|
||||
String title = toDelete.size() == 1 ? "Delete Alias?" : "Delete Aliases?";
|
||||
String prompt = toDelete.size() == 1 ? "Do you want to delete this alias?" :
|
||||
"Do you want to delete these " + toDelete.size() + " aliases?";
|
||||
|
||||
int choice = JOptionPane.showConfirmDialog(AliasController.this,
|
||||
prompt, title, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
|
||||
if(choice == JOptionPane.YES_OPTION)
|
||||
{
|
||||
for(Alias alias : toDelete)
|
||||
{
|
||||
mAliasModel.removeAlias(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorizes the cell based on the cell's integer value
|
||||
*/
|
||||
public class ColorCellRenderer extends DefaultTableCellRenderer
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table,
|
||||
Object value, boolean isSelected, boolean hasFocus, int row,
|
||||
int column)
|
||||
{
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(table,
|
||||
value, isSelected, hasFocus, row, column);
|
||||
|
||||
label.setBackground(new Color((int) value));
|
||||
|
||||
label.setText("");
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays cell's icon and name
|
||||
*/
|
||||
public class IconCellRenderer extends DefaultTableCellRenderer
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IconManager mIconManager;
|
||||
|
||||
public IconCellRenderer(IconManager iconManager)
|
||||
{
|
||||
mIconManager = iconManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table,
|
||||
Object value, boolean isSelected, boolean hasFocus, int row,
|
||||
int column)
|
||||
{
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(table,
|
||||
value, isSelected, hasFocus, row, column);
|
||||
|
||||
ImageIcon icon = mIconManager.getIcon(label.getText(), 12);
|
||||
|
||||
if(icon != null)
|
||||
{
|
||||
label.setIcon(icon);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import gui.editor.Editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JSeparator;
|
||||
|
||||
import icon.IconManager;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import sample.Listener;
|
||||
import settings.SettingsManager;
|
||||
import alias.action.AliasActionEditor;
|
||||
import alias.id.AliasIdentifierEditor;
|
||||
|
||||
import com.jidesoft.swing.JideTabbedPane;
|
||||
|
||||
public class AliasEditor extends Editor<Alias>
|
||||
implements ActionListener, Listener<AliasEvent>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String DEFAULT_NAME = "select an alias";
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
|
||||
private JLabel mAliasLabel;
|
||||
private AliasNameEditor mAliasNameEditor;
|
||||
private AliasIdentifierEditor mAliasIdentifierEditor;
|
||||
private AliasActionEditor mAliasActionEditor;
|
||||
|
||||
public AliasEditor(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager )
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mAliasNameEditor = new AliasNameEditor( mAliasModel, iconManager );
|
||||
mAliasIdentifierEditor = new AliasIdentifierEditor( aliasModel, broadcastModel );
|
||||
mAliasActionEditor = new AliasActionEditor( aliasModel );
|
||||
|
||||
mAliasModel.addListener( this );
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setItem( Alias alias )
|
||||
{
|
||||
super.setItem( alias );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
mAliasLabel.setText( getItem().getName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mAliasLabel.setText( DEFAULT_NAME );
|
||||
}
|
||||
|
||||
mAliasNameEditor.setItem( alias );
|
||||
mAliasIdentifierEditor.setItem( alias );
|
||||
mAliasActionEditor.setItem( alias );
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[grow,fill][grow,fill]",
|
||||
"[][][][][][grow,fill]" ) );
|
||||
|
||||
add( new JLabel( "Alias:" ), "align right" );
|
||||
mAliasLabel = new JLabel( DEFAULT_NAME );
|
||||
add( mAliasLabel, "align left" );
|
||||
|
||||
add( new JSeparator( JSeparator.HORIZONTAL ), "span,growx,push" );
|
||||
|
||||
JideTabbedPane tabs = new JideTabbedPane();
|
||||
tabs.setFont( this.getFont() );
|
||||
tabs.setForeground( Color.BLACK );
|
||||
|
||||
tabs.addTab( "Alias", mAliasNameEditor );
|
||||
tabs.addTab( "Audio / Identifier", mAliasIdentifierEditor );
|
||||
tabs.addTab( "Action", mAliasActionEditor );
|
||||
add( tabs, "span,grow" );
|
||||
|
||||
//Playlist management buttons
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.setToolTipText( "Save alias changes to the playlist" );
|
||||
btnSave.addActionListener( AliasEditor.this );
|
||||
add( btnSave );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.setToolTipText( "Reset alias changes since last save" );
|
||||
btnReset.addActionListener( AliasEditor.this );
|
||||
add( btnReset, "wrap" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( AliasEvent event )
|
||||
{
|
||||
//If this is the currently displayed alias, reload it
|
||||
if( hasItem() && getItem() == event.getAlias() )
|
||||
{
|
||||
switch( event.getEvent() )
|
||||
{
|
||||
case CHANGE:
|
||||
//Alias changed - reset the editor with changed alias
|
||||
setItem( event.getAlias() );
|
||||
break;
|
||||
case DELETE:
|
||||
setItem( null );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
if( hasItem() )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
{
|
||||
save();
|
||||
}
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
{
|
||||
reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
mAliasNameEditor.save();
|
||||
mAliasIdentifierEditor.save();
|
||||
mAliasActionEditor.save();
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
public class AliasEvent
|
||||
{
|
||||
private Alias mAlias;
|
||||
private Event mEvent;
|
||||
|
||||
/**
|
||||
* AliasEvent - event describing any changes to an alias
|
||||
* @param alias - alias that changed
|
||||
* @param event - change event
|
||||
*/
|
||||
public AliasEvent( Alias alias, Event event )
|
||||
{
|
||||
mAlias = alias;
|
||||
mEvent = event;
|
||||
}
|
||||
|
||||
public Alias getAlias()
|
||||
{
|
||||
return mAlias;
|
||||
}
|
||||
|
||||
public Event getEvent()
|
||||
{
|
||||
return mEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel events to describe the specific event
|
||||
*/
|
||||
public enum Event
|
||||
{
|
||||
ADD,
|
||||
CHANGE,
|
||||
DELETE;
|
||||
}
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import alias.action.AliasAction;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.beep.BeepAction;
|
||||
import alias.action.beep.BeepActionEditor;
|
||||
import alias.action.clip.ClipAction;
|
||||
import alias.action.clip.ClipActionEditor;
|
||||
import alias.action.script.ScriptAction;
|
||||
import alias.action.script.ScriptActionEditor;
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import alias.id.broadcast.BroadcastChannelEditor;
|
||||
import alias.id.esn.ESNEditor;
|
||||
import alias.id.esn.Esn;
|
||||
import alias.id.fleetsync.FleetsyncID;
|
||||
import alias.id.fleetsync.FleetsyncIDEditor;
|
||||
import alias.id.lojack.LoJackFunctionAndID;
|
||||
import alias.id.lojack.LoJackIDEditor;
|
||||
import alias.id.mdc.MDC1200ID;
|
||||
import alias.id.mdc.MDC1200IDEditor;
|
||||
import alias.id.mobileID.MINEditor;
|
||||
import alias.id.mobileID.Min;
|
||||
import alias.id.mpt1327.MPT1327ID;
|
||||
import alias.id.mpt1327.MPT1327IDEditor;
|
||||
import alias.id.nonrecordable.NonRecordable;
|
||||
import alias.id.nonrecordable.NonRecordableEditor;
|
||||
import alias.id.priority.Priority;
|
||||
import alias.id.priority.PriorityEditor;
|
||||
import alias.id.siteID.SiteID;
|
||||
import alias.id.siteID.SiteIDEditor;
|
||||
import alias.id.status.StatusID;
|
||||
import alias.id.status.StatusIDEditor;
|
||||
import alias.id.talkgroup.TalkgroupID;
|
||||
import alias.id.talkgroup.TalkgroupIDEditor;
|
||||
import alias.id.uniqueID.UniqueID;
|
||||
import alias.id.uniqueID.UniqueIDEditor;
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import gui.editor.Editor;
|
||||
import gui.editor.EmptyEditor;
|
||||
|
||||
public class AliasFactory
|
||||
{
|
||||
public static AliasID copyOf( AliasID id )
|
||||
{
|
||||
switch( id.getType() )
|
||||
{
|
||||
case BROADCAST_CHANNEL:
|
||||
BroadcastChannel originalBroadcast = (BroadcastChannel)id;
|
||||
BroadcastChannel copyBroadcast = new BroadcastChannel();
|
||||
copyBroadcast.setChannelName(originalBroadcast.getChannelName());
|
||||
return copyBroadcast;
|
||||
case ESN:
|
||||
Esn originalESN = (Esn)id;
|
||||
Esn copyESN = new Esn();
|
||||
copyESN.setEsn( originalESN.getEsn() );
|
||||
return copyESN;
|
||||
case FLEETSYNC:
|
||||
FleetsyncID originalFleetsyncID = (FleetsyncID)id;
|
||||
FleetsyncID copyFleetsyncID = new FleetsyncID();
|
||||
copyFleetsyncID.setIdent( originalFleetsyncID.getIdent() );
|
||||
return copyFleetsyncID;
|
||||
case LTR_NET_UID:
|
||||
UniqueID originalUniqueID = (UniqueID)id;
|
||||
UniqueID copyUniqueID = new UniqueID();
|
||||
copyUniqueID.setUid( originalUniqueID.getUid() );
|
||||
return copyUniqueID;
|
||||
case LOJACK:
|
||||
LoJackFunctionAndID originalLoJackFunctionAndID = (LoJackFunctionAndID)id;
|
||||
LoJackFunctionAndID copyLoJackFunctionAndID = new LoJackFunctionAndID();
|
||||
copyLoJackFunctionAndID.setFunction( originalLoJackFunctionAndID.getFunction() );
|
||||
copyLoJackFunctionAndID.setID( originalLoJackFunctionAndID.getID() );
|
||||
return copyLoJackFunctionAndID;
|
||||
case MDC1200:
|
||||
MDC1200ID originalMDC1200ID = (MDC1200ID)id;
|
||||
MDC1200ID copyMDC1200ID = new MDC1200ID();
|
||||
copyMDC1200ID.setIdent( originalMDC1200ID.getIdent() );
|
||||
return copyMDC1200ID;
|
||||
case MIN:
|
||||
Min originalMin = (Min)id;
|
||||
Min copyMin = new Min();
|
||||
copyMin.setMin( originalMin.getMin() );
|
||||
return copyMin;
|
||||
case MPT1327:
|
||||
MPT1327ID originalMPT1327ID = (MPT1327ID)id;
|
||||
MPT1327ID copyMPT1327ID = new MPT1327ID();
|
||||
copyMPT1327ID.setIdent( originalMPT1327ID.getIdent() );
|
||||
return copyMPT1327ID;
|
||||
case NON_RECORDABLE:
|
||||
return new NonRecordable();
|
||||
case PRIORITY:
|
||||
Priority originalPriority = (Priority)id;
|
||||
Priority copyPriority = new Priority();
|
||||
copyPriority.setPriority( originalPriority.getPriority() );
|
||||
return copyPriority;
|
||||
case SITE:
|
||||
SiteID originalSiteID = (SiteID)id;
|
||||
SiteID copySiteID = new SiteID();
|
||||
copySiteID.setSite( originalSiteID.getSite() );
|
||||
return copySiteID;
|
||||
case TALKGROUP:
|
||||
TalkgroupID originalTalkgroupID = (TalkgroupID)id;
|
||||
TalkgroupID copyTalkgroupID = new TalkgroupID();
|
||||
copyTalkgroupID.setTalkgroup( originalTalkgroupID.getTalkgroup() );
|
||||
return copyTalkgroupID;
|
||||
case STATUS:
|
||||
StatusID originalStatusID = (StatusID)id;
|
||||
StatusID copyStatusID = new StatusID();
|
||||
copyStatusID.setStatus( originalStatusID.getStatus() );
|
||||
return copyStatusID;
|
||||
default:
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static AliasAction copyOf( AliasAction action )
|
||||
{
|
||||
if( action instanceof BeepAction )
|
||||
{
|
||||
return new BeepAction();
|
||||
}
|
||||
else if( action instanceof ClipAction )
|
||||
{
|
||||
ClipAction originalClip = (ClipAction)action;
|
||||
ClipAction copyClip = new ClipAction();
|
||||
copyClip.setInterval( originalClip.getInterval() );
|
||||
copyClip.setPath( originalClip.getPath() );
|
||||
copyClip.setPeriod( originalClip.getPeriod() );
|
||||
return copyClip;
|
||||
}
|
||||
else if( action instanceof ScriptAction )
|
||||
{
|
||||
ScriptAction originalScript = (ScriptAction)action;
|
||||
ScriptAction copyScript = new ScriptAction();
|
||||
copyScript.setInterval( originalScript.getInterval() );
|
||||
copyScript.setPeriod( originalScript.getPeriod() );
|
||||
copyScript.setScript( originalScript.getScript() );
|
||||
return copyScript;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Alias copyOf( Alias original )
|
||||
{
|
||||
Alias copy = new Alias( original.getName() );
|
||||
copy.setList( original.getList() );
|
||||
copy.setGroup( original.getGroup() );
|
||||
copy.setColor( original.getColor() );
|
||||
copy.setIconName( original.getIconName() );
|
||||
|
||||
for( AliasID id: original.getId() )
|
||||
{
|
||||
AliasID copyID = copyOf( id );
|
||||
|
||||
if( copyID != null )
|
||||
{
|
||||
copy.addAliasID( copyID );
|
||||
}
|
||||
}
|
||||
|
||||
for( AliasAction action: original.getAction() )
|
||||
{
|
||||
AliasAction copyAction = copyOf( action );
|
||||
|
||||
if( copyAction != null )
|
||||
{
|
||||
copy.addAliasAction( copyAction );
|
||||
}
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
public static Editor<AliasID> getEditor( AliasID aliasID, BroadcastModel broadcastModel )
|
||||
{
|
||||
if( aliasID != null )
|
||||
{
|
||||
switch( aliasID.getType() )
|
||||
{
|
||||
case BROADCAST_CHANNEL:
|
||||
return new BroadcastChannelEditor(aliasID, broadcastModel);
|
||||
case ESN:
|
||||
return new ESNEditor( aliasID );
|
||||
case FLEETSYNC:
|
||||
return new FleetsyncIDEditor( aliasID );
|
||||
case LTR_NET_UID:
|
||||
return new UniqueIDEditor( aliasID );
|
||||
case LOJACK:
|
||||
return new LoJackIDEditor( aliasID );
|
||||
case MDC1200:
|
||||
return new MDC1200IDEditor( aliasID );
|
||||
case MIN:
|
||||
return new MINEditor( aliasID );
|
||||
case MPT1327:
|
||||
return new MPT1327IDEditor( aliasID );
|
||||
case NON_RECORDABLE:
|
||||
return new NonRecordableEditor( aliasID );
|
||||
case PRIORITY:
|
||||
return new PriorityEditor( aliasID );
|
||||
case SITE:
|
||||
return new SiteIDEditor( aliasID );
|
||||
case STATUS:
|
||||
return new StatusIDEditor( aliasID );
|
||||
case TALKGROUP:
|
||||
return new TalkgroupIDEditor( aliasID );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new EmptyEditor<AliasID>();
|
||||
}
|
||||
|
||||
public static Editor<AliasAction> getEditor( AliasAction aliasAction )
|
||||
{
|
||||
if( aliasAction != null )
|
||||
{
|
||||
switch( aliasAction.getType() )
|
||||
{
|
||||
case BEEP:
|
||||
return new BeepActionEditor( aliasAction );
|
||||
case CLIP:
|
||||
return new ClipActionEditor( aliasAction );
|
||||
case SCRIPT:
|
||||
return new ScriptActionEditor( aliasAction );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new EmptyEditor<AliasAction>();
|
||||
}
|
||||
|
||||
public static AliasID getAliasID( AliasIDType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case BROADCAST_CHANNEL:
|
||||
return new BroadcastChannel();
|
||||
case ESN:
|
||||
return new Esn();
|
||||
case FLEETSYNC:
|
||||
return new FleetsyncID();
|
||||
case LTR_NET_UID:
|
||||
return new UniqueID();
|
||||
case LOJACK:
|
||||
return new LoJackFunctionAndID();
|
||||
case MDC1200:
|
||||
return new MDC1200ID();
|
||||
case MIN:
|
||||
return new Min();
|
||||
case MPT1327:
|
||||
return new MPT1327ID();
|
||||
case NON_RECORDABLE:
|
||||
return new NonRecordable();
|
||||
case PRIORITY:
|
||||
return new Priority();
|
||||
case SITE:
|
||||
return new SiteID();
|
||||
case STATUS:
|
||||
return new StatusID();
|
||||
case TALKGROUP:
|
||||
return new TalkgroupID();
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unrecognized Alias ID type: " + type );
|
||||
}
|
||||
}
|
||||
|
||||
public static AliasAction getAliasAction( AliasActionType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case BEEP:
|
||||
return new BeepAction();
|
||||
case CLIP:
|
||||
return new ClipAction();
|
||||
case SCRIPT:
|
||||
return new ScriptAction();
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unrecognized Alias Action type: " + type );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,677 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.WildcardID;
|
||||
import alias.id.esn.Esn;
|
||||
import alias.id.fleetsync.FleetsyncID;
|
||||
import alias.id.lojack.LoJackFunctionAndID;
|
||||
import alias.id.mdc.MDC1200ID;
|
||||
import alias.id.mobileID.Min;
|
||||
import alias.id.mpt1327.MPT1327ID;
|
||||
import alias.id.siteID.SiteID;
|
||||
import alias.id.status.StatusID;
|
||||
import alias.id.talkgroup.TalkgroupID;
|
||||
import alias.id.uniqueID.UniqueID;
|
||||
import module.decode.lj1200.LJ1200Message.Function;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sample.Listener;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AliasList implements Listener<AliasEvent>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(AliasList.class);
|
||||
public static final String WILDCARD = "*";
|
||||
public static final String REGEX_WILDCARD = ".";
|
||||
|
||||
private Map<String,Alias> mESN = new HashMap<>();
|
||||
private Map<String,Alias> mFleetsync = new HashMap<>();
|
||||
private Map<LoJackFunctionAndID,Alias> mLoJack = new HashMap<>();
|
||||
private Map<String,Alias> mMDC1200 = new HashMap<>();
|
||||
private Map<String,Alias> mMobileID = new HashMap<>();
|
||||
private Map<String,Alias> mMPT1327 = new HashMap<>();
|
||||
private Map<String,Alias> mSiteID = new HashMap<>();
|
||||
private Map<Integer,Alias> mStatus = new HashMap<>();
|
||||
private Map<String,Alias> mTalkgroup = new HashMap<>();
|
||||
private Map<Integer,Alias> mUniqueID = new HashMap<>();
|
||||
|
||||
private List<WildcardID> mESNWildcards = new ArrayList<>();
|
||||
private List<WildcardID> mMobileIDWildcards = new ArrayList<>();
|
||||
private List<WildcardID> mFleetsyncWildcards = new ArrayList<>();
|
||||
private List<WildcardID> mMDC1200Wildcards = new ArrayList<>();
|
||||
private List<WildcardID> mMPT1327Wildcards = new ArrayList<>();
|
||||
private List<WildcardID> mSiteWildcards = new ArrayList<>();
|
||||
private List<WildcardID> mTalkgroupWildcards = new ArrayList<>();
|
||||
|
||||
private String mName;
|
||||
|
||||
/**
|
||||
* List of aliases where all aliases share the same list name. Contains
|
||||
* several methods for alias lookup from identifier values, like talkgroups.
|
||||
*
|
||||
* Responds to alias change events to keep the internal alias list updated.
|
||||
*/
|
||||
public AliasList(String name)
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the alias to this list
|
||||
*/
|
||||
public void addAlias(Alias alias)
|
||||
{
|
||||
if(alias != null)
|
||||
{
|
||||
for(AliasID aliasID : alias.getId())
|
||||
{
|
||||
addAliasID(aliasID, alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the alias and alias identifier to the internal type mapping.
|
||||
*/
|
||||
private void addAliasID(AliasID id, Alias alias)
|
||||
{
|
||||
if(id.isValid())
|
||||
{
|
||||
try
|
||||
{
|
||||
switch(id.getType())
|
||||
{
|
||||
case ESN:
|
||||
String esn = ((Esn) id).getEsn();
|
||||
|
||||
if(esn != null)
|
||||
{
|
||||
if(esn.contains(WILDCARD))
|
||||
{
|
||||
mESNWildcards.add(new WildcardID(esn));
|
||||
Collections.sort(mESNWildcards);
|
||||
}
|
||||
|
||||
mESN.put(esn, alias);
|
||||
}
|
||||
break;
|
||||
case FLEETSYNC:
|
||||
String fleetsync = ((FleetsyncID) id).getIdent();
|
||||
|
||||
if(fleetsync != null)
|
||||
{
|
||||
if(fleetsync.contains(WILDCARD))
|
||||
{
|
||||
mFleetsyncWildcards.add(new WildcardID(fleetsync));
|
||||
Collections.sort(mFleetsyncWildcards);
|
||||
}
|
||||
|
||||
mFleetsync.put(fleetsync, alias);
|
||||
}
|
||||
break;
|
||||
case LOJACK:
|
||||
mLoJack.put((LoJackFunctionAndID) id, alias);
|
||||
break;
|
||||
case MDC1200:
|
||||
String mdc = ((MDC1200ID) id).getIdent();
|
||||
|
||||
if(mdc != null)
|
||||
{
|
||||
if(mdc.contains(WILDCARD))
|
||||
{
|
||||
mMDC1200Wildcards.add(new WildcardID(mdc));
|
||||
Collections.sort(mMDC1200Wildcards);
|
||||
}
|
||||
|
||||
mMDC1200.put(mdc, alias);
|
||||
}
|
||||
break;
|
||||
case MPT1327:
|
||||
String mpt = ((MPT1327ID) id).getIdent();
|
||||
|
||||
if(mpt != null)
|
||||
{
|
||||
if(mpt.contains(WILDCARD))
|
||||
{
|
||||
mMPT1327Wildcards.add(new WildcardID(mpt));
|
||||
Collections.sort(mMPT1327Wildcards);
|
||||
}
|
||||
|
||||
mMPT1327.put(mpt, alias);
|
||||
}
|
||||
break;
|
||||
case MIN:
|
||||
String min = ((Min) id).getMin();
|
||||
|
||||
if(min != null)
|
||||
{
|
||||
if(min.contains(WILDCARD))
|
||||
{
|
||||
mMobileIDWildcards.add(new WildcardID(min));
|
||||
Collections.sort(mMobileIDWildcards);
|
||||
}
|
||||
|
||||
mMobileID.put(min, alias);
|
||||
}
|
||||
break;
|
||||
case LTR_NET_UID:
|
||||
mUniqueID.put(((UniqueID) id).getUid(), alias);
|
||||
break;
|
||||
case SITE:
|
||||
String siteID = ((SiteID) id).getSite();
|
||||
|
||||
if(siteID != null)
|
||||
{
|
||||
if(siteID.contains(WILDCARD))
|
||||
{
|
||||
mSiteWildcards.add(new WildcardID(siteID));
|
||||
Collections.sort(mSiteWildcards);
|
||||
}
|
||||
|
||||
mSiteID.put(siteID, alias);
|
||||
}
|
||||
break;
|
||||
case STATUS:
|
||||
mStatus.put(((StatusID) id).getStatus(), alias);
|
||||
break;
|
||||
case TALKGROUP:
|
||||
String tgid = ((TalkgroupID) id).getTalkgroup();
|
||||
|
||||
if(tgid != null)
|
||||
{
|
||||
if(tgid.contains(WILDCARD))
|
||||
{
|
||||
mTalkgroupWildcards.add(new WildcardID(tgid));
|
||||
Collections.sort(mTalkgroupWildcards);
|
||||
}
|
||||
|
||||
mTalkgroup.put(tgid, alias);
|
||||
}
|
||||
break;
|
||||
case BROADCAST_CHANNEL:
|
||||
case NON_RECORDABLE:
|
||||
case PRIORITY:
|
||||
//We don't maintain lookups for these items
|
||||
break;
|
||||
default:
|
||||
mLog.warn("Unrecognized Alias ID Type:" + id.getType().name() + " - can't ADD to lookup table");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
mLog.error("Couldn't add alias ID " + id + " for alias " + alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the alias from this list
|
||||
*/
|
||||
public void removeAlias(Alias alias)
|
||||
{
|
||||
if(alias != null)
|
||||
{
|
||||
for(AliasID aliasID : alias.getId())
|
||||
{
|
||||
removeAliasID(aliasID, alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeWildcard(String value, List<WildcardID> wildcards)
|
||||
{
|
||||
if(value != null)
|
||||
{
|
||||
for(WildcardID wildcardID : wildcards)
|
||||
{
|
||||
if(wildcardID.value().equals(value))
|
||||
{
|
||||
wildcards.remove(wildcardID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the alias and alias identifier from internal mappings.
|
||||
*/
|
||||
private void removeAliasID(AliasID id, Alias alias)
|
||||
{
|
||||
if(id.isValid())
|
||||
{
|
||||
switch(id.getType())
|
||||
{
|
||||
case ESN:
|
||||
String esn = ((Esn) id).getEsn();
|
||||
|
||||
if(esn != null)
|
||||
{
|
||||
if(esn.contains(WILDCARD))
|
||||
{
|
||||
removeWildcard(esn, mESNWildcards);
|
||||
}
|
||||
}
|
||||
|
||||
mESN.remove(esn);
|
||||
break;
|
||||
case FLEETSYNC:
|
||||
String fleetsync = ((FleetsyncID) id).getIdent();
|
||||
|
||||
if(fleetsync != null)
|
||||
{
|
||||
if(fleetsync.contains(WILDCARD))
|
||||
{
|
||||
removeWildcard(fleetsync, mFleetsyncWildcards);
|
||||
}
|
||||
|
||||
mFleetsync.remove(fleetsync);
|
||||
}
|
||||
break;
|
||||
case LOJACK:
|
||||
mLoJack.remove((LoJackFunctionAndID) id);
|
||||
break;
|
||||
case MDC1200:
|
||||
String mdc = ((MDC1200ID) id).getIdent();
|
||||
|
||||
if(mdc != null)
|
||||
{
|
||||
if(mdc.contains(WILDCARD))
|
||||
{
|
||||
removeWildcard(mdc, mMDC1200Wildcards);
|
||||
}
|
||||
|
||||
mMDC1200.remove(mdc);
|
||||
}
|
||||
break;
|
||||
case MPT1327:
|
||||
String mpt = ((MPT1327ID) id).getIdent();
|
||||
|
||||
if(mpt != null)
|
||||
{
|
||||
if(mpt.contains(WILDCARD))
|
||||
{
|
||||
removeWildcard(mpt, mMPT1327Wildcards);
|
||||
}
|
||||
|
||||
mMPT1327.remove(mpt);
|
||||
}
|
||||
break;
|
||||
case MIN:
|
||||
String min = ((Min) id).getMin();
|
||||
|
||||
if(min != null)
|
||||
{
|
||||
if(min.contains(WILDCARD))
|
||||
{
|
||||
removeWildcard(min, mMobileIDWildcards);
|
||||
}
|
||||
|
||||
mMobileID.remove(min);
|
||||
}
|
||||
break;
|
||||
case LTR_NET_UID:
|
||||
mUniqueID.remove(((UniqueID) id).getUid());
|
||||
break;
|
||||
case SITE:
|
||||
mSiteID.remove(((SiteID) id).getSite());
|
||||
break;
|
||||
case STATUS:
|
||||
mStatus.remove(((StatusID) id).getStatus());
|
||||
break;
|
||||
case TALKGROUP:
|
||||
String tgid = ((TalkgroupID) id).getTalkgroup();
|
||||
|
||||
if(tgid != null)
|
||||
{
|
||||
if(tgid.contains(WILDCARD))
|
||||
{
|
||||
removeWildcard(tgid, mTalkgroupWildcards);
|
||||
}
|
||||
|
||||
mTalkgroup.remove(tgid);
|
||||
}
|
||||
break;
|
||||
case NON_RECORDABLE:
|
||||
case PRIORITY:
|
||||
case BROADCAST_CHANNEL:
|
||||
//We don't maintain lookups for these items
|
||||
break;
|
||||
default:
|
||||
mLog.warn("Unrecognized Alias ID Type:" + id.getType().name() + " - can't REMOVE from lookup table");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first matching regex wildcard from the list of wildcards that matches the
|
||||
* identifier.
|
||||
*
|
||||
* @param id to match
|
||||
* @param wildcards to match against
|
||||
* @return matching wildcard ID or null
|
||||
*/
|
||||
private String getWildcardMatch(String id, List<WildcardID> wildcards)
|
||||
{
|
||||
if(id != null)
|
||||
{
|
||||
for(WildcardID wildcard : wildcards)
|
||||
{
|
||||
if(wildcard.matches(id))
|
||||
{
|
||||
return wildcard.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by site ID
|
||||
*/
|
||||
public Alias getSiteID(String siteID)
|
||||
{
|
||||
Alias alias = null;
|
||||
|
||||
if(siteID != null)
|
||||
{
|
||||
alias = mSiteID.get(siteID);
|
||||
|
||||
if(alias == null)
|
||||
{
|
||||
String wildcard = getWildcardMatch(siteID, mSiteWildcards);
|
||||
|
||||
if(wildcard != null)
|
||||
{
|
||||
alias = mSiteID.get(wildcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by status ID
|
||||
*/
|
||||
public Alias getStatus(int status)
|
||||
{
|
||||
return mStatus.get(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by Unique ID (UID)
|
||||
*/
|
||||
public Alias getUniqueID(int uniqueID)
|
||||
{
|
||||
return mUniqueID.get(uniqueID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by ESN
|
||||
*/
|
||||
public Alias getESNAlias(String esn)
|
||||
{
|
||||
Alias alias = null;
|
||||
|
||||
if(esn != null)
|
||||
{
|
||||
alias = mESN.get(esn);
|
||||
|
||||
if(alias == null)
|
||||
{
|
||||
String wildcard = getWildcardMatch(esn, mESNWildcards);
|
||||
|
||||
if(wildcard != null)
|
||||
{
|
||||
alias = mESN.get(wildcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by fleetsync ID
|
||||
*/
|
||||
public Alias getFleetsyncAlias(String ident)
|
||||
{
|
||||
Alias alias = null;
|
||||
|
||||
if(ident != null)
|
||||
{
|
||||
alias = mFleetsync.get(ident);
|
||||
|
||||
if(alias == null)
|
||||
{
|
||||
String wildcard = getWildcardMatch(ident, mFleetsyncWildcards);
|
||||
|
||||
if(wildcard != null)
|
||||
{
|
||||
alias = mFleetsync.get(wildcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by lojack function and ID
|
||||
*/
|
||||
public Alias getLoJackAlias(Function function, String id)
|
||||
{
|
||||
if(id != null)
|
||||
{
|
||||
for(LoJackFunctionAndID lojack : mLoJack.keySet())
|
||||
{
|
||||
if(lojack.matches(function, id))
|
||||
{
|
||||
return mLoJack.get(lojack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by MDC1200 ID
|
||||
*/
|
||||
public Alias getMDC1200Alias(String ident)
|
||||
{
|
||||
Alias alias = null;
|
||||
|
||||
if(ident != null)
|
||||
{
|
||||
alias = mMDC1200.get(ident);
|
||||
|
||||
if(alias == null)
|
||||
{
|
||||
String wildcard = getWildcardMatch(ident, mMDC1200Wildcards);
|
||||
|
||||
if(wildcard != null)
|
||||
{
|
||||
alias = mMDC1200.get(wildcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by MPT1327 Ident
|
||||
*/
|
||||
public Alias getMPT1327Alias(String ident)
|
||||
{
|
||||
Alias alias = null;
|
||||
|
||||
if(ident != null)
|
||||
{
|
||||
alias = mMPT1327.get(ident);
|
||||
|
||||
if(alias == null)
|
||||
{
|
||||
String wildcard = getWildcardMatch(ident, mMPT1327Wildcards);
|
||||
|
||||
if(wildcard != null)
|
||||
{
|
||||
alias = mMPT1327.get(wildcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by Mobile ID Number (MIN)
|
||||
*/
|
||||
public Alias getMobileIDNumberAlias(String ident)
|
||||
{
|
||||
Alias alias = null;
|
||||
|
||||
if(ident != null)
|
||||
{
|
||||
alias = mMobileID.get(ident);
|
||||
|
||||
if(alias == null)
|
||||
{
|
||||
String wildcard = getWildcardMatch(ident, mMobileIDWildcards);
|
||||
|
||||
if(wildcard != null)
|
||||
{
|
||||
alias = mMobileID.get(wildcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by talkgroup
|
||||
*
|
||||
* @param tgid to use when searching for an alias
|
||||
* @param includeWildcards true if you want to additionally search for a matching alias that contains wildcard(s)
|
||||
* when there is not a direct match to the TGID.
|
||||
*/
|
||||
public Alias getTalkgroupAlias(String tgid, boolean includeWildcards)
|
||||
{
|
||||
Alias alias = null;
|
||||
|
||||
if(tgid != null)
|
||||
{
|
||||
alias = mTalkgroup.get(tgid);
|
||||
|
||||
if(alias == null && includeWildcards)
|
||||
{
|
||||
String wildcard = getWildcardMatch(tgid, mTalkgroupWildcards);
|
||||
|
||||
if(wildcard != null)
|
||||
{
|
||||
alias = mTalkgroup.get(wildcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup alias by talkgroup. Defaults to matching to wildcard talkgroups.
|
||||
*/
|
||||
public Alias getTalkgroupAlias(String tgid)
|
||||
{
|
||||
return getTalkgroupAlias(tgid, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias list name
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias list name
|
||||
*/
|
||||
@XmlAttribute
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this alias list has a non-null, non-empty name
|
||||
*/
|
||||
private boolean hasName()
|
||||
{
|
||||
return mName != null && !mName.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive alias change event notifications and modify this list accordingly
|
||||
*/
|
||||
@Override
|
||||
public void receive(AliasEvent event)
|
||||
{
|
||||
if(hasName())
|
||||
{
|
||||
Alias alias = event.getAlias();
|
||||
|
||||
switch(event.getEvent())
|
||||
{
|
||||
case ADD:
|
||||
if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList()))
|
||||
{
|
||||
addAlias(alias);
|
||||
}
|
||||
break;
|
||||
case CHANGE:
|
||||
if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList()))
|
||||
{
|
||||
addAlias(alias);
|
||||
}
|
||||
break;
|
||||
case DELETE:
|
||||
if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList()))
|
||||
{
|
||||
removeAlias(alias);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,350 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import alias.AliasEvent.Event;
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import sample.Broadcaster;
|
||||
import sample.Listener;
|
||||
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Alias Model
|
||||
*/
|
||||
public class AliasModel extends AbstractTableModel
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final int COLUMN_LIST = 0;
|
||||
public static final int COLUMN_GROUP = 1;
|
||||
public static final int COLUMN_NAME = 2;
|
||||
public static final int COLUMN_ICON = 3;
|
||||
public static final int COLUMN_COLOR = 4;
|
||||
|
||||
private List<Alias> mAliases = new CopyOnWriteArrayList<>();
|
||||
private Broadcaster<AliasEvent> mAliasEventBroadcaster = new Broadcaster<>();
|
||||
private Map<String,AliasList> mAliasListMap = new HashMap<>();
|
||||
|
||||
public AliasModel()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmodifiable list of all aliases currently in the model
|
||||
*/
|
||||
public List<Alias> getAliases()
|
||||
{
|
||||
return Collections.unmodifiableList(mAliases);
|
||||
}
|
||||
|
||||
public Alias getAliasAtIndex(int row)
|
||||
{
|
||||
if(mAliases.size() >= row)
|
||||
{
|
||||
return mAliases.get(row);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public AliasList getAliasList(String name)
|
||||
{
|
||||
if(name != null && mAliasListMap.containsKey(name))
|
||||
{
|
||||
return mAliasListMap.get(name);
|
||||
}
|
||||
|
||||
AliasList aliasList = new AliasList(name);
|
||||
|
||||
if(name != null)
|
||||
{
|
||||
for(Alias alias : mAliases)
|
||||
{
|
||||
if(alias.hasList() && alias.getList().equalsIgnoreCase(name))
|
||||
{
|
||||
aliasList.addAlias(alias);
|
||||
}
|
||||
}
|
||||
|
||||
mAliasListMap.put(name, aliasList);
|
||||
|
||||
//Register the new alias list to receive updates from this model
|
||||
addListener(aliasList);
|
||||
}
|
||||
|
||||
return aliasList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of unique alias list names from across the alias set
|
||||
*/
|
||||
public List<String> getListNames()
|
||||
{
|
||||
List<String> listNames = new ArrayList<>();
|
||||
|
||||
for(Alias alias : mAliases)
|
||||
{
|
||||
if(alias.hasList() && !listNames.contains(alias.getList()))
|
||||
{
|
||||
listNames.add(alias.getList());
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(listNames);
|
||||
|
||||
return listNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of alias group names for all aliases
|
||||
*/
|
||||
public List<String> getGroupNames()
|
||||
{
|
||||
List<String> groupNames = new ArrayList<>();
|
||||
|
||||
for(Alias alias : mAliases)
|
||||
{
|
||||
if(alias.hasGroup() && !groupNames.contains(alias.getGroup()))
|
||||
{
|
||||
groupNames.add(alias.getGroup());
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(groupNames);
|
||||
|
||||
return groupNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of alias group names for all aliases that have a matching
|
||||
* list name value
|
||||
*/
|
||||
public List<String> getGroupNames(String listName)
|
||||
{
|
||||
List<String> groupNames = new ArrayList<>();
|
||||
|
||||
if(listName != null)
|
||||
{
|
||||
for(Alias alias : mAliases)
|
||||
{
|
||||
if(alias.hasList() &&
|
||||
alias.hasGroup() &&
|
||||
listName.equals(alias.getList()) &&
|
||||
!groupNames.contains(alias.getGroup()))
|
||||
{
|
||||
groupNames.add(alias.getGroup());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(groupNames);
|
||||
|
||||
return groupNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk loading of aliases
|
||||
*/
|
||||
public void addAliases(List<Alias> aliases)
|
||||
{
|
||||
for(Alias alias : aliases)
|
||||
{
|
||||
addAlias(alias);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the alias to the model
|
||||
*/
|
||||
public int addAlias(Alias alias)
|
||||
{
|
||||
if(alias != null)
|
||||
{
|
||||
mAliases.add(alias);
|
||||
|
||||
int index = mAliases.size() - 1;
|
||||
|
||||
fireTableRowsInserted(index, index);
|
||||
|
||||
broadcast(new AliasEvent(alias, Event.ADD));
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the channel from the model and broadcasts a channel remove event
|
||||
*/
|
||||
public void removeAlias(Alias alias)
|
||||
{
|
||||
if(alias != null)
|
||||
{
|
||||
int index = mAliases.indexOf(alias);
|
||||
|
||||
mAliases.remove(alias);
|
||||
|
||||
fireTableRowsDeleted(index, index);
|
||||
|
||||
broadcast(new AliasEvent(alias, Event.DELETE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames any broadcast channels that have the previous name.
|
||||
*
|
||||
* @param previousName to rename
|
||||
* @param newName to assign to the broadcast channel
|
||||
*/
|
||||
public void renameBroadcastChannel(String previousName, String newName)
|
||||
{
|
||||
if(previousName == null || previousName.isEmpty() || newName == null || newName.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(Alias alias : mAliases)
|
||||
{
|
||||
if(alias.hasBroadcastChannel(previousName))
|
||||
{
|
||||
for(BroadcastChannel broadcastChannel : alias.getBroadcastChannels())
|
||||
{
|
||||
if(broadcastChannel.getChannelName().contentEquals(previousName))
|
||||
{
|
||||
broadcastChannel.setChannelName(newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount()
|
||||
{
|
||||
return mAliases.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int columnIndex)
|
||||
{
|
||||
switch(columnIndex)
|
||||
{
|
||||
case COLUMN_LIST:
|
||||
return "List";
|
||||
case COLUMN_GROUP:
|
||||
return "Group";
|
||||
case COLUMN_NAME:
|
||||
return "Name";
|
||||
case COLUMN_ICON:
|
||||
return "Icon";
|
||||
case COLUMN_COLOR:
|
||||
return "Color";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex)
|
||||
{
|
||||
if(columnIndex == COLUMN_COLOR)
|
||||
{
|
||||
return Integer.class;
|
||||
}
|
||||
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex)
|
||||
{
|
||||
Alias alias = mAliases.get(rowIndex);
|
||||
|
||||
switch(columnIndex)
|
||||
{
|
||||
case COLUMN_LIST:
|
||||
return alias.getList();
|
||||
case COLUMN_GROUP:
|
||||
return alias.getGroup();
|
||||
case COLUMN_NAME:
|
||||
return alias.getName();
|
||||
case COLUMN_ICON:
|
||||
return alias.getIconName();
|
||||
case COLUMN_COLOR:
|
||||
return alias.getColor();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex)
|
||||
{
|
||||
throw new IllegalArgumentException("Not yet implemented");
|
||||
}
|
||||
|
||||
public void broadcast(AliasEvent event)
|
||||
{
|
||||
Alias alias = event.getAlias();
|
||||
|
||||
//Validate the alias following a user action that changed the alias or any alias IDs
|
||||
if(alias != null)
|
||||
{
|
||||
alias.validate();
|
||||
}
|
||||
|
||||
if(event.getEvent() == Event.CHANGE)
|
||||
{
|
||||
int index = mAliases.indexOf(event.getAlias());
|
||||
|
||||
fireTableRowsUpdated(index, index);
|
||||
}
|
||||
|
||||
mAliasEventBroadcaster.broadcast(event);
|
||||
}
|
||||
|
||||
public void addListener(Listener<AliasEvent> listener)
|
||||
{
|
||||
mAliasEventBroadcaster.addListener(listener);
|
||||
}
|
||||
|
||||
public void removeListener(Listener<AliasEvent> listener)
|
||||
{
|
||||
mAliasEventBroadcaster.removeListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -1,334 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import alias.AliasEvent.Event;
|
||||
import gui.editor.Editor;
|
||||
import icon.Icon;
|
||||
import icon.IconListCellRenderer;
|
||||
import icon.IconManager;
|
||||
import icon.IconTableModel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
|
||||
public class AliasNameEditor extends Editor<Alias>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static ComboBoxModel<String> EMPTY_LIST_MODEL = new DefaultComboBoxModel<>();
|
||||
private static ComboBoxModel<String> EMPTY_GROUP_MODEL = new DefaultComboBoxModel<>();
|
||||
|
||||
private JComboBox<String> mListCombo = new JComboBox<>(EMPTY_LIST_MODEL);
|
||||
private JComboBox<String> mGroupCombo = new JComboBox<>(EMPTY_GROUP_MODEL);
|
||||
private JComboBox<Icon> mIconCombo;
|
||||
private JTextField mName;
|
||||
private JButton mButtonColor;
|
||||
private JButton mBtnIconManager;
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
private IconManager mIconManager;
|
||||
|
||||
public AliasNameEditor(AliasModel aliasModel, IconManager iconManager)
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mIconManager = iconManager;
|
||||
|
||||
mIconManager.getModel().addTableModelListener(new TableModelListener()
|
||||
{
|
||||
@Override
|
||||
public void tableChanged(TableModelEvent e)
|
||||
{
|
||||
refreshIcons();
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout(new MigLayout("fill,wrap 2", "[right][grow,fill]", "[][][][][][][grow]"));
|
||||
|
||||
add(new JLabel("Name:"));
|
||||
mName = new JTextField();
|
||||
mName.getDocument().addDocumentListener(new DocumentListener()
|
||||
{
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e)
|
||||
{
|
||||
}
|
||||
});
|
||||
add(mName, "wrap");
|
||||
|
||||
add(new JLabel("List:"));
|
||||
mListCombo.setEditable(true);
|
||||
mListCombo.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
if(mListCombo.getSelectedItem() != null)
|
||||
{
|
||||
List<String> groups = mAliasModel
|
||||
.getGroupNames((String) mListCombo.getSelectedItem());
|
||||
|
||||
if(groups.isEmpty())
|
||||
{
|
||||
mGroupCombo.setModel(EMPTY_GROUP_MODEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groups.toArray(new String[groups.size()])));
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mListCombo, "wrap");
|
||||
|
||||
add(new JLabel("Group:"));
|
||||
mGroupCombo.setEditable(true);
|
||||
mGroupCombo.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mGroupCombo, "wrap");
|
||||
|
||||
add(new JLabel("Color:"));
|
||||
|
||||
mButtonColor = new JButton("Select ...");
|
||||
mButtonColor.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
Color newColor = JColorChooser.showDialog(
|
||||
AliasNameEditor.this,
|
||||
"Choose color for this alias",
|
||||
(hasItem() ? getItem().getDisplayColor() : null));
|
||||
|
||||
if(newColor != null)
|
||||
{
|
||||
mButtonColor.setForeground(newColor);
|
||||
mButtonColor.setBackground(newColor);
|
||||
|
||||
setModified(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
add(mButtonColor, "wrap");
|
||||
|
||||
add(new JLabel("Icon:"));
|
||||
|
||||
mIconCombo = new JComboBox<Icon>(mIconManager.getIcons());
|
||||
|
||||
IconListCellRenderer renderer = new IconListCellRenderer(mIconManager);
|
||||
renderer.setPreferredSize(new Dimension(200, 30));
|
||||
mIconCombo.setRenderer(renderer);
|
||||
mIconCombo.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
|
||||
add(mIconCombo, "wrap");
|
||||
|
||||
//Dummy place holder
|
||||
add(new JLabel());
|
||||
|
||||
mBtnIconManager = new JButton("Icon Manager");
|
||||
mBtnIconManager.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
mIconManager.showEditor(AliasNameEditor.this);
|
||||
}
|
||||
});
|
||||
|
||||
add(mBtnIconManager, "span 2,wrap");
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
private void refreshIcons()
|
||||
{
|
||||
if(mIconCombo != null)
|
||||
{
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons()));
|
||||
|
||||
if(hasItem())
|
||||
{
|
||||
String iconName = getItem().getIconName();
|
||||
Icon aliasIcon = mIconManager.getModel().getIcon(iconName);
|
||||
|
||||
if(aliasIcon != null)
|
||||
{
|
||||
mIconCombo.setSelectedItem(aliasIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(Alias alias)
|
||||
{
|
||||
super.setItem(alias);
|
||||
|
||||
if(hasItem())
|
||||
{
|
||||
mName.setText(alias.getName());
|
||||
|
||||
mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons()));
|
||||
|
||||
List<String> listNames = mAliasModel.getListNames();
|
||||
|
||||
if(listNames.isEmpty())
|
||||
{
|
||||
mListCombo.setModel(EMPTY_LIST_MODEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
mListCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
listNames.toArray(new String[listNames.size()])));
|
||||
;
|
||||
}
|
||||
|
||||
mListCombo.setSelectedItem(alias.getList());
|
||||
|
||||
List<String> groupNames = mAliasModel.getGroupNames(alias.getList());
|
||||
|
||||
if(groupNames.isEmpty())
|
||||
{
|
||||
mGroupCombo.setModel(EMPTY_GROUP_MODEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groupNames.toArray(new String[groupNames.size()])));
|
||||
;
|
||||
}
|
||||
|
||||
mGroupCombo.setSelectedItem(alias.getGroup());
|
||||
|
||||
Color color = alias.getDisplayColor();
|
||||
|
||||
mButtonColor.setBackground(color);
|
||||
mButtonColor.setForeground(color);
|
||||
|
||||
String iconName = alias.getIconName();
|
||||
|
||||
if(iconName == null)
|
||||
{
|
||||
iconName = IconTableModel.DEFAULT_ICON;
|
||||
}
|
||||
|
||||
Icon savedIcon = mIconManager.getModel().getIcon(iconName);
|
||||
|
||||
if(savedIcon != null)
|
||||
{
|
||||
mIconCombo.setSelectedItem(savedIcon);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mListCombo.setModel(EMPTY_LIST_MODEL);
|
||||
mGroupCombo.setModel(EMPTY_GROUP_MODEL);
|
||||
mName.setText(null);
|
||||
|
||||
mButtonColor.setBackground(getBackground());
|
||||
mButtonColor.setForeground(getForeground());
|
||||
}
|
||||
|
||||
repaint();
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if(hasItem() && isModified())
|
||||
{
|
||||
Alias alias = getItem();
|
||||
|
||||
if(mListCombo.getSelectedItem() != null)
|
||||
{
|
||||
alias.setList((String) mListCombo.getSelectedItem());
|
||||
}
|
||||
|
||||
if(mGroupCombo.getSelectedItem() != null)
|
||||
{
|
||||
alias.setGroup((String) mGroupCombo.getSelectedItem());
|
||||
}
|
||||
|
||||
alias.setName(mName.getText());
|
||||
|
||||
alias.setColor(mButtonColor.getBackground().getRGB());
|
||||
|
||||
if(mIconCombo.getSelectedItem() != null)
|
||||
{
|
||||
alias.setIconName(((Icon) mIconCombo.getSelectedItem()).getName());
|
||||
}
|
||||
|
||||
setModified(false);
|
||||
|
||||
//Broadcast an alias change event to save the updates
|
||||
mAliasModel.broadcast(new AliasEvent(getItem(), Event.CHANGE));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
public abstract class ComponentEditor<T> extends JPanel implements DocumentListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private boolean mModified;
|
||||
private ComponentModificationListener mListener;
|
||||
protected T mComponent;
|
||||
|
||||
/**
|
||||
* Abstract class for editor with notifications when contents are modified
|
||||
* and methods for saving or resetting the component values with the
|
||||
* contents of the editor.
|
||||
*/
|
||||
public ComponentEditor( T component )
|
||||
{
|
||||
mComponent = component;
|
||||
}
|
||||
|
||||
public ComponentEditor()
|
||||
{
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mComponent = null;
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
public T getComponent()
|
||||
{
|
||||
return mComponent;
|
||||
}
|
||||
|
||||
protected void setModified( boolean modified )
|
||||
{
|
||||
mModified = modified;
|
||||
|
||||
if( modified && mListener != null )
|
||||
{
|
||||
mListener.componentModified();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the contents of the editor have been modified
|
||||
*/
|
||||
public boolean isModified()
|
||||
{
|
||||
return mModified;
|
||||
}
|
||||
|
||||
public void setComponentModificationListener( ComponentModificationListener listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or resets the editable component
|
||||
*/
|
||||
public abstract void setComponent( T t );
|
||||
|
||||
/**
|
||||
* Saves changed editor values to the component
|
||||
*/
|
||||
public abstract void save();
|
||||
|
||||
/**
|
||||
* Reloads the editor contents from the source component and resets the
|
||||
* modified flag
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
setComponent( getComponent() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate contents of other editors against this component editor before
|
||||
* saving. Override this method to allow controller to pass other editors
|
||||
* to this editor for content inspection/validation before indicating that
|
||||
* this editor passes validation. This allows for validating editor contents
|
||||
* that are contingent on settings in other editors.
|
||||
*
|
||||
* @throws ComponentValidationException if the contents of the editor
|
||||
* argument cannot be validated, with the exception containing a detailed
|
||||
* description of the issue.
|
||||
*/
|
||||
public void validate( ComponentEditor<?> editor ) throws ComponentValidationException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener interface to receive notification that the contents of the
|
||||
* editor have been modified from the original component value and either
|
||||
* need to be saved or reset
|
||||
*/
|
||||
public interface ComponentModificationListener
|
||||
{
|
||||
public void componentModified();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package alias;
|
||||
|
||||
public class ComponentValidationException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Component editor contents validation error
|
||||
*/
|
||||
public ComponentValidationException( String message )
|
||||
{
|
||||
super( message );
|
||||
}
|
||||
}
|
||||
@@ -1,467 +0,0 @@
|
||||
package alias;
|
||||
|
||||
import alias.AliasEvent.Event;
|
||||
import alias.id.AliasIDType;
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import alias.id.priority.Priority;
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import gui.editor.Editor;
|
||||
import icon.Icon;
|
||||
import icon.IconListCellRenderer;
|
||||
import icon.IconManager;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sample.Listener;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
|
||||
public class MultipleAliasEditor extends Editor<List<Alias>>
|
||||
implements Listener<AliasEvent>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger mLog = LoggerFactory.getLogger(MultipleAliasEditor.class);
|
||||
|
||||
private static String HELP_TEXT =
|
||||
"<html>Select attributes below to change for all selected aliases</html>";
|
||||
|
||||
private JLabel mAliasCountLabel;
|
||||
private JLabel mAliasCount;
|
||||
|
||||
private JCheckBox mListCheckBox = new JCheckBox("List");
|
||||
private JComboBox<String> mListCombo = new JComboBox<>();
|
||||
private JCheckBox mGroupCheckBox = new JCheckBox("Group");
|
||||
private JComboBox<String> mGroupCombo = new JComboBox<>();
|
||||
private JCheckBox mIconCheckBox = new JCheckBox("Icon");
|
||||
private JComboBox<Icon> mIconCombo;
|
||||
private JCheckBox mColorCheckBox = new JCheckBox("Color");
|
||||
private JButton mButtonColor;
|
||||
private JButton mBtnIconManager;
|
||||
private JCheckBox mRecordCheckBox = new JCheckBox("Record");
|
||||
private JComboBox<Record> mRecordActionCombo = new JComboBox<>(Record.values());
|
||||
private JCheckBox mPriorityCheckBox = new JCheckBox("Priority");
|
||||
private JSlider mPrioritySlider;
|
||||
private JLabel mPrioritySliderLabel;
|
||||
private JCheckBox mStreamCheckBox = new JCheckBox("Stream");
|
||||
private JComboBox<String> mStreamCombo;
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
private BroadcastModel mBroadcastModel;
|
||||
private IconManager mIconManager;
|
||||
|
||||
public MultipleAliasEditor(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager)
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mBroadcastModel = broadcastModel;
|
||||
mIconManager = iconManager;
|
||||
|
||||
mAliasModel.addListener(this);
|
||||
mIconManager.getModel().addTableModelListener(new TableModelListener()
|
||||
{
|
||||
@Override
|
||||
public void tableChanged(TableModelEvent e)
|
||||
{
|
||||
refreshIcons();
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
public List<Alias> getAliases()
|
||||
{
|
||||
if (hasItem())
|
||||
{
|
||||
return (List<Alias>) getItem();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
setLayout(new MigLayout("fill,wrap 2", "[grow,fill][grow,fill]",
|
||||
"[][][][][][][][][][][][][][grow,fill]"));
|
||||
|
||||
mAliasCountLabel = new JLabel("Alias:");
|
||||
add(mAliasCountLabel);
|
||||
|
||||
mAliasCount = new JLabel("Multiple");
|
||||
add(mAliasCount, "span");
|
||||
|
||||
add(new JSeparator(), "span");
|
||||
|
||||
add(new JLabel(HELP_TEXT), "span");
|
||||
|
||||
add(mListCheckBox);
|
||||
|
||||
mListCombo.setEditable(true);
|
||||
add(mListCombo, "wrap");
|
||||
|
||||
add(mGroupCheckBox);
|
||||
|
||||
mGroupCombo.setEditable(true);
|
||||
add(mGroupCombo, "wrap");
|
||||
|
||||
add(mColorCheckBox);
|
||||
|
||||
mButtonColor = new JButton("Select ...");
|
||||
mButtonColor.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
Color newColor = JColorChooser.showDialog(
|
||||
MultipleAliasEditor.this,
|
||||
"Choose color for this alias", null);
|
||||
|
||||
if (newColor != null)
|
||||
{
|
||||
mButtonColor.setForeground(newColor);
|
||||
mButtonColor.setBackground(newColor);
|
||||
}
|
||||
}
|
||||
});
|
||||
add(mButtonColor, "wrap");
|
||||
|
||||
add(mIconCheckBox);
|
||||
|
||||
mIconCombo = new JComboBox<Icon>(mIconManager.getIcons());
|
||||
|
||||
IconListCellRenderer renderer = new IconListCellRenderer(mIconManager);
|
||||
renderer.setPreferredSize(new Dimension(200, 30));
|
||||
mIconCombo.setRenderer(renderer);
|
||||
add(mIconCombo, "wrap");
|
||||
|
||||
//Dummy place holder
|
||||
add(new JLabel());
|
||||
|
||||
mBtnIconManager = new JButton("Icon Manager");
|
||||
mBtnIconManager.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
mIconManager.showEditor(MultipleAliasEditor.this);
|
||||
}
|
||||
});
|
||||
|
||||
add(mBtnIconManager, "span,wrap");
|
||||
|
||||
add(mRecordCheckBox);
|
||||
add(mRecordActionCombo);
|
||||
|
||||
//Placeholder
|
||||
add(new JLabel(" "));
|
||||
mPrioritySliderLabel = new JLabel("Audio Priority: " + Priority.MIN_PRIORITY);
|
||||
add(mPrioritySliderLabel);
|
||||
|
||||
add(mPriorityCheckBox);
|
||||
|
||||
mPrioritySlider = new JSlider(JSlider.HORIZONTAL,
|
||||
Priority.MIN_PRIORITY,
|
||||
Priority.MAX_PRIORITY + 1,
|
||||
Priority.MIN_PRIORITY);
|
||||
|
||||
mPrioritySlider.setMajorTickSpacing(20);
|
||||
mPrioritySlider.setMinorTickSpacing(5);
|
||||
mPrioritySlider.setPaintTicks(true);
|
||||
mPrioritySlider.setLabelTable(mPrioritySlider.createStandardLabels(25, 25));
|
||||
mPrioritySlider.setPaintLabels(true);
|
||||
mPrioritySlider.addChangeListener(new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e)
|
||||
{
|
||||
int priority = mPrioritySlider.getValue();
|
||||
|
||||
if (priority > Priority.MAX_PRIORITY)
|
||||
{
|
||||
mPrioritySliderLabel.setText("Audio Priority: Do Not Monitor");
|
||||
}
|
||||
else
|
||||
{
|
||||
mPrioritySliderLabel.setText("Audio Priority: " + mPrioritySlider.getValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
mPrioritySlider.setToolTipText(HELP_TEXT);
|
||||
|
||||
add(mPrioritySlider);
|
||||
|
||||
add(mStreamCheckBox);
|
||||
|
||||
mStreamCombo = new JComboBox<String>();
|
||||
mStreamCombo.setEditable(true);
|
||||
add(mStreamCombo, "wrap");
|
||||
|
||||
JButton saveButton = new JButton("Save");
|
||||
saveButton.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
save();
|
||||
}
|
||||
});
|
||||
add(saveButton);
|
||||
|
||||
JButton resetButton = new JButton("Reset");
|
||||
resetButton.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
});
|
||||
add(resetButton);
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
private void refreshIcons()
|
||||
{
|
||||
if(mIconCombo != null)
|
||||
{
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(List<Alias> item)
|
||||
{
|
||||
super.setItem(item);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Multiple Selected [ ");
|
||||
|
||||
if (hasItem())
|
||||
{
|
||||
sb.append(String.valueOf(getAliases().size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(" ]");
|
||||
|
||||
mAliasCount.setText(sb.toString());
|
||||
|
||||
List<String> listNames = mAliasModel.getListNames();
|
||||
listNames.add(0, "");
|
||||
mListCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
listNames.toArray(new String[listNames.size()])));
|
||||
|
||||
List<String> groupNames = mAliasModel.getGroupNames();
|
||||
groupNames.add(0, "");
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groupNames.toArray(new String[groupNames.size()])));
|
||||
|
||||
List<String> streamNames = mBroadcastModel.getBroadcastConfigurationNames();
|
||||
mStreamCombo.setModel(new DefaultComboBoxModel<String>(streamNames.toArray(new String[streamNames.size()])));
|
||||
|
||||
mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons()));
|
||||
|
||||
setCheckBoxesUnselected();
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
private void setCheckBoxesUnselected()
|
||||
{
|
||||
mListCheckBox.setSelected(false);
|
||||
mGroupCheckBox.setSelected(false);
|
||||
mColorCheckBox.setSelected(false);
|
||||
mIconCheckBox.setSelected(false);
|
||||
mRecordCheckBox.setSelected(false);
|
||||
mPriorityCheckBox.setSelected(false);
|
||||
mStreamCheckBox.setSelected(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
List<String> listNames = mAliasModel.getListNames();
|
||||
listNames.add(0, "");
|
||||
mListCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
listNames.toArray(new String[listNames.size()])));
|
||||
|
||||
List<String> groupNames = mAliasModel.getGroupNames();
|
||||
groupNames.add(0, "");
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groupNames.toArray(new String[groupNames.size()])));
|
||||
|
||||
mButtonColor.setForeground(getForeground());
|
||||
mButtonColor.setBackground(getBackground());
|
||||
|
||||
super.reset();
|
||||
}
|
||||
|
||||
private boolean hasRequestedChanges()
|
||||
{
|
||||
return mListCheckBox.isSelected() ||
|
||||
mGroupCheckBox.isSelected() ||
|
||||
mColorCheckBox.isSelected() ||
|
||||
mIconCheckBox.isSelected() ||
|
||||
mRecordCheckBox.isSelected() ||
|
||||
mPriorityCheckBox.isSelected() ||
|
||||
mStreamCheckBox.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if (hasRequestedChanges() && hasItem())
|
||||
{
|
||||
List<Alias> aliases = getAliases();
|
||||
|
||||
for (Alias alias : aliases)
|
||||
{
|
||||
if (mListCheckBox.isSelected())
|
||||
{
|
||||
String list = null;
|
||||
|
||||
if (mListCombo.getSelectedItem() != null)
|
||||
{
|
||||
list = (String) mListCombo.getSelectedItem();
|
||||
}
|
||||
|
||||
alias.setList(list);
|
||||
}
|
||||
|
||||
if (mGroupCheckBox.isSelected())
|
||||
{
|
||||
String group = null;
|
||||
|
||||
if (mGroupCombo.getSelectedItem() != null)
|
||||
{
|
||||
group = (String) mGroupCombo.getSelectedItem();
|
||||
}
|
||||
|
||||
alias.setGroup(group);
|
||||
}
|
||||
|
||||
if (mColorCheckBox.isSelected())
|
||||
{
|
||||
alias.setColor(mButtonColor.getForeground().getRGB());
|
||||
}
|
||||
|
||||
if (mIconCheckBox.isSelected())
|
||||
{
|
||||
if (mIconCombo.getSelectedItem() != null)
|
||||
{
|
||||
alias.setIconName(((Icon)mIconCombo.getSelectedItem()).getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
alias.setIconName(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (mRecordCheckBox.isSelected())
|
||||
{
|
||||
Record action =
|
||||
(Record) mRecordActionCombo.getSelectedItem();
|
||||
|
||||
alias.setRecordable(action == Record.RECORDABLE);
|
||||
}
|
||||
|
||||
if (mPriorityCheckBox.isSelected())
|
||||
{
|
||||
int priority = mPrioritySlider.getValue();
|
||||
|
||||
//This is a work-around -- we use max priority + 1 in the
|
||||
//gui to indicate do not monitor, and change the value here
|
||||
if (priority == Priority.MAX_PRIORITY + 1)
|
||||
{
|
||||
priority = Priority.DO_NOT_MONITOR;
|
||||
}
|
||||
|
||||
alias.setCallPriority(priority);
|
||||
}
|
||||
|
||||
if(mStreamCheckBox.isSelected())
|
||||
{
|
||||
if(mStreamCombo.getSelectedItem() != null)
|
||||
{
|
||||
String streamName = (String)mStreamCombo.getSelectedItem();
|
||||
|
||||
boolean hasChannel = false;
|
||||
|
||||
//Ensure the alias doesn't already have the channel
|
||||
for(BroadcastChannel channel: alias.getBroadcastChannels())
|
||||
{
|
||||
if(channel.getChannelName().equals(streamName))
|
||||
{
|
||||
hasChannel = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(!hasChannel)
|
||||
{
|
||||
BroadcastChannel channel = (BroadcastChannel)AliasFactory
|
||||
.getAliasID(AliasIDType.BROADCAST_CHANNEL);
|
||||
|
||||
channel.setChannelName(streamName);
|
||||
alias.addAliasID(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Alias alias : aliases)
|
||||
{
|
||||
//Broadcast an alias change event to save the updates
|
||||
mAliasModel.broadcast(new AliasEvent(alias, Event.CHANGE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(AliasEvent event)
|
||||
{
|
||||
if (event.getEvent() == Event.DELETE &&
|
||||
hasItem() &&
|
||||
getAliases().contains(event.getAlias()))
|
||||
{
|
||||
getAliases().remove(event.getAlias());
|
||||
setItem(getAliases());
|
||||
}
|
||||
}
|
||||
|
||||
public enum Record
|
||||
{
|
||||
NON_RECORDABLE("Non-Recordable"),
|
||||
RECORDABLE("Recordable");
|
||||
|
||||
private String mLabel;
|
||||
|
||||
private Record(String label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,381 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import alias.action.AliasAction;
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import alias.id.priority.Priority;
|
||||
import alias.id.talkgroup.TalkgroupID;
|
||||
import gui.SDRTrunk;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import playlist.version1.System;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class PatchGroupAlias extends Alias
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(PatchGroupAlias.class);
|
||||
|
||||
private Alias mPatchGroupAlias;
|
||||
private List<Alias> mPatchedAliases = new ArrayList<>();
|
||||
private List<String> mPatchedTalkgroupIDs = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Patch group alias is a single alias for a group of aliases that are temporarily patched together. This will
|
||||
* normally be used for patched talkgroups, but could be used with any type of alias identifiers that can be
|
||||
* temporarily joined to form a patch group.
|
||||
*
|
||||
* Alias properties such as recordable, streamable and call priority are an aggregation from the set of patched
|
||||
* aliases contained in this patch group alias and the patch group ID alias and where applicable, return the highest
|
||||
* value/priority from the group of patched aliases.
|
||||
*/
|
||||
public PatchGroupAlias()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor()
|
||||
{
|
||||
if(mPatchGroupAlias != null)
|
||||
{
|
||||
return mPatchGroupAlias.getColor();
|
||||
}
|
||||
|
||||
return super.getColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alias for this patch group ID
|
||||
*/
|
||||
public void setPatchGroupAlias(Alias alias)
|
||||
{
|
||||
mPatchGroupAlias = alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for this patch group
|
||||
*/
|
||||
public Alias getPatchGroupAlias()
|
||||
{
|
||||
return mPatchGroupAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this patch group has an alias
|
||||
*/
|
||||
public boolean hasPatchGroupAlias()
|
||||
{
|
||||
return mPatchGroupAlias != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of patched aliases contained in this patch group
|
||||
*/
|
||||
public List<Alias> getPatchedAliases()
|
||||
{
|
||||
return mPatchedAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes/clears all patched aliases from this patch alias group
|
||||
*/
|
||||
public void clearPatchedAliases()
|
||||
{
|
||||
mPatchedAliases.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the patched alias to this patch alias group
|
||||
*/
|
||||
public void addPatchedAlias(Alias alias)
|
||||
{
|
||||
if(alias == PatchGroupAlias.this)
|
||||
{
|
||||
throw new IllegalArgumentException("Can't add patch group alias to itself - would create an infinite loop");
|
||||
}
|
||||
|
||||
mPatchedAliases.add(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the patched alias from this patch alias group
|
||||
*/
|
||||
public void removePatchedAlias(Alias alias)
|
||||
{
|
||||
mPatchedAliases.remove(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of patched talkgroup IDs for this patch group
|
||||
*/
|
||||
public void setPatchedTalkgroupIDs(List<String> talkgroupIDs)
|
||||
{
|
||||
mPatchedTalkgroupIDs = talkgroupIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of patched talkgroup IDs for this patch group
|
||||
*/
|
||||
public List<String> getPatchedTalkgroupIDs()
|
||||
{
|
||||
return mPatchedTalkgroupIDs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
if(hasPatchGroupAlias())
|
||||
{
|
||||
return getPatchGroupAlias().getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
for(AliasID id: getId())
|
||||
{
|
||||
if(id.getType() == AliasIDType.TALKGROUP)
|
||||
{
|
||||
return "PATCH:" + ((TalkgroupID)id).getTalkgroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "PATCH:****";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AliasAction> getAction()
|
||||
{
|
||||
List<AliasAction> aliasActions = new ArrayList<>();
|
||||
|
||||
if(hasPatchGroupAlias())
|
||||
{
|
||||
aliasActions.addAll(getPatchGroupAlias().getAction());
|
||||
}
|
||||
|
||||
for(Alias alias: mPatchedAliases)
|
||||
{
|
||||
if(!(alias instanceof PatchGroupAlias))
|
||||
{
|
||||
for(AliasAction action: alias.getAction())
|
||||
{
|
||||
if(!aliasActions.contains(action))
|
||||
{
|
||||
aliasActions.add(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aliasActions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasActions()
|
||||
{
|
||||
for(Alias alias: mPatchedAliases)
|
||||
{
|
||||
if(!(alias instanceof PatchGroupAlias) && alias.hasActions())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasPatchGroupAlias() && getPatchGroupAlias().hasActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest listenable audio priority defined among the aliases in the group, or returns 'Do Not Monitor'
|
||||
* if that is the only priority defined. Otherwise, returns default (100) priority.
|
||||
*/
|
||||
@Override
|
||||
public int getCallPriority()
|
||||
{
|
||||
boolean hasDoNotMonitor = false;
|
||||
|
||||
int highestPriority = (hasPatchGroupAlias() ? getPatchGroupAlias().getCallPriority() : Priority.DEFAULT_PRIORITY + 1);
|
||||
|
||||
for(Alias alias: mPatchedAliases)
|
||||
{
|
||||
if(!(alias instanceof PatchGroupAlias) && alias.hasCallPriority() && alias.getCallPriority() < highestPriority)
|
||||
{
|
||||
if(alias.getCallPriority() == Priority.DO_NOT_MONITOR)
|
||||
{
|
||||
hasDoNotMonitor = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
highestPriority = alias.getCallPriority();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(highestPriority <= Priority.DEFAULT_PRIORITY)
|
||||
{
|
||||
return highestPriority;
|
||||
}
|
||||
else if(hasDoNotMonitor)
|
||||
{
|
||||
return Priority.DO_NOT_MONITOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Priority.DEFAULT_PRIORITY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCallPriority()
|
||||
{
|
||||
if(hasPatchGroupAlias() && getPatchGroupAlias().hasCallPriority())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for(Alias alias: mPatchedAliases)
|
||||
{
|
||||
if(!(alias instanceof PatchGroupAlias) && alias.hasCallPriority())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecordable()
|
||||
{
|
||||
if(hasPatchGroupAlias() && getPatchGroupAlias().isRecordable())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for(Alias alias: mPatchedAliases)
|
||||
{
|
||||
if(!(alias instanceof PatchGroupAlias) && alias.isRecordable())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStreamable()
|
||||
{
|
||||
if(hasPatchGroupAlias() && getPatchGroupAlias().isStreamable())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for(Alias alias: mPatchedAliases)
|
||||
{
|
||||
if(!(alias instanceof PatchGroupAlias) && alias.isStreamable())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<BroadcastChannel> getBroadcastChannels()
|
||||
{
|
||||
Set<BroadcastChannel> broadcastChannels = new TreeSet<>();
|
||||
|
||||
if(hasPatchGroupAlias())
|
||||
{
|
||||
broadcastChannels.addAll(getPatchGroupAlias().getBroadcastChannels());
|
||||
}
|
||||
|
||||
for(Alias alias: mPatchedAliases)
|
||||
{
|
||||
if(!(alias instanceof PatchGroupAlias))
|
||||
{
|
||||
broadcastChannels.addAll(alias.getBroadcastChannels());
|
||||
}
|
||||
}
|
||||
|
||||
return broadcastChannels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBroadcastChannel(String channel)
|
||||
{
|
||||
if(hasPatchGroupAlias() && getPatchGroupAlias().hasBroadcastChannel(channel))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for(Alias alias: mPatchedAliases)
|
||||
{
|
||||
if(!(alias instanceof PatchGroupAlias) && alias.hasBroadcastChannel(channel))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Alias a1 = new Alias("Alias 1");
|
||||
a1.addAliasID(new BroadcastChannel("Channel 1"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 2"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 3"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 4"));
|
||||
|
||||
Alias a2 = new Alias("Alias 1");
|
||||
a1.addAliasID(new BroadcastChannel("Channel 1"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 2"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 3"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 4"));
|
||||
|
||||
Alias a3 = new Alias("Alias 1");
|
||||
a1.addAliasID(new BroadcastChannel("Channel 1"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 2"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 3"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 4"));
|
||||
|
||||
Alias a4 = new Alias("Alias 1");
|
||||
a1.addAliasID(new BroadcastChannel("Channel 1"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 2"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 3"));
|
||||
a1.addAliasID(new BroadcastChannel("Channel 4"));
|
||||
|
||||
PatchGroupAlias pga = new PatchGroupAlias();
|
||||
pga.setPatchGroupAlias(a1);
|
||||
pga.addPatchedAlias(a2);
|
||||
pga.addPatchedAlias(a3);
|
||||
pga.addPatchedAlias(a4);
|
||||
|
||||
Set<BroadcastChannel> bc = pga.getBroadcastChannels();
|
||||
|
||||
mLog.debug("Channels:" + bc);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
package alias.action;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.action.beep.BeepAction;
|
||||
import alias.action.clip.ClipAction;
|
||||
import alias.action.script.ScriptAction;
|
||||
import message.Message;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* Alias action defines an action to execute when an alias is detected active.
|
||||
*/
|
||||
@XmlSeeAlso( { BeepAction.class, ClipAction.class, ScriptAction.class } )
|
||||
@XmlRootElement( name = "action" )
|
||||
public abstract class AliasAction
|
||||
{
|
||||
public AliasAction()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public abstract AliasActionType getType();
|
||||
|
||||
/**
|
||||
* Task to execute when an alias action is defined. The message argument is
|
||||
* the original message containing one or more aliases that have an alias
|
||||
* action attached. The alias argument is the parent alias containing the
|
||||
* alias action.
|
||||
*/
|
||||
public abstract void execute( ScheduledExecutorService scheduledExecutorService, Alias alias, Message message );
|
||||
|
||||
/**
|
||||
* Dismiss a persistent alias action
|
||||
*/
|
||||
public abstract void dismiss( boolean reset );
|
||||
}
|
||||
@@ -1,350 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias.action;
|
||||
|
||||
import gui.editor.Editor;
|
||||
import gui.editor.EmptyEditor;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import alias.Alias;
|
||||
import alias.AliasEvent;
|
||||
import alias.AliasEvent.Event;
|
||||
import alias.AliasFactory;
|
||||
import alias.AliasModel;
|
||||
|
||||
public class AliasActionEditor extends Editor<Alias>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static ListModel<AliasAction> EMPTY_MODEL = new DefaultListModel<>();
|
||||
private JList<AliasAction> mAliasActionList = new JList<>( EMPTY_MODEL );
|
||||
private JButton mNewActionButton;
|
||||
private JButton mCloneActionButton;
|
||||
private JButton mDeleteActionButton;
|
||||
private EditorContainer mEditorContainer = new EditorContainer();
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
|
||||
public AliasActionEditor( AliasModel model )
|
||||
{
|
||||
mAliasModel = model;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 3",
|
||||
"[grow,fill][grow,fill][grow,fill]", "[][grow,fill][]" ) );
|
||||
|
||||
mAliasActionList.setVisibleRowCount( 6 );
|
||||
mAliasActionList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
|
||||
mAliasActionList.setLayoutOrientation( JList.VERTICAL );
|
||||
mAliasActionList.addListSelectionListener( new ListSelectionListener()
|
||||
{
|
||||
@Override
|
||||
public void valueChanged( ListSelectionEvent event )
|
||||
{
|
||||
if( !event.getValueIsAdjusting() )
|
||||
{
|
||||
JList<?> list = (JList<?>)event.getSource();
|
||||
|
||||
Object selectedItem = list.getSelectedValue();
|
||||
|
||||
if( selectedItem != null && selectedItem instanceof AliasAction )
|
||||
{
|
||||
AliasAction selected = (AliasAction)selectedItem;
|
||||
|
||||
mEditorContainer.setAliasAction( selected );
|
||||
|
||||
mCloneActionButton.setEnabled( true );
|
||||
mDeleteActionButton.setEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
mCloneActionButton.setEnabled( false );
|
||||
mDeleteActionButton.setEnabled( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
JScrollPane scroller = new JScrollPane( mAliasActionList );
|
||||
add( scroller, "span,grow" );
|
||||
|
||||
add( mEditorContainer, "span,grow" );
|
||||
|
||||
mNewActionButton = new JButton( "New ..." );
|
||||
mNewActionButton.setToolTipText( "Create a new Alias Action" );
|
||||
mNewActionButton.addMouseListener( new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e )
|
||||
{
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
|
||||
menu.add( new AddAliasActionItem( AliasActionType.BEEP ) );
|
||||
menu.add( new AddAliasActionItem( AliasActionType.CLIP ) );
|
||||
menu.add( new AddAliasActionItem( AliasActionType.SCRIPT ) );
|
||||
|
||||
menu.show( e.getComponent(), e.getX(), e.getY() );
|
||||
}
|
||||
} );
|
||||
|
||||
add( mNewActionButton );
|
||||
|
||||
mCloneActionButton = new JButton( "Clone" );
|
||||
mCloneActionButton.setToolTipText( "Create a copy of the currently selected action" );
|
||||
mCloneActionButton.setEnabled( false );
|
||||
mCloneActionButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
AliasAction selected = mAliasActionList.getSelectedValue();
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
AliasAction clone = AliasFactory.copyOf( selected );
|
||||
|
||||
if( clone != null )
|
||||
{
|
||||
addAliasActionToList( clone );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
add( mCloneActionButton );
|
||||
|
||||
mDeleteActionButton = new JButton( "Delete" );
|
||||
mDeleteActionButton.setToolTipText( "Delete the currently selected action" );
|
||||
mDeleteActionButton.setEnabled( false );
|
||||
mDeleteActionButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
final AliasAction selected = mAliasActionList.getSelectedValue();
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
int choice = JOptionPane.showConfirmDialog( mDeleteActionButton,
|
||||
"Do you want to delete [" + selected.toString() + "]",
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION );
|
||||
|
||||
if( choice == JOptionPane.YES_OPTION && hasItem() )
|
||||
{
|
||||
Alias alias = getItem();
|
||||
|
||||
alias.removeAliasAction( selected );
|
||||
|
||||
mAliasModel.broadcast( new AliasEvent( alias, Event.CHANGE ) );
|
||||
|
||||
setItem( alias );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
add( mDeleteActionButton, "wrap" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem( Alias alias )
|
||||
{
|
||||
super.setItem( alias );
|
||||
|
||||
if( alias == null || alias.getAction().isEmpty() )
|
||||
{
|
||||
mAliasActionList.setModel( EMPTY_MODEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultListModel<AliasAction> model = new DefaultListModel<>();
|
||||
|
||||
List<AliasAction> actions = alias.getAction();
|
||||
|
||||
Collections.sort( actions, new Comparator<AliasAction>()
|
||||
{
|
||||
@Override
|
||||
public int compare( AliasAction o1, AliasAction o2 )
|
||||
{
|
||||
return o1.toString().compareTo( o2.toString() );
|
||||
}
|
||||
} );
|
||||
|
||||
for( AliasAction action: actions )
|
||||
{
|
||||
model.addElement( action );
|
||||
}
|
||||
|
||||
mAliasActionList.setModel( model );
|
||||
}
|
||||
|
||||
mEditorContainer.setAliasAction( null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( isModified() || mEditorContainer.isModified() )
|
||||
{
|
||||
if( mEditorContainer.isModified() )
|
||||
{
|
||||
mEditorContainer.save();
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
mAliasModel.broadcast( new AliasEvent( getItem(), Event.CHANGE ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EditorContainer extends JPanel
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Editor<AliasAction> mEditor = new EmptyEditor<>();
|
||||
|
||||
public EditorContainer()
|
||||
{
|
||||
setLayout( new MigLayout( "","[grow,fill]", "[grow,fill]" ) );
|
||||
|
||||
add( mEditor );
|
||||
}
|
||||
|
||||
public boolean isModified()
|
||||
{
|
||||
if( mEditor != null )
|
||||
{
|
||||
return mEditor.isModified();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
if( mEditor != null )
|
||||
{
|
||||
mEditor.save();
|
||||
}
|
||||
}
|
||||
|
||||
public void setAliasAction( AliasAction aliasAction )
|
||||
{
|
||||
if( mEditor != null )
|
||||
{
|
||||
if( mEditor.isModified() )
|
||||
{
|
||||
int option = JOptionPane.showConfirmDialog(
|
||||
EditorContainer.this,
|
||||
"Action settings have changed. Do you want to save these changes?",
|
||||
"Save Changes?",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE );
|
||||
|
||||
if( option == JOptionPane.YES_OPTION )
|
||||
{
|
||||
mEditor.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAll();
|
||||
|
||||
//This will always give us an editor
|
||||
mEditor = AliasFactory.getEditor( aliasAction );
|
||||
|
||||
add( mEditor );
|
||||
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void addAliasActionToList( final AliasAction action )
|
||||
{
|
||||
if( action != null && hasItem() )
|
||||
{
|
||||
final Alias alias = getItem();
|
||||
|
||||
alias.addAliasAction( action );
|
||||
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
setItem( alias );
|
||||
|
||||
mAliasActionList.setSelectedValue( action, true );
|
||||
|
||||
AliasActionEditor.this.setModified( true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
public class AddAliasActionItem extends JMenuItem
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private AliasActionType mAliasActionType;
|
||||
|
||||
public AddAliasActionItem( AliasActionType type )
|
||||
{
|
||||
super( type.toString() );
|
||||
|
||||
mAliasActionType = type;
|
||||
|
||||
addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
final AliasAction action =
|
||||
AliasFactory.getAliasAction( mAliasActionType );
|
||||
|
||||
addAliasActionToList( action );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias.action;
|
||||
|
||||
import alias.AliasEvent;
|
||||
|
||||
/**
|
||||
* Interface for receiving alias events. Each listener will receive
|
||||
* notification of all alias events.
|
||||
*/
|
||||
public interface AliasActionListener
|
||||
{
|
||||
/**
|
||||
* Notifies the listener that an alias event has occurred
|
||||
*/
|
||||
public void aliasChanged( AliasEvent event );
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
package alias.action;
|
||||
|
||||
import alias.Alias;
|
||||
import message.Message;
|
||||
import sample.Listener;
|
||||
import util.ThreadPool;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages all alias action events. Each received message is interrogated for
|
||||
* any alias entries and then each alias is interrogated for any alias actions.
|
||||
*
|
||||
* Each alias action is executed and provided a copy of the source message so
|
||||
* that the contents of the message can be used as part of the action.
|
||||
*/
|
||||
public class AliasActionManager implements Listener<Message>
|
||||
{
|
||||
public AliasActionManager()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(Message message)
|
||||
{
|
||||
if(message.isValid())
|
||||
{
|
||||
List<Alias> aliases = message.getAliases();
|
||||
|
||||
if(aliases != null)
|
||||
{
|
||||
for(Alias alias : aliases)
|
||||
{
|
||||
if(alias.hasActions())
|
||||
{
|
||||
List<AliasAction> actions = alias.getAction();
|
||||
|
||||
for(AliasAction action : actions)
|
||||
{
|
||||
/* Provide access to the thread pool manager in case the
|
||||
* action needs to setup a timer, and provide the original
|
||||
* message to be used as part of the action (e.g. sending
|
||||
* the message as a text message to a cell phone */
|
||||
action.execute(ThreadPool.SCHEDULED, alias, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
package alias.action;
|
||||
|
||||
import alias.Alias;
|
||||
import message.Message;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import java.awt.*;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public abstract class RecurringAction extends AliasAction
|
||||
{
|
||||
@XmlTransient
|
||||
protected AtomicBoolean mRunning = new AtomicBoolean(false);
|
||||
@XmlTransient
|
||||
private ScheduledFuture<?> mPerpetualAction;
|
||||
@XmlTransient
|
||||
protected ScheduledExecutorService mScheduledExecutorService;
|
||||
|
||||
protected Interval mInterval = Interval.ONCE;
|
||||
protected int mPeriod = 5;
|
||||
|
||||
public abstract void performAction(Alias alias, Message message);
|
||||
|
||||
@Override
|
||||
public void execute(ScheduledExecutorService scheduledExecutorService, Alias alias, Message message)
|
||||
{
|
||||
mScheduledExecutorService = scheduledExecutorService;
|
||||
|
||||
if(mRunning.compareAndSet(false, true))
|
||||
{
|
||||
switch(mInterval)
|
||||
{
|
||||
case ONCE:
|
||||
performThreadedAction(alias, message);
|
||||
/* Don't reset */
|
||||
break;
|
||||
case DELAYED_RESET:
|
||||
performThreadedAction(alias, message);
|
||||
mScheduledExecutorService.schedule(new ResetTask(), mPeriod, TimeUnit.SECONDS);
|
||||
break;
|
||||
case UNTIL_DISMISSED:
|
||||
mPerpetualAction = mScheduledExecutorService.scheduleAtFixedRate(
|
||||
new PerformActionTask(alias, message), mPeriod, mPeriod, TimeUnit.SECONDS);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html><div width='250'>Alias [");
|
||||
sb.append(alias.getName());
|
||||
sb.append("] is active in message [");
|
||||
sb.append(message.toString());
|
||||
sb.append("]</div></html>");
|
||||
|
||||
final String text = sb.toString();
|
||||
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
JOptionPane.showMessageDialog(null, text,
|
||||
"Alias Alert", JOptionPane.INFORMATION_MESSAGE);
|
||||
|
||||
dismiss(false);
|
||||
|
||||
mScheduledExecutorService.schedule(new ResetTask(), 15, TimeUnit.SECONDS);
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns the performAction() event into a new thread so that it doesn't
|
||||
* delay any decoder actions.
|
||||
*/
|
||||
private void performThreadedAction(final Alias alias, final Message message)
|
||||
{
|
||||
mScheduledExecutorService.schedule(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
performAction(alias, message);
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismiss(boolean reset)
|
||||
{
|
||||
if(mPerpetualAction != null)
|
||||
{
|
||||
mPerpetualAction.cancel(true);
|
||||
|
||||
mPerpetualAction = null;
|
||||
}
|
||||
|
||||
if(reset)
|
||||
{
|
||||
mRunning.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public int getPeriod()
|
||||
{
|
||||
return mPeriod;
|
||||
}
|
||||
|
||||
public void setPeriod(int period)
|
||||
{
|
||||
mPeriod = period;
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public Interval getInterval()
|
||||
{
|
||||
return mInterval;
|
||||
}
|
||||
|
||||
public void setInterval(Interval interval)
|
||||
{
|
||||
mInterval = interval;
|
||||
|
||||
mRunning.set(false);
|
||||
}
|
||||
|
||||
public enum Interval
|
||||
{
|
||||
ONCE("Once"),
|
||||
DELAYED_RESET("Once, Reset After Delay"),
|
||||
UNTIL_DISMISSED("Until Dismissed");
|
||||
|
||||
private String mLabel;
|
||||
|
||||
private Interval(String label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
}
|
||||
|
||||
public class PerformActionTask implements Runnable
|
||||
{
|
||||
private Alias mAlias;
|
||||
private Message mMessage;
|
||||
|
||||
public PerformActionTask(Alias alias, Message message)
|
||||
{
|
||||
mAlias = alias;
|
||||
mMessage = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
/* Don't use the performThreadedAction() method, since this is
|
||||
* already running in a separate thread */
|
||||
performAction(mAlias, mMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public class ResetTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mRunning.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package alias.action.beep;
|
||||
|
||||
import message.Message;
|
||||
import alias.Alias;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.RecurringAction;
|
||||
|
||||
public class BeepAction extends RecurringAction
|
||||
{
|
||||
|
||||
@Override
|
||||
public AliasActionType getType()
|
||||
{
|
||||
return AliasActionType.BEEP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction( Alias alias, Message message )
|
||||
{
|
||||
System.out.println( "\007" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Beep";
|
||||
}
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias.action.beep;
|
||||
|
||||
import gui.editor.DocumentListenerEditor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.SpinnerModel;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import alias.action.AliasAction;
|
||||
import alias.action.RecurringAction.Interval;
|
||||
|
||||
public class BeepActionEditor extends DocumentListenerEditor<AliasAction>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String HELP_TEXT =
|
||||
"<html><h3>Beep Action</h3>"
|
||||
+ "This action will sound a beep according to the interval<br>"
|
||||
+ "that you select:<br><br>"
|
||||
+ "<b>Once:</b> Beep the first time the alias is active and<br>"
|
||||
+ "never again<br><br>"
|
||||
+ "<b>Once, Reset After Delay:</b> Beep once and suppress<br>"
|
||||
+ "subsequent beeps for the specified period in seconds.<br>"
|
||||
+ "After the reset period, beep again when the alias is active.<br><br>"
|
||||
+ "<b>Until Dismissed:</b> Beep every period seconds until you<br>"
|
||||
+ "click OK on the dialog that appears. Alerting is suppressed<br>"
|
||||
+ "for 15 seconds after you click OK.<br>"
|
||||
+ "</html>";
|
||||
|
||||
private JComboBox<Interval> mComboInterval;
|
||||
private JSlider mPeriodSlider;
|
||||
private JLabel mPeriodSliderLabel;
|
||||
|
||||
public BeepActionEditor( AliasAction aliasAction )
|
||||
{
|
||||
init();
|
||||
|
||||
setItem( aliasAction );
|
||||
}
|
||||
|
||||
public BeepAction getBeepAction()
|
||||
{
|
||||
if( getItem() instanceof BeepAction )
|
||||
{
|
||||
return (BeepAction)getItem();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][]" ) );
|
||||
|
||||
add( new JLabel( "Beep Interval:" ) );
|
||||
|
||||
mComboInterval = new JComboBox<Interval>( Interval.values() );
|
||||
mComboInterval.setToolTipText( HELP_TEXT );
|
||||
mComboInterval.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Interval selected = mComboInterval
|
||||
.getItemAt( mComboInterval.getSelectedIndex() );
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
/* Enable/disable period spinner based on selection */
|
||||
boolean enabled = selected != Interval.ONCE;
|
||||
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
});
|
||||
add( mComboInterval, "wrap" );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel( 1, 1, 30, 1 );
|
||||
model.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
mPeriodSlider = new JSlider( JSlider.HORIZONTAL, 1, 60, 1 );
|
||||
mPeriodSlider.setMajorTickSpacing( 10 );
|
||||
mPeriodSlider.setMinorTickSpacing( 2 );
|
||||
mPeriodSlider.setPaintTicks( true );
|
||||
mPeriodSlider.setLabelTable( mPeriodSlider.createStandardLabels( 10, 10 ) );
|
||||
mPeriodSlider.setPaintLabels( true );
|
||||
mPeriodSlider.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
mPeriodSliderLabel.setText( "Period: " + mPeriodSlider.getValue() );
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
mPeriodSlider.setToolTipText( HELP_TEXT );
|
||||
|
||||
mPeriodSliderLabel = new JLabel( "Period: " + mPeriodSlider.getValue() + " " );
|
||||
add( mPeriodSliderLabel );
|
||||
add( mPeriodSlider, "wrap,grow" );
|
||||
|
||||
JLabel help = new JLabel( "Help ..." );
|
||||
help.setForeground( Color.BLUE.brighter() );
|
||||
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
|
||||
help.addMouseListener( new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e )
|
||||
{
|
||||
JOptionPane.showMessageDialog( BeepActionEditor.this,
|
||||
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
|
||||
}
|
||||
} );
|
||||
add( help, "align left" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem( AliasAction item )
|
||||
{
|
||||
super.setItem( item );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
BeepAction beep = getBeepAction();
|
||||
|
||||
Interval interval = beep.getInterval();
|
||||
|
||||
mComboInterval.setSelectedItem( interval );
|
||||
|
||||
boolean enabled = interval != Interval.ONCE;
|
||||
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSlider.setValue( beep.getPeriod() );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
BeepAction beep = getBeepAction();
|
||||
|
||||
beep.setInterval( (Interval)mComboInterval.getSelectedItem() );
|
||||
beep.setPeriod( mPeriodSlider.getValue() );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
package alias.action.clip;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.Clip;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import message.Message;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.RecurringAction;
|
||||
|
||||
public class ClipAction extends RecurringAction
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( ClipAction.class );
|
||||
|
||||
private String mFilePath;
|
||||
|
||||
@XmlTransient
|
||||
private Clip mClip;
|
||||
|
||||
public ClipAction()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasActionType getType()
|
||||
{
|
||||
return AliasActionType.CLIP;
|
||||
}
|
||||
|
||||
public String getPath()
|
||||
{
|
||||
return mFilePath;
|
||||
}
|
||||
|
||||
public void setPath( String path )
|
||||
{
|
||||
mFilePath = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction( Alias alias, Message message )
|
||||
{
|
||||
try
|
||||
{
|
||||
play();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't play audio clip", e );
|
||||
}
|
||||
}
|
||||
|
||||
public void play() throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
if( mFilePath != null )
|
||||
{
|
||||
if( mClip == null )
|
||||
{
|
||||
mClip = AudioSystem.getClip();
|
||||
|
||||
AudioInputStream ais =
|
||||
AudioSystem.getAudioInputStream( new File( mFilePath ) );
|
||||
|
||||
mClip.open( ais );
|
||||
}
|
||||
|
||||
if( mClip.isRunning() )
|
||||
{
|
||||
mClip.stop();
|
||||
}
|
||||
|
||||
mClip.setFramePosition( 0 );
|
||||
|
||||
mClip.start();
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
mClip = null;
|
||||
|
||||
mLog.error( "Error playing sound clip [" + mFilePath + "] - " + e.getMessage() );
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if( mFilePath == null )
|
||||
{
|
||||
return "Play Clip";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Play Clip: " + mFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias.action.clip;
|
||||
|
||||
import gui.editor.DocumentListenerEditor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SpinnerModel;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import alias.action.AliasAction;
|
||||
import alias.action.RecurringAction.Interval;
|
||||
|
||||
public class ClipActionEditor extends DocumentListenerEditor<AliasAction>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String PLEASE_SELECT_A_FILE = "Please select a file";
|
||||
private static final String HELP_TEXT =
|
||||
"<html><h3>Clip Action</h3>"
|
||||
+ "This action will play an audio clip according to the interval<br>"
|
||||
+ "that you select:<br><br>"
|
||||
+ "<b>Once:</b> play the first time the alias is active and<br>"
|
||||
+ "never again<br><br>"
|
||||
+ "<b>Once, Reset After Delay:</b> play once and suppress<br>"
|
||||
+ "subsequent runs for the specified period in seconds.<br>"
|
||||
+ "After the reset period, play again when the alias is active.<br><br>"
|
||||
+ "<b>Until Dismissed:</b> play every period seconds until you<br>"
|
||||
+ "click OK on the dialog that appears. Alerting is suppressed<br>"
|
||||
+ "for 15 seconds after you click OK.<br>"
|
||||
+ "</html>";
|
||||
|
||||
private JComboBox<Interval> mComboInterval;
|
||||
private JSlider mPeriodSlider;
|
||||
private JLabel mPeriodSliderLabel;
|
||||
private JTextField mTextFilePath;
|
||||
|
||||
public ClipActionEditor( AliasAction aliasAction )
|
||||
{
|
||||
init();
|
||||
|
||||
setItem( aliasAction );
|
||||
}
|
||||
|
||||
public ClipAction getClipAction()
|
||||
{
|
||||
if( getItem() instanceof ClipAction )
|
||||
{
|
||||
return (ClipAction)getItem();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][][]" ) );
|
||||
|
||||
add( new JLabel( "Play Interval:" ) );
|
||||
|
||||
mComboInterval = new JComboBox<Interval>( Interval.values() );
|
||||
mComboInterval.setToolTipText( HELP_TEXT );
|
||||
mComboInterval.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Interval selected = mComboInterval
|
||||
.getItemAt( mComboInterval.getSelectedIndex() );
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
/* Enable/disable period slider based on selection */
|
||||
boolean enabled = selected != Interval.ONCE;
|
||||
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
});
|
||||
add( mComboInterval );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel( 1, 1, 30, 1 );
|
||||
model.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
mPeriodSlider = new JSlider( JSlider.HORIZONTAL, 1, 60, 1 );
|
||||
mPeriodSlider.setMajorTickSpacing( 10 );
|
||||
mPeriodSlider.setMinorTickSpacing( 2 );
|
||||
mPeriodSlider.setPaintTicks( true );
|
||||
mPeriodSlider.setLabelTable( mPeriodSlider.createStandardLabels( 10, 10 ) );
|
||||
mPeriodSlider.setPaintLabels( true );
|
||||
mPeriodSlider.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
mPeriodSliderLabel.setText( "Period: " + mPeriodSlider.getValue() );
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
mPeriodSlider.setToolTipText( HELP_TEXT );
|
||||
|
||||
mPeriodSliderLabel = new JLabel( "Period: " + mPeriodSlider.getValue() + " " );
|
||||
add( mPeriodSliderLabel );
|
||||
add( mPeriodSlider, "wrap,grow" );
|
||||
|
||||
mTextFilePath = new JTextField( PLEASE_SELECT_A_FILE );
|
||||
add( mTextFilePath, "growx,span" );
|
||||
|
||||
JButton fileButton = new JButton( "File" );
|
||||
|
||||
fileButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
final JFileChooser chooser = new JFileChooser();
|
||||
|
||||
int value = chooser.showOpenDialog( ClipActionEditor.this );
|
||||
|
||||
if( value == JFileChooser.APPROVE_OPTION )
|
||||
{
|
||||
File file = chooser.getSelectedFile();
|
||||
|
||||
mTextFilePath.setText( file.getAbsolutePath() );
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( fileButton, "grow" );
|
||||
|
||||
JButton testButton = new JButton( "Test" );
|
||||
|
||||
testButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
if( hasItem() )
|
||||
{
|
||||
String path = mTextFilePath.getText();
|
||||
|
||||
if( path == null || path.trim().isEmpty() )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ClipActionEditor.this,
|
||||
"Please select an audio file", PLEASE_SELECT_A_FILE,
|
||||
JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( isModified() )
|
||||
{
|
||||
int option = JOptionPane.showConfirmDialog(
|
||||
ClipActionEditor.this,
|
||||
"Settings have changed. Do you want to save these changes?",
|
||||
"Save Changes?",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE );
|
||||
|
||||
if( option == JOptionPane.YES_OPTION )
|
||||
{
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
new Thread( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
getClipAction().play();
|
||||
}
|
||||
catch( Exception e1 )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ClipActionEditor.this,
|
||||
"Couldn't play audio clip [" + e1.getMessage() + "]",
|
||||
"Error", JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( testButton, "grow,wrap" );
|
||||
|
||||
JLabel help = new JLabel( "Help ..." );
|
||||
help.setForeground( Color.BLUE.brighter() );
|
||||
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
|
||||
help.addMouseListener( new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ClipActionEditor.this,
|
||||
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
|
||||
}
|
||||
} );
|
||||
add( help, "align left" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem( AliasAction item )
|
||||
{
|
||||
super.setItem( item );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
ClipAction clip = getClipAction();
|
||||
|
||||
Interval interval = clip.getInterval();
|
||||
|
||||
mComboInterval.setSelectedItem( interval );
|
||||
|
||||
boolean enabled = interval != Interval.ONCE;
|
||||
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSlider.setValue( clip.getPeriod() );
|
||||
|
||||
String filepath = clip.getPath();
|
||||
|
||||
if( filepath != null && !filepath.isEmpty() )
|
||||
{
|
||||
mTextFilePath.setText( filepath );
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextFilePath.setText( PLEASE_SELECT_A_FILE );
|
||||
}
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
ClipAction script = getClipAction();
|
||||
|
||||
script.setInterval( (Interval)mComboInterval.getSelectedItem() );
|
||||
script.setPeriod( mPeriodSlider.getValue() );
|
||||
script.setPath( mTextFilePath.getText() );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package alias.action.script;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import message.Message;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.RecurringAction;
|
||||
|
||||
public class ScriptAction extends RecurringAction
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( ScriptAction.class );
|
||||
|
||||
private String mScript;
|
||||
|
||||
public ScriptAction()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasActionType getType()
|
||||
{
|
||||
return AliasActionType.SCRIPT;
|
||||
}
|
||||
|
||||
public String getScript()
|
||||
{
|
||||
return mScript;
|
||||
}
|
||||
|
||||
public void setScript( String script )
|
||||
{
|
||||
mScript = script;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction( Alias alias, Message message )
|
||||
{
|
||||
try
|
||||
{
|
||||
play();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't execute script [" + mScript + "]", e );
|
||||
}
|
||||
}
|
||||
|
||||
public void play() throws Exception
|
||||
{
|
||||
if( mScript != null )
|
||||
{
|
||||
ProcessBuilder pb = new ProcessBuilder( mScript );
|
||||
|
||||
pb.redirectErrorStream( true );
|
||||
|
||||
Process p = pb.start();
|
||||
|
||||
int exitCode = p.waitFor();
|
||||
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader( p.getInputStream() ) );
|
||||
|
||||
String line = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
while( ( line = reader.readLine() ) != null )
|
||||
{
|
||||
sb.append(line + "\n");
|
||||
}
|
||||
|
||||
if( exitCode != 0 )
|
||||
{
|
||||
throw new RuntimeException( "Exit Code: " + exitCode +
|
||||
" Console:" + sb.toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if( mScript == null )
|
||||
{
|
||||
return "Run Script";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Run Script: " + mScript;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,292 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias.action.script;
|
||||
|
||||
import gui.editor.DocumentListenerEditor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SpinnerModel;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import alias.action.AliasAction;
|
||||
import alias.action.RecurringAction.Interval;
|
||||
|
||||
public class ScriptActionEditor extends DocumentListenerEditor<AliasAction>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String PLEASE_SELECT_A_FILE = "Please select a file";
|
||||
private static final String HELP_TEXT =
|
||||
"<html><h3>Script Action</h3>"
|
||||
+ "This action will run a script according to the interval<br>"
|
||||
+ "that you select:<br><br>"
|
||||
+ "<b>Once:</b> run the first time the alias is active and<br>"
|
||||
+ "never again<br><br>"
|
||||
+ "<b>Once, Reset After Delay:</b> run once and suppress<br>"
|
||||
+ "subsequent runs for the specified period in seconds.<br>"
|
||||
+ "After the reset period, run again when the alias is active.<br><br>"
|
||||
+ "<b>Until Dismissed:</b> run every period seconds until you<br>"
|
||||
+ "click OK on the dialog that appears. Alerting is suppressed<br>"
|
||||
+ "for 15 seconds after you click OK.<br>"
|
||||
+ "</html>";
|
||||
|
||||
private JComboBox<Interval> mComboInterval;
|
||||
private JSlider mPeriodSlider;
|
||||
private JLabel mPeriodSliderLabel;
|
||||
private JTextField mTextFilePath;
|
||||
|
||||
public ScriptActionEditor( AliasAction aliasAction )
|
||||
{
|
||||
init();
|
||||
|
||||
setItem( aliasAction );
|
||||
}
|
||||
|
||||
public ScriptAction getScriptAction()
|
||||
{
|
||||
if( getItem() instanceof ScriptAction )
|
||||
{
|
||||
return (ScriptAction)getItem();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][][]" ) );
|
||||
|
||||
add( new JLabel( "Run Interval:" ) );
|
||||
|
||||
mComboInterval = new JComboBox<Interval>( Interval.values() );
|
||||
mComboInterval.setToolTipText( HELP_TEXT );
|
||||
mComboInterval.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Interval selected = mComboInterval
|
||||
.getItemAt( mComboInterval.getSelectedIndex() );
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
/* Enable/disable period slider based on selection */
|
||||
boolean enabled = selected != Interval.ONCE;
|
||||
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
});
|
||||
add( mComboInterval );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel( 1, 1, 30, 1 );
|
||||
model.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
mPeriodSlider = new JSlider( JSlider.HORIZONTAL, 1, 60, 1 );
|
||||
mPeriodSlider.setMajorTickSpacing( 10 );
|
||||
mPeriodSlider.setMinorTickSpacing( 2 );
|
||||
mPeriodSlider.setPaintTicks( true );
|
||||
mPeriodSlider.setLabelTable( mPeriodSlider.createStandardLabels( 10, 10 ) );
|
||||
mPeriodSlider.setPaintLabels( true );
|
||||
mPeriodSlider.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
mPeriodSliderLabel.setText( "Period: " + mPeriodSlider.getValue() );
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
mPeriodSlider.setToolTipText( HELP_TEXT );
|
||||
|
||||
mPeriodSliderLabel = new JLabel( "Period: " + mPeriodSlider.getValue() + " " );
|
||||
add( mPeriodSliderLabel );
|
||||
add( mPeriodSlider, "wrap,grow" );
|
||||
|
||||
mTextFilePath = new JTextField( PLEASE_SELECT_A_FILE );
|
||||
add( mTextFilePath, "growx,span" );
|
||||
|
||||
JButton fileButton = new JButton( "File" );
|
||||
|
||||
fileButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
final JFileChooser chooser = new JFileChooser();
|
||||
|
||||
int value = chooser.showOpenDialog( ScriptActionEditor.this );
|
||||
|
||||
if( value == JFileChooser.APPROVE_OPTION )
|
||||
{
|
||||
File file = chooser.getSelectedFile();
|
||||
|
||||
mTextFilePath.setText( file.getAbsolutePath() );
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( fileButton, "grow" );
|
||||
|
||||
JButton testButton = new JButton( "Test" );
|
||||
testButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent actionEvent )
|
||||
{
|
||||
String script = mTextFilePath.getText();
|
||||
|
||||
if( script == null || script.trim().isEmpty() )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ScriptActionEditor.this,
|
||||
"Please select a script file", PLEASE_SELECT_A_FILE,
|
||||
JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( isModified() )
|
||||
{
|
||||
int option = JOptionPane.showConfirmDialog(
|
||||
ScriptActionEditor.this,
|
||||
"Settings have changed. Do you want to save these changes?",
|
||||
"Save Changes?",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE );
|
||||
|
||||
if( option == JOptionPane.YES_OPTION )
|
||||
{
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
new Thread( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
getScriptAction().play();
|
||||
}
|
||||
catch( Exception e1 )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ScriptActionEditor.this,
|
||||
e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
} );
|
||||
|
||||
add( testButton, "grow,wrap" );
|
||||
|
||||
JLabel help = new JLabel( "Help ..." );
|
||||
help.setForeground( Color.BLUE.brighter() );
|
||||
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
|
||||
help.addMouseListener( new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ScriptActionEditor.this,
|
||||
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
|
||||
}
|
||||
} );
|
||||
add( help, "align left" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem( AliasAction item )
|
||||
{
|
||||
super.setItem( item );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
ScriptAction script = getScriptAction();
|
||||
|
||||
Interval interval = script.getInterval();
|
||||
|
||||
mComboInterval.setSelectedItem( interval );
|
||||
|
||||
boolean enabled = interval != Interval.ONCE;
|
||||
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSlider.setValue( script.getPeriod() );
|
||||
|
||||
String filepath = script.getScript();
|
||||
|
||||
if( filepath != null && !filepath.isEmpty() )
|
||||
{
|
||||
mTextFilePath.setText( filepath );
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextFilePath.setText( PLEASE_SELECT_A_FILE );
|
||||
}
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
ScriptAction script = getScriptAction();
|
||||
|
||||
script.setInterval( (Interval)mComboInterval.getSelectedItem() );
|
||||
script.setPeriod( mPeriodSlider.getValue() );
|
||||
script.setScript( mTextFilePath.getText() );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias.id;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import playlist.version1.Group;
|
||||
import alias.id.esn.Esn;
|
||||
import alias.id.fleetsync.FleetsyncID;
|
||||
import alias.id.lojack.LoJackFunctionAndID;
|
||||
import alias.id.mdc.MDC1200ID;
|
||||
import alias.id.mobileID.Min;
|
||||
import alias.id.mpt1327.MPT1327ID;
|
||||
import alias.id.nonrecordable.NonRecordable;
|
||||
import alias.id.priority.Priority;
|
||||
import alias.id.siteID.SiteID;
|
||||
import alias.id.status.StatusID;
|
||||
import alias.id.talkgroup.TalkgroupID;
|
||||
import alias.id.uniqueID.UniqueID;
|
||||
|
||||
@SuppressWarnings( "deprecation" )
|
||||
@XmlSeeAlso( {BroadcastChannel.class, Esn.class, FleetsyncID.class, Group.class, LoJackFunctionAndID.class,
|
||||
MDC1200ID.class, Min.class, MPT1327ID.class, NonRecordable.class,
|
||||
Priority.class, SiteID.class, StatusID.class, TalkgroupID.class,
|
||||
UniqueID.class } )
|
||||
@XmlRootElement( name = "id" )
|
||||
public abstract class AliasID
|
||||
{
|
||||
public AliasID()
|
||||
{
|
||||
}
|
||||
|
||||
public abstract AliasIDType getType();
|
||||
|
||||
public abstract boolean matches( AliasID id );
|
||||
|
||||
@XmlTransient
|
||||
public abstract boolean isValid();
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias.id;
|
||||
|
||||
public enum AliasIDType
|
||||
{
|
||||
ESN( "ESN" ),
|
||||
FLEETSYNC( "Fleetsync" ),
|
||||
LOJACK( "LoJack" ),
|
||||
LTR_NET_UID( "LTR-Net UID" ),
|
||||
MDC1200( "MDC-1200" ),
|
||||
MIN( "Passport MIN" ),
|
||||
MPT1327( "MPT-1327" ),
|
||||
SITE( "Site" ),
|
||||
STATUS( "Status" ),
|
||||
TALKGROUP( "Talkgroup" ),
|
||||
|
||||
INVERT( "Audio Inversion" ),
|
||||
PRIORITY( "Audio Priority" ),
|
||||
NON_RECORDABLE( "Audio Non-Recordable" ),
|
||||
BROADCAST_CHANNEL( "Audio Broadcast Channel" );
|
||||
|
||||
private String mLabel;
|
||||
|
||||
private AliasIDType( String label )
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
}
|
||||
@@ -1,379 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
package alias.id;
|
||||
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import gui.editor.Editor;
|
||||
import gui.editor.EmptyEditor;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import alias.Alias;
|
||||
import alias.AliasEvent;
|
||||
import alias.AliasEvent.Event;
|
||||
import alias.AliasFactory;
|
||||
import alias.AliasModel;
|
||||
|
||||
public class AliasIdentifierEditor extends Editor<Alias>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static ListModel<AliasID> EMPTY_MODEL = new DefaultListModel<>();
|
||||
private JList<AliasID> mAliasIDList = new JList<>( EMPTY_MODEL );
|
||||
private JButton mNewIDButton;
|
||||
private JButton mCloneIDButton;
|
||||
private JButton mDeleteIDButton;
|
||||
private EditorContainer mEditorContainer = new EditorContainer();
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
private BroadcastModel mBroadcastModel;
|
||||
|
||||
public AliasIdentifierEditor( AliasModel aliasModel, BroadcastModel broadcastModel )
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mBroadcastModel = broadcastModel;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 3",
|
||||
"[grow,fill][grow,fill][grow,fill]", "[][grow,fill][]" ) );
|
||||
|
||||
mAliasIDList.setVisibleRowCount( 6 );
|
||||
mAliasIDList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
|
||||
mAliasIDList.setLayoutOrientation( JList.VERTICAL );
|
||||
mAliasIDList.addListSelectionListener( new ListSelectionListener()
|
||||
{
|
||||
@Override
|
||||
public void valueChanged( ListSelectionEvent event )
|
||||
{
|
||||
if( !event.getValueIsAdjusting() )
|
||||
{
|
||||
JList<?> list = (JList<?>)event.getSource();
|
||||
|
||||
Object selectedItem = list.getSelectedValue();
|
||||
|
||||
if( selectedItem != null && selectedItem instanceof AliasID )
|
||||
{
|
||||
AliasID selected = (AliasID)selectedItem;
|
||||
|
||||
mEditorContainer.setAliasID( selected );
|
||||
|
||||
mCloneIDButton.setEnabled( true );
|
||||
mDeleteIDButton.setEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
mCloneIDButton.setEnabled( false );
|
||||
mDeleteIDButton.setEnabled( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
JScrollPane scroller = new JScrollPane( mAliasIDList );
|
||||
add( scroller, "span,grow" );
|
||||
|
||||
add( mEditorContainer, "span,grow" );
|
||||
|
||||
mNewIDButton = new JButton( "New ..." );
|
||||
mNewIDButton.setToolTipText( "Create a new Alias Identifier" );
|
||||
mNewIDButton.addMouseListener( new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e )
|
||||
{
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.ESN ) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.FLEETSYNC) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.LOJACK) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.LTR_NET_UID) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.MDC1200 ) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.MPT1327 ) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.MIN ) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.SITE) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.STATUS) );
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.TALKGROUP) );
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.BROADCAST_CHANNEL) );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
Alias alias = getItem();
|
||||
|
||||
if( alias.isRecordable() )
|
||||
{
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.NON_RECORDABLE) );
|
||||
}
|
||||
|
||||
if( !alias.hasCallPriority() )
|
||||
{
|
||||
menu.add( new AddAliasIdentifierItem( AliasIDType.PRIORITY) );
|
||||
}
|
||||
}
|
||||
|
||||
menu.show( e.getComponent(), e.getX(), e.getY() );
|
||||
}
|
||||
} );
|
||||
|
||||
add( mNewIDButton );
|
||||
|
||||
mCloneIDButton = new JButton( "Clone" );
|
||||
mCloneIDButton.setToolTipText( "Create a copy of the currently selected identifier" );
|
||||
mCloneIDButton.setEnabled( false );
|
||||
mCloneIDButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
AliasID selected = mAliasIDList.getSelectedValue();
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
AliasID clone = AliasFactory.copyOf( selected );
|
||||
|
||||
if( clone != null )
|
||||
{
|
||||
addAliasIDToList( clone );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
add( mCloneIDButton );
|
||||
|
||||
mDeleteIDButton = new JButton( "Delete" );
|
||||
mDeleteIDButton.setToolTipText( "Delete the currently selected identifier" );
|
||||
mDeleteIDButton.setEnabled( false );
|
||||
mDeleteIDButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
final AliasID selected = mAliasIDList.getSelectedValue();
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
int choice = JOptionPane.showConfirmDialog( mDeleteIDButton,
|
||||
"Do you want to delete [" + selected.toString() + "]",
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION );
|
||||
|
||||
if( choice == JOptionPane.YES_OPTION && hasItem() )
|
||||
{
|
||||
Alias alias = getItem();
|
||||
|
||||
alias.removeAliasID( selected );
|
||||
|
||||
mAliasModel.broadcast( new AliasEvent( alias, Event.CHANGE ) );
|
||||
|
||||
setItem( alias );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
add( mDeleteIDButton, "wrap" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem( Alias alias )
|
||||
{
|
||||
super.setItem( alias );
|
||||
|
||||
if( alias == null || alias.getId().isEmpty() )
|
||||
{
|
||||
mAliasIDList.setModel( EMPTY_MODEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultListModel<AliasID> model = new DefaultListModel<AliasID>();
|
||||
|
||||
List<AliasID> ids = alias.getId();
|
||||
|
||||
Collections.sort( ids, new Comparator<AliasID>()
|
||||
{
|
||||
@Override
|
||||
public int compare( AliasID o1, AliasID o2 )
|
||||
{
|
||||
return o1.toString().compareTo( o2.toString() );
|
||||
}
|
||||
} );
|
||||
|
||||
for( AliasID id: ids )
|
||||
{
|
||||
model.addElement( id );
|
||||
}
|
||||
|
||||
mAliasIDList.setModel( model );
|
||||
}
|
||||
|
||||
mEditorContainer.setAliasID( null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( isModified() || mEditorContainer.isModified() )
|
||||
{
|
||||
if( mEditorContainer.isModified() )
|
||||
{
|
||||
mEditorContainer.save();
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
mAliasModel.broadcast( new AliasEvent( getItem(), Event.CHANGE ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EditorContainer extends JPanel
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Editor<AliasID> mEditor = new EmptyEditor<>();
|
||||
|
||||
public EditorContainer()
|
||||
{
|
||||
setLayout( new MigLayout( "","[grow,fill]", "[grow,fill]" ) );
|
||||
|
||||
add( mEditor );
|
||||
}
|
||||
|
||||
public boolean isModified()
|
||||
{
|
||||
if( mEditor != null )
|
||||
{
|
||||
return mEditor.isModified();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
if( mEditor != null )
|
||||
{
|
||||
mEditor.save();
|
||||
}
|
||||
}
|
||||
|
||||
public void setAliasID( AliasID aliasID )
|
||||
{
|
||||
if( mEditor != null )
|
||||
{
|
||||
if( mEditor.isModified() )
|
||||
{
|
||||
int option = JOptionPane.showConfirmDialog(
|
||||
EditorContainer.this,
|
||||
"Identifier settings have changed. Do you want to save these changes?",
|
||||
"Save Changes?",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE );
|
||||
|
||||
if( option == JOptionPane.YES_OPTION )
|
||||
{
|
||||
mEditor.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAll();
|
||||
|
||||
//This will always give us an editor
|
||||
mEditor = AliasFactory.getEditor( aliasID, mBroadcastModel );
|
||||
|
||||
add( mEditor );
|
||||
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void addAliasIDToList( final AliasID id )
|
||||
{
|
||||
if( id != null && hasItem() )
|
||||
{
|
||||
final Alias alias = getItem();
|
||||
|
||||
alias.addAliasID( id );
|
||||
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
setItem( alias );
|
||||
|
||||
mAliasIDList.setSelectedValue( id, true );
|
||||
|
||||
AliasIdentifierEditor.this.setModified( true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
public class AddAliasIdentifierItem extends JMenuItem
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private AliasIDType mAliasIDType;
|
||||
|
||||
public AddAliasIdentifierItem( AliasIDType type )
|
||||
{
|
||||
super( type.toString() );
|
||||
|
||||
mAliasIDType = type;
|
||||
|
||||
addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
final AliasID id = AliasFactory.getAliasID( mAliasIDType );
|
||||
|
||||
addAliasIDToList( id );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
package alias.id;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class WildcardID implements Comparable<WildcardID>
|
||||
{
|
||||
public static final String WILDCARD = "*";
|
||||
public static final String REGEX_WILDCARD = ".";
|
||||
|
||||
private String mValue;
|
||||
private Pattern mPattern;
|
||||
private int mWeight;
|
||||
|
||||
/**
|
||||
* Wildcard identifier for matching to string identifiers containing single-character (*) wildcard values.
|
||||
*
|
||||
* Supports ordering from most-specific to least-specific using the build-in weighting calculation where identifier
|
||||
* patterns containing fewer wildcards closer to the least significant digit will be weighted more heavily than
|
||||
* identifier patterns containing more wildcards, or wildcard characters in the most significant digits.
|
||||
*
|
||||
* @param value is a string value containing one or more asterisk (*) single character wildcard with a maximum
|
||||
* length of 10 characters.
|
||||
*
|
||||
* @throws AssertionError if the value is null, longer than 10 characters, or doesn't contain at least 1 asterisk
|
||||
* @throws IllegalArgumentException if the value cannot be compiled as a regular expression after converting the
|
||||
* asterisk characters to the regex single-character wildcard value (.)
|
||||
*/
|
||||
public WildcardID(String value)
|
||||
{
|
||||
Validate.isTrue(value != null && value.contains(WILDCARD) && value.length() < 10);
|
||||
|
||||
mValue = value;
|
||||
|
||||
try
|
||||
{
|
||||
mPattern = Pattern.compile(value.replace(WILDCARD, REGEX_WILDCARD));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw new IllegalArgumentException("Invalid regex pattern for alias ID value [" + value + "]", e);
|
||||
}
|
||||
|
||||
mWeight = calculateWeight();
|
||||
}
|
||||
|
||||
public String value()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the id matches the internal regex pattern for this wildcard alias ID
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public boolean matches(String id)
|
||||
{
|
||||
return id != null && mPattern.matcher(id).matches();
|
||||
}
|
||||
|
||||
public int weight()
|
||||
{
|
||||
return mWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a weighting value for wildcard character quantity and significant digit location
|
||||
*/
|
||||
private int calculateWeight()
|
||||
{
|
||||
int weight = 0;
|
||||
int characterCount = -1;
|
||||
|
||||
for( int x = 0; x < mValue.length(); x++)
|
||||
{
|
||||
if(mValue.substring(x, x + 1).equals(WILDCARD))
|
||||
{
|
||||
weight += (int)(Math.pow(2, mValue.length() - x - 1)); //Position weight
|
||||
characterCount++;
|
||||
}
|
||||
}
|
||||
|
||||
weight += (int)(Math.pow(2, characterCount)) * 1000; //Character count weight
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(WildcardID otherWildcardID)
|
||||
{
|
||||
return Integer.compare(this.weight(), otherWildcardID.weight());
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
package alias.id.broadcast;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
public class BroadcastChannel extends AliasID implements Comparable<BroadcastChannel>
|
||||
{
|
||||
private String mChannelName;
|
||||
|
||||
public BroadcastChannel()
|
||||
{
|
||||
//JAXB Constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BroadcastChannel other)
|
||||
{
|
||||
if(mChannelName != null && other.getChannelName() != null)
|
||||
{
|
||||
return mChannelName.compareTo(other.getChannelName());
|
||||
}
|
||||
else if(mChannelName != null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if(this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(!(o instanceof BroadcastChannel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BroadcastChannel that = (BroadcastChannel)o;
|
||||
|
||||
return getChannelName() != null ? getChannelName().equals(that.getChannelName()) : that.getChannelName() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return getChannelName() != null ? getChannelName().hashCode() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a named broadcast channel
|
||||
*/
|
||||
public BroadcastChannel(String channelName)
|
||||
{
|
||||
mChannelName = channelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the broadcastAudio channel configuration
|
||||
*/
|
||||
@XmlAttribute(name = "channel")
|
||||
public String getChannelName()
|
||||
{
|
||||
return mChannelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the broadcastAudio channel configuration
|
||||
*/
|
||||
public void setChannelName(String channel)
|
||||
{
|
||||
mChannelName = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.BROADCAST_CHANNEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mChannelName != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(AliasID id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if(isValid())
|
||||
{
|
||||
return "Broadcast Channel: " + mChannelName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Broadcast Channel: None Selected";
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user