Compare commits
418 Commits
v0.2.0-bet
...
v0.3.2-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b42e64f50 | ||
|
|
1ddc0a33a5 | ||
|
|
88580af436 | ||
|
|
64688a3c20 | ||
|
|
8be3399a6b | ||
|
|
28340809ca | ||
|
|
f3d3a8187a | ||
|
|
8484e837b8 | ||
|
|
01b188ea25 | ||
|
|
108691dc3c | ||
|
|
455aa97286 | ||
|
|
d608834214 | ||
|
|
41660e1881 | ||
|
|
110ccb158c | ||
|
|
64ccacf04a | ||
|
|
f00b9555fe | ||
|
|
85442a9648 | ||
|
|
c67a0b329d | ||
|
|
8035d64fcd | ||
|
|
df2a061a08 | ||
|
|
e430319937 | ||
|
|
724f769771 | ||
|
|
c196cfebed | ||
|
|
e80b5866d4 | ||
|
|
c8994d5593 | ||
|
|
99ef57c90f | ||
|
|
be62ae0459 | ||
|
|
b9be6f43e0 | ||
|
|
d5ad3f807d | ||
|
|
d85ebd018d | ||
|
|
ab4e31ae00 | ||
|
|
5efd89632e | ||
|
|
1dc3863489 | ||
|
|
441286ba13 | ||
|
|
e4323df347 | ||
|
|
a872e0d664 | ||
|
|
fbc92cfe31 | ||
|
|
1a432197ac | ||
|
|
fbc6e508bd | ||
|
|
f9b6e67b00 | ||
|
|
a628800a71 | ||
|
|
25f71a76c4 | ||
|
|
5fe8ccd478 | ||
|
|
069f951a86 | ||
|
|
dab6df7836 | ||
|
|
89da46b63c | ||
|
|
5f2ce2a9f2 | ||
|
|
7a0b377971 | ||
|
|
5dbe0ecce3 | ||
|
|
6647c581a6 | ||
|
|
a2ab5bfa95 | ||
|
|
ed486440b8 | ||
|
|
13464e01fc | ||
|
|
ea46a8b0e8 | ||
|
|
d510c34356 | ||
|
|
ae8a44caed | ||
|
|
1aa85a86ca | ||
|
|
17539d4d55 | ||
|
|
1db1d28390 | ||
|
|
37a941e904 | ||
|
|
57f6655824 | ||
|
|
4cd8f8209f | ||
|
|
61bfef5798 | ||
|
|
ef172a04c6 | ||
|
|
a877afcceb | ||
|
|
980ad72d4d | ||
|
|
9b746cc032 | ||
|
|
f51ae0b5da | ||
|
|
561078e9bf | ||
|
|
e052b01f9b | ||
|
|
09cf4fcfd7 | ||
|
|
5e731d0e9f | ||
|
|
670a02b0ba | ||
|
|
9ef156b061 | ||
|
|
d9cf1b19f3 | ||
|
|
a4a339b505 | ||
|
|
119370c46e | ||
|
|
4eb66e6045 | ||
|
|
8827ecd0e9 | ||
|
|
8660002f93 | ||
|
|
2058fcbc1d | ||
|
|
9515dfa380 | ||
|
|
9e9a604c6a | ||
|
|
234e313b7a | ||
|
|
e1e7169029 | ||
|
|
f3605db0ed | ||
|
|
c0a6d578c7 | ||
|
|
79b4b30ec7 | ||
|
|
17c7466c6b | ||
|
|
8162d6ffd6 | ||
|
|
cd60251337 | ||
|
|
5647879b37 | ||
|
|
6916d95cdf | ||
|
|
a0c32f6fe0 | ||
|
|
c3d60dc174 | ||
|
|
e55a2226a2 | ||
|
|
9f01678b00 | ||
|
|
46425e9cae | ||
|
|
3726401563 | ||
|
|
a3e50acfe3 | ||
|
|
cf0018e6ba | ||
|
|
e8055dcab0 | ||
|
|
fce3d5c4f3 | ||
|
|
9cc0d367a8 | ||
|
|
2ca9e5d5ce | ||
|
|
861203c3a0 | ||
|
|
7c930deefe | ||
|
|
0e0af932eb | ||
|
|
6ba5e91fcb | ||
|
|
34dd2161ef | ||
|
|
2543072e08 | ||
|
|
281be147f8 | ||
|
|
12ecca4555 | ||
|
|
4c27d04120 | ||
|
|
ece202315f | ||
|
|
6afe5dcec9 | ||
|
|
8db47c25bc | ||
|
|
6a340050c6 | ||
|
|
183eb2f7c7 | ||
|
|
6bc92e8b94 | ||
|
|
767b302ed7 | ||
|
|
952d930b5b | ||
|
|
26087c465f | ||
|
|
74c15d530b | ||
|
|
8621d1c8e2 | ||
|
|
1cd45a1b79 | ||
|
|
8215b78a43 | ||
|
|
f53519ad59 | ||
|
|
e6ab615931 | ||
|
|
0c84984fcc | ||
|
|
b3e493989e | ||
|
|
50e838749d | ||
|
|
c097e536e0 | ||
|
|
a228f29a40 | ||
|
|
74aab2cc72 | ||
|
|
3543712fd3 | ||
|
|
4780f00c44 | ||
|
|
7e4acc568c | ||
|
|
a1757686e9 | ||
|
|
960bf975d9 | ||
|
|
57a52a662a | ||
|
|
f7c144ca16 | ||
|
|
f63b05c1e4 | ||
|
|
78a4bfe915 | ||
|
|
3b2ff7144b | ||
|
|
cd9bb5a84d | ||
|
|
37d447066d | ||
|
|
2ec882a87f | ||
|
|
7b9004af08 | ||
|
|
eba9367674 | ||
|
|
8ffe91911b | ||
|
|
a0e0a5ddc0 | ||
|
|
d500346ba2 | ||
|
|
3283b66bdc | ||
|
|
c16416ab14 | ||
|
|
5e46e22721 | ||
|
|
97e2ac31cd | ||
|
|
a302d098de | ||
|
|
b9e1efa92f | ||
|
|
07933831d2 | ||
|
|
e2e00a98d5 | ||
|
|
ea0e1b152f | ||
|
|
afa451a070 | ||
|
|
eaeedc53fc | ||
|
|
1786ffac47 | ||
|
|
8b403e6d87 | ||
|
|
8a8fbc4936 | ||
|
|
3c9c7794c9 | ||
|
|
48d3d7a8c1 | ||
|
|
d81ef8db2a | ||
|
|
3d644c2460 | ||
|
|
6e94d9ce51 | ||
|
|
523ac0314e | ||
|
|
b252159250 | ||
|
|
2168ed112e | ||
|
|
2faaa93785 | ||
|
|
7dc32954bf | ||
|
|
a57183c4cc | ||
|
|
8fb2a66411 | ||
|
|
26837b8a68 | ||
|
|
6b67a74055 | ||
|
|
2d9c3c0aa4 | ||
|
|
ce47d2545d | ||
|
|
5f179c4863 | ||
|
|
acabab35ff | ||
|
|
929fbdb21e | ||
|
|
95a6deaae1 | ||
|
|
bc8873de01 | ||
|
|
16b69d4aef | ||
|
|
7115b4feb1 | ||
|
|
6a9e522d77 | ||
|
|
c39c49b049 | ||
|
|
471685b576 | ||
|
|
2268879cec | ||
|
|
86e4ce817d | ||
|
|
75cb6c27d4 | ||
|
|
1352ef9092 | ||
|
|
8a150451c4 | ||
|
|
5ff3f4169a | ||
|
|
b6498d048a | ||
|
|
488dc9da4c | ||
|
|
4481560c41 | ||
|
|
1dbdede5a2 | ||
|
|
6bfe98dae6 | ||
|
|
de9c51c228 | ||
|
|
7865e813de | ||
|
|
a55296eb45 | ||
|
|
2c558ce929 | ||
|
|
49a1ea04f8 | ||
|
|
2226306de3 | ||
|
|
0cf26da94e | ||
|
|
59671738a2 | ||
|
|
c6f4d6da05 | ||
|
|
2d07734cc5 | ||
|
|
ad377f4006 | ||
|
|
648b12fd16 | ||
|
|
bc430b255f | ||
|
|
4578e45f60 | ||
|
|
42c18341b6 | ||
|
|
e71a1dbeda | ||
|
|
a4e3c53ba8 | ||
|
|
0cebe7e5d9 | ||
|
|
5611f594c7 | ||
|
|
524a76e583 | ||
|
|
c216f56c4f | ||
|
|
5e4cbf2a4e | ||
|
|
1d7354b4a8 | ||
|
|
d085ecc0c9 | ||
|
|
1c8362c1fc | ||
|
|
b65ff17ede | ||
|
|
ebca330730 | ||
|
|
ef373daeef | ||
|
|
4290d8e403 | ||
|
|
293dec8a1c | ||
|
|
f44892c62b | ||
|
|
b71415b82a | ||
|
|
ecfac83eb4 | ||
|
|
357979a5dd | ||
|
|
893cbba277 | ||
|
|
ac23aea602 | ||
|
|
a43ae9ce53 | ||
|
|
02f470cf91 | ||
|
|
6138838d60 | ||
|
|
2537a71375 | ||
|
|
9031fd78c9 | ||
|
|
e75290c42c | ||
|
|
d466ec9f5e | ||
|
|
3af4b953f4 | ||
|
|
cc65d44237 | ||
|
|
ae6ccc5d51 | ||
|
|
77cdcf1862 | ||
|
|
bccd4f0e32 | ||
|
|
a76268b32c | ||
|
|
ba31015423 | ||
|
|
c635dc5d79 | ||
|
|
d57c485450 | ||
|
|
6e1f28917e | ||
|
|
6af24ffa38 | ||
|
|
b19bfb400e | ||
|
|
a56935f92c | ||
|
|
b33c0359ef | ||
|
|
078a6fddce | ||
|
|
bf5ded53e2 | ||
|
|
3c53f864c4 | ||
|
|
61d9698ca5 | ||
|
|
8fec7c7314 | ||
|
|
90324404b2 | ||
|
|
d520f43265 | ||
|
|
192d39294b | ||
|
|
129dba869f | ||
|
|
72390cc62a | ||
|
|
5cd51c3199 | ||
|
|
097884337b | ||
|
|
3231e9828b | ||
|
|
5672182609 | ||
|
|
631ce112bd | ||
|
|
c3d52ff86e | ||
|
|
03e641525c | ||
|
|
64fee2c718 | ||
|
|
55443b42f3 | ||
|
|
3caadf0c90 | ||
|
|
58160d6c6b | ||
|
|
112083a22f | ||
|
|
f2b189ee2b | ||
|
|
3f0581dad1 | ||
|
|
e89e7bd361 | ||
|
|
d93f497b33 | ||
|
|
f32c520cab | ||
|
|
13617e8fe2 | ||
|
|
4adffbdca7 | ||
|
|
7a5dc5ad58 | ||
|
|
d3e8816bb4 | ||
|
|
6bb417f69a | ||
|
|
a4d69ce0aa | ||
|
|
45f0e09d5a | ||
|
|
f518c15a06 | ||
|
|
6eade2b7ea | ||
|
|
86816228c2 | ||
|
|
0605760fcd | ||
|
|
415f95ec89 | ||
|
|
1078bdc4fd | ||
|
|
218eeb1848 | ||
|
|
9d4afb8c1f | ||
|
|
6fa3089bc9 | ||
|
|
9273f679f4 | ||
|
|
b6e4c4e7aa | ||
|
|
2394ac2fa9 | ||
|
|
8aebdd1c26 | ||
|
|
8b11fabf3d | ||
|
|
4ad16296d8 | ||
|
|
e8fd4f363a | ||
|
|
00d2b43c2a | ||
|
|
2c3dbe1b22 | ||
|
|
6d1e7a78cf | ||
|
|
d1ea8656c4 | ||
|
|
e31b6adf52 | ||
|
|
63cea60c42 | ||
|
|
ece555dead | ||
|
|
15716d1270 | ||
|
|
8d10b502ab | ||
|
|
62851351a4 | ||
|
|
daf2b58cf2 | ||
|
|
cf2c0ca07d | ||
|
|
eead22ffad | ||
|
|
1550c62782 | ||
|
|
5f2d8c8fe6 | ||
|
|
22d3871d0b | ||
|
|
455e45269c | ||
|
|
ca8406bdc0 | ||
|
|
399d164bd0 | ||
|
|
6f2a7e89a9 | ||
|
|
a807ff5c07 | ||
|
|
e5004f9fa6 | ||
|
|
bd09911e68 | ||
|
|
ca2b12b868 | ||
|
|
7ff9e9a7ce | ||
|
|
7da541ed06 | ||
|
|
d90684dbdc | ||
|
|
9286fdf42d | ||
|
|
b821588e54 | ||
|
|
62aca27e66 | ||
|
|
cdcc487095 | ||
|
|
d5b6589e36 | ||
|
|
be7ab871d1 | ||
|
|
294a830aaf | ||
|
|
a7da60cd27 | ||
|
|
894ebeb040 | ||
|
|
682fe0c779 | ||
|
|
62c5265bce | ||
|
|
1687ca2c4b | ||
|
|
5ee4a48ab3 | ||
|
|
c8328b3eff | ||
|
|
691e4c3383 | ||
|
|
5573b9a9fb | ||
|
|
f7f6c2fc3e | ||
|
|
88d3088ebc | ||
|
|
dc3390460a | ||
|
|
8db226cd7b | ||
|
|
b7a54598b1 | ||
|
|
dd22397f75 | ||
|
|
e2a0451bfb | ||
|
|
e7d3713791 | ||
|
|
2c6e35c739 | ||
|
|
1f654b5b9c | ||
|
|
1d7f255784 | ||
|
|
3f674c0b8f | ||
|
|
5071205e73 | ||
|
|
37a93c8884 | ||
|
|
12ff5513b7 | ||
|
|
bca39e74ce | ||
|
|
75714072b2 | ||
|
|
15edcdebe6 | ||
|
|
da924e8b3a | ||
|
|
61f68c08e8 | ||
|
|
ec10bb7e62 | ||
|
|
7d1ec344de | ||
|
|
4be63d4b95 | ||
|
|
c405ddad96 | ||
|
|
d8a20b5adb | ||
|
|
c670f1d855 | ||
|
|
1dc0125ef4 | ||
|
|
225e747d6e | ||
|
|
36f9953156 | ||
|
|
47c452e7e6 | ||
|
|
06c8bba97e | ||
|
|
a25bb83dea | ||
|
|
8e11cb4554 | ||
|
|
2892e4609e | ||
|
|
d6e161f3e9 | ||
|
|
ba952af721 | ||
|
|
d9be346d7f | ||
|
|
133adec27a | ||
|
|
981a8fec55 | ||
|
|
9c94266adb | ||
|
|
4460f1ee30 | ||
|
|
ddfefe4b85 | ||
|
|
debdc39a5f | ||
|
|
6f76f6fca4 | ||
|
|
1290b8c4d3 | ||
|
|
b95b3ff415 | ||
|
|
3e8db5b216 | ||
|
|
f0c11f2590 | ||
|
|
99a5fc9bcf | ||
|
|
f5fadc5004 | ||
|
|
c922029233 | ||
|
|
94d85f636d | ||
|
|
1db6779dec | ||
|
|
676d26f4d8 | ||
|
|
abca4ebbd7 | ||
|
|
cffc6b6eed | ||
|
|
39ebec78a8 | ||
|
|
4066a4b3c3 | ||
|
|
c12f535f3c | ||
|
|
810bb7384e | ||
|
|
0c5692cb1e | ||
|
|
663378ad20 | ||
|
|
5807bb191e | ||
|
|
ab9ef2d8cc |
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<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"/>
|
||||
@@ -25,5 +24,11 @@
|
||||
<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>
|
||||
|
||||
7
.gitignore
vendored
@@ -1,3 +1,6 @@
|
||||
/*.class
|
||||
*.class
|
||||
/classes*
|
||||
/product*
|
||||
/product*
|
||||
/bin*
|
||||
.directory
|
||||
.settings
|
||||
9
.idea/codeStyleSettings.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?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
Normal file
@@ -0,0 +1,22 @@
|
||||
<?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
Normal file
@@ -0,0 +1,9 @@
|
||||
<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
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
||||
25
.idea/dictionaries/denny.xml
generated
Normal file
@@ -0,0 +1,25 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="denny">
|
||||
<words>
|
||||
<w>bahroo</w>
|
||||
<w>broadcastify</w>
|
||||
<w>esnid</w>
|
||||
<w>fleetsync</w>
|
||||
<w>icecast</w>
|
||||
<w>ident</w>
|
||||
<w>overflowable</w>
|
||||
<w>polyphase</w>
|
||||
<w>remez</w>
|
||||
<w>samplerate</w>
|
||||
<w>sdrtrunk</w>
|
||||
<w>sheirer</w>
|
||||
<w>shoutcast</w>
|
||||
<w>streamable</w>
|
||||
<w>talkgroup</w>
|
||||
<w>tgid</w>
|
||||
<w>ultravox</w>
|
||||
<w>wacn</w>
|
||||
<w>xtea</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
35
.idea/libraries/imports.xml
generated
Normal file
@@ -0,0 +1,35 @@
|
||||
<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>
|
||||
20
.idea/libraries/org_asynchttpclient_async_http_client_2_0_18.xml
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
<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>
|
||||
44
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,44 @@
|
||||
<?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>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?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
Normal file
@@ -0,0 +1,124 @@
|
||||
<?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>
|
||||
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
6
.project
@@ -5,6 +5,11 @@
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
@@ -13,5 +18,6 @@
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
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.7
|
||||
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.7
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
||||
39
CHANGELOG
@@ -1,13 +1,44 @@
|
||||
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
|
||||
|
||||
0.2.0 2015xxxx
|
||||
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
|
||||
stream can be independently configured with a delay. Audio calls are directed
|
||||
to one or more streams by attaching one or more stream identifiers to each alias.
|
||||
- Extensive GUI updates for tuner, channel and alias management. Includes new
|
||||
'Now Playing' channel view and 'Detail' view.
|
||||
- Updated alias list management of alias id values and wildcards. Weighting is now
|
||||
applied to each wildcard so that they can be ordered from most specific to least
|
||||
specific for lookup value matching purposes.
|
||||
- Added handling for Motorola-specific P25 patch messages and auto-generation of
|
||||
patch group aliases that roll-up aliases from each patched talkgroup to support
|
||||
audio recording and streaming of patch calls according to the identifiers and
|
||||
actions defined for each of the patched talkgroups.
|
||||
- Implemented bounded queues for both tuner and individual channel IQ sample
|
||||
buffers. Bounded queues have ability to enter/exit overflow state when queue
|
||||
size reaches overflow threshold and reset when queue size falls below the reset
|
||||
threshold. Channel state will show OVERFLOW in red/yellow.
|
||||
- Improves handling of P25 TDMA channels (NO Phase 2 decoder support yet)
|
||||
- Updated airspy controller for airspy-mini specific sample rate handling.
|
||||
- New developer remez filter designer tool and internal usage
|
||||
|
||||
0.2.0 20160329
|
||||
- Major overhaul of underlying processing chain and extensive updates to all
|
||||
decoders and filters
|
||||
- New audio playback interface with global mute and support for one or two
|
||||
audio channels
|
||||
- Audio playback is prioritized using a new Call Priority alias action
|
||||
- Audio playback is prioritized using a new Call Priority name action
|
||||
with selected channels having the highest priority and any audio without
|
||||
an alias identifier having the lowest priority.
|
||||
- Updated Audio recording per call with new 'Non-Recordable' alias action
|
||||
an name identifier having the lowest priority.
|
||||
- Updated Audio recording per call with new 'Non-Recordable' name action
|
||||
- Updated Baseband (I/Q) recording at 48 kHz
|
||||
- Added Airspy tuner support
|
||||
- New traffic channel pool manager for trunked call following
|
||||
|
||||
@@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
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
|
||||
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
17
README.md
@@ -2,18 +2,9 @@
|
||||
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](https://github.com/DSheirer/sdrtrunk/wiki/UserManual)
|
||||
* [Download](https://drive.google.com/folderview?id=0B7BHsssXUq8eOHBTNndCczZTd0k&usp=sharing)
|
||||
* [User's Manual Version 0.3.0](https://github.com/DSheirer/sdrtrunk/wiki/UserManual_Version0.3.0)
|
||||
* [Download](https://github.com/DSheirer/sdrtrunk/releases)
|
||||
* [Support](https://groups.google.com/forum/#!forum/sdrtrunk)
|
||||
|
||||

|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-67489234-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||

|
||||
**Figure 1:** sdrtrunk **Version 0.3.0** Application Screenshot
|
||||
|
||||
39
bin/dsp/filter/design/FilterView.css
Normal file
@@ -0,0 +1,39 @@
|
||||
/* ....Show License.... */
|
||||
.chart {
|
||||
-fx-background-image: url("../../../../images/Curve-fitted-background.png");
|
||||
-fx-padding: 15 25 15 15;
|
||||
}
|
||||
.chart-plot-background {
|
||||
-fx-background-color: red;
|
||||
-fx-background-image: url("../../../../images/Curve-fitted-chart-background.png"),
|
||||
url("../../../../images/Curve-fitted-graph-gridlines.png");
|
||||
-fx-background-size: cover, auto;
|
||||
-fx-background-repeat: no-repeat, repeat;
|
||||
-fx-background-position: 0% 0%, 0% 100%;
|
||||
-fx-border-color: black black transparent transparent;
|
||||
}
|
||||
.chart-area-symbol {
|
||||
-fx-background-color: white;
|
||||
}
|
||||
.chart-series-area-line {
|
||||
-fx-stroke: white;
|
||||
-fx-stroke-width: 2px;
|
||||
}
|
||||
.chart-series-area-fill {
|
||||
-fx-fill: linear-gradient(to right, white, rgba(255,255,255,0));
|
||||
-fx-blend-mode: OVERLAY;
|
||||
}
|
||||
.axis {
|
||||
-fx-tick-mark-visible: false;
|
||||
-fx-minor-tick-visible: false;
|
||||
-fx-tick-length: 3;
|
||||
-fx-minor-tick-length: 0;
|
||||
-fx-border-color: transparent;
|
||||
-fx-tick-label-fill: white;
|
||||
}
|
||||
.axis:bottom {
|
||||
-fx-border-color: black transparent transparent transparent;
|
||||
}
|
||||
.axis:left {
|
||||
-fx-border-color: transparent black transparent transparent;
|
||||
}
|
||||
233
build/build.xml
@@ -1,119 +1,142 @@
|
||||
<project name="SDRTrunk" default="SDRTrunk" basedir=".">
|
||||
<description>
|
||||
Ant build script for SDRTrunk Decoder Application
|
||||
</description>
|
||||
<description>
|
||||
Ant build script for SDRTrunk Decoder Application
|
||||
</description>
|
||||
|
||||
<!-- version properties -->
|
||||
<property name="major" value="0"/>
|
||||
<property name="minor" value="2"/>
|
||||
<property name="build" value="0"/>
|
||||
<property name="release" value="beta.2"/>
|
||||
<!-- version properties -->
|
||||
<property name="major" value="0"/>
|
||||
<property name="minor" value="3"/>
|
||||
<property name="patch" value="1"/>
|
||||
<property name="release" value=""/> <!-- Use dash (-) prefix (e.g. -beta1) -->
|
||||
<property name="filename" value="sdrtrunk_${major}.${minor}.${patch}${release}"/>
|
||||
|
||||
<!-- Build properties -->
|
||||
<property name="classes" location="../classes"/>
|
||||
<property name="configs" location="../config"/>
|
||||
<property name="images" location="../images"/>
|
||||
<property name="libs" location="../imports"/>
|
||||
<property name="license" location="../license"/>
|
||||
<property name="product" location="../product"/>
|
||||
<property name="scripts" location="../scripts"/>
|
||||
<property name="src" location="../src"/>
|
||||
<!-- 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"/>
|
||||
|
||||
<path id="classpath">
|
||||
<fileset dir="${libs}" includes="*.jar" />
|
||||
</path>
|
||||
|
||||
<target name="init">
|
||||
<!-- Create the classes folder to contain the compiled java classes -->
|
||||
<mkdir dir="${classes}"/>
|
||||
|
||||
<!-- Create version file -->
|
||||
<echo message="${major}.${minor}.${build}-${release}" file="${classes}/sdrtrunk-version"/>
|
||||
</target>
|
||||
<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"/>
|
||||
|
||||
<target name="compile" depends="clean,init"
|
||||
description="Compile java classes" >
|
||||
<!-- Compile the java code from ${src} into ${classes} -->
|
||||
<javac srcdir="${src}"
|
||||
destdir="${classes}"
|
||||
classpathref="classpath"
|
||||
includeantruntime="false" />
|
||||
</target>
|
||||
<path id="classpath">
|
||||
<fileset dir="${source.libs}" includes="*.jar"/>
|
||||
</path>
|
||||
|
||||
<target name="SDRTrunk" depends="compile" description="Create SDRTrunk application" >
|
||||
<!-- Create the distribution directory -->
|
||||
<mkdir dir="${product}"/>
|
||||
<target name="init">
|
||||
<!-- Create the classes folder to contain the compiled java classes -->
|
||||
<mkdir dir="${output.classes}"/>
|
||||
|
||||
<!-- Create jar file -->
|
||||
<jar jarfile="${product}/SDRTrunk.jar" basedir="${classes}">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="gui.SDRTrunk"/>
|
||||
</manifest>
|
||||
<fileset dir="${configs}">
|
||||
<exclude name="*.rules"/>
|
||||
</fileset>
|
||||
|
||||
<fileset dir="${license}">
|
||||
<include name="license.txt"/>
|
||||
</fileset>
|
||||
</jar>
|
||||
|
||||
<!-- Copy third-party libraries -->
|
||||
<mkdir dir="${product}/libs"/>
|
||||
<copy todir="${product}/libs">
|
||||
<fileset dir="${libs}" includes="*.jar" />
|
||||
</copy>
|
||||
|
||||
<!-- Copy config files -->
|
||||
<mkdir dir="${product}/config"/>
|
||||
<!-- Create version file -->
|
||||
<echo message="${major}.${minor}.${patch}${release}" file="${output.classes}/sdrtrunk-version"/>
|
||||
</target>
|
||||
|
||||
<copy todir="${product}/config">
|
||||
<fileset dir="${configs}">
|
||||
<include name="*.rules"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Copy image files -->
|
||||
<mkdir dir="${product}/images"/>
|
||||
<copy todir="${product}/images">
|
||||
<fileset dir="${images}" />
|
||||
</copy>
|
||||
|
||||
<!-- Copy license file -->
|
||||
<copy todir="${product}">
|
||||
<fileset dir="${license}" />
|
||||
</copy>
|
||||
|
||||
<!-- Copy program scripts -->
|
||||
<copy todir="${product}">
|
||||
<fileset dir="${scripts}" />
|
||||
</copy>
|
||||
<target name="compile" depends="clean,init,compile-java-8,compile-java-9"
|
||||
description="Compile java classes" />
|
||||
|
||||
<!-- Set linux permissions on start script -->
|
||||
<chmod file="${product}/run_sdrtrunk_linux.sh" perm="777" />
|
||||
|
||||
<tstamp prefix="build" />
|
||||
<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>
|
||||
|
||||
<property name="filename" value="sdrtrunk_${build.DSTAMP}_${build.TSTAMP}_${major}.${minor}.${build}-${release}"/>
|
||||
<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>
|
||||
|
||||
<!-- Bundle the files into .zip -->
|
||||
<zip destfile="${product}/${filename}.zip" basedir="${product}" />
|
||||
|
||||
<!-- Bundle the files into .tar.gz to preserve linux script permissions -->
|
||||
<tar destfile="${product}/${filename}.tar.gz" compression="gzip">
|
||||
<tarfileset dir="${product}" filemode="777">
|
||||
<include name="*.sh"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="${product}">
|
||||
<exclude name="*.sh"/>
|
||||
<exclude name="${filename}.zip"/>
|
||||
</tarfileset>
|
||||
</tar>
|
||||
</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="clean" description="Clean previous build artifacts" >
|
||||
<delete dir="${classes}"/>
|
||||
<delete dir="${product}"/>
|
||||
</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,4 +1,6 @@
|
||||
<configuration>
|
||||
<conversionRule conversionWord="memory_usage" converterClass="util.MemoryUsageLogger" />
|
||||
|
||||
<timestamp key="appstart" datePattern="HHmmss"/>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
@@ -9,7 +11,7 @@
|
||||
<maxHistory>10</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%-25(%d{yyyyMMdd HHmmss.SSS} [%thread]) %-5level %logger{30} - %msg%n</pattern>
|
||||
<pattern>%-25(%d{yyyyMMdd HHmmss.SSS} [%thread]) %-5level %logger{30} - %msg %memory_usage%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
@@ -19,7 +21,7 @@
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-12(%d{HH:mm:ss.SSS}) %-5level %logger{25} - %msg%n</pattern>
|
||||
<pattern>%-12(%d{HH:mm:ss.SSS}) %-5level %logger{25} - %msg %memory_usage%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
@@ -27,4 +29,7 @@
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<!-- Apache Mina TCP/HTTP library -->
|
||||
<logger name="org.apache.mina" level="INFO" />
|
||||
|
||||
</configuration>
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2015 Dennis Sheirer
|
||||
* 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
|
||||
BIN
images/Curve-fitted-background.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
images/Curve-fitted-chart-background.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
images/Curve-fitted-graph-gridlines.png
Normal file
|
After Width: | Height: | Size: 152 B |
BIN
images/broadcastify.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
images/control_play.png
Normal file
|
After Width: | Height: | Size: 592 B |
BIN
images/control_stop.png
Normal file
|
After Width: | Height: | Size: 403 B |
BIN
images/icecast.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 688 B After Width: | Height: | Size: 743 B |
BIN
images/shoutcast.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
imports/activation-1.1.jar
Normal file
BIN
imports/axis.jar
Normal file
BIN
imports/commons-codec-1.9.jar
Normal file
BIN
imports/commons-discovery-0.2.jar
Normal file
BIN
imports/commons-logging-1.2.jar
Normal file
BIN
imports/java-lame-3.98.4.jar
Normal file
BIN
imports/java-mail-1.4.jar
Normal file
BIN
imports/javassist-3.20.0-GA.jar
Normal file
BIN
imports/jaxrpc.jar
Normal file
BIN
imports/libusb4java-1.2.0-linux-aarch64.jar
Normal file
BIN
imports/mina-core-2.0.16.jar
Normal file
BIN
imports/mina-http-2.0.16.jar
Normal file
BIN
imports/radioreference-14.jar
Normal file
BIN
imports/slf4j-api-1.7.21.jar
Normal file
BIN
imports/tablefilter-swing-5.2.1.jar
Normal file
BIN
imports/wsdl4j-1.5.1.jar
Normal file
16
scripts/run_sdrtrunk_linux.sh
Normal file → Executable file
@@ -1,2 +1,16 @@
|
||||
#!/bin/bash
|
||||
java -XX:+UseG1GC -cp "*:libs/*" gui.SDRTrunk&
|
||||
|
||||
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 +1,25 @@
|
||||
java -XX:+UseG1GC -cp "SDRTrunk.jar;*;libs/*;config/*;images/*" gui.SDRTrunk
|
||||
@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
|
||||
|
||||
25
sdrtrunk.iml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -19,32 +19,51 @@ 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.priority.Priority;
|
||||
import audio.inverted.AudioType;
|
||||
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 ArrayList<AliasID> mAliasIDs = new ArrayList<AliasID>();
|
||||
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
|
||||
@XmlAttribute( name="name" )
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
@@ -55,6 +74,38 @@ public class Alias
|
||||
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()
|
||||
{
|
||||
@@ -66,9 +117,9 @@ public class Alias
|
||||
mColor = color;
|
||||
}
|
||||
|
||||
public Color getMapColor()
|
||||
public Color getDisplayColor()
|
||||
{
|
||||
return new Color( mColor );
|
||||
return new Color( getColor() );
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
@@ -82,7 +133,8 @@ public class Alias
|
||||
mIconName = iconName;
|
||||
}
|
||||
|
||||
public ArrayList<AliasID> getId()
|
||||
@XmlElement( name="id" )
|
||||
public List<AliasID> getId()
|
||||
{
|
||||
return mAliasIDs;
|
||||
}
|
||||
@@ -102,6 +154,7 @@ public class Alias
|
||||
mAliasIDs.remove( id );
|
||||
}
|
||||
|
||||
@XmlElement( name="action" )
|
||||
public List<AliasAction> getAction()
|
||||
{
|
||||
return mAliasActions;
|
||||
@@ -126,41 +179,22 @@ public class Alias
|
||||
{
|
||||
return !mAliasActions.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasAudioType()
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.hasAudioType() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public AudioType getAudioType()
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.hasAudioType() )
|
||||
{
|
||||
return id.getAudioType();
|
||||
}
|
||||
}
|
||||
|
||||
return AudioType.NORMAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
if( id.getType() == AliasIDType.PRIORITY)
|
||||
{
|
||||
return ((Priority)id).getPriority();
|
||||
}
|
||||
@@ -169,11 +203,11 @@ public class Alias
|
||||
return Priority.DEFAULT_PRIORITY;
|
||||
}
|
||||
|
||||
public boolean hasPriority()
|
||||
public boolean hasCallPriority()
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.getType() == AliasIDType.Priority )
|
||||
if( id.getType() == AliasIDType.PRIORITY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -181,15 +215,40 @@ public class Alias
|
||||
|
||||
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.NonRecordable )
|
||||
if( id.getType() == AliasIDType.NON_RECORDABLE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -197,4 +256,99 @@ public class Alias
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
356
src/alias/AliasController.java
Normal file
@@ -0,0 +1,356 @@
|
||||
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,91 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import controller.ConfigurableNode;
|
||||
|
||||
public class AliasDirectoryNode extends ConfigurableNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AliasDirectoryNode( AliasDirectory directory )
|
||||
{
|
||||
super( directory );
|
||||
}
|
||||
|
||||
public AliasDirectory getAliasDirectory()
|
||||
{
|
||||
return (AliasDirectory)getUserObject();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
for( AliasList list: getAliasDirectory().getAliasList() )
|
||||
{
|
||||
AliasListNode node = new AliasListNode( list );
|
||||
|
||||
getModel().addNode( node, AliasDirectoryNode.this, getChildCount() );
|
||||
|
||||
node.init();
|
||||
}
|
||||
|
||||
sort();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Alias Lists [" + this.getChildCount() + "]";
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenuItem addItem = new JMenuItem( "Add Alias List" );
|
||||
addItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
AliasList list = new AliasList();
|
||||
|
||||
getAliasDirectory().addAliasList( list );
|
||||
|
||||
AliasListNode node = new AliasListNode( list );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasDirectoryNode.this,
|
||||
AliasDirectoryNode.this.getChildCount() );
|
||||
|
||||
sort();
|
||||
|
||||
getModel().showNode( node );
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( addItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -17,189 +17,148 @@
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import gui.editor.Editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JColorChooser;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.JSeparator;
|
||||
|
||||
import map.MapIcon;
|
||||
import map.MapIconListCellRenderer;
|
||||
import icon.IconManager;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import sample.Listener;
|
||||
import settings.SettingsManager;
|
||||
import controller.ConfigurableNode;
|
||||
import controller.ResourceManager;
|
||||
import alias.action.AliasActionEditor;
|
||||
import alias.id.AliasIdentifierEditor;
|
||||
|
||||
public class AliasEditor extends JPanel implements ActionListener
|
||||
import com.jidesoft.swing.JideTabbedPane;
|
||||
|
||||
public class AliasEditor extends Editor<Alias>
|
||||
implements ActionListener, Listener<AliasEvent>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private AliasNode mAliasNode;
|
||||
private ResourceManager mResourceManager;
|
||||
|
||||
private JLabel mLabelName;
|
||||
private JTextField mTextAlias;
|
||||
|
||||
private JLabel mLabelMapColor;
|
||||
private JButton mButtonColor;
|
||||
private JComboBox<MapIcon> mComboMapIcon;
|
||||
private JButton mBtnIconManager;
|
||||
|
||||
public AliasEditor( AliasNode aliasNode, ResourceManager resourceManager )
|
||||
{
|
||||
mAliasNode = aliasNode;
|
||||
mResourceManager = resourceManager;
|
||||
|
||||
initGUI();
|
||||
}
|
||||
private static final String DEFAULT_NAME = "select an alias";
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
|
||||
private void initGUI()
|
||||
private JLabel mAliasLabel;
|
||||
private AliasNameEditor mAliasNameEditor;
|
||||
private AliasIdentifierEditor mAliasIdentifierEditor;
|
||||
private AliasActionEditor mAliasActionEditor;
|
||||
|
||||
public AliasEditor(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager )
|
||||
{
|
||||
setLayout( new MigLayout( "", "[right][grow,fill]", "[][][][][][grow][]" ) );
|
||||
mAliasModel = aliasModel;
|
||||
mAliasNameEditor = new AliasNameEditor( mAliasModel, iconManager );
|
||||
mAliasIdentifierEditor = new AliasIdentifierEditor( aliasModel, broadcastModel );
|
||||
mAliasActionEditor = new AliasActionEditor( aliasModel );
|
||||
|
||||
mAliasModel.addListener( this );
|
||||
|
||||
setBorder( BorderFactory.createTitledBorder( "Alias" ) );
|
||||
init();
|
||||
}
|
||||
|
||||
mLabelName = new JLabel( "Name:" );
|
||||
add( mLabelName );
|
||||
|
||||
@Override
|
||||
public void setItem( Alias alias )
|
||||
{
|
||||
super.setItem( alias );
|
||||
|
||||
mTextAlias = new JTextField( mAliasNode.getAlias().getName() );
|
||||
add( mTextAlias, "wrap" );
|
||||
|
||||
mLabelMapColor = new JLabel( "Map Color:" );
|
||||
add( mLabelMapColor );
|
||||
|
||||
mButtonColor = new JButton( "Map Color" );
|
||||
mButtonColor.setBackground( mAliasNode.getAlias().getMapColor() );
|
||||
mButtonColor.setForeground( mAliasNode.getAlias().getMapColor() );
|
||||
mButtonColor.addActionListener( new ActionListener()
|
||||
if( hasItem() )
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Color newColor = JColorChooser.showDialog(
|
||||
AliasEditor.this,
|
||||
"Choose color for map labels and routes",
|
||||
mAliasNode.getAlias().getMapColor() );
|
||||
|
||||
mButtonColor.setForeground( newColor );
|
||||
mButtonColor.setBackground( newColor );
|
||||
}
|
||||
} );
|
||||
add( mButtonColor, "wrap" );
|
||||
|
||||
add( new JLabel( "Icon:" ) );
|
||||
|
||||
mComboMapIcon = new JComboBox<MapIcon>(
|
||||
mResourceManager.getSettingsManager().getMapIcons() );
|
||||
|
||||
MapIconListCellRenderer renderer = new MapIconListCellRenderer();
|
||||
renderer.setPreferredSize( new Dimension( 200, 30 ) );
|
||||
mComboMapIcon.setRenderer( renderer );
|
||||
|
||||
String iconName = mAliasNode.getAlias().getIconName();
|
||||
|
||||
if( iconName == null )
|
||||
mAliasLabel.setText( getItem().getName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
iconName = SettingsManager.DEFAULT_ICON;
|
||||
mAliasLabel.setText( DEFAULT_NAME );
|
||||
}
|
||||
|
||||
MapIcon savedIcon = mResourceManager.getSettingsManager()
|
||||
.getMapIcon( iconName );
|
||||
mAliasNameEditor.setItem( alias );
|
||||
mAliasIdentifierEditor.setItem( alias );
|
||||
mAliasActionEditor.setItem( alias );
|
||||
}
|
||||
|
||||
if( savedIcon != null )
|
||||
{
|
||||
mComboMapIcon.setSelectedItem( savedIcon );
|
||||
}
|
||||
|
||||
add( mComboMapIcon, "wrap" );
|
||||
|
||||
//Dummy place holder
|
||||
add( new JLabel() );
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[grow,fill][grow,fill]",
|
||||
"[][][][][][grow,fill]" ) );
|
||||
|
||||
mBtnIconManager = new JButton( "Icon Manager" );
|
||||
mBtnIconManager.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent arg0 )
|
||||
{
|
||||
mResourceManager.getController().showIconManager();
|
||||
}
|
||||
} );
|
||||
add( mBtnIconManager, "span 2,wrap" );
|
||||
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 )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
if( hasItem() )
|
||||
{
|
||||
String alias = mTextAlias.getText();
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( alias != null )
|
||||
if( command.contentEquals( "Save" ) )
|
||||
{
|
||||
boolean expanded = mAliasNode.getModel().getTree()
|
||||
.isExpanded( new TreePath( mAliasNode ) );
|
||||
|
||||
mAliasNode.getAlias().setName( alias );
|
||||
((ConfigurableNode)mAliasNode.getParent()).sort();
|
||||
|
||||
mAliasNode.getAlias().setColor(
|
||||
mButtonColor.getBackground().getRGB() );
|
||||
|
||||
MapIcon selectedIcon = (MapIcon)mComboMapIcon.getSelectedItem();
|
||||
|
||||
if( selectedIcon != null )
|
||||
{
|
||||
mAliasNode.getAlias().setIconName( selectedIcon.getName() );
|
||||
}
|
||||
|
||||
mAliasNode.save();
|
||||
|
||||
mAliasNode.show();
|
||||
|
||||
if( expanded )
|
||||
{
|
||||
mAliasNode.getModel().getTree()
|
||||
.expandPath( new TreePath( mAliasNode ) );
|
||||
}
|
||||
save();
|
||||
}
|
||||
else
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
{
|
||||
JOptionPane.showMessageDialog( AliasEditor.this, "Please enter an alias name" );
|
||||
reset();
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
{
|
||||
mTextAlias.setText( mAliasNode.getAlias().getName() );
|
||||
|
||||
mButtonColor.setBackground( mAliasNode.getAlias().getMapColor() );
|
||||
mButtonColor.setForeground( mAliasNode.getAlias().getMapColor() );
|
||||
|
||||
MapIcon savedIcon = mResourceManager.getSettingsManager()
|
||||
.getMapIcon( mAliasNode.getAlias().getIconName() );
|
||||
|
||||
mComboMapIcon.setSelectedItem( savedIcon );
|
||||
}
|
||||
|
||||
mAliasNode.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
mAliasNameEditor.save();
|
||||
mAliasIdentifierEditor.save();
|
||||
mAliasActionEditor.save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -17,25 +17,39 @@
|
||||
******************************************************************************/
|
||||
package alias;
|
||||
|
||||
import audio.inverted.AudioType;
|
||||
|
||||
public abstract class AliasID
|
||||
public class AliasEvent
|
||||
{
|
||||
public AliasID()
|
||||
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 abstract AliasIDType getType();
|
||||
|
||||
public boolean hasAudioType()
|
||||
public Alias getAlias()
|
||||
{
|
||||
return false;
|
||||
return mAlias;
|
||||
}
|
||||
|
||||
public AudioType getAudioType()
|
||||
public Event getEvent()
|
||||
{
|
||||
return AudioType.NORMAL;
|
||||
return mEvent;
|
||||
}
|
||||
|
||||
public abstract boolean matches( AliasID id );
|
||||
/**
|
||||
* Channel events to describe the specific event
|
||||
*/
|
||||
public enum Event
|
||||
{
|
||||
ADD,
|
||||
CHANGE,
|
||||
DELETE;
|
||||
}
|
||||
}
|
||||
304
src/alias/AliasFactory.java
Normal file
@@ -0,0 +1,304 @@
|
||||
/*******************************************************************************
|
||||
* 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,35 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 controller.ConfigurableNode;
|
||||
|
||||
public class AliasIDNode extends ConfigurableNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AliasIDNode( AliasID id )
|
||||
{
|
||||
super( id );
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
getModel().getResourceManager().getPlaylistManager().save();
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JSeparator;
|
||||
|
||||
import controller.ConfigurableNode;
|
||||
|
||||
public class AliasListNode extends ConfigurableNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AliasListNode( AliasList list )
|
||||
{
|
||||
super( list );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor()
|
||||
{
|
||||
return new ListEditor( this );
|
||||
}
|
||||
|
||||
public AliasList getList()
|
||||
{
|
||||
return (AliasList)getUserObject();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
for( Group group: getList().getGroup() )
|
||||
{
|
||||
GroupNode node = new GroupNode( group );
|
||||
|
||||
getModel().addNode( node, AliasListNode.this, getChildCount() );
|
||||
|
||||
node.init();
|
||||
}
|
||||
|
||||
sort();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getList().getName() + " [" + this.getChildCount() + "]";
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenuItem addItem = new JMenuItem( "Add Group" );
|
||||
addItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Group group = new Group();
|
||||
|
||||
getList().addGroup( group );
|
||||
|
||||
GroupNode node = new GroupNode( group );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasListNode.this,
|
||||
AliasListNode.this.getChildCount() );
|
||||
|
||||
sort();
|
||||
|
||||
getModel().showNode( node );
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( addItem );
|
||||
|
||||
retVal.add( new JSeparator() );
|
||||
|
||||
JMenuItem deleteItem = new JMenuItem( "Delete" );
|
||||
deleteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
|
||||
"Are you sure you want to permanently delete this node?" );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
AliasDirectoryNode parent = (AliasDirectoryNode)getParent();
|
||||
|
||||
parent.getAliasDirectory().removeAliasList( getList() );
|
||||
|
||||
save();
|
||||
|
||||
getModel().removeNodeFromParent( AliasListNode.this );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( deleteItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
350
src/alias/AliasModel.java
Normal file
@@ -0,0 +1,350 @@
|
||||
/*******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
334
src/alias/AliasNameEditor.java
Normal file
@@ -0,0 +1,334 @@
|
||||
/*******************************************************************************
|
||||
* 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,562 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import map.MapIcon;
|
||||
import alias.action.AliasAction;
|
||||
import alias.action.beep.BeepAction;
|
||||
import alias.action.beep.BeepActionNode;
|
||||
import alias.action.clip.ClipAction;
|
||||
import alias.action.clip.ClipActionNode;
|
||||
import alias.action.script.ScriptAction;
|
||||
import alias.action.script.ScriptActionNode;
|
||||
import alias.id.esn.ESNNode;
|
||||
import alias.id.esn.Esn;
|
||||
import alias.id.fleetsync.FleetsyncID;
|
||||
import alias.id.fleetsync.FleetsyncIDNode;
|
||||
import alias.id.fleetsync.StatusID;
|
||||
import alias.id.fleetsync.StatusIDNode;
|
||||
import alias.id.lojack.LoJackFunctionAndID;
|
||||
import alias.id.lojack.LoJackIDNode;
|
||||
import alias.id.mdc.MDC1200ID;
|
||||
import alias.id.mdc.MDC1200IDNode;
|
||||
import alias.id.mobileID.MINNode;
|
||||
import alias.id.mobileID.Min;
|
||||
import alias.id.mpt1327.MPT1327ID;
|
||||
import alias.id.mpt1327.MPT1327IDNode;
|
||||
import alias.id.siteID.SiteID;
|
||||
import alias.id.siteID.SiteIDNode;
|
||||
import alias.id.talkgroup.TalkgroupID;
|
||||
import alias.id.talkgroup.TalkgroupIDNode;
|
||||
import alias.id.uniqueID.UniqueID;
|
||||
import alias.id.uniqueID.UniqueIDNode;
|
||||
import alias.priority.Priority;
|
||||
import alias.priority.PriorityNode;
|
||||
import alias.record.NonRecordable;
|
||||
import alias.record.NonRecordableNode;
|
||||
import controller.ConfigurableNode;
|
||||
|
||||
public class AliasNode extends ConfigurableNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AliasNode( Alias alias )
|
||||
{
|
||||
super( alias );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor()
|
||||
{
|
||||
return new AliasEditor( this, getModel().getResourceManager() );
|
||||
}
|
||||
|
||||
public Alias getAlias()
|
||||
{
|
||||
return (Alias)getUserObject();
|
||||
}
|
||||
|
||||
public String getIconPath()
|
||||
{
|
||||
String icon = getAlias().getIconName();
|
||||
|
||||
MapIcon mapIcon = getModel().getResourceManager()
|
||||
.getSettingsManager().getMapIcon( icon );
|
||||
|
||||
if( mapIcon != null )
|
||||
{
|
||||
return mapIcon.getPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
for( AliasID aliasID: getAlias().getId() )
|
||||
{
|
||||
switch( aliasID.getType() )
|
||||
{
|
||||
case ESN:
|
||||
getModel().addNode( new ESNNode( (Esn)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case Fleetsync:
|
||||
getModel().addNode( new FleetsyncIDNode( (FleetsyncID)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case LoJack:
|
||||
getModel().addNode( new LoJackIDNode( (LoJackFunctionAndID)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case LTRNetUID:
|
||||
getModel().addNode( new UniqueIDNode( (UniqueID)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case MDC1200:
|
||||
getModel().addNode( new MDC1200IDNode( (MDC1200ID)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case MIN:
|
||||
getModel().addNode( new MINNode( (Min)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case MPT1327:
|
||||
getModel().addNode( new MPT1327IDNode( (MPT1327ID)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case NonRecordable:
|
||||
getModel().addNode( new NonRecordableNode( (NonRecordable)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case Priority:
|
||||
getModel().addNode( new PriorityNode( (Priority)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case Site:
|
||||
getModel().addNode( new SiteIDNode( (SiteID)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case Status:
|
||||
getModel().addNode( new StatusIDNode( (StatusID)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
case Talkgroup:
|
||||
getModel().addNode( new TalkgroupIDNode( (TalkgroupID)aliasID ),
|
||||
AliasNode.this, getChildCount() );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unrecognized alias ID [" +
|
||||
aliasID.getType() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
for( AliasAction action: getAlias().getAction() )
|
||||
{
|
||||
if( action instanceof BeepAction )
|
||||
{
|
||||
getModel().addNode( new BeepActionNode( (BeepAction)action ),
|
||||
AliasNode.this, getChildCount() );
|
||||
}
|
||||
else if( action instanceof ClipAction )
|
||||
{
|
||||
getModel().addNode( new ClipActionNode( (ClipAction)action ),
|
||||
AliasNode.this, getChildCount() );
|
||||
}
|
||||
else if( action instanceof ScriptAction )
|
||||
{
|
||||
getModel().addNode( new ScriptActionNode( (ScriptAction)action ),
|
||||
AliasNode.this, getChildCount() );
|
||||
}
|
||||
}
|
||||
|
||||
sort();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getAlias().getName() + " [" + this.getChildCount() + "]";
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenu addIDMenu = new JMenu( "Add ID" );
|
||||
|
||||
JMenuItem addESNItem = new JMenuItem( "ESN" );
|
||||
addESNItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Esn esn = new Esn();
|
||||
|
||||
getAlias().addAliasID( esn );
|
||||
|
||||
ESNNode node = new ESNNode( esn );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addESNItem );
|
||||
|
||||
JMenuItem addFleetsyncItem = new JMenuItem( "Fleetsync" );
|
||||
addFleetsyncItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
FleetsyncID fs = new FleetsyncID();
|
||||
|
||||
getAlias().addAliasID( fs );
|
||||
|
||||
FleetsyncIDNode node = new FleetsyncIDNode( fs );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addFleetsyncItem );
|
||||
|
||||
JMenuItem addLoJackItem = new JMenuItem( "LoJack" );
|
||||
addLoJackItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
LoJackFunctionAndID lj = new LoJackFunctionAndID();
|
||||
|
||||
getAlias().addAliasID( lj );
|
||||
|
||||
LoJackIDNode node = new LoJackIDNode( lj );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addLoJackItem );
|
||||
|
||||
JMenuItem addMDCItem = new JMenuItem( "MDC-1200" );
|
||||
addMDCItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
MDC1200ID mdc = new MDC1200ID();
|
||||
|
||||
getAlias().addAliasID( mdc );
|
||||
|
||||
MDC1200IDNode node = new MDC1200IDNode( mdc );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addMDCItem );
|
||||
|
||||
JMenuItem addMINItem = new JMenuItem( "MIN" );
|
||||
addMINItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Min min = new Min();
|
||||
|
||||
getAlias().addAliasID( min );
|
||||
|
||||
MINNode node = new MINNode( min );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addMINItem );
|
||||
|
||||
JMenuItem addMPTItem = new JMenuItem( "MPT-1327" );
|
||||
addMPTItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
MPT1327ID mpt = new MPT1327ID();
|
||||
|
||||
getAlias().addAliasID( mpt );
|
||||
|
||||
MPT1327IDNode node = new MPT1327IDNode( mpt );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addMPTItem );
|
||||
|
||||
JMenuItem addSiteItem = new JMenuItem( "Site" );
|
||||
addSiteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
SiteID siteID = new SiteID();
|
||||
|
||||
getAlias().addAliasID( siteID );
|
||||
|
||||
SiteIDNode node = new SiteIDNode( siteID );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addSiteItem );
|
||||
|
||||
JMenuItem addStatusItem = new JMenuItem( "Status" );
|
||||
addStatusItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
StatusID statusID = new StatusID();
|
||||
|
||||
getAlias().addAliasID( statusID );
|
||||
|
||||
StatusIDNode node = new StatusIDNode( statusID );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
|
||||
addIDMenu.add( addStatusItem );
|
||||
|
||||
JMenuItem addTalkgroupItem = new JMenuItem( "Talkgroup" );
|
||||
addTalkgroupItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
TalkgroupID tg = new TalkgroupID();
|
||||
|
||||
getAlias().addAliasID( tg );
|
||||
|
||||
TalkgroupIDNode node = new TalkgroupIDNode( tg );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addTalkgroupItem );
|
||||
|
||||
JMenuItem addUniqueIDItem = new JMenuItem( "Unique ID" );
|
||||
addUniqueIDItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
UniqueID uid = new UniqueID();
|
||||
|
||||
getAlias().addAliasID( uid );
|
||||
|
||||
UniqueIDNode node = new UniqueIDNode( uid );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
addIDMenu.add( addUniqueIDItem );
|
||||
|
||||
retVal.add( addIDMenu );
|
||||
|
||||
JMenu addActionMenu = new JMenu( "Add Action" );
|
||||
|
||||
JMenuItem addClipItem = new JMenuItem( "Audio Clip" );
|
||||
|
||||
addClipItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
ClipAction clipAction = new ClipAction();
|
||||
|
||||
getAlias().addAliasAction( clipAction );
|
||||
|
||||
ClipActionNode node = new ClipActionNode( clipAction );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
|
||||
addActionMenu.add( addClipItem );
|
||||
|
||||
JMenuItem addBeepItem = new JMenuItem( "Beep" );
|
||||
|
||||
addBeepItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
BeepAction beepAction = new BeepAction();
|
||||
|
||||
getAlias().addAliasAction( beepAction );
|
||||
|
||||
BeepActionNode node = new BeepActionNode( beepAction );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
|
||||
addActionMenu.add( addBeepItem );
|
||||
|
||||
JMenuItem addScriptItem = new JMenuItem( "Script" );
|
||||
|
||||
addScriptItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
ScriptAction scriptAction = new ScriptAction();
|
||||
|
||||
getAlias().addAliasAction( scriptAction );
|
||||
|
||||
ScriptActionNode node = new ScriptActionNode( scriptAction );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
|
||||
addActionMenu.add( addScriptItem );
|
||||
|
||||
retVal.add( addActionMenu );
|
||||
|
||||
retVal.addSeparator();
|
||||
|
||||
if( getAlias().isRecordable() )
|
||||
{
|
||||
JMenuItem nonRecordableItem = new JMenuItem( "Set Non-Recordable" );
|
||||
|
||||
nonRecordableItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
NonRecordable non = new NonRecordable();
|
||||
|
||||
getAlias().addAliasID( non );
|
||||
|
||||
NonRecordableNode node = new NonRecordableNode( non );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( nonRecordableItem );
|
||||
retVal.addSeparator();
|
||||
}
|
||||
|
||||
if( !getAlias().hasPriority() )
|
||||
{
|
||||
JMenuItem priorityItem = new JMenuItem( "Set Call Priority" );
|
||||
|
||||
priorityItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Priority priority = new Priority();
|
||||
|
||||
getAlias().addAliasID( priority );
|
||||
|
||||
PriorityNode node = new PriorityNode( priority );
|
||||
|
||||
getModel().addNode( node,
|
||||
AliasNode.this,
|
||||
AliasNode.this.getChildCount() );
|
||||
|
||||
node.show();
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( priorityItem );
|
||||
retVal.addSeparator();
|
||||
}
|
||||
|
||||
|
||||
JMenuItem deleteItem = new JMenuItem( "Delete" );
|
||||
deleteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
|
||||
"Are you sure you want to permanently delete this node?" );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
GroupNode parent = (GroupNode)getParent();
|
||||
|
||||
parent.getGroup().removeAlias( getAlias() );
|
||||
|
||||
save();
|
||||
|
||||
getModel().removeNodeFromParent( AliasNode.this );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( deleteItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
121
src/alias/ComponentEditor.java
Normal file
@@ -0,0 +1,121 @@
|
||||
/*******************************************************************************
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
14
src/alias/ComponentValidationException.java
Normal file
@@ -0,0 +1,14 @@
|
||||
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,110 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import controller.ConfigurableNode;
|
||||
|
||||
public class GroupEditor extends JPanel implements ActionListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private GroupNode mGroupNode;
|
||||
|
||||
private JLabel mLabelName;
|
||||
private JTextField mTextGroup;
|
||||
|
||||
public GroupEditor( GroupNode groupNode )
|
||||
{
|
||||
mGroupNode = groupNode;
|
||||
|
||||
initGUI();
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
{
|
||||
setLayout( new MigLayout( "", "[right][grow,fill]", "[][][grow]" ) );
|
||||
|
||||
setBorder( BorderFactory.createTitledBorder( "Group" ) );
|
||||
|
||||
mLabelName = new JLabel( "Name:" );
|
||||
add( mLabelName, "align right" );
|
||||
|
||||
mTextGroup = new JTextField( mGroupNode.getGroup().getName() );
|
||||
add( mTextGroup, "wrap" );
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.addActionListener( GroupEditor.this );
|
||||
add( btnSave );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.addActionListener( GroupEditor.this );
|
||||
add( btnReset, "wrap" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
{
|
||||
String group = mTextGroup.getText();
|
||||
|
||||
if( group != null )
|
||||
{
|
||||
boolean expanded = mGroupNode.getModel().getTree()
|
||||
.isExpanded( new TreePath( mGroupNode ) );
|
||||
|
||||
mGroupNode.getGroup().setName( group );
|
||||
|
||||
((ConfigurableNode)mGroupNode.getParent()).sort();
|
||||
|
||||
mGroupNode.save();
|
||||
|
||||
mGroupNode.show();
|
||||
|
||||
if( expanded )
|
||||
{
|
||||
mGroupNode.getModel().getTree()
|
||||
.expandPath( new TreePath( mGroupNode ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( GroupEditor.this, "Please enter a group name" );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
{
|
||||
mTextGroup.setText( mGroupNode.getGroup().getName() );
|
||||
}
|
||||
|
||||
mGroupNode.refresh();
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JSeparator;
|
||||
|
||||
import controller.ConfigurableNode;
|
||||
|
||||
public class GroupNode extends ConfigurableNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public GroupNode( Group group )
|
||||
{
|
||||
super( group );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor()
|
||||
{
|
||||
return new GroupEditor( this );
|
||||
}
|
||||
|
||||
public Group getGroup()
|
||||
{
|
||||
return (Group)getUserObject();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
for( Alias alias: getGroup().getAlias() )
|
||||
{
|
||||
AliasNode node = new AliasNode( alias );
|
||||
|
||||
getModel().addNode( node, GroupNode.this, getChildCount() );
|
||||
|
||||
node.init();
|
||||
}
|
||||
|
||||
sort();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getGroup().getName() + " [" + this.getChildCount() + "]";
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenuItem addItem = new JMenuItem( "Add Alias" );
|
||||
addItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Alias alias = new Alias();
|
||||
|
||||
getGroup().addAlias( alias );
|
||||
|
||||
AliasNode node = new AliasNode( alias );
|
||||
|
||||
getModel().addNode( node,
|
||||
GroupNode.this,
|
||||
GroupNode.this.getChildCount() );
|
||||
|
||||
sort();
|
||||
|
||||
getModel().showNode( node );
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( addItem );
|
||||
|
||||
retVal.add( new JSeparator() );
|
||||
|
||||
JMenuItem deleteItem = new JMenuItem( "Delete" );
|
||||
deleteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
|
||||
"Are you sure you want to permanently delete this node?" );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
AliasListNode parent = (AliasListNode)getParent();
|
||||
|
||||
parent.getList().removeGroup( getGroup() );
|
||||
|
||||
save();
|
||||
|
||||
getModel().removeNodeFromParent( GroupNode.this );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( deleteItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import controller.ConfigurableNode;
|
||||
|
||||
public class ListEditor extends JPanel implements ActionListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private AliasListNode mListNode;
|
||||
|
||||
private JLabel mLabelName;
|
||||
private JTextField mTextGroup;
|
||||
|
||||
public ListEditor( AliasListNode listNode )
|
||||
{
|
||||
mListNode = listNode;
|
||||
|
||||
initGUI();
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
{
|
||||
setLayout( new MigLayout( "", "[right][grow,fill]", "[][][grow]" ) );
|
||||
|
||||
setBorder( BorderFactory.createTitledBorder( "List" ) );
|
||||
|
||||
mLabelName = new JLabel( "Name:" );
|
||||
add( mLabelName, "align right" );
|
||||
|
||||
mTextGroup = new JTextField( mListNode.getList().getName() );
|
||||
add( mTextGroup, "grow, wrap" );
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.addActionListener( ListEditor.this );
|
||||
add( btnSave );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.addActionListener( ListEditor.this );
|
||||
add( btnReset, "wrap" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
{
|
||||
String group = mTextGroup.getText();
|
||||
|
||||
if( group != null )
|
||||
{
|
||||
boolean expanded = mListNode.getModel().getTree()
|
||||
.isExpanded( new TreePath( mListNode ) );
|
||||
|
||||
mListNode.getList().setName( group );
|
||||
((ConfigurableNode)mListNode.getParent()).sort();
|
||||
mListNode.save();
|
||||
|
||||
mListNode.show();
|
||||
|
||||
if( expanded )
|
||||
{
|
||||
mListNode.getModel().getTree().expandPath( new TreePath( mListNode ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( ListEditor.this, "Please enter a list name" );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
{
|
||||
mTextGroup.setText( mListNode.getList().getName() );
|
||||
}
|
||||
|
||||
mListNode.refresh();
|
||||
}
|
||||
}
|
||||
467
src/alias/MultipleAliasEditor.java
Normal file
@@ -0,0 +1,467 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
381
src/alias/PatchGroupAlias.java
Normal file
@@ -0,0 +1,381 @@
|
||||
/*******************************************************************************
|
||||
* 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,17 +1,47 @@
|
||||
/*******************************************************************************
|
||||
* 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 message.Message;
|
||||
import alias.Alias;
|
||||
import controller.ThreadPoolManager;
|
||||
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
|
||||
@@ -19,9 +49,7 @@ public abstract class AliasAction
|
||||
* action attached. The alias argument is the parent alias containing the
|
||||
* alias action.
|
||||
*/
|
||||
public abstract void execute( ThreadPoolManager threadPoolManager,
|
||||
Alias alias,
|
||||
Message message );
|
||||
public abstract void execute( ScheduledExecutorService scheduledExecutorService, Alias alias, Message message );
|
||||
|
||||
/**
|
||||
* Dismiss a persistent alias action
|
||||
|
||||
350
src/alias/action/AliasActionEditor.java
Normal file
@@ -0,0 +1,350 @@
|
||||
/*******************************************************************************
|
||||
* 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,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -15,11 +15,18 @@
|
||||
* 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 buffer;
|
||||
package alias.action;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import alias.AliasEvent;
|
||||
|
||||
public interface ByteBufferListener
|
||||
/**
|
||||
* Interface for receiving alias events. Each listener will receive
|
||||
* notification of all alias events.
|
||||
*/
|
||||
public interface AliasActionListener
|
||||
{
|
||||
public void receive( ByteBuffer buffer );
|
||||
/**
|
||||
* Notifies the listener that an alias event has occurred
|
||||
*/
|
||||
public void aliasChanged( AliasEvent event );
|
||||
}
|
||||
@@ -1,62 +1,69 @@
|
||||
/*******************************************************************************
|
||||
* 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 java.util.List;
|
||||
|
||||
import message.Message;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sample.Listener;
|
||||
import alias.Alias;
|
||||
import controller.ResourceManager;
|
||||
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
|
||||
*
|
||||
* 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>
|
||||
{
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( AliasActionManager.class );
|
||||
public AliasActionManager()
|
||||
{
|
||||
}
|
||||
|
||||
private ResourceManager mResourceManager;
|
||||
|
||||
public AliasActionManager( ResourceManager resourceManager )
|
||||
{
|
||||
mResourceManager = resourceManager;
|
||||
}
|
||||
|
||||
@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
|
||||
@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( mResourceManager.getThreadPoolManager(),
|
||||
alias, message );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
action.execute(ThreadPool.SCHEDULED, alias, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 controller.ConfigurableNode;
|
||||
|
||||
public class AliasActionNode extends ConfigurableNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AliasActionNode( AliasAction action )
|
||||
{
|
||||
super( action );
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
getModel().getResourceManager().getPlaylistManager().save();
|
||||
}
|
||||
|
||||
public String getIconPath()
|
||||
{
|
||||
return "images/action.png";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -15,12 +15,23 @@
|
||||
* 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 source.tuner.frequency;
|
||||
package alias.action;
|
||||
|
||||
|
||||
public interface FrequencyChangeBroadcaster
|
||||
public enum AliasActionType
|
||||
{
|
||||
public abstract void addListener( FrequencyChangeListener listener );
|
||||
BEEP( "Beep" ),
|
||||
CLIP( "Play Clip" ),
|
||||
SCRIPT( "Run Script" );
|
||||
|
||||
public abstract void removeListener( FrequencyChangeListener listener );
|
||||
private String mLabel;
|
||||
|
||||
private AliasActionType( String label )
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
}
|
||||
@@ -1,188 +1,181 @@
|
||||
package alias.action;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
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;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import message.Message;
|
||||
import alias.Alias;
|
||||
import controller.ThreadPoolManager;
|
||||
import controller.ThreadPoolManager.ThreadType;
|
||||
|
||||
public abstract class RecurringAction extends AliasAction
|
||||
{
|
||||
@XmlTransient
|
||||
protected AtomicBoolean mRunning = new AtomicBoolean( false );
|
||||
@XmlTransient
|
||||
private ScheduledFuture<?> mPerpetualAction;
|
||||
|
||||
protected Interval mInterval = Interval.ONCE;
|
||||
protected int mPeriod = 5;
|
||||
|
||||
protected ThreadPoolManager mThreadPoolManager;
|
||||
|
||||
public abstract void performAction( Alias alias, Message message );
|
||||
@XmlTransient
|
||||
protected AtomicBoolean mRunning = new AtomicBoolean(false);
|
||||
@XmlTransient
|
||||
private ScheduledFuture<?> mPerpetualAction;
|
||||
@XmlTransient
|
||||
protected ScheduledExecutorService mScheduledExecutorService;
|
||||
|
||||
@Override
|
||||
public void execute( ThreadPoolManager threadPoolManager,
|
||||
Alias alias,
|
||||
Message message )
|
||||
{
|
||||
mThreadPoolManager = threadPoolManager;
|
||||
protected Interval mInterval = Interval.ONCE;
|
||||
protected int mPeriod = 5;
|
||||
|
||||
if( mRunning.compareAndSet( false, true ) )
|
||||
{
|
||||
switch( mInterval )
|
||||
{
|
||||
case ONCE:
|
||||
performThreadedAction( alias, message );
|
||||
/* Don't reset */
|
||||
break;
|
||||
case DELAYED_RESET:
|
||||
performThreadedAction( alias, message );
|
||||
mThreadPoolManager.scheduleOnce( new ResetTask(),
|
||||
mPeriod, TimeUnit.SECONDS );
|
||||
break;
|
||||
case UNTIL_DISMISSED:
|
||||
mPerpetualAction = mThreadPoolManager
|
||||
.scheduleFixedRate( ThreadType.DECODER,
|
||||
new PerformActionTask( alias, message ),
|
||||
mPeriod, TimeUnit.SECONDS );
|
||||
public abstract void performAction(Alias alias, Message message);
|
||||
|
||||
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 );
|
||||
|
||||
mThreadPoolManager.scheduleOnce( new ResetTask(),
|
||||
15, TimeUnit.SECONDS );
|
||||
}
|
||||
} );
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void execute(ScheduledExecutorService scheduledExecutorService, Alias alias, Message message)
|
||||
{
|
||||
mScheduledExecutorService = scheduledExecutorService;
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
{
|
||||
mThreadPoolManager.scheduleOnce( new Runnable() {
|
||||
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);
|
||||
|
||||
@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;
|
||||
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>");
|
||||
|
||||
public PerformActionTask( Alias alias, Message message )
|
||||
{
|
||||
mAlias = alias;
|
||||
mMessage = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
performAction(mAlias, mMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public class ResetTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mRunning.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,27 @@ 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,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -17,59 +17,75 @@
|
||||
******************************************************************************/
|
||||
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.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.action.AliasAction;
|
||||
import alias.action.RecurringAction.Interval;
|
||||
|
||||
public class BeepActionEditor extends JPanel implements ActionListener
|
||||
public class BeepActionEditor extends DocumentListenerEditor<AliasAction>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( BeepActionEditor.class );
|
||||
|
||||
private BeepActionNode mBeepActionNode;
|
||||
private JTextField mTextSiteID;
|
||||
private JComboBox<Interval> mComboInterval;
|
||||
private JSpinner mSpinnerPeriod;
|
||||
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>";
|
||||
|
||||
public BeepActionEditor( BeepActionNode beepActionNode )
|
||||
private JComboBox<Interval> mComboInterval;
|
||||
private JSlider mPeriodSlider;
|
||||
private JLabel mPeriodSliderLabel;
|
||||
|
||||
public BeepActionEditor( AliasAction aliasAction )
|
||||
{
|
||||
mBeepActionNode = beepActionNode;
|
||||
|
||||
initGUI();
|
||||
init();
|
||||
|
||||
setItem( aliasAction );
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
public BeepAction getBeepAction()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][][][grow]" ) );
|
||||
|
||||
add( new JLabel( "Action: Beep" ), "span,align center" );
|
||||
if( getItem() instanceof BeepAction )
|
||||
{
|
||||
return (BeepAction)getItem();
|
||||
}
|
||||
|
||||
add( new JLabel( "Interval:" ) );
|
||||
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.setSelectedItem( mBeepActionNode.getBeepAction().getInterval() );
|
||||
|
||||
mComboInterval.setToolTipText( HELP_TEXT );
|
||||
mComboInterval.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
@@ -81,71 +97,97 @@ public class BeepActionEditor extends JPanel implements ActionListener
|
||||
if( selected != null )
|
||||
{
|
||||
/* Enable/disable period spinner based on selection */
|
||||
mSpinnerPeriod.setEnabled( selected != Interval.ONCE );
|
||||
boolean enabled = selected != Interval.ONCE;
|
||||
|
||||
mBeepActionNode.getBeepAction().setInterval( selected );
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
});
|
||||
|
||||
add( mComboInterval, "wrap" );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel(
|
||||
mBeepActionNode.getBeepAction().getPeriod(), 1, 30, 1 );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel( 1, 1, 30, 1 );
|
||||
model.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
mBeepActionNode.getBeepAction().setPeriod( (int)model.getValue() );
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
mSpinnerPeriod = new JSpinner( model );
|
||||
|
||||
if( mBeepActionNode.getBeepAction().getInterval() == Interval.ONCE )
|
||||
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()
|
||||
{
|
||||
mSpinnerPeriod.setEnabled( false );
|
||||
@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() );
|
||||
}
|
||||
|
||||
add( new JLabel( "Period:" ) );
|
||||
add( mSpinnerPeriod, "wrap" );
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "This action will sound a beep according to the interval that you select.\n\n" );
|
||||
sb.append( "Once - Beep the first time the alias is active and never again.\n\n" );
|
||||
sb.append( "Once, Reset After Delay - Beep once and suppress subsequent beeps for the specified period in seconds. After the reset period, it will beep again when the alias is active.\n\n" );
|
||||
sb.append( "Until Dismissed - Beep every period seconds until you click OK on the dialog that appears. Alerting is suppressed for 15 seconds after you click OK." );
|
||||
|
||||
JTextArea description = new JTextArea( sb.toString() );
|
||||
|
||||
description.setLineWrap( true );
|
||||
description.setBackground( getBackground() );
|
||||
|
||||
add( description, "growx,span" );
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.addActionListener( BeepActionEditor.this );
|
||||
add( btnSave, "growx,push" );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.addActionListener( BeepActionEditor.this );
|
||||
add( btnReset, "growx,push" );
|
||||
setModified( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
mBeepActionNode.save();
|
||||
mBeepActionNode.show();
|
||||
BeepAction beep = getBeepAction();
|
||||
|
||||
beep.setInterval( (Interval)mComboInterval.getSelectedItem() );
|
||||
beep.setPeriod( mPeriodSlider.getValue() );
|
||||
}
|
||||
|
||||
mBeepActionNode.refresh();
|
||||
}
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import alias.AliasNode;
|
||||
import alias.action.AliasActionNode;
|
||||
|
||||
public class BeepActionNode extends AliasActionNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public BeepActionNode( BeepAction beepAction )
|
||||
{
|
||||
super( beepAction );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor()
|
||||
{
|
||||
return new BeepActionEditor( this );
|
||||
}
|
||||
|
||||
public BeepAction getBeepAction()
|
||||
{
|
||||
return (BeepAction)getUserObject();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Action: Beep";
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenuItem deleteItem = new JMenuItem( "Delete" );
|
||||
deleteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
|
||||
"Are you sure you want to permanently delete this node?" );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
AliasNode parent = (AliasNode)getParent();
|
||||
|
||||
parent.getAlias().removeAliasAction( getBeepAction() );
|
||||
|
||||
/* Save before removing the node ... so that we still have
|
||||
* a reference to the parent's resources */
|
||||
save();
|
||||
|
||||
getModel().removeNodeFromParent( BeepActionNode.this );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( deleteItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.RecurringAction;
|
||||
|
||||
public class ClipAction extends RecurringAction
|
||||
@@ -28,9 +29,14 @@ public class ClipAction extends RecurringAction
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasActionType getType()
|
||||
{
|
||||
return AliasActionType.CLIP;
|
||||
}
|
||||
|
||||
public String getPath()
|
||||
{
|
||||
|
||||
return mFilePath;
|
||||
}
|
||||
|
||||
@@ -87,4 +93,18 @@ public class ClipAction extends RecurringAction
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if( mFilePath == null )
|
||||
{
|
||||
return "Play Clip";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Play Clip: " + mFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -17,9 +17,14 @@
|
||||
******************************************************************************/
|
||||
package alias.action.clip;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
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;
|
||||
@@ -27,9 +32,7 @@ import javax.swing.JComboBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SpinnerModel;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
@@ -37,43 +40,58 @@ import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.action.AliasAction;
|
||||
import alias.action.RecurringAction.Interval;
|
||||
|
||||
public class ClipActionEditor extends JPanel implements ActionListener
|
||||
public class ClipActionEditor extends DocumentListenerEditor<AliasAction>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( ClipActionEditor.class );
|
||||
|
||||
private ClipActionNode mClipActionNode;
|
||||
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 JSpinner mSpinnerPeriod;
|
||||
private JSlider mPeriodSlider;
|
||||
private JLabel mPeriodSliderLabel;
|
||||
private JTextField mTextFilePath;
|
||||
|
||||
public ClipActionEditor( ClipActionNode clipActionNode )
|
||||
public ClipActionEditor( AliasAction aliasAction )
|
||||
{
|
||||
mClipActionNode = clipActionNode;
|
||||
|
||||
initGUI();
|
||||
init();
|
||||
|
||||
setItem( aliasAction );
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
public ClipAction getClipAction()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][][][grow]" ) );
|
||||
|
||||
add( new JLabel( "Action: Audio Clip" ), "span,align center" );
|
||||
if( getItem() instanceof ClipAction )
|
||||
{
|
||||
return (ClipAction)getItem();
|
||||
}
|
||||
|
||||
add( new JLabel( "Interval:" ) );
|
||||
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.setSelectedItem( mClipActionNode.getClipAction().getInterval() );
|
||||
|
||||
mComboInterval.setToolTipText( HELP_TEXT );
|
||||
mComboInterval.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
@@ -84,37 +102,51 @@ public class ClipActionEditor extends JPanel implements ActionListener
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
/* Enable/disable period spinner based on selection */
|
||||
mSpinnerPeriod.setEnabled( selected != Interval.ONCE );
|
||||
/* Enable/disable period slider based on selection */
|
||||
boolean enabled = selected != Interval.ONCE;
|
||||
|
||||
mClipActionNode.getClipAction().setInterval( selected );
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
});
|
||||
|
||||
add( mComboInterval, "wrap" );
|
||||
add( mComboInterval );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel(
|
||||
mClipActionNode.getClipAction().getPeriod(), 1, 30, 1 );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel( 1, 1, 30, 1 );
|
||||
model.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
mClipActionNode.getClipAction().setPeriod( (int)model.getValue() );
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
mSpinnerPeriod = new JSpinner( model );
|
||||
|
||||
if( mClipActionNode.getClipAction().getInterval() == Interval.ONCE )
|
||||
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()
|
||||
{
|
||||
mSpinnerPeriod.setEnabled( false );
|
||||
}
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
mPeriodSliderLabel.setText( "Period: " + mPeriodSlider.getValue() );
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
mPeriodSlider.setToolTipText( HELP_TEXT );
|
||||
|
||||
add( new JLabel( "Period:" ) );
|
||||
add( mSpinnerPeriod, "wrap" );
|
||||
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" );
|
||||
|
||||
@@ -131,88 +163,134 @@ public class ClipActionEditor extends JPanel implements ActionListener
|
||||
{
|
||||
File file = chooser.getSelectedFile();
|
||||
|
||||
mClipActionNode.getClipAction().setPath( file.getAbsolutePath() );
|
||||
mTextFilePath.setText( file.getAbsolutePath() );
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( fileButton );
|
||||
add( fileButton, "grow" );
|
||||
|
||||
JButton testButton = new JButton( "Test" );
|
||||
testButton.addActionListener( new ActionListener()
|
||||
|
||||
testButton.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent actionEvent )
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
String path = mClipActionNode.getClipAction().getPath();
|
||||
|
||||
if( path == null || path.trim().isEmpty() )
|
||||
if( hasItem() )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ClipActionEditor.this,
|
||||
"Please select an audio file", "Please select file",
|
||||
JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
String path = mTextFilePath.getText();
|
||||
|
||||
if( path == null || path.trim().isEmpty() )
|
||||
{
|
||||
try
|
||||
{
|
||||
mClipActionNode.getClipAction().play();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ClipActionEditor.this,
|
||||
"Couldn't play audio clip [" + e.getMessage() + "]",
|
||||
"Error", JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
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, "wrap" );
|
||||
|
||||
mTextFilePath = new JTextField( mClipActionNode.getClipAction().getPath() );
|
||||
add( mTextFilePath, "growx,span" );
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
add( testButton, "grow,wrap" );
|
||||
|
||||
sb.append( "This action will play the audio clip according to the interval that you select.\n\n" );
|
||||
sb.append( "Once - Play the first time the alias is active and never again.\n\n" );
|
||||
sb.append( "Once, Reset After Delay - Play once and suppress subsequent plays for the specified period in seconds. After the reset period, it will play again when the alias is active.\n\n" );
|
||||
sb.append( "Until Dismissed - Play audio clip every period seconds until you click OK on the dialog that appears. Alerting is suppressed for 15 seconds after you click OK." );
|
||||
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 );
|
||||
|
||||
JTextArea description = new JTextArea( sb.toString() );
|
||||
|
||||
description.setLineWrap( true );
|
||||
description.setBackground( getBackground() );
|
||||
|
||||
add( description, "growx,span" );
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.addActionListener( ClipActionEditor.this );
|
||||
add( btnSave, "growx,push" );
|
||||
if( hasItem() )
|
||||
{
|
||||
ClipAction clip = getClipAction();
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.addActionListener( ClipActionEditor.this );
|
||||
add( btnReset, "growx,push" );
|
||||
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 actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
mClipActionNode.save();
|
||||
mClipActionNode.show();
|
||||
ClipAction script = getClipAction();
|
||||
|
||||
script.setInterval( (Interval)mComboInterval.getSelectedItem() );
|
||||
script.setPeriod( mPeriodSlider.getValue() );
|
||||
script.setPath( mTextFilePath.getText() );
|
||||
}
|
||||
|
||||
mClipActionNode.refresh();
|
||||
}
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import alias.AliasNode;
|
||||
import alias.action.AliasActionNode;
|
||||
|
||||
public class ClipActionNode extends AliasActionNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ClipActionNode( ClipAction clipAction )
|
||||
{
|
||||
super( clipAction );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor()
|
||||
{
|
||||
return new ClipActionEditor( this );
|
||||
}
|
||||
|
||||
public ClipAction getClipAction()
|
||||
{
|
||||
return (ClipAction)getUserObject();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Action: Audio Clip";
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenuItem deleteItem = new JMenuItem( "Delete" );
|
||||
deleteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
|
||||
"Are you sure you want to permanently delete this node?" );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
AliasNode parent = (AliasNode)getParent();
|
||||
|
||||
parent.getAlias().removeAliasAction( getClipAction() );
|
||||
|
||||
/* Save before removing the node ... so that we still have
|
||||
* a reference to the parent's resources */
|
||||
save();
|
||||
|
||||
getModel().removeNodeFromParent( ClipActionNode.this );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( deleteItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.RecurringAction;
|
||||
|
||||
public class ScriptAction extends RecurringAction
|
||||
@@ -21,6 +22,12 @@ public class ScriptAction extends RecurringAction
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasActionType getType()
|
||||
{
|
||||
return AliasActionType.SCRIPT;
|
||||
}
|
||||
|
||||
public String getScript()
|
||||
{
|
||||
return mScript;
|
||||
@@ -75,4 +82,17 @@ public class ScriptAction extends RecurringAction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if( mScript == null )
|
||||
{
|
||||
return "Run Script";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Run Script: " + mScript;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -17,9 +17,14 @@
|
||||
******************************************************************************/
|
||||
package alias.action.script;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
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;
|
||||
@@ -27,9 +32,7 @@ import javax.swing.JComboBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SpinnerModel;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
@@ -37,43 +40,58 @@ import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.action.AliasAction;
|
||||
import alias.action.RecurringAction.Interval;
|
||||
|
||||
public class ScriptActionEditor extends JPanel implements ActionListener
|
||||
public class ScriptActionEditor extends DocumentListenerEditor<AliasAction>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( ScriptActionEditor.class );
|
||||
|
||||
private ScriptActionNode mScriptActionNode;
|
||||
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 JSpinner mSpinnerPeriod;
|
||||
private JSlider mPeriodSlider;
|
||||
private JLabel mPeriodSliderLabel;
|
||||
private JTextField mTextFilePath;
|
||||
|
||||
public ScriptActionEditor( ScriptActionNode clipActionNode )
|
||||
public ScriptActionEditor( AliasAction aliasAction )
|
||||
{
|
||||
mScriptActionNode = clipActionNode;
|
||||
|
||||
initGUI();
|
||||
init();
|
||||
|
||||
setItem( aliasAction );
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
public ScriptAction getScriptAction()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][][][grow]" ) );
|
||||
|
||||
add( new JLabel( "Action: Script" ), "span,align center" );
|
||||
if( getItem() instanceof ScriptAction )
|
||||
{
|
||||
return (ScriptAction)getItem();
|
||||
}
|
||||
|
||||
add( new JLabel( "Interval:" ) );
|
||||
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.setSelectedItem( mScriptActionNode.getScriptAction().getInterval() );
|
||||
|
||||
mComboInterval.setToolTipText( HELP_TEXT );
|
||||
mComboInterval.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
@@ -84,37 +102,51 @@ public class ScriptActionEditor extends JPanel implements ActionListener
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
/* Enable/disable period spinner based on selection */
|
||||
mSpinnerPeriod.setEnabled( selected != Interval.ONCE );
|
||||
/* Enable/disable period slider based on selection */
|
||||
boolean enabled = selected != Interval.ONCE;
|
||||
|
||||
mScriptActionNode.getScriptAction().setInterval( selected );
|
||||
mPeriodSlider.setEnabled( enabled );
|
||||
mPeriodSliderLabel.setEnabled( enabled );
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
});
|
||||
|
||||
add( mComboInterval, "wrap" );
|
||||
add( mComboInterval );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel(
|
||||
mScriptActionNode.getScriptAction().getPeriod(), 1, 30, 1 );
|
||||
|
||||
final SpinnerModel model = new SpinnerNumberModel( 1, 1, 30, 1 );
|
||||
model.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
mScriptActionNode.getScriptAction().setPeriod( (int)model.getValue() );
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
mSpinnerPeriod = new JSpinner( model );
|
||||
|
||||
if( mScriptActionNode.getScriptAction().getInterval() == Interval.ONCE )
|
||||
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()
|
||||
{
|
||||
mSpinnerPeriod.setEnabled( false );
|
||||
}
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
mPeriodSliderLabel.setText( "Period: " + mPeriodSlider.getValue() );
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
mPeriodSlider.setToolTipText( HELP_TEXT );
|
||||
|
||||
add( new JLabel( "Period:" ) );
|
||||
add( mSpinnerPeriod, "wrap" );
|
||||
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" );
|
||||
|
||||
@@ -131,13 +163,14 @@ public class ScriptActionEditor extends JPanel implements ActionListener
|
||||
{
|
||||
File file = chooser.getSelectedFile();
|
||||
|
||||
mScriptActionNode.getScriptAction().setScript( file.getAbsolutePath() );
|
||||
mTextFilePath.setText( file.getAbsolutePath() );
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( fileButton );
|
||||
add( fileButton, "grow" );
|
||||
|
||||
JButton testButton = new JButton( "Test" );
|
||||
testButton.addActionListener( new ActionListener()
|
||||
@@ -145,74 +178,115 @@ public class ScriptActionEditor extends JPanel implements ActionListener
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent actionEvent )
|
||||
{
|
||||
String script = mScriptActionNode.getScriptAction().getScript();
|
||||
String script = mTextFilePath.getText();
|
||||
|
||||
if( script == null || script.trim().isEmpty() )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ScriptActionEditor.this,
|
||||
"Please select a script file", "Please select file",
|
||||
"Please select a script file", PLEASE_SELECT_A_FILE,
|
||||
JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
else
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
if( isModified() )
|
||||
{
|
||||
try
|
||||
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 )
|
||||
{
|
||||
mScriptActionNode.getScriptAction().play();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ScriptActionEditor.this,
|
||||
"Couldn't run script [" + e.getMessage() + "]",
|
||||
"Error", JOptionPane.ERROR_MESSAGE );
|
||||
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, "wrap" );
|
||||
add( testButton, "grow,wrap" );
|
||||
|
||||
mTextFilePath = new JTextField( mScriptActionNode.getScriptAction().getScript() );
|
||||
add( mTextFilePath, "growx,span" );
|
||||
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();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "This action will run the script according to the interval that you select.\n\n" );
|
||||
sb.append( "Once - Run script the first time the alias is active and never again.\n\n" );
|
||||
sb.append( "Once, Reset After Delay - Run once and suppress subsequent runs for the specified period in seconds. After the reset period, it will play again when the alias is active.\n\n" );
|
||||
sb.append( "Until Dismissed - Run script every period seconds until you click OK on the dialog that appears. Alerting is suppressed for 15 seconds after you click OK." );
|
||||
|
||||
JTextArea description = new JTextArea( sb.toString() );
|
||||
|
||||
description.setLineWrap( true );
|
||||
description.setBackground( getBackground() );
|
||||
|
||||
add( description, "growx,span" );
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.addActionListener( ScriptActionEditor.this );
|
||||
add( btnSave, "growx,push" );
|
||||
Interval interval = script.getInterval();
|
||||
|
||||
mComboInterval.setSelectedItem( interval );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.addActionListener( ScriptActionEditor.this );
|
||||
add( btnReset, "growx,push" );
|
||||
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 actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
mScriptActionNode.save();
|
||||
mScriptActionNode.show();
|
||||
ScriptAction script = getScriptAction();
|
||||
|
||||
script.setInterval( (Interval)mComboInterval.getSelectedItem() );
|
||||
script.setPeriod( mPeriodSlider.getValue() );
|
||||
script.setScript( mTextFilePath.getText() );
|
||||
}
|
||||
|
||||
mScriptActionNode.refresh();
|
||||
}
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import alias.AliasNode;
|
||||
import alias.action.AliasActionNode;
|
||||
|
||||
public class ScriptActionNode extends AliasActionNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ScriptActionNode( ScriptAction scriptAction )
|
||||
{
|
||||
super( scriptAction );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor()
|
||||
{
|
||||
return new ScriptActionEditor( this );
|
||||
}
|
||||
|
||||
public ScriptAction getScriptAction()
|
||||
{
|
||||
return (ScriptAction)getUserObject();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Action: Script";
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenuItem deleteItem = new JMenuItem( "Delete" );
|
||||
deleteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
|
||||
"Are you sure you want to permanently delete this node?" );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
AliasNode parent = (AliasNode)getParent();
|
||||
|
||||
parent.getAlias().removeAliasAction( getScriptAction() );
|
||||
|
||||
/* Save before removing the node ... so that we still have
|
||||
* a reference to the parent's resources */
|
||||
save();
|
||||
|
||||
getModel().removeNodeFromParent( ScriptActionNode.this );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( deleteItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
57
src/alias/id/AliasID.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*******************************************************************************
|
||||
* 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,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -15,20 +15,35 @@
|
||||
* 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;
|
||||
package alias.id;
|
||||
|
||||
public enum AliasIDType
|
||||
{
|
||||
ESN,
|
||||
Fleetsync,
|
||||
LoJack,
|
||||
LTRNetUID,
|
||||
MDC1200,
|
||||
MIN,
|
||||
MPT1327,
|
||||
NonRecordable,
|
||||
Priority,
|
||||
Site,
|
||||
Status,
|
||||
Talkgroup;
|
||||
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;
|
||||
}
|
||||
}
|
||||
379
src/alias/id/AliasIdentifierEditor.java
Normal file
@@ -0,0 +1,379 @@
|
||||
/*******************************************************************************
|
||||
* 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 );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
113
src/alias/id/WildcardID.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*******************************************************************************
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
130
src/alias/id/broadcast/BroadcastChannel.java
Normal file
@@ -0,0 +1,130 @@
|
||||
/*******************************************************************************
|
||||
* 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
129
src/alias/id/broadcast/BroadcastChannelEditor.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*******************************************************************************
|
||||
* 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 audio.broadcast.BroadcastConfiguration;
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import gui.editor.DocumentListenerEditor;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
|
||||
public class BroadcastChannelEditor extends DocumentListenerEditor<AliasID>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String HELP_TEXT = "<html>"
|
||||
+ "<h3>Audio Broadcast Channel</h3>"
|
||||
+ "Name of a audio streaming broadcast configuration<br>"
|
||||
+ "to be used for streaming audio to an external<br>"
|
||||
+ "streaming server";
|
||||
|
||||
private JComboBox<String> mBroadcastConfigurations;
|
||||
private BroadcastModel mBroadcastModel;
|
||||
|
||||
public BroadcastChannelEditor(AliasID aliasID, BroadcastModel broadcastModel)
|
||||
{
|
||||
mBroadcastModel = broadcastModel;
|
||||
|
||||
initGUI();
|
||||
setItem( aliasID );
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 1", "[]", "[][]" ) );
|
||||
|
||||
add( new JLabel( "Broadcast Channel" ), "grow" );
|
||||
|
||||
List<String> channelNames = mBroadcastModel.getBroadcastConfigurationNames();
|
||||
|
||||
mBroadcastConfigurations = new JComboBox<String>(channelNames.toArray(new String[channelNames.size()]));
|
||||
mBroadcastConfigurations.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
|
||||
add(mBroadcastConfigurations, "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( BroadcastChannelEditor.this,
|
||||
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
|
||||
}
|
||||
} );
|
||||
|
||||
add( help, "align left" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(AliasID item)
|
||||
{
|
||||
super.setItem(item);
|
||||
|
||||
if(item instanceof BroadcastChannel)
|
||||
{
|
||||
BroadcastChannel channel = (BroadcastChannel)item;
|
||||
|
||||
if(channel.isValid())
|
||||
{
|
||||
mBroadcastConfigurations.setSelectedItem(channel.getChannelName());
|
||||
}
|
||||
}
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
String channel = (String)mBroadcastConfigurations.getSelectedItem();
|
||||
|
||||
BroadcastConfiguration selectedConfiguration = mBroadcastModel.getBroadcastConfiguration(channel);
|
||||
|
||||
|
||||
if(selectedConfiguration != null)
|
||||
{
|
||||
((BroadcastChannel)getItem()).setChannelName(selectedConfiguration.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
((BroadcastChannel)getItem()).setChannelName(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -17,79 +17,102 @@
|
||||
******************************************************************************/
|
||||
package alias.id.esn;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import gui.editor.DocumentListenerEditor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import controller.ConfigurableNode;
|
||||
import alias.id.AliasID;
|
||||
|
||||
public class ESNEditor extends JPanel implements ActionListener
|
||||
public class ESNEditor extends DocumentListenerEditor<AliasID>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private ESNNode mESNNode;
|
||||
private JTextField mTextESN;
|
||||
|
||||
public ESNEditor( ESNNode esnNode )
|
||||
private static final String HELP_TEXT =
|
||||
"<html><h3>Electronic Serial Number (ESN)</h3>"
|
||||
+ "<b>ESN:</b> hexadecimal 0-9, A-F (e.g. <u>ABCD1234</u> )<br>"
|
||||
+ "<b>Wildcard:</b> use an asterisk (*) to wildcard individual<br>"
|
||||
+ "digits (e.g. <u>ABCD123*</u> or <u>AB**1**4</u>)"
|
||||
+ "</html>";
|
||||
|
||||
private JTextField mTextField;
|
||||
|
||||
public ESNEditor( AliasID aliasID )
|
||||
{
|
||||
mESNNode = esnNode;
|
||||
|
||||
initGUI();
|
||||
|
||||
setItem( aliasID );
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][grow]" ) );
|
||||
|
||||
add( new JLabel( "Electronic Serial Number ID" ), "span,align center" );
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
|
||||
|
||||
add( new JLabel( "ESN:" ) );
|
||||
mTextESN = new JTextField( mESNNode.getESN().getEsn() );
|
||||
add( mTextESN, "growx,push" );
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.addActionListener( ESNEditor.this );
|
||||
add( btnSave, "growx,push" );
|
||||
mTextField = new JTextField();
|
||||
mTextField.getDocument().addDocumentListener( this );
|
||||
mTextField.setToolTipText( HELP_TEXT );
|
||||
add( mTextField, "growx,push" );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.addActionListener( ESNEditor.this );
|
||||
add( btnReset, "growx,push" );
|
||||
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( ESNEditor.this,
|
||||
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
|
||||
}
|
||||
} );
|
||||
add( help, "align left" );
|
||||
}
|
||||
|
||||
public Esn getEsn()
|
||||
{
|
||||
if( getItem() instanceof Esn )
|
||||
{
|
||||
return (Esn)getItem();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
public void setItem( AliasID aliasID )
|
||||
{
|
||||
super.setItem( aliasID );
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
Esn esn = getEsn();
|
||||
|
||||
if( esn != null )
|
||||
{
|
||||
String esn = mTextESN.getText();
|
||||
|
||||
if( esn != null )
|
||||
{
|
||||
mESNNode.getESN().setEsn( esn );
|
||||
|
||||
((ConfigurableNode)mESNNode.getParent()).sort();
|
||||
|
||||
mESNNode.save();
|
||||
|
||||
mESNNode.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( ESNEditor.this, "Please enter an ESN" );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
{
|
||||
mTextESN.setText( mESNNode.getESN().getEsn() );
|
||||
mTextField.setText( esn.getEsn() );
|
||||
}
|
||||
|
||||
mESNNode.refresh();
|
||||
}
|
||||
setModified( false );
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
Esn esn = getEsn();
|
||||
|
||||
if( esn != null )
|
||||
{
|
||||
esn.setEsn( mTextField.getText() );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.esn;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import alias.AliasIDNode;
|
||||
import alias.AliasNode;
|
||||
|
||||
public class ESNNode extends AliasIDNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ESNNode( Esn esn )
|
||||
{
|
||||
super( esn );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor()
|
||||
{
|
||||
return new ESNEditor( this );
|
||||
}
|
||||
|
||||
public Esn getESN()
|
||||
{
|
||||
return (Esn)getUserObject();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "ESN " + getESN().getEsn();
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenuItem addSystemItem = new JMenuItem( "Delete" );
|
||||
addSystemItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
|
||||
"Are you sure you want to permanently delete this node?" );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
AliasNode parent = (AliasNode)getParent();
|
||||
|
||||
parent.getAlias().removeAliasID( getESN() );
|
||||
|
||||
save();
|
||||
|
||||
getModel().removeNodeFromParent( ESNNode.this );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( addSystemItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,8 @@ package alias.id.esn;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.AliasID;
|
||||
import alias.AliasIDType;
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
public class Esn extends AliasID
|
||||
{
|
||||
@@ -36,7 +36,13 @@ public class Esn extends AliasID
|
||||
return mEsn;
|
||||
}
|
||||
|
||||
public void setEsn( String esn )
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mEsn != null;
|
||||
}
|
||||
|
||||
public void setEsn(String esn )
|
||||
{
|
||||
mEsn = esn;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ package alias.id.fleetsync;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.AliasID;
|
||||
import alias.AliasIDType;
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
|
||||
public class FleetsyncID extends AliasID
|
||||
@@ -42,6 +42,12 @@ public class FleetsyncID extends AliasID
|
||||
mID = ident;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mID != null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Fleetsync: " + mID;
|
||||
@@ -68,6 +74,6 @@ public class FleetsyncID extends AliasID
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.Fleetsync;
|
||||
return AliasIDType.FLEETSYNC;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* 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
|
||||
@@ -17,92 +17,123 @@
|
||||
******************************************************************************/
|
||||
package alias.id.fleetsync;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import gui.editor.DocumentListenerEditor;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.text.MaskFormatter;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import controller.ConfigurableNode;
|
||||
|
||||
public class FleetsyncIDEditor extends JPanel implements ActionListener
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.id.AliasID;
|
||||
|
||||
public class FleetsyncIDEditor extends DocumentListenerEditor<AliasID>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private FleetsyncIDNode mFleetsyncIDNode;
|
||||
|
||||
private JLabel mLabelName;
|
||||
private JTextField mTextIdent;
|
||||
private final static Logger mLog = LoggerFactory.getLogger( FleetsyncIDEditor.class );
|
||||
|
||||
private String mHelpText = "Enter a formatted fleetsync identifier.\n\n"
|
||||
+ "Format: PPP-IIII (P=Prefix, I=Identifier)\n\n"
|
||||
+ "Wildcard: use one or more asterisks (*) for any talkgroup "
|
||||
+ "digits.\n\n";
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public FleetsyncIDEditor( FleetsyncIDNode fsNode )
|
||||
private static final String HELP_TEXT = "<html>"
|
||||
+ "<h3>Fleetsync Identifier</h3>"
|
||||
+ "<b>Fleetsync:</b> ggg-uuuu where g=Group and u=Unit (e.g. <u>001-0001</u>)<br>"
|
||||
+ "<b>Wildcard:</b> use an asterisk (*) for each digit (e.g. <u>001-****</u>)"
|
||||
+ "</html>";
|
||||
|
||||
private JTextField mTextField;
|
||||
|
||||
public FleetsyncIDEditor( AliasID aliasID )
|
||||
{
|
||||
mFleetsyncIDNode = fsNode;
|
||||
initGUI();
|
||||
|
||||
setItem( aliasID );
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][grow]" ) );
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
|
||||
|
||||
add( new JLabel( "Fleetsync ID" ), "span,align center" );
|
||||
add( new JLabel( "Fleetsync ID:" ) );
|
||||
|
||||
add( new JLabel( "Ident:" ) );
|
||||
mTextIdent = new JTextField( mFleetsyncIDNode.getFleetsyncID().getIdent() );
|
||||
MaskFormatter formatter = null;
|
||||
|
||||
add( mTextIdent, "grow, wrap" );
|
||||
try
|
||||
{
|
||||
//Mask: 3 digits - 4 digits
|
||||
formatter = new MaskFormatter( "###-####" );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
//Do nothing, the mask was invalid
|
||||
}
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.addActionListener( FleetsyncIDEditor.this );
|
||||
add( btnSave, "growx,push" );
|
||||
mTextField = new JFormattedTextField( formatter );
|
||||
mTextField.getDocument().addDocumentListener( this );
|
||||
mTextField.setToolTipText( HELP_TEXT );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.addActionListener( FleetsyncIDEditor.this );
|
||||
add( btnReset, "growx,push" );
|
||||
add( mTextField, "growx,push" );
|
||||
|
||||
JTextArea helpText = new JTextArea( mHelpText );
|
||||
helpText.setLineWrap( true );
|
||||
helpText.setBackground( getBackground() );
|
||||
add( helpText, "span,grow,push" );
|
||||
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( FleetsyncIDEditor.this,
|
||||
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
|
||||
}
|
||||
} );
|
||||
add( help, "align left" );
|
||||
}
|
||||
|
||||
public FleetsyncID getFleetsyncID()
|
||||
{
|
||||
if( getItem() instanceof FleetsyncID )
|
||||
{
|
||||
return (FleetsyncID)getItem();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
public void setItem( AliasID aliasID )
|
||||
{
|
||||
super.setItem( aliasID );
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
FleetsyncID fleetsync = getFleetsyncID();
|
||||
|
||||
if( fleetsync != null )
|
||||
{
|
||||
String ident = mTextIdent.getText();
|
||||
|
||||
if( ident != null )
|
||||
{
|
||||
mFleetsyncIDNode.getFleetsyncID().setIdent( ident );
|
||||
mTextField.setText( fleetsync.getIdent() );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
((ConfigurableNode)mFleetsyncIDNode.getParent()).sort();
|
||||
|
||||
mFleetsyncIDNode.save();
|
||||
|
||||
mFleetsyncIDNode.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( FleetsyncIDEditor.this, "Please enter an ident" );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
FleetsyncID fleetsync = getFleetsyncID();
|
||||
|
||||
if( fleetsync != null )
|
||||
{
|
||||
mTextIdent.setText( mFleetsyncIDNode.getFleetsyncID().getIdent() );
|
||||
fleetsync.setIdent( mTextField.getText() );
|
||||
}
|
||||
|
||||
mFleetsyncIDNode.refresh();
|
||||
}
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.fleetsync;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import alias.AliasIDNode;
|
||||
import alias.AliasNode;
|
||||
|
||||
public class FleetsyncIDNode extends AliasIDNode
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public FleetsyncIDNode( FleetsyncID id )
|
||||
{
|
||||
super( id );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor()
|
||||
{
|
||||
return new FleetsyncIDEditor( this );
|
||||
}
|
||||
|
||||
public FleetsyncID getFleetsyncID()
|
||||
{
|
||||
return (FleetsyncID)getUserObject();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "Fleetsync " );
|
||||
|
||||
String ident = getFleetsyncID().getIdent();
|
||||
|
||||
if( ident != null )
|
||||
{
|
||||
sb.append( ident );
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public JPopupMenu getContextMenu()
|
||||
{
|
||||
JPopupMenu retVal = new JPopupMenu();
|
||||
|
||||
JMenuItem deleteItem = new JMenuItem( "Delete" );
|
||||
deleteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
|
||||
"Are you sure you want to permanently delete this node?" );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
AliasNode parent = (AliasNode)getParent();
|
||||
|
||||
parent.getAlias().removeAliasID( getFleetsyncID() );
|
||||
|
||||
save();
|
||||
|
||||
getModel().removeNodeFromParent( FleetsyncIDNode.this );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
retVal.add( deleteItem );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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.fleetsync;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import controller.ConfigurableNode;
|
||||
|
||||
public class StatusIDEditor extends JPanel implements ActionListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( StatusIDEditor.class );
|
||||
|
||||
private StatusIDNode mStatusIDNode;
|
||||
|
||||
private JLabel mLabelName;
|
||||
private JTextField mTextStatusID;
|
||||
|
||||
public StatusIDEditor( StatusIDNode statusIDNode )
|
||||
{
|
||||
mStatusIDNode = statusIDNode;
|
||||
|
||||
initGUI();
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
{
|
||||
setLayout( new MigLayout() );
|
||||
|
||||
setBorder( BorderFactory.createTitledBorder( "Status Code" ) );
|
||||
|
||||
mLabelName = new JLabel( "Status Code:" );
|
||||
add( mLabelName, "align right" );
|
||||
|
||||
mTextStatusID = new JTextField(
|
||||
String.valueOf( mStatusIDNode.getStatusID().getStatus() ) );
|
||||
add( mTextStatusID, "grow, wrap" );
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.addActionListener( StatusIDEditor.this );
|
||||
add( btnSave );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.addActionListener( StatusIDEditor.this );
|
||||
add( btnReset, "wrap" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
{
|
||||
String statusIDString = mTextStatusID.getText();
|
||||
|
||||
if( statusIDString != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
int id = Integer.parseInt( statusIDString );
|
||||
|
||||
mStatusIDNode.getStatusID().setStatus( id );
|
||||
|
||||
((ConfigurableNode)mStatusIDNode.getParent()).sort();
|
||||
|
||||
mStatusIDNode.save();
|
||||
|
||||
mStatusIDNode.show();
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
mLog.error( "StatusIDEditor - error parsing int status " +
|
||||
"id from [" + statusIDString + "]" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( StatusIDEditor.this,
|
||||
"Please enter a status ID code" );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
{
|
||||
mTextStatusID.setText(
|
||||
String.valueOf( mStatusIDNode.getStatusID().getStatus() ) );
|
||||
}
|
||||
|
||||
mStatusIDNode.refresh();
|
||||
}
|
||||
}
|
||||