Merge branch 'omaha_16.1.1' into field_16.1.1
Entry for NTAT missing from omaha_16.1.1's LevelMappingFile.xml. Change-Id: I39893e6aa748f7dfeb30bd23bcfca3853fa51e17 Former-commit-id: cc1e4ea67074c41be411c99ce979124a63c7c743
This commit is contained in:
commit
e075f22bf7
260 changed files with 10283 additions and 4432 deletions
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# Temporary, only be used until we get DOD certs.
|
||||
# rewrite from 16.1.1
|
||||
|
||||
SETUP_ENV=/awips2/edex/bin/setup.env
|
||||
|
@ -273,7 +274,6 @@ do
|
|||
|
||||
done
|
||||
|
||||
|
||||
cn=$(hostname)
|
||||
|
||||
echo "Generating keystore..."
|
||||
|
|
|
@ -100,6 +100,16 @@
|
|||
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
|
||||
</bean>
|
||||
-->
|
||||
|
||||
|
||||
<bean id="appInfo" class="com.raytheon.uf.common.util.app.AppInfo" factory-method="initialize">
|
||||
<constructor-arg value="EDEX"/>
|
||||
<!-- TODO provide some mechanism to get the version. -->
|
||||
<constructor-arg>
|
||||
<null />
|
||||
</constructor-arg>
|
||||
<constructor-arg value="${edex.run.mode}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="httpClientConfigBuilder" class="com.raytheon.uf.common.comm.HttpClientConfigBuilder">
|
||||
<property name="maxConnections" value="${PYPIES_MAX_CONN}"/>
|
||||
|
@ -109,7 +119,7 @@
|
|||
|
||||
<bean id="httpClientConfig" factory-bean="httpClientConfigBuilder" factory-method="build"/>
|
||||
|
||||
<bean id="httpClient" class="com.raytheon.uf.common.comm.HttpClient" factory-method="configureGlobalInstance">
|
||||
<bean id="httpClient" class="com.raytheon.uf.common.comm.HttpClient" factory-method="configureGlobalInstance" depends-on="appInfo">
|
||||
<constructor-arg ref="httpClientConfig"/>
|
||||
</bean>
|
||||
|
||||
|
|
|
@ -90,6 +90,9 @@ wrapper.java.additional.4=-Dorg.apache.camel.jmx.disabled=true
|
|||
# Enforces GMT to be used as the timezone
|
||||
wrapper.java.additional.5=-Duser.timezone=GMT
|
||||
|
||||
# Set default tmp to awips controlled directory for security
|
||||
wrapper.java.additional.6=-Djava.io.tmpdir=/awips2/tmp
|
||||
|
||||
# garbage collection settings
|
||||
wrapper.java.additional.gc.1=-XX:+UseConcMarkSweepGC
|
||||
wrapper.java.additional.gc.2=-XX:+CMSIncrementalMode
|
||||
|
|
|
@ -186,16 +186,6 @@
|
|||
<fileset dir="${buildDirectory}/../../../rpms/legal/FOSS_licenses"/>
|
||||
</zip>
|
||||
|
||||
<!-- Update the 32-bit win32 AlertViz zip with static files -->
|
||||
<zip destfile="${buildDirectory}/${buildLabel}/${buildId}-win32.win32.x86.zip"
|
||||
update="true">
|
||||
|
||||
<fileset dir="${buildDirectory}/../../static/win32.x86"
|
||||
excludes="cave/**" />
|
||||
<zipfileset dir="${buildDirectory}/../../../rpms/legal"
|
||||
includes="Master_Rights_File.pdf" prefix="alertviz"/>
|
||||
<zipfileset dir="/tmp/alertviz" includes="FOSS_licenses.zip" prefix="alertviz"/>
|
||||
</zip>
|
||||
<!-- Update the 64-bit (amd64) win32 CAVE zip with static files -->
|
||||
<zip destfile="${buildDirectory}/${buildLabel}/${buildId}-win32.win32.x86_64.zip"
|
||||
update="true">
|
||||
|
|
|
@ -69,6 +69,7 @@ java -jar $LAUNCHER_JAR -application org.eclipse.ant.core.antRunner \
|
|||
-Dbuilder=$BUILDER \
|
||||
-DbuildDirectory=${BUILDER}/tmp \
|
||||
-Dbase=$BUILDER \
|
||||
-DproductFile=awips.product \
|
||||
$OPTS_FOR_ANT
|
||||
|
||||
rc=$?
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
value="gtk" />
|
||||
<property name="build.arch"
|
||||
value="x86" />
|
||||
<property name="build.product"
|
||||
value="awips.product" />
|
||||
<!-- Copy the zip file that is produced to this location. -->
|
||||
<property name="destination.dir"
|
||||
value="" />
|
||||
|
@ -71,6 +73,7 @@
|
|||
<arg value="-DbuildDirectory=${basedir}/cave/tmp" />
|
||||
<arg value="-Dbase=${basedir}/cave" />
|
||||
<arg value="-Dconfigs=${build.os},${build.ws},${build.arch}" />
|
||||
<arg value="-DproductFile=${build.product}" />
|
||||
|
||||
<classpath>
|
||||
<pathelement
|
||||
|
@ -128,4 +131,4 @@
|
|||
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml"
|
||||
classpath="${basedir}/lib/ant/ant-contrib-1.0b3.jar" />
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
# them on the command line (e.g., -DbaseLocation=d:/eclipse
|
||||
|
||||
############# PRODUCT/PACKAGING CONTROL #############
|
||||
product=${base}/../../com.raytheon.viz.product.awips/awips.product
|
||||
|
||||
# The product file is specified in the build.xml as a default and is
|
||||
# overridable setting 'build.product' from ant.
|
||||
product=${base}/../../com.raytheon.viz.product.awips/${productFile}
|
||||
#product=${base}/../../com.raytheon.viz.product.awips/developer.product
|
||||
|
||||
runPackager=true
|
||||
|
|
|
@ -196,16 +196,6 @@
|
|||
<fileset dir="${buildDirectory}/../../../rpms/legal/FOSS_licenses"/>
|
||||
</zip>
|
||||
|
||||
<!-- Update the 32-bit win32 CAVE zip with static and license files -->
|
||||
<zip destfile="${buildDirectory}/${buildLabel}/${buildId}-win32.win32.x86.zip"
|
||||
update="true">
|
||||
|
||||
<fileset dir="${buildDirectory}/../../static/win32.x86"
|
||||
excludes="alertviz/**" />
|
||||
<zipfileset dir="${buildDirectory}/../../../rpms/legal"
|
||||
includes="Master_Rights_File.pdf" prefix="cave"/>
|
||||
<zipfileset dir="/tmp/cave" includes="FOSS_licenses.zip" prefix="cave"/>
|
||||
</zip>
|
||||
<!-- Update the 64-bit (amd64) win32 CAVE zip with static and license files -->
|
||||
<zip destfile="${buildDirectory}/${buildLabel}/${buildId}-win32.win32.x86_64.zip"
|
||||
update="true">
|
||||
|
|
|
@ -10,10 +10,8 @@ The following common directories exist within the static directory:
|
|||
architecture.
|
||||
|
||||
We also have the following os / architecture specific directories within the static
|
||||
directory. The name of the directories is based on the eclipse (3.6.1) os.arch
|
||||
directory. The name of the directories is based on the eclipse (3.8.2) os.arch
|
||||
designation.
|
||||
linux.x86 - these files will only be installed on a 32-bit Linux Operating System.
|
||||
linux.x86_64 - these files will only be installed on a 64-bit Linux Operating System.
|
||||
win32.x86 - these files will only be installed on a 32-bit MS Windows Operating System.
|
||||
win32.amd64 - these files will only be installed on a 64-bit Windows Operating System.
|
||||
macosx.x86 - these files will only be installed on a 32-bit Apple OS X Operating System.
|
|
@ -26,6 +26,7 @@
|
|||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# Oct 09, 2014 #3675 bclement added cleanExit signal trap
|
||||
# Jun 17, 2015 #4148 rferrel Logback needs fewer environment variables.
|
||||
#
|
||||
|
||||
user=`/usr/bin/whoami`
|
||||
|
@ -96,7 +97,7 @@ fi
|
|||
|
||||
#check for the logs directory, which may not be present at first start
|
||||
hostName=`hostname -s`
|
||||
LOGDIR=$HOME/caveData/logs/consoleLogs/$hostName/
|
||||
export LOGDIR=$HOME/caveData/logs/consoleLogs/$hostName/
|
||||
|
||||
if [ ! -d $LOGDIR ]; then
|
||||
mkdir -p $LOGDIR
|
||||
|
@ -122,27 +123,17 @@ trap 'cleanExit $pid' SIGHUP SIGINT SIGQUIT SIGTERM
|
|||
count=0
|
||||
while [ $exitVal -ne 0 -a $count -lt 10 ]
|
||||
do
|
||||
count=`expr $count + 1`
|
||||
curTime=`date +%Y%m%d_%H%M%S`
|
||||
LOGFILE=${LOGDIR}/alertviz_${curTime}_console.log
|
||||
export LOGFILE_ALERTVIZ=${LOGDIR}/alertviz_${curTime}_admin.log
|
||||
|
||||
#first check if we can write to the directory
|
||||
if [ -w ${LOGDIR} ]; then
|
||||
touch ${LOGFILE}
|
||||
fi
|
||||
|
||||
#check for display; if no display then exit
|
||||
if [ -z "${DISPLAY}" ]; then
|
||||
echo "Display is not available."
|
||||
exitVal=0
|
||||
else
|
||||
#finally check if we can write to the file
|
||||
if [ -w ${LOGFILE} ]; then
|
||||
${dir}/alertviz $* > ${LOGFILE} 2>&1 &
|
||||
count=`expr $count + 1`
|
||||
#check for display; if no display then exit
|
||||
if [ -z "${DISPLAY}" ]; then
|
||||
echo "Display is not available."
|
||||
exitVal=0
|
||||
else
|
||||
${dir}/alertviz $* &
|
||||
fi
|
||||
if [ -w ${LOGDIR} ] ; then
|
||||
${dir}/alertviz $* > /dev/null 2>&1 &
|
||||
else
|
||||
${dir}/alertviz $* &
|
||||
fi
|
||||
pid=$!
|
||||
wait $pid
|
||||
exitVal=$?
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
# Oct 10, 2014 #3675 njensen Logback now does console logging to ensure correct pid
|
||||
# Oct 13, 2014 #3675 bclement startup shutdown log includes both launching pid and placeholder
|
||||
# Jan 28, 2015 #4018 randerso Added a productEditor log file to changes in the GFE product editor
|
||||
# Jun 17, 2015 #4148 rferrel Logback needs fewer environment variables.
|
||||
#
|
||||
|
||||
|
||||
|
@ -194,7 +195,7 @@ then
|
|||
fi
|
||||
|
||||
BASE_LOGDIR=$HOME/caveData/logs/consoleLogs
|
||||
LOGDIR=$BASE_LOGDIR/$hostName/
|
||||
export LOGDIR=$BASE_LOGDIR/$hostName/
|
||||
|
||||
# make sure directory exists
|
||||
if [ ! -d $LOGDIR ]; then
|
||||
|
@ -212,13 +213,6 @@ export LOGFILE_STARTUP_SHUTDOWN="${LOGDIR}/${PROGRAM_NAME}_${pid}_${curTime}_pid
|
|||
# At this point fork so that log files can be set up with the process pid and
|
||||
# this process can log the exit status of cave.
|
||||
(
|
||||
# we include the PID of the launching process along with
|
||||
# a %PID% placeholder to be replaced with the "real" PID
|
||||
export LOGFILE_CAVE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_%PID%_logs.log"
|
||||
export LOGFILE_CONSOLE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_%PID%_console.log"
|
||||
export LOGFILE_PERFORMANCE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_%PID%_perf.log"
|
||||
export LOGFILE_PRODUCT_EDITOR="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_%PID%_productEditor.log"
|
||||
|
||||
# can we write to log directory
|
||||
if [ -w ${LOGDIR} ]; then
|
||||
touch ${LOGFILE_STARTUP_SHUTDOWN}
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
@echo OFF
|
||||
|
||||
REM Determine where we are located.
|
||||
SET CONTAINING_DIRECTORY=%~dp0
|
||||
|
||||
REM Prepare the environment.
|
||||
|
||||
REM Location of AWIPS II Java (the jre).
|
||||
SET JavaJreDirectory=C:\Program Files\Raytheon\AWIPS II\Java\jre7
|
||||
REM Location of AWIPS II Python.
|
||||
SET PythonInstallDirectory=C:\Program Files\Raytheon\AWIPS II\Python
|
||||
|
||||
REM Add Java and Python to the path.
|
||||
SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path%
|
||||
SET Path=%JavaJreDirectory%\bin;%Path%
|
||||
REM Define 'PythonPath'.
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%;%PythonPath%
|
||||
|
||||
REM Eliminate variables that will no longer be used.
|
||||
SET PythonInstallDirectory=
|
||||
SET JavaJreDirectory=
|
||||
|
||||
REM Determine where we will be logging to.
|
||||
SET HOME_DIRECTORY=%USERPROFILE%
|
||||
SET CAVEDATA_LOG_DIRECTORY=%HOME_DIRECTORY%\caveData\logs
|
||||
SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME%
|
||||
IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%")
|
||||
|
||||
echo Starting ALERTVIZ; leave this CMD window open to enable AlertViz 'restart'.
|
||||
REM Start AlertViz (and implement the alertviz restart capability).
|
||||
:AlertVizLoopStart
|
||||
SET RND=%random%
|
||||
SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp
|
||||
REM Python is used to retrieve the current date and time because the order
|
||||
REM of the Windows date/time fields is not necessarily guaranteed and the
|
||||
REM Windows date/time fields can only be extracted using substring operations
|
||||
REM instead of -formatter- strings like Linux allows.
|
||||
python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE%
|
||||
SET /p LOG_DATETIME= < %RND_DATETIME_FILE%
|
||||
DEL %RND_DATETIME_FILE%
|
||||
|
||||
SET LOGFILE_CONSOLE=%CAVEDATA_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%_console.log
|
||||
SET LOGFILE_ALERTVIZ=%CAVEDATA_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%_admin.log
|
||||
|
||||
"%CONTAINING_DIRECTORY%alertviz.exe" %* > "%CONSOLE_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%.log" 2>&1
|
||||
IF %ERRORLEVEL% == 0 (EXIT)
|
||||
echo Restarting AlertViz.
|
||||
GOTO AlertVizLoopStart
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
@echo OFF
|
||||
|
||||
REM Determine where we are located.
|
||||
SET CONTAINING_DIRECTORY=%~dp0
|
||||
|
||||
REM Prepare the environment.
|
||||
|
||||
REM Location of AWIPS II Java (the jre).
|
||||
SET JavaJreDirectory=C:\Program Files\Raytheon\AWIPS II\Java\jre7
|
||||
REM Location of AWIPS II Python.
|
||||
SET PythonInstallDirectory=C:\Program Files\Raytheon\AWIPS II\Python
|
||||
|
||||
REM Add Java and Python to the path.
|
||||
SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path%
|
||||
SET Path=%JavaJreDirectory%\bin;%Path%
|
||||
REM Add the CAVE lib directory to the path.
|
||||
SET Path=%CONTAINING_DIRECTORY%lib;%Path%
|
||||
REM Define 'PythonPath'.
|
||||
SET PythonPath=%CONTAINING_DIRECTORY%lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%;%PythonPath%
|
||||
|
||||
REM Eliminate variables that will no longer be used.
|
||||
SET PythonInstallDirectory=
|
||||
SET JavaJreDirectory=
|
||||
|
||||
REM Determine where we will be logging to.
|
||||
SET HOME_DIRECTORY=%USERPROFILE%
|
||||
SET CAVEDATA_LOG_DIRECTORY=%HOME_DIRECTORY%\caveData\logs
|
||||
SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME%
|
||||
IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%")
|
||||
|
||||
SET RND=%random%
|
||||
SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp
|
||||
REM Python is used to retrieve the current date and time because the order
|
||||
REM of the Windows date/time fields is not necessarily guaranteed and the
|
||||
REM Windows date/time fields can only be extracted using substring operations
|
||||
REM instead of -formatter- strings like Linux allows.
|
||||
python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE%
|
||||
SET /p LOG_DATETIME= < %RND_DATETIME_FILE%
|
||||
DEL %RND_DATETIME_FILE%
|
||||
|
||||
SET LOGFILE_CAVE=%CAVEDATA_LOG_DIRECTORY%\cave_%LOG_DATETIME%_logs.log
|
||||
SET LOGFILE_CONSOLE=%CAVEDATA_LOG_DIRECTORY%\cave_%LOG_DATETIME%_console.log
|
||||
SET LOGFILE_PERFORMANCE=%CAVEDATA_LOG_DIRECTORY%\cave_%LOG_DATETIME%_perf.log
|
||||
SET LOGFILE_PRODUCT_EDITOR=%CAVEDATA_LOG_DIRECTORY%\cave_%LOG_DATETIME%_productEditor.log
|
||||
|
||||
echo THIS CMD WINDOW CAN BE CLOSED AT ANY TIME!
|
||||
cd %HOMEPATH%
|
||||
REM Start CAVE.
|
||||
"%CONTAINING_DIRECTORY%cave.exe" %* > "%CONSOLE_LOG_DIRECTORY%\cave_%LOG_DATETIME%.log" 2>&1
|
||||
IF ERRORLEVEL 1 (echo CAVE ERROR - check the logs for additional information. && PAUSE)
|
||||
|
||||
EXIT
|
|
@ -1,69 +0,0 @@
|
|||
@echo OFF
|
||||
|
||||
REM Determine if we are running on a 32-bit or 64-bit OS.
|
||||
IF NOT EXIST C:\Windows\SysWOW64\reg.exe (
|
||||
SET REG_EXE=C:\Windows\System32\reg.exe
|
||||
) ELSE (
|
||||
SET REG_EXE=C:\Windows\SysWOW64\reg.exe
|
||||
)
|
||||
|
||||
REM Determine where we are located.
|
||||
SET CONTAINING_DIRECTORY=%~dp0
|
||||
|
||||
REM Prepare the environment.
|
||||
|
||||
REM Registry Query Variables.
|
||||
SET A2_JAVA_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Java"
|
||||
SET A2_PYTHON_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Python"
|
||||
REM Determine where AWIPS II Java (the jre) is located.
|
||||
%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory > NUL 2>&1
|
||||
IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Java. && PAUSE && EXIT)
|
||||
FOR /F "tokens=2* delims= " %%A IN (
|
||||
'%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory') DO (
|
||||
SET JavaJreDirectory=%%B)
|
||||
REM Determine where AWIPS II Python is located.
|
||||
%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory > NUL 2>&1
|
||||
IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Python. && PAUSE && EXIT)
|
||||
FOR /F "tokens=2* delims= " %%A IN (
|
||||
'%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory') DO (
|
||||
SET PythonInstallDirectory=%%B)
|
||||
|
||||
REM Add Java and Python to the path.
|
||||
SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path%
|
||||
SET Path=%JavaJreDirectory%\bin;%Path%
|
||||
REM Define 'PythonPath'.
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%;%PythonPath%
|
||||
|
||||
REM Eliminate variables that will no longer be used.
|
||||
SET PythonInstallDirectory=
|
||||
SET JavaJreDirectory=
|
||||
SET REG_EXE=
|
||||
SET A2_JAVA_REG=
|
||||
SET A2_PYTHON_REG=
|
||||
|
||||
REM Determine where we will be logging to.
|
||||
SET HOME_DIRECTORY=%HOMEDRIVE%%HOMEPATH%
|
||||
SET CAVEDATA_LOG_DIRECTORY=%HOMEDRIVE%%HOMEPATH%\caveData\logs
|
||||
SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME%
|
||||
IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%")
|
||||
|
||||
echo Starting ALERTVIZ; leave this CMD window open to enable AlertViz 'restart'.
|
||||
REM Start AlertViz (and implement the alertviz restart capability).
|
||||
:AlertVizLoopStart
|
||||
SET RND=%random%
|
||||
SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp
|
||||
REM Python is used to retrieve the current date and time because the order
|
||||
REM of the Windows date/time fields is not necessarily guaranteed and the
|
||||
REM Windows date/time fields can only be extracted using substring operations
|
||||
REM instead of -formatter- strings like Linux allows.
|
||||
python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE%
|
||||
SET /p LOG_DATETIME= < %RND_DATETIME_FILE%
|
||||
DEL %RND_DATETIME_FILE%
|
||||
"%CONTAINING_DIRECTORY%alertviz.exe" %* > "%CONSOLE_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%.log" 2>&1
|
||||
IF %ERRORLEVEL% == 0 (EXIT)
|
||||
echo Restarting AlertViz.
|
||||
GOTO AlertVizLoopStart
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
@echo OFF
|
||||
|
||||
REM Determine if we are running on a 32-bit or 64-bit OS.
|
||||
IF NOT EXIST C:\Windows\SysWOW64\reg.exe (
|
||||
SET REG_EXE=C:\Windows\System32\reg.exe
|
||||
) ELSE (
|
||||
SET REG_EXE=C:\Windows\SysWOW64\reg.exe
|
||||
)
|
||||
|
||||
REM Determine where we are located.
|
||||
SET CONTAINING_DIRECTORY=%~dp0
|
||||
|
||||
REM Prepare the environment.
|
||||
|
||||
REM Registry Query Variables.
|
||||
SET A2_JAVA_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Java"
|
||||
SET A2_PYTHON_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Python"
|
||||
REM Determine where AWIPS II Java (the jre) is located.
|
||||
%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory > NUL 2>&1
|
||||
IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Java. && PAUSE && EXIT)
|
||||
FOR /F "tokens=2* delims= " %%A IN (
|
||||
'%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory') DO (
|
||||
SET JavaJreDirectory=%%B)
|
||||
REM Determine where AWIPS II Python is located.
|
||||
%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory > NUL 2>&1
|
||||
IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Python. && PAUSE && EXIT)
|
||||
FOR /F "tokens=2* delims= " %%A IN (
|
||||
'%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory') DO (
|
||||
SET PythonInstallDirectory=%%B)
|
||||
|
||||
REM Add Java and Python to the path.
|
||||
SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path%
|
||||
SET Path=%JavaJreDirectory%\bin;%Path%
|
||||
REM Add the CAVE lib directory to the path.
|
||||
SET Path=%CONTAINING_DIRECTORY%lib;%Path%
|
||||
REM Define 'PythonPath'.
|
||||
SET PythonPath=%CONTAINING_DIRECTORY%lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%;%PythonPath%
|
||||
|
||||
REM Eliminate variables that will no longer be used.
|
||||
SET PythonInstallDirectory=
|
||||
SET JavaJreDirectory=
|
||||
SET REG_EXE=
|
||||
SET A2_JAVA_REG=
|
||||
SET A2_PYTHON_REG=
|
||||
|
||||
REM Determine where we will be logging to.
|
||||
SET HOME_DIRECTORY=%HOMEDRIVE%%HOMEPATH%
|
||||
SET CAVEDATA_LOG_DIRECTORY=%HOMEDRIVE%%HOMEPATH%\caveData\logs
|
||||
SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME%
|
||||
IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%")
|
||||
|
||||
SET RND=%random%
|
||||
SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp
|
||||
REM Python is used to retrieve the current date and time because the order
|
||||
REM of the Windows date/time fields is not necessarily guaranteed and the
|
||||
REM Windows date/time fields can only be extracted using substring operations
|
||||
REM instead of -formatter- strings like Linux allows.
|
||||
python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE%
|
||||
SET /p LOG_DATETIME= < %RND_DATETIME_FILE%
|
||||
DEL %RND_DATETIME_FILE%
|
||||
|
||||
echo THIS CMD WINDOW CAN BE CLOSED AT ANY TIME!
|
||||
cd %HOMEPATH%
|
||||
REM Start CAVE.
|
||||
"%CONTAINING_DIRECTORY%cave.exe" %* > "%CONSOLE_LOG_DIRECTORY%\cave_%LOG_DATETIME%.log" 2>&1
|
||||
IF ERRORLEVEL 1 (echo CAVE ERROR - check the logs for additional information. && PAUSE)
|
||||
|
||||
EXIT
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
17
cave/com.raytheon.uf.viz.alertview.feature/.project
Normal file
17
cave/com.raytheon.uf.viz.alertview.feature/.project
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.alertview.feature</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.FeatureBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.FeatureNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1 @@
|
|||
bin.includes = feature.xml
|
44
cave/com.raytheon.uf.viz.alertview.feature/feature.xml
Normal file
44
cave/com.raytheon.uf.viz.alertview.feature/feature.xml
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feature
|
||||
id="com.raytheon.uf.viz.alertview.feature"
|
||||
label="AlertView Feature"
|
||||
version="1.0.0.qualifier"
|
||||
provider-name="RAYTHEON">
|
||||
|
||||
<description url="http://www.example.com/description">
|
||||
[Enter Feature Description here.]
|
||||
</description>
|
||||
|
||||
<copyright url="http://www.example.com/copyright">
|
||||
[Enter Copyright Description here.]
|
||||
</copyright>
|
||||
|
||||
<license url="http://www.example.com/license">
|
||||
[Enter License Description here.]
|
||||
</license>
|
||||
|
||||
<requires>
|
||||
<import feature="com.raytheon.uf.common.base.feature" version="1.0.0.qualifier"/>
|
||||
</requires>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.viz.alertview"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.viz.alertview.logback"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.viz.alertview.localization"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
33
cave/com.raytheon.uf.viz.alertview.localization/.project
Normal file
33
cave/com.raytheon.uf.viz.alertview.localization/.project
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.alertview.localization</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ds.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,12 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: AlertView Localization
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.alertview.localization
|
||||
Bundle-Version: 1.15.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: com.raytheon.uf.common.localization;bundle-version="1.14.1",
|
||||
com.raytheon.uf.viz.alertview;bundle-version="1.15.0"
|
||||
Service-Component: OSGI-INF/*.xml
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="com.raytheon.uf.viz.alertview.localization.AlertViewLocalizationPrefStore" enabled="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0">
|
||||
<implementation class="com.raytheon.uf.viz.alertview.localization.AlertViewLocalizationPrefStore" />
|
||||
<service>
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertViewPrefStore" />
|
||||
</service>
|
||||
<property name="service.ranking" type="Integer" value="100"/>
|
||||
<reference name="PathManager"
|
||||
bind="setPathManager"
|
||||
unbind="unsetPathManager"
|
||||
interface="com.raytheon.uf.common.localization.IPathManager"
|
||||
cardinality="1..1"
|
||||
policy="static" />
|
||||
|
||||
</component>
|
|
@ -0,0 +1,5 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
OSGI-INF/
|
|
@ -0,0 +1,170 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.localization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import com.raytheon.uf.common.localization.FileUpdatedMessage;
|
||||
import com.raytheon.uf.common.localization.ILocalizationFileObserver;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.LocalizationFileOutputStream;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
|
||||
import com.raytheon.uf.viz.alertview.AlertViewPrefStore;
|
||||
|
||||
/**
|
||||
*
|
||||
* An {@link AlertViewPrefStore} that stores preferences in
|
||||
* {@link LocalizationFile}s.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 26, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertViewLocalizationPrefStore implements AlertViewPrefStore,
|
||||
ILocalizationFileObserver {
|
||||
|
||||
private static final String BASE_PATH = "alertView"
|
||||
+ IPathManager.SEPARATOR;
|
||||
|
||||
private final Set<AlertViewPrefListener> listeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
private IPathManager pathManager;
|
||||
|
||||
protected LocalizationFile getRootFile() {
|
||||
LocalizationContext context = pathManager.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
|
||||
return pathManager.getLocalizationFile(context, BASE_PATH);
|
||||
}
|
||||
|
||||
public void setPathManager(IPathManager pathManager) {
|
||||
this.pathManager = pathManager;
|
||||
getRootFile().addFileUpdatedObserver(this);
|
||||
}
|
||||
|
||||
public void unsetPathManager(IPathManager pathManager) {
|
||||
if (pathManager == this.pathManager) {
|
||||
getRootFile().removeFileUpdatedObserver(this);
|
||||
this.pathManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream readConfigFile(String fileName) throws IOException {
|
||||
LocalizationFile file = pathManager.getStaticLocalizationFile(
|
||||
LocalizationType.COMMON_STATIC, BASE_PATH + fileName);
|
||||
if (file == null) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
return file.openInputStream();
|
||||
} catch (LocalizationException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream writeConfigFile(String fileName) throws IOException {
|
||||
LocalizationContext context = pathManager.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.USER);
|
||||
LocalizationFile file = pathManager.getLocalizationFile(context,
|
||||
BASE_PATH + fileName);
|
||||
if (file == null) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
return new SavingOutputStream(file.openOutputStream());
|
||||
} catch (LocalizationException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(AlertViewPrefListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(AlertViewPrefListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileUpdated(FileUpdatedMessage message) {
|
||||
String fileName = message.getFileName().substring(BASE_PATH.length());
|
||||
for (AlertViewPrefListener listener : listeners) {
|
||||
listener.prefFileChanged(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
private class SavingOutputStream extends OutputStream {
|
||||
|
||||
private final LocalizationFileOutputStream stream;
|
||||
|
||||
public SavingOutputStream(LocalizationFileOutputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
stream.closeAndSave();
|
||||
} catch (LocalizationOpFailedException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
stream.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
stream.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
stream.write(b, off, len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
7
cave/com.raytheon.uf.viz.alertview.logback/.classpath
Normal file
7
cave/com.raytheon.uf.viz.alertview.logback/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
cave/com.raytheon.uf.viz.alertview.logback/.project
Normal file
28
cave/com.raytheon.uf.viz.alertview.logback/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.alertview.logback</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,14 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: LogBack AlertView compatibility
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.alertview.logback
|
||||
Bundle-Version: 1.15.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Eclipse-RegisterBuddy: ch.qos.logback
|
||||
Require-Bundle: ch.qos.logback;bundle-version="1.1.2",
|
||||
com.raytheon.uf.viz.alertview;bundle-version="1.15.0",
|
||||
org.slf4j;bundle-version="1.7.5"
|
||||
Import-Package: org.osgi.framework;version="1.7.0",
|
||||
org.osgi.util.tracker;version="1.5.1"
|
||||
Bundle-ActivationPolicy: lazy
|
|
@ -0,0 +1,4 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.logback;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import ch.qos.logback.classic.PatternLayout;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Appender;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
import ch.qos.logback.core.Layout;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
|
||||
/**
|
||||
*
|
||||
* An {@link Appender} that converts {@link ILoggingEvent}s to {@link Alert}s
|
||||
* and sends them to all registered {@link AlertDestination}s. The
|
||||
* {@link Appender} can be configured with a {@link Layout} to provide custom
|
||||
* details in the alert, if no layout is provided the default layout is just the
|
||||
* exception with a full stack trace.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 16, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertViewAppender extends AppenderBase<ILoggingEvent> {
|
||||
|
||||
protected Layout<ILoggingEvent> layout;
|
||||
|
||||
private transient ServiceTracker<AlertDestination, AlertDestination> destinationTracker;
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent event) {
|
||||
AlertDestination[] destinations = destinationTracker
|
||||
.getServices(new AlertDestination[0]);
|
||||
if(destinations == null || destinations.length == 0){
|
||||
return;
|
||||
}
|
||||
Alert alert = new LoggingEventAlert(layout, event);
|
||||
for (AlertDestination destination : destinations) {
|
||||
destination.handleAlert(alert);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
Bundle bundle = FrameworkUtil.getBundle(getClass());
|
||||
BundleContext context = bundle.getBundleContext();
|
||||
context.addBundleListener(new AppenderBundleListener(bundle, this));
|
||||
destinationTracker = new ServiceTracker<>(context, AlertDestination.class,
|
||||
null);
|
||||
destinationTracker.open();
|
||||
if (layout == null) {
|
||||
PatternLayout patternLayout = new PatternLayout();
|
||||
patternLayout.setContext(this.context);
|
||||
patternLayout.setPattern("%ex");
|
||||
layout = patternLayout;
|
||||
}
|
||||
layout.start();
|
||||
super.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
layout.stop();
|
||||
if (destinationTracker != null) {
|
||||
destinationTracker.close();
|
||||
destinationTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
if (super.isStarted()) {
|
||||
return destinationTracker != null;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setLayout(Layout<ILoggingEvent> layout) {
|
||||
this.layout = layout;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.logback;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.BundleListener;
|
||||
import org.osgi.framework.SynchronousBundleListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* A {@link BundleListener} that is used by the {@link AlertViewAppender} to
|
||||
* ensure that when the bundle stops the appender is also stopped.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 24, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AppenderBundleListener implements SynchronousBundleListener {
|
||||
|
||||
private final Bundle bundle;
|
||||
|
||||
private final AlertViewAppender appender;
|
||||
|
||||
public AppenderBundleListener(Bundle bundle, AlertViewAppender appender) {
|
||||
this.bundle = bundle;
|
||||
this.appender = appender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bundleChanged(BundleEvent event) {
|
||||
if (event.getType() == BundleEvent.STOPPING
|
||||
&& event.getBundle() == bundle) {
|
||||
appender.stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.logback;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Layout;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Wraps an {@link ILoggingEvent} in the {@link Alert} interface so it can be
|
||||
* added to the AlertView.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 16, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class LoggingEventAlert implements Alert {
|
||||
|
||||
private final Layout<ILoggingEvent> layout;
|
||||
|
||||
private final ILoggingEvent event;
|
||||
|
||||
public LoggingEventAlert(Layout<ILoggingEvent> layout, ILoggingEvent event) {
|
||||
this.layout = layout;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getTime() {
|
||||
return new Date(event.getTimeStamp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
if (event.getLevel() == Level.ERROR) {
|
||||
return Priority.ERROR;
|
||||
} else if (event.getLevel() == Level.WARN) {
|
||||
return Priority.WARN;
|
||||
} else if (event.getLevel() == Level.INFO) {
|
||||
return Priority.INFO;
|
||||
} else {
|
||||
return Priority.DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrigin() {
|
||||
return event.getLoggerName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return event.getFormattedMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails() {
|
||||
return layout.doLayout(event);
|
||||
}
|
||||
|
||||
}
|
7
cave/com.raytheon.uf.viz.alertview/.classpath
Normal file
7
cave/com.raytheon.uf.viz.alertview/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
33
cave/com.raytheon.uf.viz.alertview/.project
Normal file
33
cave/com.raytheon.uf.viz.alertview/.project
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.alertview</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ds.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
18
cave/com.raytheon.uf.viz.alertview/META-INF/MANIFEST.MF
Normal file
18
cave/com.raytheon.uf.viz.alertview/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,18 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: AlertView
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.alertview;singleton:=true
|
||||
Bundle-Version: 1.15.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Export-Package: com.raytheon.uf.viz.alertview
|
||||
Require-Bundle: org.eclipse.ui;bundle-version="3.8.2",
|
||||
org.eclipse.core.runtime;bundle-version="3.8.0",
|
||||
org.eclipse.jface.text;bundle-version="3.8.2",
|
||||
org.eclipse.ui.console;bundle-version="3.5.100",
|
||||
org.slf4j;bundle-version="1.7.5"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: com.raytheon.uf.viz.alertview.jar
|
||||
Service-Component: OSGI-INF/*.xml
|
||||
Bundle-Activator: com.raytheon.uf.viz.alertview.AlertViewActivator
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="com.raytheon.uf.viz.alertview.ui.view.AlertViewAutoOpen" enabled="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0">
|
||||
<implementation class="com.raytheon.uf.viz.alertview.ui.view.AlertViewAutoOpen" />
|
||||
<service>
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertDestination" />
|
||||
</service>
|
||||
</component>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="com.raytheon.uf.viz.alertview.ui.popup.AlertPopup" enabled="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0">
|
||||
<implementation class="com.raytheon.uf.viz.alertview.ui.popup.AlertPopup" />
|
||||
<service>
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertDestination" />
|
||||
</service>
|
||||
</component>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="com.raytheon.uf.viz.alertview.prefs.RCPPrefStore" enabled="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0">
|
||||
<implementation class="com.raytheon.uf.viz.alertview.prefs.RCPPrefStore" />
|
||||
<service>
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertViewPrefStore" />
|
||||
</service>
|
||||
</component>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="com.raytheon.uf.viz.alertview.store.MemoryAlertStore" enabled="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0">
|
||||
<implementation class="com.raytheon.uf.viz.alertview.store.MemoryAlertStore" />
|
||||
<service>
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertDestination" />
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertStore" />
|
||||
</service>
|
||||
</component>
|
9
cave/com.raytheon.uf.viz.alertview/build.properties
Normal file
9
cave/com.raytheon.uf.viz.alertview/build.properties
Normal file
|
@ -0,0 +1,9 @@
|
|||
jars.compile.order = com.raytheon.uf.viz.alertview.jar
|
||||
source.com.raytheon.uf.viz.alertview.jar = src/
|
||||
output.com.raytheon.uf.viz.alertview.jar = bin/
|
||||
bin.includes = META-INF/,\
|
||||
OSGI-INF/,\
|
||||
icons/,\
|
||||
plugin.xml,\
|
||||
defaultPrefs/,\
|
||||
com.raytheon.uf.viz.alertview.jar
|
|
@ -0,0 +1,7 @@
|
|||
<popUpPreferences>
|
||||
<filter>error</filter>
|
||||
<duration>3000</duration>
|
||||
<width>500</width>
|
||||
<height>50</height>
|
||||
<corner>LOWER_RIGHT</corner>
|
||||
</popUpPreferences>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<styleList>
|
||||
<style>
|
||||
<filter>error</filter>
|
||||
<foregroundColor>#FF0000</foregroundColor>
|
||||
</style>
|
||||
</styleList>
|
|
@ -0,0 +1,21 @@
|
|||
<popUpPreferences>
|
||||
<openFilter>none</openFilter>
|
||||
<activeFilter>warnPlus</activeFilter>
|
||||
<filterMenu>
|
||||
<filter>all</filter>
|
||||
<text>All</text>
|
||||
</filterMenu>
|
||||
<filterMenu>
|
||||
<filter>error</filter>
|
||||
<text>Only Errors</text>
|
||||
</filterMenu>
|
||||
<filterMenu>
|
||||
<filter>warnPlus</filter>
|
||||
<text>Errors and Warnings</text>
|
||||
</filterMenu>
|
||||
<column>Time</column>
|
||||
<column>Priority</column>
|
||||
<column>Message</column>
|
||||
<alertsToLoad>1000</alertsToLoad>
|
||||
<mergeRepeatInterval>1000</mergeRepeatInterval>
|
||||
</popUpPreferences>
|
BIN
cave/com.raytheon.uf.viz.alertview/icons/alertView.png
Normal file
BIN
cave/com.raytheon.uf.viz.alertview/icons/alertView.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 339 B |
43
cave/com.raytheon.uf.viz.alertview/plugin.xml
Normal file
43
cave/com.raytheon.uf.viz.alertview/plugin.xml
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.4"?>
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.ui.views">
|
||||
<view
|
||||
allowMultiple="false"
|
||||
category="com.raytheon.viz.ui"
|
||||
class="com.raytheon.uf.viz.alertview.ui.view.AlertView"
|
||||
icon="icons/alertView.png"
|
||||
id="com.raytheon.uf.viz.alertview.ui.view.AlertView"
|
||||
name="Alert View"
|
||||
restorable="true"/>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="menu:CAVE?after=browsers">
|
||||
<command
|
||||
commandId="com.raytheon.uf.viz.alertview.openAlertView"
|
||||
label="Open AlertView"
|
||||
style="push">
|
||||
<visibleWhen>
|
||||
<systemTest property="alertview.enabled" value="true" />
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="com.raytheon.uf.viz.alertview.ui.view.OpenAlertViewHandler"
|
||||
commandId="com.raytheon.uf.viz.alertview.openAlertView">
|
||||
</handler>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
<command
|
||||
id="com.raytheon.uf.viz.alertview.openAlertView"
|
||||
name="Open AlertView">
|
||||
</command>
|
||||
</extension>
|
||||
</plugin>
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertView;
|
||||
|
||||
/**
|
||||
* The primary interface for items that should be displayed in {@link AlertView}
|
||||
* .
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface Alert {
|
||||
|
||||
public enum Priority {
|
||||
DEBUG, INFO, WARN, ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The time the event occured that generated this alert.
|
||||
*/
|
||||
public Date getTime();
|
||||
|
||||
/**
|
||||
* @return The importance of the alert.
|
||||
*/
|
||||
public Priority getPriority();
|
||||
|
||||
/**
|
||||
* @return An arbitrary string describing the origin of the Alert. This
|
||||
* should be a short word or phrase that can be used by the user to
|
||||
* take special action based on origins that are more or less
|
||||
* important for a specific user.
|
||||
*/
|
||||
public String getOrigin();
|
||||
|
||||
/**
|
||||
* @return A short summary of the alert.
|
||||
*/
|
||||
public String getMessage();
|
||||
|
||||
/**
|
||||
* @return A detailed description of the alert.
|
||||
*/
|
||||
public String getDetails();
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
/**
|
||||
*
|
||||
* An OSGi service interface for any service component that needs to know about
|
||||
* {@link Alert}s. Any component which wants to contribute new alerts should
|
||||
* broadcast the Alert to all registered {@link AlertDestination}s. Any
|
||||
* componenet that needs to know about new Alerts should implement this
|
||||
* interface and register as a service.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AlertDestination {
|
||||
|
||||
public void handleAlert(Alert alert);
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* An OSGi service interface that provides a way for the AlertView to load
|
||||
* {@link Alert}s that arrive while it is not open. At a minimum a store should
|
||||
* be accumulating new messages as they arrive. A store may want to provide
|
||||
* persistant storage so that old alerts can be viewed from a new cave.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AlertStore {
|
||||
|
||||
/**
|
||||
* @return All stored alerts.
|
||||
*/
|
||||
public List<Alert> getAlerts();
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
import org.eclipse.jface.preference.PreferenceManager;
|
||||
import org.eclipse.jface.preference.PreferenceNode;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.Constants;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.osgi.framework.ServiceEvent;
|
||||
import org.osgi.framework.ServiceListener;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.ui.prefs.AlertViewPreferencePage;
|
||||
import com.raytheon.uf.viz.alertview.ui.prefs.PopupPreferencePage;
|
||||
import com.raytheon.uf.viz.alertview.ui.prefs.StylePreferencePage;
|
||||
|
||||
/**
|
||||
*
|
||||
* {@link BundleActivator} that is used to only show the preference pages if
|
||||
* AlertView is being used.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 30, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertViewActivator implements BundleActivator {
|
||||
|
||||
|
||||
@Override
|
||||
public void start(BundleContext context) throws InvalidSyntaxException {
|
||||
/*
|
||||
* Only show the preferences if this bundle is activated which will
|
||||
* happen through declarative services if anyone is using the
|
||||
* destination.
|
||||
*/
|
||||
if (PlatformUI.isWorkbenchRunning()) {
|
||||
addPreferencePages();
|
||||
} else {
|
||||
String workbenchFilter = "(" + Constants.OBJECTCLASS + "="
|
||||
+ IWorkbench.class.getName() + ")";
|
||||
context.addServiceListener(new ServiceListener() {
|
||||
|
||||
@Override
|
||||
public void serviceChanged(ServiceEvent event) {
|
||||
if (event.getType() == ServiceEvent.REGISTERED) {
|
||||
addPreferencePages();
|
||||
}
|
||||
}
|
||||
}, workbenchFilter);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addPreferencePages() {
|
||||
PreferenceManager pm = PlatformUI.getWorkbench().getPreferenceManager();
|
||||
PreferenceNode alertViewNode = new PreferenceNode(
|
||||
AlertViewPreferencePage.class.getName(), "Alert View", null,
|
||||
null) {
|
||||
|
||||
@Override
|
||||
public void createPage() {
|
||||
AlertViewPreferencePage page = new AlertViewPreferencePage();
|
||||
page.setTitle(getLabelText());
|
||||
page.setDescription("Configure AlertView appearance and behavior.");
|
||||
setPage(page);
|
||||
}
|
||||
|
||||
};
|
||||
PreferenceNode popUpNode = new PreferenceNode(
|
||||
PopupPreferencePage.class.getName(), "Popup", null, null) {
|
||||
|
||||
@Override
|
||||
public void createPage() {
|
||||
PopupPreferencePage page = new PopupPreferencePage();
|
||||
page.setTitle(getLabelText());
|
||||
page.setDescription("Configure Alert Popup appearance and behavior.");
|
||||
setPage(page);
|
||||
}
|
||||
|
||||
};
|
||||
PreferenceNode styleNode = new PreferenceNode(
|
||||
StylePreferencePage.class.getName(), "Style", null, null) {
|
||||
|
||||
@Override
|
||||
public void createPage() {
|
||||
StylePreferencePage page = new StylePreferencePage();
|
||||
page.setTitle(getLabelText());
|
||||
page.setDescription("Configure the way alerts appear in the alert table.");
|
||||
setPage(page);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
alertViewNode.add(popUpNode);
|
||||
alertViewNode.add(styleNode);
|
||||
pm.addToRoot(alertViewNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
if (PlatformUI.isWorkbenchRunning()) {
|
||||
PreferenceManager pm = PlatformUI.getWorkbench()
|
||||
.getPreferenceManager();
|
||||
pm.remove(AlertViewPreferencePage.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* An OSGi service interface that supplies configuration information to
|
||||
* AlertView components.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AlertViewPrefStore {
|
||||
|
||||
public InputStream readConfigFile(String fileName) throws IOException;
|
||||
|
||||
public OutputStream writeConfigFile(String fileName) throws IOException;
|
||||
|
||||
public void addListener(AlertViewPrefListener listener);
|
||||
|
||||
public void removeListener(AlertViewPrefListener listener);
|
||||
|
||||
public static interface AlertViewPrefListener {
|
||||
|
||||
public void prefFileChanged(String fileName);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.action;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.widgets.FileDialog;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertView;
|
||||
|
||||
/**
|
||||
*
|
||||
* Action for writing an alert to a file.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 24, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SaveToFileAction extends Action {
|
||||
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm:ss,SSS");
|
||||
|
||||
/** Don't waste memory keeping excessive details. */
|
||||
private static final int MAX_DETAILS_SIZE = 16 * 1024;
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(AlertView.class);
|
||||
|
||||
private final Alert alert;
|
||||
|
||||
private final Path path;
|
||||
|
||||
public SaveToFileAction(Alert alert) {
|
||||
super("Save to file...");
|
||||
this.alert = alert;
|
||||
this.path = null;
|
||||
}
|
||||
|
||||
public SaveToFileAction(Alert alert, Path path) {
|
||||
super("Save to file...");
|
||||
this.alert = alert;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Path path = this.path;
|
||||
if (path == null) {
|
||||
FileDialog fd = new FileDialog(PlatformUI.getWorkbench()
|
||||
.getActiveWorkbenchWindow().getShell(), SWT.SAVE);
|
||||
fd.setFileName("alert.txt");
|
||||
fd.setFilterExtensions(new String[] { "*.txt" });
|
||||
String fileName = fd.open();
|
||||
if (fileName != null) {
|
||||
path = Paths.get(fileName);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
write(path, alert);
|
||||
} catch (IOException e) {
|
||||
logger.error("Unable to save alert", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(Path path, Alert alert) throws IOException {
|
||||
Bundle bundle = FrameworkUtil.getBundle(SaveToFileAction.class);
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(path, UTF8)) {
|
||||
writer.write("# Written by " + bundle.getSymbolicName() + " "
|
||||
+ bundle.getVersion() + "\n");
|
||||
writer.write(alert.getPriority().toString());
|
||||
writer.write(" ");
|
||||
writer.write(TIME_FORMAT.format(alert.getTime()));
|
||||
writer.write(" ");
|
||||
writer.write(alert.getMessage());
|
||||
writer.write("\n");
|
||||
writer.write(alert.getDetails());
|
||||
}
|
||||
}
|
||||
|
||||
public static Alert read(Path path) throws IOException {
|
||||
byte[] bytes = Files.readAllBytes(path);
|
||||
String content = new String(bytes, UTF8);
|
||||
String first = "#";
|
||||
String details = content;
|
||||
while (first.startsWith("#")) {
|
||||
String[] split = details.split("\n", 2);
|
||||
if (split.length != 2) {
|
||||
throw new IOException(path.toString()
|
||||
+ " is not a valid alert file");
|
||||
}
|
||||
first = split[0];
|
||||
details = split[1];
|
||||
}
|
||||
String[] split = first.split(" ", 4);
|
||||
if (split.length != 4) {
|
||||
throw new IOException(path.toString()
|
||||
+ " is not a valid alert file");
|
||||
}
|
||||
Priority priority;
|
||||
try {
|
||||
priority = Priority.valueOf(split[0]);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IOException(split[0] + " is not a valid priority.");
|
||||
}
|
||||
Date time;
|
||||
try {
|
||||
time = TIME_FORMAT.parse(split[1] + " " + split[2]);
|
||||
} catch (ParseException e) {
|
||||
throw new IOException(path.toString()
|
||||
+ " is not a valid alert file", e);
|
||||
}
|
||||
String message = split[3];
|
||||
if (details.length() > MAX_DETAILS_SIZE) {
|
||||
details = details.substring(0, MAX_DETAILS_SIZE)
|
||||
+ "\n...file content truncated...";
|
||||
}
|
||||
return new ParsedAlert(priority, time, path.toString(), message,
|
||||
details);
|
||||
}
|
||||
|
||||
private static class ParsedAlert implements Alert {
|
||||
|
||||
private final Priority priority;
|
||||
|
||||
private final Date time;
|
||||
|
||||
private final String origin;
|
||||
|
||||
private final String message;
|
||||
|
||||
private final String details;
|
||||
|
||||
public ParsedAlert(Priority priority, Date time, String origin,
|
||||
String message, String details) {
|
||||
this.priority = priority;
|
||||
this.time = time;
|
||||
this.origin = origin;
|
||||
this.message = message;
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface for an object that filters {@link Alert}s. This is used throughout
|
||||
* alertview to ensure the user can see only alerts they are interested in.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AlertFilter {
|
||||
|
||||
public boolean filter(Alert alert);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
* An {@link AlertFilter} that always returns true, or always returns false,
|
||||
* ignoring the {@link Alert} that is passed in. This is used to implement a
|
||||
* filter that either always accepts or always rejects Alerts.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ConstantFilter implements AlertFilter {
|
||||
|
||||
public final boolean result;
|
||||
|
||||
public ConstantFilter(boolean result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(Alert alert) {
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
|
||||
/**
|
||||
*
|
||||
* Provides a lookup mechanism for getting {@link AlertFilter}s using an id.
|
||||
* This is especially useful when a filter is stored in a preference file
|
||||
* because the id provides a convenient representation to store it and the
|
||||
* manager provides a reliable way to lookup filters.
|
||||
*
|
||||
* TODO the current implementation just uses a small set of hard-coded filters.
|
||||
* This should be implemented so that new filters can be added by other plugins
|
||||
* and possibly even allow user defined filters to do things like regex the
|
||||
* message.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class FilterManager {
|
||||
|
||||
/** Name for a filter that accepts all alerts. */
|
||||
public static final String ALL = "all";
|
||||
|
||||
/** Name for a filter that accepts no alerts. */
|
||||
public static final String NONE = "none";
|
||||
|
||||
/** Name for a filter that accepts alerts with priority >= WARN. */
|
||||
public static final String WARN_PLUS = "warnPlus";
|
||||
|
||||
/** Name for a filter that accepts alerts with priority >= INFO. */
|
||||
public static final String INFO_PLUS = "infoPlus";
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(FilterManager.class);
|
||||
|
||||
private static final AlertFilter NONE_FILTER = new ConstantFilter(false);
|
||||
|
||||
private final Map<String, AlertFilter> filters = new HashMap<>();
|
||||
|
||||
public FilterManager() {
|
||||
loadDefaultFilters();
|
||||
}
|
||||
|
||||
private void loadDefaultFilters() {
|
||||
filters.put(ALL, new ConstantFilter(true));
|
||||
filters.put(NONE, new ConstantFilter(false));
|
||||
for (Priority p : Priority.values()) {
|
||||
filters.put(p.name().toLowerCase(), new PriorityFilter(p));
|
||||
}
|
||||
filters.put(WARN_PLUS, new MinPriorityFilter(Priority.WARN));
|
||||
filters.put(INFO_PLUS, new MinPriorityFilter(Priority.INFO));
|
||||
}
|
||||
|
||||
public AlertFilter getFilter(String id) {
|
||||
AlertFilter filter = filters.get(id);
|
||||
if (filter == null) {
|
||||
logger.warn("AlertView FilterManager failed to find a filter with an id of "
|
||||
+ id);
|
||||
filter = NONE_FILTER;
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
|
||||
/**
|
||||
* An {@link AlertFilter} that returns true for {@link Alert}s that have a
|
||||
* priority equal to or above a specified level.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MinPriorityFilter implements AlertFilter {
|
||||
|
||||
private final Priority priority;
|
||||
|
||||
public MinPriorityFilter(Priority priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(Alert alert) {
|
||||
return alert.getPriority().ordinal() >= priority.ordinal();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
|
||||
/**
|
||||
* An {@link AlertFilter} that returns true for {@link Alert}s that have a
|
||||
* priority equal to a specified level.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PriorityFilter implements AlertFilter {
|
||||
|
||||
private final Priority priority;
|
||||
|
||||
public PriorityFilter(Priority priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(Alert alert) {
|
||||
return alert.getPriority() == priority;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.prefs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertTable;
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertView;
|
||||
|
||||
/**
|
||||
* Contains the preferences that control how {@link AlertView} appears to the
|
||||
* user.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlRootElement
|
||||
public class AlertViewPreferences {
|
||||
|
||||
private final List<FilterMenu> DEFAULT_FILTERS = Arrays.asList(
|
||||
new FilterMenu("All", FilterManager.ALL), new FilterMenu(
|
||||
"Only Errors", Priority.ERROR.name().toLowerCase()),
|
||||
new FilterMenu("Errors + Warnings", FilterManager.WARN_PLUS));
|
||||
|
||||
private final List<String> DEFAULT_COLUMNS = Arrays.asList(
|
||||
AlertTable.COLUMN_TIME, AlertTable.COLUMN_PRIORITY,
|
||||
AlertTable.COLUMN_MESSAGE);
|
||||
|
||||
private String openFilter;
|
||||
|
||||
private String activeFilter;
|
||||
|
||||
private List<FilterMenu> filterMenu;
|
||||
|
||||
private List<String> columns;
|
||||
|
||||
private int alertsToLoad;
|
||||
|
||||
/* Time in ms */
|
||||
private int mergeRepeatInterval;
|
||||
|
||||
public AlertViewPreferences() {
|
||||
/* Everything needs reasonable defaults to keep PreferenceFile happy. */
|
||||
openFilter = FilterManager.NONE;
|
||||
activeFilter = FilterManager.WARN_PLUS;
|
||||
filterMenu = new ArrayList<>(DEFAULT_FILTERS);
|
||||
columns = new ArrayList<>(DEFAULT_COLUMNS);
|
||||
alertsToLoad = 1000;
|
||||
mergeRepeatInterval = 1000;
|
||||
}
|
||||
|
||||
public AlertViewPreferences(AlertViewPreferences other) {
|
||||
this.openFilter = other.getOpenFilter();
|
||||
this.activeFilter = other.getActiveFilter();
|
||||
this.filterMenu = other.getFilterMenu();
|
||||
this.columns = other.getColumns();
|
||||
this.alertsToLoad = other.getAlertsToLoad();
|
||||
this.mergeRepeatInterval = other.getMergeRepeatInterval();
|
||||
}
|
||||
|
||||
public String getOpenFilter() {
|
||||
return openFilter;
|
||||
}
|
||||
|
||||
public void setOpenFilter(String openFilter) {
|
||||
this.openFilter = openFilter;
|
||||
}
|
||||
|
||||
public String getActiveFilter() {
|
||||
return activeFilter;
|
||||
}
|
||||
|
||||
public void setActiveFilter(String activeFilter) {
|
||||
this.activeFilter = activeFilter;
|
||||
}
|
||||
|
||||
public List<FilterMenu> getFilterMenu() {
|
||||
return filterMenu;
|
||||
}
|
||||
|
||||
public void setFilterMenu(List<FilterMenu> filterMenu) {
|
||||
this.filterMenu = filterMenu;
|
||||
}
|
||||
|
||||
public int getAlertsToLoad() {
|
||||
return alertsToLoad;
|
||||
}
|
||||
|
||||
public void setAlertsToLoad(int alertsToLoad) {
|
||||
this.alertsToLoad = alertsToLoad;
|
||||
}
|
||||
|
||||
@XmlElement(name = "column")
|
||||
public List<String> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public void setColumns(List<String> columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
public int getMergeRepeatInterval() {
|
||||
return mergeRepeatInterval;
|
||||
}
|
||||
|
||||
public void setMergeRepeatInterval(int mergeRepeatInterval) {
|
||||
this.mergeRepeatInterval = mergeRepeatInterval;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result
|
||||
+ ((activeFilter == null) ? 0 : activeFilter.hashCode());
|
||||
result = prime * result + alertsToLoad;
|
||||
result = prime * result + ((columns == null) ? 0 : columns.hashCode());
|
||||
result = prime * result
|
||||
+ ((filterMenu == null) ? 0 : filterMenu.hashCode());
|
||||
result = prime * result + mergeRepeatInterval;
|
||||
result = prime * result
|
||||
+ ((openFilter == null) ? 0 : openFilter.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AlertViewPreferences other = (AlertViewPreferences) obj;
|
||||
if (activeFilter == null) {
|
||||
if (other.activeFilter != null)
|
||||
return false;
|
||||
} else if (!activeFilter.equals(other.activeFilter))
|
||||
return false;
|
||||
if (alertsToLoad != other.alertsToLoad)
|
||||
return false;
|
||||
if (columns == null) {
|
||||
if (other.columns != null)
|
||||
return false;
|
||||
} else if (!columns.equals(other.columns))
|
||||
return false;
|
||||
if (filterMenu == null) {
|
||||
if (other.filterMenu != null)
|
||||
return false;
|
||||
} else if (!filterMenu.equals(other.filterMenu))
|
||||
return false;
|
||||
if (mergeRepeatInterval != other.mergeRepeatInterval)
|
||||
return false;
|
||||
if (openFilter == null) {
|
||||
if (other.openFilter != null)
|
||||
return false;
|
||||
} else if (!openFilter.equals(other.openFilter))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static class FilterMenu {
|
||||
|
||||
private String text;
|
||||
|
||||
private String filter;
|
||||
|
||||
public FilterMenu() {
|
||||
|
||||
}
|
||||
|
||||
public FilterMenu(String text, String filter) {
|
||||
this.text = text;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result
|
||||
+ ((filter == null) ? 0 : filter.hashCode());
|
||||
result = prime * result + ((text == null) ? 0 : text.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
FilterMenu other = (FilterMenu) obj;
|
||||
if (filter == null) {
|
||||
if (other.filter != null)
|
||||
return false;
|
||||
} else if (!filter.equals(other.filter))
|
||||
return false;
|
||||
if (text == null) {
|
||||
if (other.text != null)
|
||||
return false;
|
||||
} else if (!text.equals(other.text))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static PreferenceFile<AlertViewPreferences> load(
|
||||
PreferenceFile.Listener<? super AlertViewPreferences> listener) {
|
||||
return new PreferenceFile<>("alert_view.xml",
|
||||
AlertViewPreferences.class, listener);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.prefs;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
import com.raytheon.uf.viz.alertview.ui.popup.AlertPopup;
|
||||
|
||||
/**
|
||||
* Contains the preferences that control how {@link AlertPopup} appears to the
|
||||
* user.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlRootElement
|
||||
public class PopUpPreferences {
|
||||
|
||||
public static enum PopUpCorner {
|
||||
UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT;
|
||||
|
||||
public String getPrettyName() {
|
||||
String name = name();
|
||||
String[] words = name.split("_");
|
||||
StringBuilder pretty = new StringBuilder(name.length());
|
||||
for (String word : words) {
|
||||
if (pretty.length() > 0) {
|
||||
pretty.append(' ');
|
||||
}
|
||||
pretty.append(word.charAt(0));
|
||||
pretty.append(word.substring(1).toLowerCase());
|
||||
}
|
||||
return pretty.toString();
|
||||
}
|
||||
|
||||
public static PopUpCorner fromPrettyName(String corner) {
|
||||
return valueOf(corner.replace(' ', '_').toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
private String filter;
|
||||
|
||||
/* Time in ms. */
|
||||
private int duration;
|
||||
|
||||
private PopUpCorner corner;
|
||||
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
public PopUpPreferences() {
|
||||
/* Everything needs reasonable defaults to keep PreferenceFile happy. */
|
||||
filter = Priority.ERROR.name().toLowerCase();
|
||||
duration = 3000;
|
||||
corner = PopUpCorner.LOWER_RIGHT;
|
||||
width = 500;
|
||||
height = 50;
|
||||
}
|
||||
|
||||
public PopUpPreferences(PopUpPreferences other) {
|
||||
this.filter = other.getFilter();
|
||||
this.duration = other.getDuration();
|
||||
this.corner = other.getCorner();
|
||||
this.width = other.getWidth();
|
||||
this.height = other.getHeight();
|
||||
}
|
||||
|
||||
public String getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public PopUpCorner getCorner() {
|
||||
return corner;
|
||||
}
|
||||
|
||||
public void setCorner(PopUpCorner corner) {
|
||||
this.corner = corner;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((corner == null) ? 0 : corner.hashCode());
|
||||
result = prime * result + duration;
|
||||
result = prime * result + ((filter == null) ? 0 : filter.hashCode());
|
||||
result = prime * result + height;
|
||||
result = prime * result + width;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PopUpPreferences other = (PopUpPreferences) obj;
|
||||
if (corner != other.corner)
|
||||
return false;
|
||||
if (duration != other.duration)
|
||||
return false;
|
||||
if (filter == null) {
|
||||
if (other.filter != null)
|
||||
return false;
|
||||
} else if (!filter.equals(other.filter))
|
||||
return false;
|
||||
if (height != other.height)
|
||||
return false;
|
||||
if (width != other.width)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static PreferenceFile<PopUpPreferences> load(
|
||||
PreferenceFile.Listener<? super PopUpPreferences> listener) {
|
||||
return new PreferenceFile<>("alert_popup.xml", PopUpPreferences.class,
|
||||
listener);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.prefs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.xml.bind.DataBindingException;
|
||||
import javax.xml.bind.JAXB;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.Constants;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.osgi.framework.ServiceEvent;
|
||||
import org.osgi.framework.ServiceListener;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.AlertViewPrefStore;
|
||||
import com.raytheon.uf.viz.alertview.AlertViewPrefStore.AlertViewPrefListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* Handles the serialization and service management of a preference file. This
|
||||
* class is designed to be a more friendly way to consume an
|
||||
* {@link AlertViewPrefStore} service. To load preferences using this class the
|
||||
* Preference class P should be JAXB serializable and must provide a no-arg
|
||||
* constructor that initializaes the preferences to a usable state. In cases
|
||||
* when loading the preferences from files fails the no-arg constructor will be
|
||||
* used to return a default preference object.
|
||||
*
|
||||
* This class listens to changes from the {@link AlertViewPrefStore} service and
|
||||
* notifies its own listeners of changes to the specified file. It also listens
|
||||
* to changes to the available AlertViewPrefStore services and when a better
|
||||
* service becomes available it will reload the preferences from the new service
|
||||
* and notify listeners. This is especially useful during startup if the
|
||||
* prefered AlertViewPrefStore starts after other components.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 16, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
* @param <P>
|
||||
*/
|
||||
public class PreferenceFile<P> {
|
||||
|
||||
private static final String FILTER = "(" + Constants.OBJECTCLASS + "="
|
||||
+ AlertViewPrefStore.class.getName() + ")";
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final BundleContext context;
|
||||
|
||||
private final String fileName;
|
||||
|
||||
private final Class<P> type;
|
||||
|
||||
private final Listener<? super P> listener;
|
||||
|
||||
private final AlertViewPrefListener prefStoreListener = new AlertViewPrefListener() {
|
||||
|
||||
@Override
|
||||
public void prefFileChanged(String fileName) {
|
||||
if (fileName.equals(PreferenceFile.this.fileName)) {
|
||||
updatePreferences(loadFromStore());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final ServiceListener serviceListener = new ServiceListener() {
|
||||
|
||||
@Override
|
||||
public void serviceChanged(ServiceEvent event) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ServiceReference<AlertViewPrefStore> ref = (ServiceReference<AlertViewPrefStore>) event
|
||||
.getServiceReference();
|
||||
if (event.getType() == ServiceEvent.REGISTERED) {
|
||||
add(ref);
|
||||
} else if (event.getType() == ServiceEvent.UNREGISTERING) {
|
||||
remove(ref);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private ServiceReference<AlertViewPrefStore> serviceReference;
|
||||
|
||||
private AlertViewPrefStore prefStore;
|
||||
|
||||
private P preferences;
|
||||
|
||||
public PreferenceFile(String fileName, Class<P> type,
|
||||
Listener<? super P> listener) {
|
||||
this.fileName = fileName;
|
||||
this.type = type;
|
||||
this.listener = listener;
|
||||
context = FrameworkUtil.getBundle(getClass()).getBundleContext();
|
||||
try {
|
||||
context.addServiceListener(serviceListener, FILTER);
|
||||
} catch (InvalidSyntaxException e) {
|
||||
/*
|
||||
* The FILTER is statically defined and very simple syntax so it is
|
||||
* unlikely that this will ever happen.
|
||||
*/
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.preferences = updateServiceReference(context
|
||||
.getServiceReference(AlertViewPrefStore.class));
|
||||
}
|
||||
|
||||
public void close(){
|
||||
if(serviceReference != null){
|
||||
prefStore.removeListener(prefStoreListener);
|
||||
context.ungetService(serviceReference);
|
||||
}
|
||||
context.removeServiceListener(serviceListener);
|
||||
}
|
||||
|
||||
protected P updateServiceReference(
|
||||
ServiceReference<AlertViewPrefStore> serviceReference) {
|
||||
this.serviceReference = serviceReference;
|
||||
if (serviceReference != null) {
|
||||
return updatePrefStore(context.getService(serviceReference));
|
||||
} else {
|
||||
return updatePrefStore(null);
|
||||
}
|
||||
}
|
||||
|
||||
protected P updatePrefStore(AlertViewPrefStore prefStore) {
|
||||
this.prefStore = prefStore;
|
||||
if (prefStore != null) {
|
||||
prefStore.addListener(prefStoreListener);
|
||||
}
|
||||
return loadFromStore();
|
||||
}
|
||||
|
||||
protected P loadFromStore() {
|
||||
P preferences = null;
|
||||
if (prefStore != null) {
|
||||
try (InputStream in = prefStore.readConfigFile(fileName)) {
|
||||
if (in != null) {
|
||||
preferences = JAXB.unmarshal(in, type);
|
||||
}
|
||||
} catch (IOException | DataBindingException e) {
|
||||
logger.error("Unable to load {} from {}", type.getSimpleName(),
|
||||
fileName, e);
|
||||
}
|
||||
}
|
||||
if (preferences == null) {
|
||||
try {
|
||||
preferences = type.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
/*
|
||||
* Docs indicate you should have a public no arg constructor, if
|
||||
* there isn't one then you get RuntimeExceptions.
|
||||
*/
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return preferences;
|
||||
}
|
||||
|
||||
protected void updatePreferences(P preferences) {
|
||||
if (!this.preferences.equals(preferences)) {
|
||||
this.preferences = preferences;
|
||||
listener.update(preferences);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void add(ServiceReference<AlertViewPrefStore> ref) {
|
||||
if (serviceReference == null || ref.compareTo(serviceReference) > 0) {
|
||||
if (serviceReference != null) {
|
||||
prefStore.removeListener(prefStoreListener);
|
||||
context.ungetService(serviceReference);
|
||||
}
|
||||
updatePreferences(updateServiceReference(ref));
|
||||
}
|
||||
}
|
||||
|
||||
protected void remove(ServiceReference<AlertViewPrefStore> ref) {
|
||||
if (ref.equals(serviceReference)) {
|
||||
prefStore.removeListener(prefStoreListener);
|
||||
context.ungetService(serviceReference);
|
||||
updatePreferences(updateServiceReference(context
|
||||
.getServiceReference(AlertViewPrefStore.class)));
|
||||
}
|
||||
}
|
||||
|
||||
public P get() {
|
||||
return preferences;
|
||||
}
|
||||
|
||||
public void write(P preferences) {
|
||||
if (prefStore != null) {
|
||||
try (OutputStream out = prefStore.writeConfigFile(fileName)) {
|
||||
JAXB.marshal(preferences, out);
|
||||
} catch (IOException e) {
|
||||
logger.error("Unable to write {} to {}", type.getSimpleName(),
|
||||
fileName, e);
|
||||
}
|
||||
}
|
||||
updatePreferences(preferences);
|
||||
}
|
||||
|
||||
public static interface Listener<P> {
|
||||
|
||||
public void update(P preference);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.prefs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.AlertViewPrefStore;
|
||||
|
||||
/**
|
||||
*
|
||||
* A simple {@link AlertViewPrefStore} that stores preferences in the state area
|
||||
* that the Eclipse Runtime Platform provides for this bundle. When no user file
|
||||
* is available the default version of the file is loaded from within this
|
||||
* bundle.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RCPPrefStore implements AlertViewPrefStore {
|
||||
|
||||
private final Bundle bundle;
|
||||
|
||||
private final IPath root = new Path("defaultPrefs");
|
||||
|
||||
private final Set<AlertViewPrefListener> listeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
public RCPPrefStore() {
|
||||
this.bundle = FrameworkUtil.getBundle(getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream readConfigFile(String fileName) throws IOException {
|
||||
IPath userPath = Platform.getStateLocation(bundle).append(fileName);
|
||||
File file = userPath.toFile();
|
||||
if (file.exists()) {
|
||||
return new FileInputStream(file);
|
||||
} else {
|
||||
return FileLocator.openStream(bundle, root.append(fileName), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream writeConfigFile(String fileName)
|
||||
throws FileNotFoundException {
|
||||
IPath userPath = Platform.getStateLocation(bundle).append(fileName);
|
||||
return new NotificationOutputStream(userPath.toFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(AlertViewPrefListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(AlertViewPrefListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
private class NotificationOutputStream extends FileOutputStream {
|
||||
|
||||
private final String fileName;
|
||||
|
||||
public NotificationOutputStream(File file) throws FileNotFoundException {
|
||||
super(file);
|
||||
this.fileName = file.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
for (AlertViewPrefListener listener : listeners) {
|
||||
listener.prefFileChanged(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.store;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
import com.raytheon.uf.viz.alertview.AlertStore;
|
||||
import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* A simple {@link AlertStore} that retains all {@link Alert}s that arrive in
|
||||
* memory.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MemoryAlertStore implements AlertStore, AlertDestination,
|
||||
PreferenceFile.Listener<AlertViewPreferences> {
|
||||
|
||||
private ConcurrentLinkedQueue<Alert> alerts = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private final PreferenceFile<AlertViewPreferences> prefsFile;
|
||||
|
||||
private int retentionCount;
|
||||
|
||||
public MemoryAlertStore() {
|
||||
prefsFile = AlertViewPreferences.load(this);
|
||||
retentionCount = prefsFile.get().getAlertsToLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AlertViewPreferences preferences) {
|
||||
retentionCount = preferences.getAlertsToLoad();
|
||||
while (alerts.size() > retentionCount) {
|
||||
alerts.poll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will get called automatically by declaritive services.
|
||||
*/
|
||||
public void deactivate() {
|
||||
prefsFile.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAlert(Alert alert) {
|
||||
/* Trim too desired number of alerts */
|
||||
if (alerts.size() >= retentionCount) {
|
||||
alerts.poll();
|
||||
}
|
||||
alerts.offer(alert);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Alert> getAlerts() {
|
||||
return Arrays.asList(alerts.toArray(new Alert[0]));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.style;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Styles that apply to an {@link Alert}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertStyle {
|
||||
|
||||
private String filter;
|
||||
|
||||
private String backgroundColor;
|
||||
|
||||
private String foregroundColor;
|
||||
|
||||
private String fontName;
|
||||
|
||||
private String fontStyle;
|
||||
|
||||
private Integer fontSize;
|
||||
|
||||
public AlertStyle() {
|
||||
|
||||
}
|
||||
|
||||
public AlertStyle(AlertStyle other) {
|
||||
this.filter = other.filter;
|
||||
this.backgroundColor = other.backgroundColor;
|
||||
this.foregroundColor = other.foregroundColor;
|
||||
}
|
||||
|
||||
public String getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public String getBackgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
public void setBackgroundColor(String backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
public String getForegroundColor() {
|
||||
return foregroundColor;
|
||||
}
|
||||
|
||||
public void setForegroundColor(String foregroundColor) {
|
||||
this.foregroundColor = foregroundColor;
|
||||
}
|
||||
|
||||
public String getFontName() {
|
||||
return fontName;
|
||||
}
|
||||
|
||||
public void setFontName(String fontName) {
|
||||
this.fontName = fontName;
|
||||
}
|
||||
|
||||
public String getFontStyle() {
|
||||
return fontStyle;
|
||||
}
|
||||
|
||||
public void setFontStyle(String fontStyle) {
|
||||
this.fontStyle = fontStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result
|
||||
+ ((backgroundColor == null) ? 0 : backgroundColor.hashCode());
|
||||
result = prime * result + ((filter == null) ? 0 : filter.hashCode());
|
||||
result = prime * result
|
||||
+ ((fontName == null) ? 0 : fontName.hashCode());
|
||||
result = prime * result
|
||||
+ ((fontSize == null) ? 0 : fontSize.hashCode());
|
||||
result = prime * result
|
||||
+ ((fontStyle == null) ? 0 : fontStyle.hashCode());
|
||||
result = prime * result
|
||||
+ ((foregroundColor == null) ? 0 : foregroundColor.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AlertStyle other = (AlertStyle) obj;
|
||||
if (backgroundColor == null) {
|
||||
if (other.backgroundColor != null)
|
||||
return false;
|
||||
} else if (!backgroundColor.equals(other.backgroundColor))
|
||||
return false;
|
||||
if (filter == null) {
|
||||
if (other.filter != null)
|
||||
return false;
|
||||
} else if (!filter.equals(other.filter))
|
||||
return false;
|
||||
if (fontName == null) {
|
||||
if (other.fontName != null)
|
||||
return false;
|
||||
} else if (!fontName.equals(other.fontName))
|
||||
return false;
|
||||
if (fontSize == null) {
|
||||
if (other.fontSize != null)
|
||||
return false;
|
||||
} else if (!fontSize.equals(other.fontSize))
|
||||
return false;
|
||||
if (fontStyle == null) {
|
||||
if (other.fontStyle != null)
|
||||
return false;
|
||||
} else if (!fontStyle.equals(other.fontStyle))
|
||||
return false;
|
||||
if (foregroundColor == null) {
|
||||
if (other.foregroundColor != null)
|
||||
return false;
|
||||
} else if (!foregroundColor.equals(other.foregroundColor))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Integer getFontSize() {
|
||||
return fontSize;
|
||||
}
|
||||
|
||||
public void setFontSize(Integer fontSize) {
|
||||
this.fontSize = fontSize;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.style;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Device;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.filter.AlertFilter;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
|
||||
/**
|
||||
* Converts {@link AlertStyle}s into SWT colors and fonts.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class StyleManager implements PreferenceFile.Listener<StylePreferences> {
|
||||
|
||||
private static final String REGULAR = "Regular";
|
||||
|
||||
private static final String BOLD = "Bold";
|
||||
|
||||
private static final String ITALIC = "Italic";
|
||||
|
||||
private static final String BOLD_ITALIC = BOLD + "-" + ITALIC;
|
||||
|
||||
private final FilterManager filterManager = new FilterManager();
|
||||
|
||||
private final PreferenceFile<StylePreferences> preferenceFile;
|
||||
|
||||
private final CopyOnWriteArraySet<StyleListener> listeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
public StyleManager() {
|
||||
preferenceFile = StylePreferences.load(this);
|
||||
}
|
||||
|
||||
public void addListener(StyleListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(StyleListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(StylePreferences preference) {
|
||||
for(StyleListener listener : listeners){
|
||||
listener.updateStyle();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
preferenceFile.close();
|
||||
}
|
||||
|
||||
public Color getForegroundColor(Device device, Alert alert) {
|
||||
for (AlertStyle style : preferenceFile.get().getStyles()) {
|
||||
if (style.getForegroundColor() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
return parseColor(device, style.getForegroundColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Color getBackgroundColor(Device device, Alert alert) {
|
||||
for (AlertStyle style : preferenceFile.get().getStyles()) {
|
||||
if (style.getBackgroundColor() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
return parseColor(device, style.getBackgroundColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Font getFont(Device device, Alert alert) {
|
||||
String name = null;
|
||||
Integer size = null;
|
||||
String fstyle = null;
|
||||
for (AlertStyle style : preferenceFile.get().getStyles()) {
|
||||
if (name == null && style.getFontName() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
name = style.getFontName();
|
||||
}
|
||||
}
|
||||
if (size == null && style.getFontSize() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
size = style.getFontSize();
|
||||
}
|
||||
}
|
||||
if (fstyle == null && style.getFontStyle() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
fstyle = style.getFontStyle();
|
||||
}
|
||||
}
|
||||
if (name != null && size != null && fstyle != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return getFont(device, name, size, fstyle);
|
||||
}
|
||||
|
||||
public static Font getFont(Device device, AlertStyle style) {
|
||||
return getFont(device, style.getFontName(), style.getFontSize(),
|
||||
style.getFontStyle());
|
||||
}
|
||||
|
||||
public static Font getFont(Device device, String name, Integer size,
|
||||
String style) {
|
||||
Integer fstyle = parseFontStyle(style);
|
||||
if (name != null && size != null && fstyle != null) {
|
||||
return new Font(device, new FontData(name, size, fstyle));
|
||||
}
|
||||
if (name == null && size == null && fstyle == null) {
|
||||
return device.getSystemFont();
|
||||
}
|
||||
FontData systemFontData = device.getSystemFont().getFontData()[0];
|
||||
if (name == null) {
|
||||
name = systemFontData.getName();
|
||||
}
|
||||
if (size == null) {
|
||||
size = systemFontData.getHeight();
|
||||
}
|
||||
if (fstyle == null) {
|
||||
fstyle = systemFontData.getStyle();
|
||||
}
|
||||
return new Font(device, new FontData(name, size, fstyle));
|
||||
}
|
||||
|
||||
public static void setFont(AlertStyle style, FontData data) {
|
||||
style.setFontName(data.getName());
|
||||
style.setFontSize(data.getHeight());
|
||||
style.setFontStyle(formatFontStyle(data.getStyle()));
|
||||
}
|
||||
|
||||
private static Integer parseFontStyle(String style) {
|
||||
if (style == null) {
|
||||
return null;
|
||||
} else if (style.equalsIgnoreCase(REGULAR)) {
|
||||
return SWT.NORMAL;
|
||||
} else if (style.equalsIgnoreCase(BOLD)) {
|
||||
return SWT.BOLD;
|
||||
} else if (style.equals(ITALIC)) {
|
||||
return SWT.ITALIC;
|
||||
} else if (style.equals(BOLD_ITALIC)) {
|
||||
return SWT.BOLD | SWT.ITALIC;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String formatFontStyle(Integer style) {
|
||||
if (style == null) {
|
||||
return null;
|
||||
} else if ((style & SWT.BOLD) == SWT.BOLD
|
||||
&& (style & SWT.ITALIC) == SWT.ITALIC) {
|
||||
return BOLD_ITALIC;
|
||||
} else if ((style & SWT.BOLD) == SWT.BOLD) {
|
||||
return BOLD;
|
||||
} else if ((style & SWT.ITALIC) == SWT.ITALIC) {
|
||||
return ITALIC;
|
||||
} else if ((style & SWT.NORMAL) == SWT.NORMAL) {
|
||||
return REGULAR;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Color parseColor(Device device, String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
int red = Integer.parseInt(str.substring(1, 3), 16);
|
||||
int green = Integer.parseInt(str.substring(3, 5), 16);
|
||||
int blue = Integer.parseInt(str.substring(5, 7), 16);
|
||||
return new Color(device, red, green, blue);
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String formatColor(RGB colorValue) {
|
||||
return String.format("#%02x%02x%02x", colorValue.red, colorValue.green,
|
||||
colorValue.blue);
|
||||
}
|
||||
|
||||
public static interface StyleListener {
|
||||
|
||||
public void updateStyle();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.style;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* JAXB serializable list of {@link AlertStyle}s.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class StylePreferences {
|
||||
|
||||
@XmlElement(name = "style")
|
||||
private List<AlertStyle> styles = new ArrayList<>();
|
||||
|
||||
public StylePreferences() {
|
||||
AlertStyle errorStyle = new AlertStyle();
|
||||
errorStyle.setFilter(Priority.ERROR.name().toLowerCase());
|
||||
errorStyle.setForegroundColor(StyleManager.formatColor(new RGB(255, 0,
|
||||
0)));
|
||||
styles.add(errorStyle);
|
||||
}
|
||||
|
||||
public StylePreferences(List<AlertStyle> styles) {
|
||||
this.styles = styles;
|
||||
}
|
||||
|
||||
public List<AlertStyle> getStyles() {
|
||||
return styles;
|
||||
}
|
||||
|
||||
public void setStyles(List<AlertStyle> styles) {
|
||||
this.styles = styles;
|
||||
}
|
||||
|
||||
public void addStyle(AlertStyle style) {
|
||||
if (styles == null) {
|
||||
styles = new ArrayList<AlertStyle>();
|
||||
}
|
||||
styles.add(style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((styles == null) ? 0 : styles.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
StylePreferences other = (StylePreferences) obj;
|
||||
if (styles == null) {
|
||||
if (other.styles != null)
|
||||
return false;
|
||||
} else if (!styles.equals(other.styles))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static PreferenceFile<StylePreferences> load(
|
||||
PreferenceFile.Listener<? super StylePreferences> listener) {
|
||||
return new PreferenceFile<>("alert_styles.xml", StylePreferences.class,
|
||||
listener);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.popup;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.MouseAdapter;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PopUpPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
import com.raytheon.uf.viz.alertview.style.StyleManager;
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertView;
|
||||
import com.raytheon.uf.viz.alertview.ui.view.OpenAlertViewHandler;
|
||||
|
||||
/**
|
||||
*
|
||||
* An {@link AlertDestination} which displays {@link Alert}s in a small popup
|
||||
* window. The window only display for a few seconds(exact time is configurable)
|
||||
* and then disappears. If the user clicks the popup it will open the displayed
|
||||
* alert in the {@link AlertView}
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertPopup implements AlertDestination,
|
||||
PreferenceFile.Listener<PopUpPreferences> {
|
||||
|
||||
private final PopupAlertTask task = new PopupAlertTask();
|
||||
|
||||
private final PreferenceFile<PopUpPreferences> prefsFile;
|
||||
|
||||
protected final FilterManager filters = new FilterManager();
|
||||
|
||||
protected final StyleManager styles = new StyleManager();
|
||||
|
||||
protected PopUpPreferences prefs;
|
||||
|
||||
public AlertPopup() {
|
||||
prefsFile = PopUpPreferences.load(this);
|
||||
prefs = prefsFile.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(PopUpPreferences preferences) {
|
||||
prefs = preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will get called automatically by declaritive services.
|
||||
*/
|
||||
public void deactivate() {
|
||||
prefsFile.close();
|
||||
styles.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAlert(Alert alert) {
|
||||
if (filters.getFilter(prefs.getFilter()).filter(alert)) {
|
||||
task.update(alert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This task will run on the UI thread and is responsible for managing the
|
||||
* popup window. This should not be run directly but will schedule itself
|
||||
* when {@link #update(Alert)} or {@link #clear(Alert)} is called.
|
||||
*/
|
||||
private class PopupAlertTask implements Runnable {
|
||||
|
||||
private final Timer timer = new Timer("Remove Alert Popup");
|
||||
|
||||
private Shell shell;
|
||||
|
||||
private Label label;
|
||||
|
||||
/**
|
||||
* This is the alert that should be dispalyed, the most recent alert
|
||||
* passed to update which has not been passed to clear.
|
||||
*/
|
||||
private volatile Alert alert;
|
||||
|
||||
/**
|
||||
* This is the currently displayed alert, it should only be used from
|
||||
* the UI thread. If this task is waiting to be run on the UI thread
|
||||
* then this will not be the same as alert.
|
||||
*/
|
||||
private Alert displayedAlert;
|
||||
|
||||
/**
|
||||
* Update the popup window with the provided alert. If the window is not
|
||||
* currently open then a new popup window will be opened to display the
|
||||
* alert. If a popup window is already displayed then this alert will
|
||||
* replace any other alert in the popup window. This method schedules an
|
||||
* update on the UI thread but it does not block. If multiple calls to
|
||||
* {@link #update(Alert)} are made before the UI thread becomes
|
||||
* available then only the most recent Alert will be displayed.
|
||||
*/
|
||||
public synchronized void update(Alert alert) {
|
||||
this.alert = alert;
|
||||
Display.getDefault().asyncExec(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the popup if the provided alert is the most recent alert that
|
||||
* should be displayed. The alert is provided to make clear an atomic
|
||||
* operation. If another alert has been provided to
|
||||
* {@link #update(Alert)} since clear was called then it will be a no-op
|
||||
* because the more recent alert needs to be displayed.
|
||||
*/
|
||||
public synchronized void clear(Alert alert) {
|
||||
if (alert == this.alert) {
|
||||
this.alert = null;
|
||||
Display.getDefault().asyncExec(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void openInAlertView() {
|
||||
if (displayedAlert != null) {
|
||||
OpenAlertViewHandler.openInAlertView(displayedAlert);
|
||||
clear(displayedAlert);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
this.displayedAlert = this.alert;
|
||||
if (displayedAlert != null && (shell == null || shell.isDisposed())) {
|
||||
shell = new Shell(Display.getDefault(), SWT.NO_FOCUS
|
||||
| SWT.NO_TRIM | SWT.ON_TOP);
|
||||
GridLayout layout = new GridLayout(1, false);
|
||||
layout.marginHeight = 0;
|
||||
layout.marginWidth = 0;
|
||||
shell.setLayout(layout);
|
||||
shell.setForeground(Display.getDefault().getSystemColor(
|
||||
SWT.COLOR_BLACK));
|
||||
shell.addListener(SWT.Dispose, new Listener() {
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
shell = null;
|
||||
}
|
||||
});
|
||||
|
||||
final Composite comp = new Composite(shell, SWT.BORDER);
|
||||
|
||||
layout = new GridLayout(1, false);
|
||||
layout.marginHeight = 0;
|
||||
layout.marginWidth = 0;
|
||||
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
comp.setLayout(layout);
|
||||
comp.setLayoutData(data);
|
||||
|
||||
label = new Label(comp, SWT.WRAP);
|
||||
data = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
label.setLayoutData(data);
|
||||
label.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseUp(MouseEvent e) {
|
||||
openInAlertView();
|
||||
}
|
||||
|
||||
});
|
||||
shell.setSize(prefs.getWidth(), prefs.getHeight());
|
||||
|
||||
Rectangle clientArea = Display.getDefault().getMonitors()[0]
|
||||
.getClientArea();
|
||||
|
||||
int offset = 2;
|
||||
int startX = offset;
|
||||
int startY = offset;
|
||||
switch (prefs.getCorner()) {
|
||||
case UPPER_LEFT:
|
||||
startX = clientArea.x + offset;
|
||||
startY = clientArea.y + offset;
|
||||
break;
|
||||
case UPPER_RIGHT:
|
||||
startX = clientArea.x + clientArea.width
|
||||
- shell.getSize().x - offset;
|
||||
startY = clientArea.y + offset;
|
||||
break;
|
||||
case LOWER_LEFT:
|
||||
startX = clientArea.x + offset;
|
||||
startY = clientArea.y + clientArea.height
|
||||
- shell.getSize().y - offset;
|
||||
break;
|
||||
case LOWER_RIGHT:
|
||||
startX = clientArea.x + clientArea.width
|
||||
- shell.getSize().x - offset;
|
||||
startY = clientArea.y + clientArea.height
|
||||
- shell.getSize().y - offset;
|
||||
break;
|
||||
}
|
||||
|
||||
shell.setLocation(startX, startY);
|
||||
shell.setVisible(true);
|
||||
}
|
||||
if (displayedAlert == null) {
|
||||
if (shell != null && !shell.isDisposed()) {
|
||||
shell.dispose();
|
||||
}
|
||||
} else {
|
||||
Display display = shell.getDisplay();
|
||||
label.setBackground(styles.getBackgroundColor(display,
|
||||
displayedAlert));
|
||||
label.setForeground(styles.getForegroundColor(display,
|
||||
displayedAlert));
|
||||
label.setFont(styles.getFont(display, displayedAlert));
|
||||
label.setText(displayedAlert.getMessage());
|
||||
timer.schedule(new ClosePopupTask(displayedAlert),
|
||||
prefs.getDuration());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This task is scheduled from the UI thread whenever an alert is displayed
|
||||
* in a popup. It will call clear after the popup has expired. It is never
|
||||
* canceled but instead it relies on the atomic nature of
|
||||
* {@link #clear(Alert)} to ensure that if another alert arrives it will not
|
||||
* close the popup.
|
||||
*/
|
||||
private class ClosePopupTask extends TimerTask {
|
||||
|
||||
private final Alert alert;
|
||||
|
||||
public ClosePopupTask(Alert alert) {
|
||||
this.alert = alert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
task.clear(alert);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.prefs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jface.preference.PreferencePage;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.layout.RowLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertTable;
|
||||
|
||||
/**
|
||||
* Preference page for configuring {@link AlertViewPreferences}
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 25, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertViewPreferencePage extends PreferencePage implements
|
||||
PreferenceFile.Listener<AlertViewPreferences> {
|
||||
|
||||
protected PreferenceFile<AlertViewPreferences> preferenceFile;
|
||||
|
||||
protected PriorityFilterCombo openFilterCombo;
|
||||
|
||||
protected Text intervalText;
|
||||
|
||||
protected Table columnTable;
|
||||
|
||||
@Override
|
||||
protected Control createContents(Composite parent) {
|
||||
preferenceFile = AlertViewPreferences.load(this);
|
||||
Composite composite = new Composite(parent, SWT.NONE);
|
||||
composite.setLayout(new GridLayout(2, false));
|
||||
|
||||
new Label(composite, SWT.NONE).setText("Auto Open Priority: ");
|
||||
openFilterCombo = new PriorityFilterCombo(composite);
|
||||
|
||||
new Label(composite, SWT.NONE)
|
||||
.setText("Hide Duplicate Interval(seconds): ");
|
||||
intervalText = new Text(composite, SWT.SINGLE | SWT.BORDER);
|
||||
GridData gridData = new GridData();
|
||||
gridData.widthHint = 30;
|
||||
intervalText.setLayoutData(gridData);
|
||||
Group columnGroup = new Group(composite, SWT.NONE);
|
||||
columnGroup.setLayout(new GridLayout(2, false));
|
||||
columnGroup.setText("Column Configuration");
|
||||
columnTable = new Table(columnGroup, SWT.CHECK);
|
||||
Composite columnButtonComp = new Composite(columnGroup, SWT.NONE);
|
||||
RowLayout rowLayout = new RowLayout(SWT.VERTICAL);
|
||||
rowLayout.fill = true;
|
||||
rowLayout.justify = true;
|
||||
columnButtonComp.setLayout(rowLayout);
|
||||
Button up = new Button(columnButtonComp, SWT.PUSH);
|
||||
up.setText("Up");
|
||||
up.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
moveColumn(true);
|
||||
}
|
||||
|
||||
});
|
||||
Button down = new Button(columnButtonComp, SWT.PUSH);
|
||||
down.setText("Down");
|
||||
down.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
moveColumn(false);
|
||||
}
|
||||
|
||||
});
|
||||
populate();
|
||||
return composite;
|
||||
}
|
||||
|
||||
public void moveColumn(boolean up) {
|
||||
int selection = columnTable.getSelectionIndex();
|
||||
if (selection < 0) {
|
||||
return;
|
||||
}
|
||||
int newIndex;
|
||||
if (up) {
|
||||
if (selection == 0) {
|
||||
return;
|
||||
}
|
||||
newIndex = selection - 1;
|
||||
} else {
|
||||
if (selection == columnTable.getItemCount() - 1) {
|
||||
return;
|
||||
}
|
||||
newIndex = selection + 2;
|
||||
}
|
||||
TableItem oldItem = columnTable.getItem(selection);
|
||||
TableItem newItem = new TableItem(columnTable, SWT.NONE, newIndex);
|
||||
newItem.setText(oldItem.getText());
|
||||
newItem.setChecked(oldItem.getChecked());
|
||||
oldItem.dispose();
|
||||
columnTable.setSelection(newItem);
|
||||
}
|
||||
|
||||
protected void populate() {
|
||||
AlertViewPreferences preferences = preferenceFile.get();
|
||||
openFilterCombo.setSelection(preferences.getOpenFilter());
|
||||
intervalText.setText(Double.toString(preferences
|
||||
.getMergeRepeatInterval() / 1000.0));
|
||||
columnTable.removeAll();
|
||||
List<String> columns = preferences.getColumns();
|
||||
for (String column : columns) {
|
||||
TableItem item = new TableItem(columnTable, SWT.NONE);
|
||||
item.setText(column);
|
||||
item.setChecked(true);
|
||||
}
|
||||
for (String column : AlertTable.ALL_COLUMNS) {
|
||||
if (!columns.contains(column)) {
|
||||
TableItem item = new TableItem(columnTable, SWT.NONE);
|
||||
item.setText(column);
|
||||
item.setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performDefaults() {
|
||||
populate();
|
||||
super.performDefaults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performOk() {
|
||||
AlertViewPreferences newPrefs = new AlertViewPreferences(
|
||||
preferenceFile.get());
|
||||
String openFilter = openFilterCombo.getSelection();
|
||||
if (openFilter != null) {
|
||||
newPrefs.setOpenFilter(openFilter);
|
||||
}
|
||||
newPrefs.setMergeRepeatInterval((int) (Double.parseDouble(intervalText
|
||||
.getText()) * 1000));
|
||||
List<String> columns = new ArrayList<>();
|
||||
for (TableItem item : columnTable.getItems()) {
|
||||
if (item.getChecked()) {
|
||||
columns.add(item.getText());
|
||||
}
|
||||
}
|
||||
newPrefs.setColumns(columns);
|
||||
preferenceFile.write(newPrefs);
|
||||
return super.performOk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
preferenceFile.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AlertViewPreferences preferences) {
|
||||
Display.getDefault().asyncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!getControl().isDisposed()) {
|
||||
populate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.prefs;
|
||||
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.preference.IPreferencePage;
|
||||
import org.eclipse.jface.preference.PreferenceDialog;
|
||||
import org.eclipse.ui.dialogs.PreferencesUtil;
|
||||
|
||||
/**
|
||||
* Action which opens {@link PreferenceDialog} with the
|
||||
* {@link AlertViewPreferencePage} and other associated {@link IPreferencePage}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 25, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class OpenPreferencesAction extends Action {
|
||||
|
||||
public OpenPreferencesAction() {
|
||||
super("Preferences");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PreferencesUtil.createPreferenceDialogOn(
|
||||
null,
|
||||
AlertViewPreferencePage.class.getName(),
|
||||
new String[] { AlertViewPreferencePage.class.getName(),
|
||||
StylePreferencePage.class.getName(),
|
||||
PopupPreferencePage.class.getName() }, null).open();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.prefs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jface.preference.PreferencePage;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.prefs.PopUpPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PopUpPreferences.PopUpCorner;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
|
||||
/**
|
||||
* Preference page for configuring {@link PopUpPreferences}
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 25, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PopupPreferencePage extends PreferencePage implements
|
||||
PreferenceFile.Listener<PopUpPreferences> {
|
||||
|
||||
private static final List<String> SIZES = Arrays.asList("Small", "Medium",
|
||||
"Large");
|
||||
|
||||
private static final int BASE_WIDTH = 500;
|
||||
|
||||
private static final int BASE_HEIGHT = 50;
|
||||
|
||||
protected PreferenceFile<PopUpPreferences> preferenceFile;
|
||||
|
||||
protected PriorityFilterCombo filterCombo;
|
||||
|
||||
protected Text durationText;
|
||||
|
||||
protected Combo positionCombo;
|
||||
|
||||
protected Combo sizeCombo;
|
||||
|
||||
@Override
|
||||
protected Control createContents(Composite parent) {
|
||||
preferenceFile = PopUpPreferences.load(this);
|
||||
Composite composite = new Composite(parent, SWT.NONE);
|
||||
composite.setLayout(new GridLayout(2, false));
|
||||
new Label(composite, SWT.NONE).setText("Popup Priority: ");
|
||||
filterCombo = new PriorityFilterCombo(composite);
|
||||
new Label(composite, SWT.NONE).setText("Duration(seconds): ");
|
||||
durationText = new Text(composite, SWT.SINGLE | SWT.BORDER);
|
||||
GridData gridData = new GridData();
|
||||
gridData.widthHint = 30;
|
||||
durationText.setLayoutData(gridData);
|
||||
new Label(composite, SWT.NONE).setText("Position: ");
|
||||
positionCombo = new Combo(composite, SWT.READ_ONLY);
|
||||
for (PopUpCorner position : PopUpCorner.values()) {
|
||||
positionCombo.add(position.getPrettyName());
|
||||
}
|
||||
|
||||
new Label(composite, SWT.NONE).setText("Size: ");
|
||||
sizeCombo = new Combo(composite, SWT.READ_ONLY);
|
||||
for (String size : SIZES) {
|
||||
sizeCombo.add(size);
|
||||
}
|
||||
populate();
|
||||
return composite;
|
||||
}
|
||||
|
||||
protected void populate() {
|
||||
PopUpPreferences preferences = preferenceFile.get();
|
||||
filterCombo.setSelection(preferences.getFilter());
|
||||
durationText
|
||||
.setText(Double.toString(preferences.getDuration() / 1000.0));
|
||||
positionCombo.select(positionCombo.indexOf(preferences.getCorner()
|
||||
.getPrettyName()));
|
||||
boolean sizeFound = false;
|
||||
for (int i = 0; i < SIZES.size(); i += 1) {
|
||||
if (preferences.getHeight() == BASE_HEIGHT + 25 * i
|
||||
&& preferences.getWidth() == BASE_WIDTH + 50 * i) {
|
||||
sizeCombo.select(i);
|
||||
sizeFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!sizeFound) {
|
||||
if (sizeCombo.getItemCount() > SIZES.size()) {
|
||||
sizeCombo.remove(SIZES.size());
|
||||
}
|
||||
sizeCombo.add(preferences.getWidth() + " x "
|
||||
+ preferences.getHeight());
|
||||
sizeCombo.select(SIZES.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performDefaults() {
|
||||
populate();
|
||||
super.performDefaults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performOk() {
|
||||
PopUpPreferences newPrefs = new PopUpPreferences(preferenceFile.get());
|
||||
String filter = filterCombo.getSelection();
|
||||
if (filter != null) {
|
||||
newPrefs.setFilter(filter);
|
||||
}
|
||||
newPrefs.setDuration((int) (Double.parseDouble(durationText.getText()) * 1000));
|
||||
newPrefs.setCorner(PopUpCorner.fromPrettyName(positionCombo.getText()));
|
||||
int index = SIZES.indexOf(sizeCombo.getText());
|
||||
if (index >= 0) {
|
||||
newPrefs.setWidth(BASE_WIDTH + 50 * index);
|
||||
newPrefs.setHeight(BASE_HEIGHT + 25 * index);
|
||||
}
|
||||
preferenceFile.write(newPrefs);
|
||||
return super.performOk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
preferenceFile.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(PopUpPreferences preferences) {
|
||||
Display.getDefault().asyncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!getControl().isDisposed()) {
|
||||
populate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.prefs;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
|
||||
/**
|
||||
* Class for using an {@link Combo} to select a priority level.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 25, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PriorityFilterCombo {
|
||||
|
||||
/**
|
||||
* Mapping for pretty user text to filter names for populating priority
|
||||
* combos.
|
||||
*/
|
||||
private static final Map<String, String> MAPPING = getPriorityFilterMapping();
|
||||
|
||||
private final Combo combo;
|
||||
|
||||
public PriorityFilterCombo(Composite parent) {
|
||||
combo = new Combo(parent, SWT.READ_ONLY);
|
||||
for (Entry<String, String> entry : MAPPING.entrySet()) {
|
||||
combo.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelection(String filter) {
|
||||
for (Entry<String, String> entry : MAPPING.entrySet()) {
|
||||
if (filter.equals(entry.getValue())) {
|
||||
int index = combo.indexOf(entry.getKey());
|
||||
if (index >= 0) {
|
||||
combo.select(index);
|
||||
} else {
|
||||
combo.deselectAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getSelection() {
|
||||
String filter = combo.getText();
|
||||
if (filter != null && !filter.isEmpty()) {
|
||||
return MAPPING.get(filter);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Map<String, String> getPriorityFilterMapping() {
|
||||
Map<String, String> mapping = new LinkedHashMap<>();
|
||||
mapping.put("None", FilterManager.NONE);
|
||||
mapping.put("Error", Priority.ERROR.name().toLowerCase());
|
||||
mapping.put("Error+Warning", FilterManager.WARN_PLUS);
|
||||
mapping.put("Error+Warning+Info", FilterManager.INFO_PLUS);
|
||||
mapping.put("All", FilterManager.ALL);
|
||||
return mapping;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,306 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.prefs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jface.preference.ColorSelector;
|
||||
import org.eclipse.jface.preference.PreferencePage;
|
||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.layout.RowLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.FontDialog;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
import com.raytheon.uf.viz.alertview.style.AlertStyle;
|
||||
import com.raytheon.uf.viz.alertview.style.StyleManager;
|
||||
import com.raytheon.uf.viz.alertview.style.StylePreferences;
|
||||
|
||||
/**
|
||||
* Preference page for configuring {@link StylePreferences}
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 25, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class StylePreferencePage extends PreferencePage implements
|
||||
PreferenceFile.Listener<StylePreferences> {
|
||||
|
||||
protected PreferenceFile<StylePreferences> preferenceFile;
|
||||
|
||||
protected Table table;
|
||||
|
||||
protected Combo filterCombo;
|
||||
|
||||
protected ColorSelector foregroundSelector;
|
||||
|
||||
protected ColorSelector backgroundSelector;
|
||||
|
||||
protected Button fontButton;
|
||||
|
||||
@Override
|
||||
protected Control createContents(Composite parent) {
|
||||
preferenceFile = StylePreferences.load(this);
|
||||
Composite composite = new Composite(parent, SWT.NONE);
|
||||
composite.setLayout(new GridLayout(1, false));
|
||||
Composite tableComp = new Composite(composite, SWT.NONE);
|
||||
tableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||
tableComp.setLayout(new GridLayout(2, false));
|
||||
table = new Table(tableComp, SWT.NONE);
|
||||
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||
table.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
styleSelected();
|
||||
}
|
||||
|
||||
});
|
||||
Composite columnButtonComp = new Composite(tableComp, SWT.NONE);
|
||||
RowLayout rowLayout = new RowLayout(SWT.VERTICAL);
|
||||
rowLayout.fill = true;
|
||||
rowLayout.justify = true;
|
||||
columnButtonComp.setLayout(rowLayout);
|
||||
columnButtonComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false,
|
||||
true));
|
||||
Button newButton = new Button(columnButtonComp, SWT.PUSH);
|
||||
newButton.setText("New");
|
||||
newButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
newStyle();
|
||||
}
|
||||
|
||||
});
|
||||
Button deleteButton = new Button(columnButtonComp, SWT.PUSH);
|
||||
deleteButton.setText("Delete");
|
||||
deleteButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
deleteStyle();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Composite editComp = new Composite(composite, SWT.NONE);
|
||||
editComp.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false,
|
||||
false));
|
||||
editComp.setLayout(new GridLayout(2, false));
|
||||
new Label(editComp, SWT.NONE).setText("Priority: ");
|
||||
filterCombo = new Combo(editComp, SWT.READ_ONLY);
|
||||
for (Priority priority : Priority.values()) {
|
||||
filterCombo.add(priority.name());
|
||||
}
|
||||
filterCombo.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
filterSelected();
|
||||
}
|
||||
|
||||
});
|
||||
new Label(editComp, SWT.NONE).setText("Foreground Color: ");
|
||||
foregroundSelector = new ColorSelector(editComp);
|
||||
foregroundSelector.getButton().setLayoutData(
|
||||
new GridData(GridData.FILL_HORIZONTAL));
|
||||
foregroundSelector.addListener(new IPropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
foregroundSelected();
|
||||
}
|
||||
});
|
||||
new Label(editComp, SWT.NONE).setText("Background Color: ");
|
||||
backgroundSelector = new ColorSelector(editComp);
|
||||
backgroundSelector.getButton().setLayoutData(
|
||||
new GridData(GridData.FILL_HORIZONTAL));
|
||||
backgroundSelector.addListener(new IPropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
backgroundSelected();
|
||||
}
|
||||
});
|
||||
new Label(editComp, SWT.NONE).setText("Font: ");
|
||||
fontButton = new Button(editComp, SWT.PUSH);
|
||||
fontButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
fontButton.setText("Configure Font");
|
||||
fontButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
fontSelected();
|
||||
}
|
||||
|
||||
});
|
||||
performDefaults();
|
||||
styleSelected();
|
||||
return composite;
|
||||
}
|
||||
|
||||
protected void fontSelected() {
|
||||
FontData data = new FontDialog(getShell()).open();
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
TableItem selection = table.getSelection()[0];
|
||||
AlertStyle style = (AlertStyle) selection.getData();
|
||||
StyleManager.setFont(style, data);
|
||||
selection.setFont(StyleManager.getFont(getShell().getDisplay(), style));
|
||||
}
|
||||
|
||||
protected void backgroundSelected() {
|
||||
TableItem selection = table.getSelection()[0];
|
||||
selection.setBackground(new Color(getShell().getDisplay(),
|
||||
backgroundSelector.getColorValue()));
|
||||
AlertStyle style = (AlertStyle) selection.getData();
|
||||
style.setBackgroundColor(StyleManager.formatColor(backgroundSelector
|
||||
.getColorValue()));
|
||||
}
|
||||
|
||||
protected void foregroundSelected() {
|
||||
TableItem selection = table.getSelection()[0];
|
||||
selection.setForeground(new Color(getShell().getDisplay(),
|
||||
foregroundSelector.getColorValue()));
|
||||
AlertStyle style = (AlertStyle) selection.getData();
|
||||
style.setForegroundColor(StyleManager.formatColor(foregroundSelector
|
||||
.getColorValue()));
|
||||
}
|
||||
|
||||
protected void filterSelected() {
|
||||
TableItem selection = table.getSelection()[0];
|
||||
selection.setText(filterCombo.getItem(filterCombo.getSelectionIndex()));
|
||||
AlertStyle style = (AlertStyle) selection.getData();
|
||||
style.setFilter(selection.getText().toLowerCase());
|
||||
}
|
||||
|
||||
protected void newStyle() {
|
||||
TableItem item = new TableItem(table, SWT.NONE);
|
||||
item.setText("INFO");
|
||||
AlertStyle style = new AlertStyle();
|
||||
style.setFilter(item.getText().toLowerCase());
|
||||
item.setData(style);
|
||||
table.select(table.indexOf(item));
|
||||
styleSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
preferenceFile.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
protected void deleteStyle() {
|
||||
table.getSelection()[0].dispose();
|
||||
styleSelected();
|
||||
}
|
||||
|
||||
protected void styleSelected() {
|
||||
int index = table.getSelectionIndex();
|
||||
if (index < 0) {
|
||||
filterCombo.deselectAll();
|
||||
filterCombo.setEnabled(false);
|
||||
foregroundSelector.setEnabled(false);
|
||||
backgroundSelector.setEnabled(false);
|
||||
fontButton.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
TableItem selection = table.getItem(index);
|
||||
filterCombo.setEnabled(true);
|
||||
foregroundSelector.setEnabled(true);
|
||||
backgroundSelector.setEnabled(true);
|
||||
fontButton.setEnabled(true);
|
||||
|
||||
index = filterCombo.indexOf(selection.getText());
|
||||
filterCombo.select(index);
|
||||
backgroundSelector.setColorValue(selection.getBackground().getRGB());
|
||||
foregroundSelector.setColorValue(selection.getForeground().getRGB());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performDefaults() {
|
||||
table.removeAll();
|
||||
for (AlertStyle style : preferenceFile.get().getStyles()) {
|
||||
TableItem item = new TableItem(table, SWT.NONE);
|
||||
item.setText(style.getFilter().toUpperCase());
|
||||
item.setBackground(StyleManager.parseColor(getShell().getDisplay(),
|
||||
style.getBackgroundColor()));
|
||||
item.setForeground(StyleManager.parseColor(getShell().getDisplay(),
|
||||
style.getForegroundColor()));
|
||||
item.setFont(StyleManager.getFont(getShell().getDisplay(), style));
|
||||
item.setData(new AlertStyle(style));
|
||||
}
|
||||
super.performDefaults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performOk() {
|
||||
List<AlertStyle> styles = new ArrayList<AlertStyle>();
|
||||
for (TableItem item : table.getItems()) {
|
||||
styles.add((AlertStyle) item.getData());
|
||||
}
|
||||
StylePreferences newPrefs = new StylePreferences();
|
||||
newPrefs.setStyles(styles);
|
||||
preferenceFile.write(newPrefs);
|
||||
return super.performOk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(StylePreferences preferences) {
|
||||
Display.getDefault().asyncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!getControl().isDisposed()) {
|
||||
performDefaults();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jface.action.ActionContributionItem;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.swt.custom.StyledText;
|
||||
import org.eclipse.swt.events.MenuAdapter;
|
||||
import org.eclipse.swt.events.MenuEvent;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.MenuItem;
|
||||
import org.eclipse.ui.console.ConsolePlugin;
|
||||
import org.eclipse.ui.console.IHyperlink;
|
||||
import org.eclipse.ui.console.IOConsole;
|
||||
import org.eclipse.ui.console.IOConsoleOutputStream;
|
||||
import org.eclipse.ui.console.TextConsoleViewer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.action.SaveToFileAction;
|
||||
|
||||
/**
|
||||
*
|
||||
* Used for viewing the details of {@link Alert}s. Since most alerts are
|
||||
* generated from logged errors this console is created so that links appear in
|
||||
* stack traces when the view is used in eclipse.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertConsoleViewer extends TextConsoleViewer {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(AlertView.class);
|
||||
|
||||
private AlertConsole console;
|
||||
|
||||
private Alert alert;
|
||||
|
||||
public AlertConsoleViewer(Composite parent) {
|
||||
this(parent, new AlertConsole());
|
||||
}
|
||||
|
||||
private AlertConsoleViewer(Composite parent, AlertConsole console) {
|
||||
super(parent, console);
|
||||
this.console = console;
|
||||
console.setViewer(this);
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
StyledText text = getTextWidget();
|
||||
text.setEditable(false);
|
||||
Menu menu = new Menu(text);
|
||||
text.setMenu(menu);
|
||||
menu.addMenuListener(new MenuAdapter() {
|
||||
|
||||
@Override
|
||||
public void menuShown(MenuEvent e) {
|
||||
populateContextMenu(getTextWidget().getMenu());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected void populateContextMenu(Menu menu) {
|
||||
for (MenuItem item : menu.getItems()) {
|
||||
item.dispose();
|
||||
}
|
||||
if (alert == null) {
|
||||
return;
|
||||
}
|
||||
new ActionContributionItem(new SaveToFileAction(alert)).fill(menu, -1);
|
||||
}
|
||||
|
||||
public void setAlert(Alert alert) {
|
||||
if (this.alert == alert) {
|
||||
return;
|
||||
}
|
||||
this.alert = alert;
|
||||
console.clearConsole();
|
||||
if (alert == null) {
|
||||
return;
|
||||
}
|
||||
String details = alert.getDetails();
|
||||
if (details.isEmpty()) {
|
||||
details = alert.getMessage();
|
||||
}
|
||||
try (IOConsoleOutputStream os = console.newOutputStream()) {
|
||||
os.write(details);
|
||||
} catch (IOException e) {
|
||||
logger.error("Unexpected IO exception writing to console.", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void redraw() {
|
||||
Display.getDefault().syncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
getTextWidget().redraw();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static class AlertConsole extends IOConsole {
|
||||
|
||||
private AlertConsoleViewer viewer;
|
||||
|
||||
public AlertConsole() {
|
||||
super("AlertViewConsole", "javaStackTraceConsole", null);
|
||||
ConsolePlugin.getDefault().getConsoleManager()
|
||||
.createPatternMatchListeners(this);
|
||||
}
|
||||
|
||||
public void setViewer(AlertConsoleViewer viewer) {
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHyperlink(IHyperlink hyperlink, int offset, int length)
|
||||
throws BadLocationException {
|
||||
super.addHyperlink(hyperlink, offset, length);
|
||||
viewer.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,456 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jface.action.ActionContributionItem;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.MenuAdapter;
|
||||
import org.eclipse.swt.events.MenuEvent;
|
||||
import org.eclipse.swt.events.MouseAdapter;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.MouseMoveListener;
|
||||
import org.eclipse.swt.events.MouseTrackAdapter;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.MenuItem;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
import org.eclipse.ui.progress.UIJob;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.action.SaveToFileAction;
|
||||
import com.raytheon.uf.viz.alertview.filter.AlertFilter;
|
||||
import com.raytheon.uf.viz.alertview.style.StyleManager;
|
||||
import com.raytheon.uf.viz.alertview.style.StyleManager.StyleListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* Table that displays {@link Alert}s.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
* Jun 23, 2015 4474 njensen Added removeAll() and getFilter()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertTable extends Composite implements StyleListener {
|
||||
|
||||
public static final String COLUMN_TIME = "Time";
|
||||
|
||||
public static final String COLUMN_PRIORITY = "Priority";
|
||||
|
||||
public static final String COLUMN_ORIGIN = "Origin";
|
||||
|
||||
public static final String COLUMN_MESSAGE = "Message";
|
||||
|
||||
public static final String[] ALL_COLUMNS = { COLUMN_TIME, COLUMN_PRIORITY,
|
||||
COLUMN_ORIGIN, COLUMN_MESSAGE };
|
||||
|
||||
private StyleManager styles = new StyleManager();
|
||||
|
||||
private BlockingQueue<Alert> alertsToAdd = new LinkedBlockingQueue<Alert>();
|
||||
|
||||
private Table alertTable;
|
||||
|
||||
private AlertFilter filter;
|
||||
|
||||
private int mergeRepeatInterval;
|
||||
|
||||
/**
|
||||
* When things are going terribly wrong and a gazillion alerts are coming in
|
||||
* the UI will freeze if they aren't throttled a bit. This job tries to be
|
||||
* reasonablish about how much CPU to suck updating the table.
|
||||
*/
|
||||
private Job addAlertJob = new UIJob("Updating AlertView") {
|
||||
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
if (AlertTable.this.isDisposed()) {
|
||||
alertsToAdd.clear();
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
Alert next = alertsToAdd.poll();
|
||||
if (next != null) {
|
||||
int processed = 0;
|
||||
while (next != null) {
|
||||
|
||||
addAlertInternal(next);
|
||||
if (processed++ > 500) {
|
||||
this.schedule(100);
|
||||
break;
|
||||
}
|
||||
next = alertsToAdd.poll();
|
||||
}
|
||||
packColumns();
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
|
||||
public AlertTable(Composite parent, List<String> columns) {
|
||||
super(parent, SWT.NONE);
|
||||
this.setLayout(new FillLayout());
|
||||
createAlertTable();
|
||||
rebuildColums(columns);
|
||||
styles.addListener(this);
|
||||
}
|
||||
|
||||
protected void createAlertTable() {
|
||||
alertTable = new Table(this, SWT.H_SCROLL | SWT.V_SCROLL
|
||||
| SWT.FULL_SELECTION | SWT.MULTI);
|
||||
alertTable.setHeaderVisible(true);
|
||||
alertTable.setLinesVisible(true);
|
||||
alertTable.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
alertSelected();
|
||||
}
|
||||
|
||||
});
|
||||
alertTable.addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseDoubleClick(MouseEvent e) {
|
||||
alertDoubleClick();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
alertTable.addMouseMoveListener(new MouseMoveListener() {
|
||||
|
||||
@Override
|
||||
public void mouseMove(MouseEvent e) {
|
||||
alertTable.setToolTipText(null);
|
||||
}
|
||||
});
|
||||
|
||||
alertTable.addMouseTrackListener(new MouseTrackAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseHover(MouseEvent e) {
|
||||
TableItem item = alertTable.getItem(new Point(e.x, e.y));
|
||||
if (item == null) {
|
||||
alertTable.setToolTipText(null);
|
||||
} else {
|
||||
Alert alert = getAlert(item);
|
||||
alertTable.setToolTipText(getToolTip(alert));
|
||||
}
|
||||
}
|
||||
});
|
||||
Menu menu = new Menu(alertTable);
|
||||
alertTable.setMenu(menu);
|
||||
menu.addMenuListener(new MenuAdapter() {
|
||||
|
||||
@Override
|
||||
public void menuShown(MenuEvent e) {
|
||||
populateContextMenu(alertTable.getMenu());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void addAlert(Alert alert) {
|
||||
alertsToAdd.add(alert);
|
||||
addAlertJob.schedule();
|
||||
}
|
||||
|
||||
protected TableItem addAlertInternal(Alert alert) {
|
||||
if (filter != null && !filter.filter(alert)) {
|
||||
return null;
|
||||
}
|
||||
TableItem newItem = null;
|
||||
for (int index = 0; index < alertTable.getItemCount(); index += 1) {
|
||||
TableItem item = alertTable.getItem(index);
|
||||
List<Alert> alerts = getAlerts(item);
|
||||
Alert sample = alerts.get(0);
|
||||
if (alerts.contains(alert)) {
|
||||
return item;
|
||||
} else if (equalsEnough(sample, alert)) {
|
||||
alerts.add(alert);
|
||||
return item;
|
||||
} else if (sample.getTime().before(alert.getTime())) {
|
||||
newItem = new TableItem(alertTable, SWT.NONE, index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newItem == null) {
|
||||
newItem = new TableItem(alertTable, SWT.NONE);
|
||||
}
|
||||
newItem.setData(new ArrayList<Alert>(Arrays.asList(alert)));
|
||||
newItem.setText(getText(alert));
|
||||
applyStyle(newItem);
|
||||
alertTable.showItem(newItem);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine if 2 messages are similar enough that they should not
|
||||
* be displayed as separate items.
|
||||
*/
|
||||
protected boolean equalsEnough(Alert a1, Alert a2) {
|
||||
if (a1.getMessage() == null) {
|
||||
if (a2.getMessage() != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!a1.getMessage().equals(a2.getMessage())) {
|
||||
return false;
|
||||
}
|
||||
if (a1.getOrigin() == null) {
|
||||
if (a2.getOrigin() != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!a1.getOrigin().equals(a2.getOrigin())) {
|
||||
return false;
|
||||
}
|
||||
if (a1.getDetails() == null) {
|
||||
if (a2.getDetails() != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!a1.getDetails().equals(a2.getDetails())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long timeDiff = Math.abs(a2.getTime().getTime()
|
||||
- a1.getTime().getTime());
|
||||
if (timeDiff > mergeRepeatInterval) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMergeRepeatInterval(int mergeRepeatInterval) {
|
||||
this.mergeRepeatInterval = mergeRepeatInterval;
|
||||
}
|
||||
|
||||
protected void applyStyle(TableItem item) {
|
||||
Alert alert = getAlert(item);
|
||||
item.setBackground(styles.getBackgroundColor(item.getDisplay(), alert));
|
||||
item.setForeground(styles.getForegroundColor(item.getDisplay(), alert));
|
||||
item.setFont(styles.getFont(item.getDisplay(), alert));
|
||||
}
|
||||
|
||||
public void setFilter(AlertFilter filter) {
|
||||
this.filter = filter;
|
||||
for (TableItem item : alertTable.getSelection()) {
|
||||
Alert alert = getAlert(item);
|
||||
if (!filter.filter(alert)) {
|
||||
item.dispose();
|
||||
}
|
||||
}
|
||||
for (TableItem item : alertTable.getItems()) {
|
||||
Alert alert = getAlert(item);
|
||||
if (!filter.filter(alert)) {
|
||||
item.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected AlertFilter getFilter() {
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
public void select(Alert alert) {
|
||||
if (alertsToAdd.contains(alert)) {
|
||||
TableItem item = addAlertInternal(alert);
|
||||
alertTable.setSelection(alertTable.indexOf(item));
|
||||
alertSelected();
|
||||
return;
|
||||
}
|
||||
for (TableItem item : alertTable.getItems()) {
|
||||
List<Alert> alerts = getAlerts(item);
|
||||
if (alerts.contains(alert)) {
|
||||
alertTable.setSelection(alertTable.indexOf(item));
|
||||
alertSelected();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void packColumns() {
|
||||
for (TableColumn column : alertTable.getColumns()) {
|
||||
column.pack();
|
||||
}
|
||||
}
|
||||
|
||||
protected String[] getText(Alert alert) {
|
||||
TableColumn[] columns = alertTable.getColumns();
|
||||
String[] text = new String[columns.length];
|
||||
for (int i = 0; i < columns.length; i += 1) {
|
||||
if (columns[i].getText().equals(COLUMN_MESSAGE)) {
|
||||
text[i] = alert.getMessage().split("\n")[0];
|
||||
} else if (columns[i].getText().equals(COLUMN_TIME)) {
|
||||
text[i] = new SimpleDateFormat("hh:mm a").format(alert
|
||||
.getTime());
|
||||
} else if (columns[i].getText().equals(COLUMN_PRIORITY)) {
|
||||
text[i] = alert.getPriority().toString();
|
||||
} else if (columns[i].getText().equals(COLUMN_ORIGIN)) {
|
||||
text[i] = alert.getOrigin();
|
||||
} else {
|
||||
text[i] = "Unknown Field";
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public void rebuildColums(List<String> columns) {
|
||||
for (TableColumn column : alertTable.getColumns()) {
|
||||
column.dispose();
|
||||
}
|
||||
for (String columnText : columns) {
|
||||
TableColumn column = new TableColumn(alertTable, SWT.NONE);
|
||||
column.setText(columnText);
|
||||
}
|
||||
for (TableItem item : alertTable.getItems()) {
|
||||
item.setText(getText(getAlert(item)));
|
||||
}
|
||||
for (TableColumn column : alertTable.getColumns()) {
|
||||
column.pack();
|
||||
}
|
||||
}
|
||||
|
||||
protected String getToolTip(Alert alert) {
|
||||
StringBuilder toolTip = new StringBuilder();
|
||||
if (alert.getTime() != null) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(
|
||||
"yyyy-MM-dd_HH:mm:ss.SSS");
|
||||
toolTip.append("Time: ").append(sdf.format(alert.getTime()))
|
||||
.append("\n");
|
||||
}
|
||||
if (alert.getPriority() != null) {
|
||||
toolTip.append("Priority: ").append(alert.getPriority())
|
||||
.append("\n");
|
||||
}
|
||||
if (toolTip.charAt(toolTip.length() - 1) == '\n') {
|
||||
toolTip.deleteCharAt(toolTip.length() - 1);
|
||||
}
|
||||
return toolTip.toString();
|
||||
}
|
||||
|
||||
protected void populateContextMenu(Menu menu) {
|
||||
for (MenuItem item : menu.getItems()) {
|
||||
item.dispose();
|
||||
}
|
||||
Alert alert = getSingleSelection();
|
||||
if (alert != null) {
|
||||
new ActionContributionItem(new SaveToFileAction(alert)).fill(menu,
|
||||
-1);
|
||||
}
|
||||
}
|
||||
|
||||
public Alert getSingleSelection() {
|
||||
TableItem[] selection = alertTable.getSelection();
|
||||
if (selection == null || selection.length != 1) {
|
||||
return null;
|
||||
} else {
|
||||
return getAlert(selection[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Alert> getMultiSelection() {
|
||||
TableItem[] selection = alertTable.getSelection();
|
||||
if (selection == null || selection.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Alert> result = new ArrayList<Alert>();
|
||||
for (int i = 0; i < selection.length; i += 1) {
|
||||
result.addAll(getAlerts(selection[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Alert getAlert(TableItem item) {
|
||||
return getAlerts(item).get(0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Alert> getAlerts(TableItem item) {
|
||||
return (List<Alert>) item.getData();
|
||||
}
|
||||
|
||||
public void removeAll() {
|
||||
alertTable.removeAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
styles.close();
|
||||
}
|
||||
|
||||
protected void alertSelected() {
|
||||
// sub classes can override this easily
|
||||
}
|
||||
|
||||
protected void alertDoubleClick() {
|
||||
// sub classes can override this easily
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStyle() {
|
||||
Display display = getDisplay();
|
||||
if (display.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
display.asyncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (alertTable.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
for (TableItem item : alertTable.getItems()) {
|
||||
applyStyle(item);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.action.IMenuManager;
|
||||
import org.eclipse.jface.action.MenuManager;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.SashForm;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.ui.IViewPart;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.IWorkbenchWindow;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.part.ViewPart;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
import com.raytheon.uf.viz.alertview.AlertStore;
|
||||
import com.raytheon.uf.viz.alertview.filter.AlertFilter;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences.FilterMenu;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
import com.raytheon.uf.viz.alertview.ui.prefs.OpenPreferencesAction;
|
||||
|
||||
/**
|
||||
*
|
||||
* {@link IViewPart} for displaying {@link Alert}s. View is essentially just a
|
||||
* combination of an {@link AlertTable} and an {@link AlertConsoleViewer}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
* Jun 22, 2015 4474 njensen Fix bugs
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertView extends ViewPart implements AlertDestination,
|
||||
PreferenceFile.Listener<AlertViewPreferences> {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(AlertView.class);
|
||||
|
||||
private FilterManager filterManager = new FilterManager();
|
||||
|
||||
private ServiceRegistration<AlertDestination> destinationRegistration;
|
||||
|
||||
private PreferenceFile<AlertViewPreferences> preferencesFile;
|
||||
|
||||
private SashForm sashForm;
|
||||
|
||||
private AlertTable alertTable;
|
||||
|
||||
private AlertConsoleViewer detailsConsoleViewer;
|
||||
|
||||
@Override
|
||||
public void createPartControl(Composite parent) {
|
||||
preferencesFile = AlertViewPreferences.load(this);
|
||||
AlertViewPreferences preferences = preferencesFile.get();
|
||||
|
||||
sashForm = new SashForm(parent, SWT.NONE);
|
||||
sashForm.setOrientation(SWT.VERTICAL);
|
||||
|
||||
alertTable = new AlertTable(sashForm, preferences.getColumns()) {
|
||||
|
||||
@Override
|
||||
protected void alertSelected() {
|
||||
detailsConsoleViewer.setAlert(alertTable.getSingleSelection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void alertDoubleClick() {
|
||||
if (sashForm.getMaximizedControl() == alertTable) {
|
||||
sashForm.setMaximizedControl(null);
|
||||
} else {
|
||||
sashForm.setMaximizedControl(alertTable);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
detailsConsoleViewer = new AlertConsoleViewer(sashForm);
|
||||
|
||||
sashForm.setMaximizedControl(alertTable);
|
||||
|
||||
alertTable.setMergeRepeatInterval(preferences.getMergeRepeatInterval());
|
||||
|
||||
populateFilterMenu();
|
||||
destinationRegistration = getBundleContext().registerService(
|
||||
AlertDestination.class, this, null);
|
||||
}
|
||||
|
||||
protected void populateFilterMenu() {
|
||||
/*
|
||||
* TODO the menu button creates excessive unusable space in CAVE because
|
||||
* there are no toolbar items and the tabs are so small.
|
||||
*/
|
||||
IMenuManager menuManager = getViewSite().getActionBars()
|
||||
.getMenuManager();
|
||||
menuManager.removeAll();
|
||||
MenuManager filterMenu = new MenuManager("Show", null);
|
||||
menuManager.add(filterMenu);
|
||||
AlertViewPreferences prefs = preferencesFile.get();
|
||||
for (FilterMenu menuItem : prefs.getFilterMenu()) {
|
||||
Action action = new ShowFilteredAction(menuItem);
|
||||
if (prefs.getActiveFilter().equals(menuItem.getFilter())) {
|
||||
action.setChecked(true);
|
||||
action.run();
|
||||
}
|
||||
filterMenu.add(action);
|
||||
}
|
||||
menuManager.add(new OpenPreferencesAction());
|
||||
}
|
||||
|
||||
private void loadAlerts() {
|
||||
BundleContext context = getBundleContext();
|
||||
ServiceReference<AlertStore> ref = context
|
||||
.getServiceReference(AlertStore.class);
|
||||
if (ref != null) {
|
||||
AlertStore store = context.getService(ref);
|
||||
for (Alert alert : store.getAlerts()) {
|
||||
alertTable.addAlert(alert);
|
||||
}
|
||||
context.ungetService(ref);
|
||||
}
|
||||
alertTable.packColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocus() {
|
||||
alertTable.setFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
destinationRegistration.unregister();
|
||||
preferencesFile.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAlert(Alert alert) {
|
||||
alertTable.addAlert(alert);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final AlertViewPreferences preferences) {
|
||||
Display display = Display.getCurrent();
|
||||
if (display.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
display.asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (alertTable.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
alertTable.setMergeRepeatInterval(preferences
|
||||
.getMergeRepeatInterval());
|
||||
alertTable.rebuildColums(preferences.getColumns());
|
||||
populateFilterMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void show(IWorkbenchWindow window, Alert alert) {
|
||||
IWorkbenchPage activePage = window.getActivePage();
|
||||
|
||||
try {
|
||||
AlertView view = (AlertView) activePage.showView(AlertView.class
|
||||
.getName());
|
||||
if (alert != null) {
|
||||
view.handleAlert(alert);
|
||||
view.alertTable.select(alert);
|
||||
view.sashForm.setMaximizedControl(null);
|
||||
}
|
||||
} catch (PartInitException e) {
|
||||
logger.error("Cannot open AlertView", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static BundleContext getBundleContext() {
|
||||
return FrameworkUtil.getBundle(AlertView.class).getBundleContext();
|
||||
}
|
||||
|
||||
private class ShowFilteredAction extends Action {
|
||||
|
||||
private final String filterName;
|
||||
|
||||
private final AlertFilter filter;
|
||||
|
||||
public ShowFilteredAction(FilterMenu menuItem) {
|
||||
super(menuItem.getText(), IAction.AS_RADIO_BUTTON);
|
||||
this.filterName = menuItem.getFilter();
|
||||
this.filter = filterManager.getFilter(filterName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!this.filter.equals(alertTable.getFilter())) {
|
||||
alertTable.setFilter(filter);
|
||||
detailsConsoleViewer.setAlert(alertTable.getSingleSelection());
|
||||
loadAlerts();
|
||||
AlertViewPreferences prefs = preferencesFile.get();
|
||||
if (!filterName.equals(prefs.getActiveFilter())) {
|
||||
prefs = new AlertViewPreferences(prefs);
|
||||
prefs.setActiveFilter(filterName);
|
||||
preferencesFile.write(prefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
import com.raytheon.uf.viz.alertview.filter.AlertFilter;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
|
||||
/**
|
||||
* Automatically open {@link AlertView} whenever new {@link Alert}s arrive that
|
||||
* have a high enough priority.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 25, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertViewAutoOpen implements AlertDestination,
|
||||
PreferenceFile.Listener<AlertViewPreferences> {
|
||||
|
||||
private final PreferenceFile<AlertViewPreferences> prefsFile;
|
||||
|
||||
private final FilterManager filters = new FilterManager();
|
||||
|
||||
private AlertFilter filter;
|
||||
|
||||
public AlertViewAutoOpen() {
|
||||
prefsFile = AlertViewPreferences.load(this);
|
||||
filter = filters.getFilter(prefsFile.get().getOpenFilter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AlertViewPreferences preference) {
|
||||
filter = filters.getFilter(prefsFile.get().getOpenFilter());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAlert(final Alert alert) {
|
||||
if (filter.filter(alert)) {
|
||||
Display.getDefault().asyncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
OpenAlertViewHandler.openInAlertView(alert);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import org.eclipse.core.commands.AbstractHandler;
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.core.commands.ExecutionException;
|
||||
import org.eclipse.core.commands.IHandler;
|
||||
import org.eclipse.ui.IWindowListener;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
import org.eclipse.ui.IWorkbenchWindow;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
*
|
||||
* {@link IHandler} that opens an {@link AlertView}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class OpenAlertViewHandler extends AbstractHandler {
|
||||
|
||||
private final Alert alert;
|
||||
|
||||
public OpenAlertViewHandler() {
|
||||
this.alert = null;
|
||||
}
|
||||
|
||||
public OpenAlertViewHandler(Alert alert) {
|
||||
this.alert = alert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(ExecutionEvent event) throws ExecutionException {
|
||||
openInAlertView(alert);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void openInAlertView(Alert alert) {
|
||||
IWorkbench workbench = PlatformUI.getWorkbench();
|
||||
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
|
||||
if (workbench.isStarting()) {
|
||||
workbench.addWindowListener(new ShowAlertViewWindowListener(alert));
|
||||
} else if (window != null) {
|
||||
AlertView.show(window, alert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user clicks on the alert popup while the workbench is starting
|
||||
* then this listener will be used to wait until the workbench window is
|
||||
* opened and then display the alert.
|
||||
*/
|
||||
private static class ShowAlertViewWindowListener implements IWindowListener {
|
||||
|
||||
private final Alert alert;
|
||||
|
||||
public ShowAlertViewWindowListener(Alert alert) {
|
||||
this.alert = alert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowOpened(IWorkbenchWindow window) {
|
||||
AlertView.show(window, alert);
|
||||
window.getWorkbench().removeWindowListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(IWorkbenchWindow window) {
|
||||
/* Unused method required by interface. */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosed(IWorkbenchWindow window) {
|
||||
/* Unused method required by interface. */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowActivated(IWorkbenchWindow window) {
|
||||
/* Unused method required by interface. */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -33,6 +33,8 @@ import org.eclipse.swt.events.SelectionAdapter;
|
|||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
|
@ -68,6 +70,7 @@ import com.raytheon.uf.viz.alertviz.config.AlertMetadata;
|
|||
* 13 Jan 2011 7375 cjeanbap Commented out shell.setVisible(...) in
|
||||
* acknowledgeLastMessage().
|
||||
* 20 Apr 2015 4311 lvenable Fixed text field to accept really long text strings.
|
||||
* 29 Jun 2015 4311 randerso Reworking AlertViz dialogs to be resizable.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -77,6 +80,20 @@ import com.raytheon.uf.viz.alertviz.config.AlertMetadata;
|
|||
*/
|
||||
public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
||||
MouseListener {
|
||||
private static final int MAX_INITIAL_LINES = 5;
|
||||
|
||||
private static final int WIDTH_IN_CHARS = 135;
|
||||
|
||||
private static final double PERCENT_OF_SCREEN_WIDTH = 0.75;
|
||||
|
||||
private static final int NUM_LIST_ITEMS = 10;
|
||||
|
||||
/*
|
||||
* Adjustment for SWT bug where shell.getSize() returns incorrect value when
|
||||
* SWT.ON_TOP style is used.
|
||||
*/
|
||||
private static final int SWT_BUG_FACTOR = 6;
|
||||
|
||||
/**
|
||||
* Dialog shell.
|
||||
*/
|
||||
|
@ -87,21 +104,11 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
*/
|
||||
private Display display;
|
||||
|
||||
/**
|
||||
* Font used for the controls.
|
||||
*/
|
||||
private Font controlFont;
|
||||
|
||||
/**
|
||||
* Font used for labels
|
||||
*/
|
||||
private Font labelFont;
|
||||
|
||||
/**
|
||||
* Font used for the double click label.
|
||||
*/
|
||||
private Font dblClickLblFont;
|
||||
|
||||
/**
|
||||
* Message text field.
|
||||
*/
|
||||
|
@ -268,7 +275,9 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
*/
|
||||
private boolean initialized = false;
|
||||
|
||||
private final AlertVisualization av;
|
||||
private boolean first;
|
||||
|
||||
private int controlWidth;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -285,13 +294,12 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
* Color to be displayed at startup.
|
||||
*/
|
||||
public AlertPopupMessageDlg(Shell parent, StatusMessage statMsg,
|
||||
boolean expanded, Listener listener, RGB startUpRGB,
|
||||
AlertVisualization av) {
|
||||
boolean expanded, Listener listener, RGB startUpRGB) {
|
||||
super(parent, 0);
|
||||
hideListener = listener;
|
||||
statMsgArray.add(statMsg);
|
||||
this.expanded = expanded;
|
||||
this.av = av;
|
||||
this.first = true;
|
||||
|
||||
initShell(startUpRGB);
|
||||
}
|
||||
|
@ -303,15 +311,14 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
Shell parent = getParent();
|
||||
display = parent.getDisplay();
|
||||
|
||||
shell = new Shell(parent, SWT.ON_TOP);
|
||||
shell = new Shell(parent, SWT.ON_TOP | SWT.RESIZE);
|
||||
shell.setText("Alert Visualization Popup Message Dialog");
|
||||
Rectangle prvLocation = av.getAlertPopupMsgPrvLocation();
|
||||
if (prvLocation != null) {
|
||||
shell.getBounds().add(prvLocation);
|
||||
}
|
||||
|
||||
// Create the main layout for the shell.
|
||||
GridLayout mainLayout = new GridLayout(1, false);
|
||||
mainLayout.marginWidth = 0;
|
||||
mainLayout.marginHeight = 0;
|
||||
mainLayout.verticalSpacing = 0;
|
||||
shell.setLayout(mainLayout);
|
||||
|
||||
// initialize data, fonts, and arrays
|
||||
|
@ -345,12 +352,13 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
* @return True/False/null.
|
||||
*/
|
||||
public Object open() {
|
||||
shell.pack();
|
||||
|
||||
setInitialDialogLocation();
|
||||
|
||||
initialized = true;
|
||||
|
||||
showHideLog();
|
||||
|
||||
shell.open();
|
||||
|
||||
while (!shell.isDisposed()) {
|
||||
|
@ -361,9 +369,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
|
||||
initialized = false;
|
||||
|
||||
controlFont.dispose();
|
||||
labelFont.dispose();
|
||||
dblClickLblFont.dispose();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -372,10 +378,26 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
* Initialize font data
|
||||
*/
|
||||
private void initalizeData() {
|
||||
controlFont = new Font(shell.getDisplay(), "Monospace", 10, SWT.NORMAL);
|
||||
labelFont = new Font(shell.getDisplay(), "Monospace", 14, SWT.BOLD);
|
||||
dblClickLblFont = new Font(shell.getDisplay(), "Monospace", 10,
|
||||
SWT.BOLD);
|
||||
FontData fontData = display.getSystemFont().getFontData()[0];
|
||||
labelFont = new Font(shell.getDisplay(), fontData.getName(),
|
||||
(int) (fontData.getHeight() * 1.4), SWT.BOLD);
|
||||
|
||||
/*
|
||||
* compute preferred height to display entire message.
|
||||
*/
|
||||
int screenWidth = display.getPrimaryMonitor().getBounds().width;
|
||||
|
||||
/*
|
||||
* compute width of controls as the lesser of WIDTH_IN_CHARS or
|
||||
* PERCENT_OF_SCREEN_WIDTH
|
||||
*/
|
||||
GC gc = new GC(display);
|
||||
gc.setFont(display.getSystemFont());
|
||||
int charWidth = gc.getFontMetrics().getAverageCharWidth();
|
||||
gc.dispose();
|
||||
|
||||
controlWidth = Math.min(charWidth * WIDTH_IN_CHARS,
|
||||
(int) (screenWidth * PERCENT_OF_SCREEN_WIDTH));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -399,7 +421,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
private void createTitleBarLabel() {
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
gd.horizontalSpan = 3;
|
||||
moveLabel = new Label(shell, SWT.CENTER | SWT.BORDER);
|
||||
moveLabel = new Label(shell, SWT.CENTER);
|
||||
moveLabel.setText("Alert Visualization Popup Message Dialog");
|
||||
moveLabel.setLayoutData(gd);
|
||||
moveLabel.setFont(labelFont);
|
||||
|
@ -415,97 +437,90 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
* Create the labels at the top of the dialog.
|
||||
*/
|
||||
private void createTopLabels() {
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
topLabelComp = new Composite(shell, SWT.NONE);
|
||||
GridLayout gl = new GridLayout(3, false);
|
||||
gl.horizontalSpacing = 35;
|
||||
topLabelComp.setLayout(gl);
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
topLabelComp.setLayoutData(gd);
|
||||
topLabelComp.setBackground(display.getSystemColor(SWT.COLOR_RED));
|
||||
|
||||
sourceLbl = new Label(topLabelComp, SWT.BORDER);
|
||||
sourceLbl.setText(sourceStr + statMsgArray.get(0).getSourceKey());
|
||||
gd = new GridData(200, SWT.DEFAULT);
|
||||
gd.verticalIndent = 10;
|
||||
sourceLbl = new Label(topLabelComp, SWT.NONE);
|
||||
sourceLbl.setText(sourceStr + statMsgArray.get(0).getSourceKey());
|
||||
sourceLbl.setLayoutData(gd);
|
||||
|
||||
gd = new GridData(200, SWT.DEFAULT);
|
||||
gd.verticalIndent = 10;
|
||||
priorityLbl = new Label(topLabelComp, SWT.NONE);
|
||||
priorityLbl = new Label(topLabelComp, SWT.BORDER);
|
||||
priorityLbl.setText(priorityStr
|
||||
+ statMsgArray.get(0).getPriority().ordinal());
|
||||
priorityLbl.setLayoutData(gd);
|
||||
|
||||
gd = new GridData(200, SWT.DEFAULT);
|
||||
gd.verticalIndent = 10;
|
||||
categoryLbl = new Label(topLabelComp, SWT.NONE);
|
||||
categoryLbl.setText(categoryStr + statMsgArray.get(0).getCategory());
|
||||
categoryLbl.setLayoutData(gd);
|
||||
priorityLbl.setLayoutData(gd);
|
||||
|
||||
/*
|
||||
* If the expanded flag is false then hide the labels that display the
|
||||
* Category/Source/Priority information.
|
||||
*/
|
||||
if (expanded == false) {
|
||||
// Hide the message labels
|
||||
((GridData) topLabelComp.getLayoutData()).exclude = true;
|
||||
topLabelComp.setVisible(false);
|
||||
shell.layout();
|
||||
shell.pack();
|
||||
}
|
||||
categoryLbl = new Label(topLabelComp, SWT.BORDER);
|
||||
categoryLbl.setText(categoryStr + statMsgArray.get(0).getCategory());
|
||||
gd = new GridData(200, SWT.DEFAULT);
|
||||
gd.verticalIndent = 10;
|
||||
categoryLbl.setLayoutData(gd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the message text control.
|
||||
*/
|
||||
private void createMessageControl() {
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
messageComp = new Composite(shell, SWT.NONE);
|
||||
messageComp.setLayout(new GridLayout(1, false));
|
||||
messageComp.setLayoutData(gd);
|
||||
messageComp.setBackground(display.getSystemColor(SWT.COLOR_RED));
|
||||
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
gd.heightHint = 20;
|
||||
gd.widthHint = 920;
|
||||
messageTF = new Text(messageComp, SWT.BORDER | SWT.MULTI | SWT.WRAP
|
||||
| SWT.V_SCROLL);
|
||||
messageTF.setLayoutData(gd);
|
||||
messageTF.setText(statMsgArray.get(0).getMessage());
|
||||
messageTF.setEditable(false);
|
||||
messageTF.setText(statMsgArray.get(0).getMessage());
|
||||
|
||||
int preferredHeight = messageTF.computeSize(controlWidth, SWT.DEFAULT).y;
|
||||
|
||||
/*
|
||||
* compute size to display only max initial lines
|
||||
*/
|
||||
int height = messageTF.getLineHeight() * MAX_INITIAL_LINES;
|
||||
Rectangle initialSize = messageTF.computeTrim(0, 0, controlWidth,
|
||||
height);
|
||||
|
||||
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
gd.widthHint = initialSize.width;
|
||||
|
||||
gd.heightHint = Math.min(preferredHeight, initialSize.height);
|
||||
gd.minimumHeight = gd.heightHint;
|
||||
messageTF.setLayoutData(gd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the action buttons for the dialog.
|
||||
*/
|
||||
private void createActionButtons() {
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
actionComp = new Composite(shell, SWT.NONE);
|
||||
actionComp.setLayout(new GridLayout(7, false));
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
actionComp.setLayoutData(gd);
|
||||
actionComp.setBackground(display.getSystemColor(SWT.COLOR_RED));
|
||||
|
||||
gd = new GridData(200, SWT.DEFAULT);
|
||||
timeLbl = new Label(actionComp, SWT.NONE);
|
||||
timeLbl = new Label(actionComp, SWT.BORDER);
|
||||
timeLbl.setText(dateFormat.format(statMsgArray.get(0).getEventTime()));
|
||||
gd = new GridData(200, SWT.DEFAULT);
|
||||
timeLbl.setLayoutData(gd);
|
||||
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
fillerLbl = new Label(actionComp, SWT.NONE);
|
||||
fillerLbl.setText("");
|
||||
fillerLbl.setBackground(display.getSystemColor(SWT.COLOR_RED));
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
fillerLbl.setLayoutData(gd);
|
||||
|
||||
gd = new GridData(100, SWT.DEFAULT);
|
||||
hideShowLogBtn = new Button(actionComp, SWT.PUSH);
|
||||
hideShowLogBtn.setLayoutData(gd);
|
||||
|
||||
if (expanded == true) {
|
||||
hideShowLogBtn.setText("Hide Log");
|
||||
} else {
|
||||
hideShowLogBtn.setText("Show Log");
|
||||
}
|
||||
|
||||
hideShowLogBtn.setLayoutData(new GridData());
|
||||
hideShowLogBtn.setText("Hide Log");
|
||||
hideShowLogBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
|
@ -547,90 +562,69 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
hideDialogBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
Rectangle prevLocation = Display.getCurrent().getBounds();
|
||||
av.setAlertPopupMsgPrvLocation(prevLocation);
|
||||
shell.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* If the expanded flag is false then hide the Acknowledge Selected
|
||||
* button.
|
||||
*/
|
||||
if (expanded == false) {
|
||||
// Hide the Acknowledge Selected button
|
||||
((GridData) ackSelectedBtn.getLayoutData()).exclude = true;
|
||||
ackSelectedBtn.setVisible(false);
|
||||
actionComp.layout();
|
||||
actionComp.pack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the message log list control.
|
||||
*/
|
||||
private void createMessageLogControl() {
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
logComp = new Composite(shell, SWT.NONE);
|
||||
logComp.setLayout(new GridLayout(1, false));
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
logComp.setLayoutData(gd);
|
||||
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
Label dblClickLBl = new Label(logComp, SWT.BORDER | SWT.CENTER);
|
||||
dblClickLBl
|
||||
.setText("Double-click message to display more information:");
|
||||
dblClickLBl.setFont(dblClickLblFont);
|
||||
dblClickLBl.setFont(labelFont);
|
||||
dblClickLBl.setForeground(display.getSystemColor(SWT.COLOR_DARK_BLUE));
|
||||
dblClickLBl.setLayoutData(gd);
|
||||
|
||||
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
gd.widthHint = 900;
|
||||
gd.heightHint = 250;
|
||||
msgLogList = new List(logComp, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
|
||||
msgLogList.setFont(controlFont);
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
Rectangle size = msgLogList.computeTrim(0, 0, controlWidth,
|
||||
msgLogList.getItemHeight() * NUM_LIST_ITEMS);
|
||||
gd.widthHint = size.width;
|
||||
gd.heightHint = size.height;
|
||||
gd.heightHint = (msgLogList.getItemHeight() * 10)
|
||||
+ (msgLogList.getBorderWidth() * 2);
|
||||
msgLogList.setLayoutData(gd);
|
||||
msgLogList.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
showSelectedListData();
|
||||
}
|
||||
});
|
||||
|
||||
detailsComp = new SimpleDetailsComp(logComp, SWT.NONE);
|
||||
|
||||
msgLogList.addMouseListener(new MouseListener() {
|
||||
@Override
|
||||
public void mouseDoubleClick(MouseEvent e) {
|
||||
|
||||
if (detailsComp.isVisible() == false) {
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
int delta = 0;
|
||||
if (detailsComp.isVisible()) {
|
||||
((GridData) detailsComp.getLayoutData()).exclude = true;
|
||||
detailsComp.setVisible(false);
|
||||
delta -= detailsComp.getSize().y;
|
||||
} else {
|
||||
int idx = msgLogList.getSelectionIndex();
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
StatusMessage sm = statMsgArray.get(idx);
|
||||
detailsComp.displayDetails(sm);
|
||||
((GridData) detailsComp.getLayoutData()).exclude = false;
|
||||
detailsComp.setVisible(true);
|
||||
} else {
|
||||
detailsComp.setVisible(false);
|
||||
delta += detailsComp.getSize().y;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDown(MouseEvent e) {
|
||||
adjustHeight(delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(MouseEvent e) {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (expanded == false) {
|
||||
((GridData) logComp.getLayoutData()).exclude = true;
|
||||
logComp.setVisible(false);
|
||||
shell.layout();
|
||||
shell.pack();
|
||||
}
|
||||
detailsComp = new SimpleDetailsComp(shell, SWT.NONE);
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
detailsComp.setLayoutData(gd);
|
||||
|
||||
msgLogList.add(getFormattedMessage(statMsgArray.get(0)));
|
||||
msgLogList.select(0);
|
||||
|
@ -641,46 +635,59 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
* Show/Hide the message log list.
|
||||
*/
|
||||
private void showHideLog() {
|
||||
int delta = 0;
|
||||
if (expanded == true) {
|
||||
// Show the message labels
|
||||
((GridData) topLabelComp.getLayoutData()).exclude = false;
|
||||
topLabelComp.setVisible(true);
|
||||
shell.layout();
|
||||
shell.pack();
|
||||
delta += topLabelComp.getSize().y;
|
||||
|
||||
// Show the Acknowledge Selected button
|
||||
((GridData) ackSelectedBtn.getLayoutData()).exclude = false;
|
||||
ackSelectedBtn.setVisible(true);
|
||||
actionComp.layout();
|
||||
actionComp.pack();
|
||||
hideShowLogBtn.setText("Hide Log");
|
||||
|
||||
// Show the message log
|
||||
((GridData) logComp.getLayoutData()).exclude = false;
|
||||
logComp.setVisible(true);
|
||||
shell.layout();
|
||||
shell.pack();
|
||||
hideShowLogBtn.setText("Hide Log");
|
||||
delta += logComp.getSize().y;
|
||||
} else {
|
||||
// Hide the message labels
|
||||
((GridData) topLabelComp.getLayoutData()).exclude = true;
|
||||
topLabelComp.setVisible(false);
|
||||
shell.layout();
|
||||
shell.pack();
|
||||
delta -= topLabelComp.getSize().y;
|
||||
|
||||
// Hide the Acknowledge Selected button
|
||||
((GridData) ackSelectedBtn.getLayoutData()).exclude = true;
|
||||
ackSelectedBtn.setVisible(false);
|
||||
actionComp.layout();
|
||||
actionComp.pack();
|
||||
hideShowLogBtn.setText("Show Log");
|
||||
|
||||
// Hide the message log
|
||||
detailsComp.setVisible(false);
|
||||
if (this.first || detailsComp.isVisible()) {
|
||||
((GridData) detailsComp.getLayoutData()).exclude = true;
|
||||
detailsComp.setVisible(false);
|
||||
delta -= detailsComp.getSize().y;
|
||||
this.first = false;
|
||||
}
|
||||
|
||||
((GridData) logComp.getLayoutData()).exclude = true;
|
||||
logComp.setVisible(false);
|
||||
shell.layout();
|
||||
shell.pack();
|
||||
hideShowLogBtn.setText("Show Log");
|
||||
delta -= logComp.getSize().y;
|
||||
}
|
||||
actionComp.layout();
|
||||
|
||||
adjustHeight(delta);
|
||||
}
|
||||
|
||||
private void adjustHeight(int delta) {
|
||||
Point minSize = shell.getMinimumSize();
|
||||
minSize.y += delta;
|
||||
shell.setMinimumSize(minSize);
|
||||
|
||||
Point size = shell.getSize();
|
||||
size.x += SWT_BUG_FACTOR;
|
||||
size.y += delta + SWT_BUG_FACTOR;
|
||||
shell.setSize(size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -701,10 +708,19 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
sourceLbl.setText(sourceStr + sm.getSourceKey());
|
||||
timeLbl.setText(dateFormat.format(sm.getEventTime()));
|
||||
messageTF.setText(sm.getMessage());
|
||||
int desiredHeight = Math.min(MAX_INITIAL_LINES,
|
||||
messageTF.getLineCount())
|
||||
* messageTF.getLineHeight();
|
||||
Rectangle clientArea = messageTF.getClientArea();
|
||||
if (clientArea.height < desiredHeight) {
|
||||
Rectangle trim = messageTF.computeTrim(clientArea.x, clientArea.y,
|
||||
clientArea.width, desiredHeight);
|
||||
Point oldSize = messageTF.getSize();
|
||||
messageTF.setSize(oldSize.x, trim.height);
|
||||
adjustHeight(trim.height - oldSize.y);
|
||||
}
|
||||
|
||||
detailsComp.displayDetails(sm);
|
||||
|
||||
this.shell.pack();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -747,7 +763,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
}
|
||||
|
||||
// Check if a message is not selected.
|
||||
if (currentIndex < 0 || !expanded) {
|
||||
if ((currentIndex < 0) || !expanded) {
|
||||
if (msgLogList.getItemCount() > 0) {
|
||||
msgLogList.select(0);
|
||||
showSelectedListData();
|
||||
|
@ -759,7 +775,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
|
||||
// Check if the current index will go outside the array
|
||||
// (it should never do this but check anyway...)
|
||||
if (currentIndex > 0 && currentIndex == statMsgArray.size()) {
|
||||
if ((currentIndex > 0) && (currentIndex == statMsgArray.size())) {
|
||||
msgLogList.select(0);
|
||||
showSelectedListData();
|
||||
return;
|
||||
|
@ -877,6 +893,8 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
messageComp.setBackground(bgColor);
|
||||
actionComp.setBackground(bgColor);
|
||||
fillerLbl.setBackground(bgColor);
|
||||
logComp.setBackground(bgColor);
|
||||
detailsComp.setBackground(bgColor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -890,18 +908,18 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
return;
|
||||
}
|
||||
|
||||
boolean expandedForPromp = false;
|
||||
boolean expandedForPrompt = false;
|
||||
if (!expanded) {
|
||||
expandedForPromp = expanded = true;
|
||||
expandedForPrompt = expanded = true;
|
||||
showHideLog();
|
||||
}
|
||||
|
||||
showHideLog();
|
||||
if (confirmPrompt) {
|
||||
ConfirmationDlg cd = new ConfirmationDlg(shell,
|
||||
"Are you sure you want to acknowledge all popup messages?",
|
||||
SWT.ICON_QUESTION);
|
||||
|
||||
if (msgLogList != null && !msgLogList.isDisposed()) {
|
||||
if ((msgLogList != null) && !msgLogList.isDisposed()) {
|
||||
Rectangle logBounds = msgLogList.getBounds();
|
||||
Point logDisplayOrigin = msgLogList.toDisplay(0, 0);
|
||||
logBounds.x = logDisplayOrigin.x;
|
||||
|
@ -912,7 +930,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
result = cd.open();
|
||||
|
||||
if (result != SWT.YES) {
|
||||
if (result == SWT.CANCEL && expandedForPromp) {
|
||||
if ((result == SWT.CANCEL) && expandedForPrompt) {
|
||||
expanded = false;
|
||||
showHideLog();
|
||||
}
|
||||
|
@ -951,17 +969,18 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
private void setInitialDialogLocation() {
|
||||
|
||||
if (dialogXY == null) {
|
||||
Point minSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
||||
shell.setMinimumSize(minSize);
|
||||
|
||||
int screenHeight = display.getBounds().height;
|
||||
int screenWidth = display.getPrimaryMonitor().getBounds().width;
|
||||
|
||||
int newX = screenWidth / 2
|
||||
- (shell.getChildren())[0].getBounds().width / 2;
|
||||
int newY = (screenHeight / 2 - (shell.getChildren())[0].getBounds().height / 2) - 200;
|
||||
Point size = minSize;
|
||||
shell.setSize(size);
|
||||
|
||||
shell.setLocation(newX, newY);
|
||||
|
||||
dialogXY = new Point(newX, newY);
|
||||
dialogXY = new Point((screenWidth - size.x) / 2,
|
||||
(screenHeight - size.y) / 4);
|
||||
shell.setLocation(dialogXY);
|
||||
} else {
|
||||
shell.setLocation(dialogXY);
|
||||
}
|
||||
|
@ -997,7 +1016,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
* @return True if open, false if not.
|
||||
*/
|
||||
public boolean dialogIsOpen() {
|
||||
return (shell != null && !shell.isDisposed() && shell.isVisible());
|
||||
return ((shell != null) && !shell.isDisposed() && shell.isVisible());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1042,7 +1061,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener,
|
|||
*/
|
||||
@Override
|
||||
public void mouseMove(MouseEvent e) {
|
||||
if (origin != null && moveDialog == true) {
|
||||
if ((origin != null) && (moveDialog == true)) {
|
||||
// Move the dialog.
|
||||
dialogLoc = display.map(shell, null, e.x, e.y);
|
||||
dialogXY.x = dialogLoc.x - origin.x;
|
||||
|
|
|
@ -95,6 +95,7 @@ import com.raytheon.uf.viz.core.VizApp;
|
|||
* then set the icon to the default image.
|
||||
* 18 Mar 2015 4234 njensen Remove reference to non-working python
|
||||
* 03 Jun 2015 4473 njensen Updated for new AlertvizJob API
|
||||
* 29 Jun 2015 4311 randerso Reworking AlertViz dialogs to be resizable.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -377,8 +378,8 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if (alertPopupDlg != null
|
||||
&& alertPopupDlg.getNumberOfMessages() > 0) {
|
||||
if ((alertPopupDlg != null)
|
||||
&& (alertPopupDlg.getNumberOfMessages() > 0)) {
|
||||
cancelTimer();
|
||||
openAlertPopupDialog();
|
||||
}
|
||||
|
@ -437,20 +438,15 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
MenuItem viewLogMI = new MenuItem(trayItemMenu, SWT.NONE);
|
||||
viewLogMI.setText("System Log...");
|
||||
viewLogMI.addSelectionListener(new SelectionAdapter() {
|
||||
boolean open = false;
|
||||
|
||||
SimpleLogViewer slv = null;
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
if (open) {
|
||||
open = slv.focus(); // Do Nothing! It's open
|
||||
} else {
|
||||
open = true;
|
||||
if ((slv == null) || slv.isDisposed()) {
|
||||
slv = new SimpleLogViewer(shell);
|
||||
slv.setText("System Log");
|
||||
slv.open();
|
||||
open = false;
|
||||
} else {
|
||||
slv.bringToTop();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -597,7 +593,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
* Show the Alert Visualization Configuration dialog.
|
||||
*/
|
||||
private void showConfigDialog() {
|
||||
if (configDlg != null && !configDlg.isDisposed()) {
|
||||
if ((configDlg != null) && !configDlg.isDisposed()) {
|
||||
configDlg.close();
|
||||
}
|
||||
configDlg = new AlertVisConfigDlg(shell, alertMessageDlg, configData,
|
||||
|
@ -640,7 +636,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
.hasMissing(statMsg))) {
|
||||
Source source = configData.lookupSource("GDN_ADMIN");
|
||||
RGB backgroundRBG = null;
|
||||
if (source == null || source.getConfigurationItem() == null) {
|
||||
if ((source == null) || (source.getConfigurationItem() == null)) {
|
||||
backgroundRBG = ColorUtil.getColorValue("COLOR_YELLOW");
|
||||
} else {
|
||||
AlertMetadata am = source.getConfigurationItem().lookup(
|
||||
|
@ -663,7 +659,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
}
|
||||
} else {
|
||||
if (cat.getCategoryName().equals(Constants.MONITOR)
|
||||
|| amd.isText() == true) {
|
||||
|| (amd.isText() == true)) {
|
||||
alertMessageDlg.messageHandler(statMsg, amd, cat,
|
||||
gConfig);
|
||||
}
|
||||
|
@ -689,8 +685,8 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
audioFile = getFullAudioFilePath(audioFile);
|
||||
} else {
|
||||
audioFile = statMsg.getAudioFile();
|
||||
if (audioFile != null
|
||||
&& (audioFile.trim().length() == 0 || audioFile
|
||||
if ((audioFile != null)
|
||||
&& ((audioFile.trim().length() == 0) || audioFile
|
||||
.equals("NONE"))) {
|
||||
audioFile = null;
|
||||
}
|
||||
|
@ -703,10 +699,9 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
|
||||
// Pop-up message
|
||||
if (amd.isPopup() == true) {
|
||||
if (alertPopupDlg == null || alertPopupDlg.isDisposed() == true) {
|
||||
if ((alertPopupDlg == null) || (alertPopupDlg.isDisposed() == true)) {
|
||||
alertPopupDlg = new AlertPopupMessageDlg(shell, statMsg,
|
||||
gConfig.isExpandedPopup(), this, amd.getBackground(),
|
||||
this);
|
||||
gConfig.isExpandedPopup(), this, amd.getBackground());
|
||||
} else {
|
||||
alertPopupDlg.addNewMessage(statMsg, amd);
|
||||
}
|
||||
|
@ -739,7 +734,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
if (!file.exists()) {
|
||||
file = PathManagerFactory.getPathManager().getStaticFile(
|
||||
"alertVizAudio/" + file.getName());
|
||||
if (file == null || !file.exists()) {
|
||||
if ((file == null) || !file.exists()) {
|
||||
filename = null;
|
||||
} else {
|
||||
filename = file.getPath();
|
||||
|
@ -752,7 +747,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
* Opens the alert pop-up dialog
|
||||
*/
|
||||
public void openAlertPopupDialog() {
|
||||
if (alertPopupDlg != null && alertPopupDlg.dialogIsOpen() == true) {
|
||||
if ((alertPopupDlg != null) && (alertPopupDlg.dialogIsOpen() == true)) {
|
||||
alertPopupDlg.showDialog(true);
|
||||
} else {
|
||||
alertPopupDlg.open();
|
||||
|
@ -849,7 +844,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
configData = ConfigurationManager.getInstance()
|
||||
.getCurrentConfiguration();
|
||||
configContext = ConfigurationManager.getInstance().getCurrentContext();
|
||||
if (alertMessageDlg != null && showAlertDialogMI != null) {
|
||||
if ((alertMessageDlg != null) && (showAlertDialogMI != null)) {
|
||||
alertMessageDlg.setConfigData(configData);
|
||||
if (configData.isMonitorLayoutChanged(prevConfigFile)) {
|
||||
if (alertMessageDlg.reLayout()) {
|
||||
|
@ -864,21 +859,6 @@ public class AlertVisualization implements ITimerAction, IAudioAction,
|
|||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Alert Popup Message previous location.
|
||||
*/
|
||||
public void setAlertPopupMsgPrvLocation(Rectangle prevLocation) {
|
||||
this.prevLocation = prevLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Alert Popup Message to restore the window to its previous
|
||||
* location.
|
||||
*/
|
||||
public Rectangle getAlertPopupMsgPrvLocation() {
|
||||
return this.prevLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of text control composites.
|
||||
*
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.eclipse.swt.widgets.Button;
|
|||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.MenuItem;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.raytheon.uf.common.message.StatusMessage;
|
||||
|
||||
|
@ -40,7 +39,8 @@ import com.raytheon.uf.common.message.StatusMessage;
|
|||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 9, 2008 chammack Initial creation
|
||||
* Oct 09, 2008 chammack Initial creation
|
||||
* Jun 29, 2015 4311 randerso Reworking AlertViz dialogs to be resizable.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -49,10 +49,7 @@ import com.raytheon.uf.common.message.StatusMessage;
|
|||
|
||||
public class SimpleDetailsComp extends Composite {
|
||||
|
||||
/**
|
||||
* Shell of the parent composite
|
||||
*/
|
||||
private Shell shell = null;
|
||||
private static final int NUM_DETAIL_LINES = 13;
|
||||
|
||||
/**
|
||||
* Actually contains text of details message, lives in textBox
|
||||
|
@ -66,25 +63,22 @@ public class SimpleDetailsComp extends Composite {
|
|||
*/
|
||||
public SimpleDetailsComp(Composite parent, int style) {
|
||||
super(parent, style);
|
||||
this.shell = parent.getShell();
|
||||
|
||||
initComponents();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lay out composite with StyledText
|
||||
*/
|
||||
private void initComponents() {
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
setLayout(new GridLayout(1, false));
|
||||
setLayoutData(gd);
|
||||
GridLayout layout = new GridLayout(1, false);
|
||||
setLayout(layout);
|
||||
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
gd.heightHint = 250;
|
||||
st = new StyledText(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
|
||||
st = new StyledText(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER
|
||||
| SWT.WRAP);
|
||||
st.setEditable(false);
|
||||
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
gd.heightHint = (st.getLineHeight() * NUM_DETAIL_LINES)
|
||||
+ (st.getBorderWidth() * 2);
|
||||
st.setLayoutData(gd);
|
||||
|
||||
Menu popupMenu = new Menu(st);
|
||||
|
@ -121,43 +115,10 @@ public class SimpleDetailsComp extends Composite {
|
|||
if (sm == null) {
|
||||
st.setText("");
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// sb.append(sm.getMessage()).append("\n");
|
||||
|
||||
String details = sm.getDetails();
|
||||
String[] lines = details.split("[\n]");
|
||||
|
||||
for (String line : lines) {
|
||||
if (line.length() > 500) {
|
||||
sb.append(line.substring(0, 500)).append(
|
||||
"...text truncated\n");
|
||||
|
||||
} else {
|
||||
sb.append(line).append("\n");
|
||||
}
|
||||
}
|
||||
st.setText(sb.toString());
|
||||
st.setText(sm.getDetails());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override so we can exclude this composite from the layout when hidden
|
||||
*/
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
((GridData) this.getLayoutData()).exclude = !visible;
|
||||
|
||||
if (visible == true) {
|
||||
((GridData) st.getLayoutData()).widthHint = getParent().getBounds().width - 46;
|
||||
}
|
||||
|
||||
super.setVisible(visible);
|
||||
|
||||
shell.layout();
|
||||
shell.pack();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -26,12 +26,11 @@ import org.eclipse.core.runtime.IStatus;
|
|||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.MouseAdapter;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
|
@ -51,10 +50,15 @@ import com.raytheon.uf.common.message.StatusMessage;
|
|||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.alertviz.Activator;
|
||||
import com.raytheon.uf.viz.alertviz.AlertvizException;
|
||||
import com.raytheon.uf.viz.alertviz.AlertvizJob;
|
||||
import com.raytheon.uf.viz.alertviz.Container;
|
||||
import com.raytheon.uf.viz.alertviz.IAlertArrivedCallback;
|
||||
import com.raytheon.uf.viz.alertviz.LogUtil;
|
||||
import com.raytheon.uf.viz.alertviz.LogUtil.Order;
|
||||
import com.raytheon.uf.viz.alertviz.SystemStatusHandler;
|
||||
import com.raytheon.uf.viz.alertviz.config.AlertMetadata;
|
||||
import com.raytheon.uf.viz.alertviz.config.Category;
|
||||
import com.raytheon.uf.viz.alertviz.config.TrayConfiguration;
|
||||
|
||||
/**
|
||||
* Implements a basic log viewer capability
|
||||
|
@ -65,6 +69,8 @@ import com.raytheon.uf.viz.alertviz.SystemStatusHandler;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 30, 2008 1433 chammack Initial creation
|
||||
* Jun 02, 2015 4473 njensen Cleaned up warnings
|
||||
* Jul 01, 2015 4473 njensen Fix update of table on alert arrival
|
||||
* Jun 29, 2015 4311 randerso Reworking AlertViz dialogs to be resizable.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -72,69 +78,67 @@ import com.raytheon.uf.viz.alertviz.SystemStatusHandler;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class SimpleLogViewer extends Dialog {
|
||||
public class SimpleLogViewer extends Dialog implements IAlertArrivedCallback {
|
||||
|
||||
private Display display;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Shell shell;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private SimpleDetailsComp sdb;
|
||||
private SimpleDetailsComp detailsComp;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Button showLog;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Table reference;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
int[] range;
|
||||
|
||||
private Table table;
|
||||
|
||||
private Color yellow;
|
||||
|
||||
private Color red;
|
||||
|
||||
private Color orange;
|
||||
|
||||
private Color black;
|
||||
|
||||
boolean first;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param parent
|
||||
*/
|
||||
public SimpleLogViewer(Shell parent) {
|
||||
super(parent, SWT.NONE);
|
||||
first = true;
|
||||
|
||||
display = parent.getDisplay();
|
||||
|
||||
// Create a new shell object and set the text for the dialog.
|
||||
shell = new Shell(display, SWT.DIALOG_TRIM | SWT.MIN | SWT.TITLE
|
||||
| SWT.RESIZE);
|
||||
shell.setText("System Log");
|
||||
|
||||
initializeComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* set focus to the dialog
|
||||
*
|
||||
* @return false if not open or disposed, true otherwise
|
||||
* @return true if shell is null or disposed;
|
||||
*/
|
||||
public boolean focus() {
|
||||
if (shell == null || shell.isDisposed()) {
|
||||
return false;
|
||||
} else {
|
||||
public boolean isDisposed() {
|
||||
return ((shell != null) && shell.isDisposed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Bring dialog to the top
|
||||
*/
|
||||
public void bringToTop() {
|
||||
if ((shell != null) && !shell.isDisposed()) {
|
||||
shell.setVisible(true);
|
||||
shell.forceFocus();
|
||||
return true;
|
||||
shell.forceActive();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the dialog (makes visible).
|
||||
*
|
||||
* @return Null
|
||||
*/
|
||||
public Object open() {
|
||||
// Create a new shell object and set the text for the dialog.
|
||||
Shell parent = getParent();
|
||||
// shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.MIN | SWT.RESIZE);
|
||||
shell = new Shell(parent.getDisplay(), SWT.DIALOG_TRIM | SWT.MIN
|
||||
| SWT.TITLE | SWT.RESIZE);
|
||||
shell.setText(getText());
|
||||
|
||||
/* TODO: Max Code: */
|
||||
private void initializeComponents() {
|
||||
GridLayout mainLayout = new GridLayout(1, true);
|
||||
mainLayout.marginHeight = 0;
|
||||
mainLayout.marginWidth = 0;
|
||||
|
@ -143,15 +147,7 @@ public class SimpleLogViewer extends Dialog {
|
|||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
|
||||
shell.setLayoutData(gd);
|
||||
|
||||
// shell.setLayout(new GridLayout(1, false));
|
||||
|
||||
// shell.setSize(800, 400);
|
||||
// shell.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
|
||||
// | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL
|
||||
// | GridData.VERTICAL_ALIGN_FILL));
|
||||
|
||||
final Table table = new Table(shell, SWT.BORDER | SWT.VIRTUAL);
|
||||
reference = table;
|
||||
table = new Table(shell, SWT.BORDER | SWT.VIRTUAL);
|
||||
final TableColumn[] columns = new TableColumn[] {
|
||||
new TableColumn(table, SWT.NONE),
|
||||
new TableColumn(table, SWT.NONE),
|
||||
|
@ -159,10 +155,6 @@ public class SimpleLogViewer extends Dialog {
|
|||
new TableColumn(table, SWT.NONE),
|
||||
new TableColumn(table, SWT.NONE) };
|
||||
|
||||
// table.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
|
||||
// | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL
|
||||
// | GridData.VERTICAL_ALIGN_FILL));
|
||||
|
||||
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
gd.widthHint = 800;
|
||||
gd.heightHint = 400;
|
||||
|
@ -179,47 +171,39 @@ public class SimpleLogViewer extends Dialog {
|
|||
columns[3].setWidth(100);
|
||||
columns[4].setText("Message");
|
||||
columns[4].setWidth(100);
|
||||
final int[] range;
|
||||
final int sz;
|
||||
int sz = 0;
|
||||
try {
|
||||
range = SystemStatusHandler.getCurrentRange();
|
||||
this.range = range;
|
||||
sz = range[1] - range[0];
|
||||
if ((range[0] == 0) && (range[1] == 0)) {
|
||||
// database is empty
|
||||
sz = 0;
|
||||
} else {
|
||||
sz = (range[1] - range[0]) + 1;
|
||||
}
|
||||
} catch (AlertvizException e2) {
|
||||
Container
|
||||
.logInternal(
|
||||
Priority.ERROR,
|
||||
"SimpleLogViewer: exception getting current range from SystemStatusHandler.",
|
||||
e2);
|
||||
return null;
|
||||
}
|
||||
|
||||
table.setSortColumn(columns[0]);
|
||||
table.setSortDirection(SWT.UP);
|
||||
|
||||
final Color red = new Color(Display.getCurrent(), new RGB(255, 0, 0));
|
||||
final Color yellow = new Color(Display.getCurrent(), new RGB(255, 255,
|
||||
0));
|
||||
final Color orange = new Color(Display.getCurrent(), new RGB(255, 128,
|
||||
0));
|
||||
final Color black = new Color(Display.getCurrent(), new RGB(0, 0, 0));
|
||||
|
||||
table.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseDoubleClick(MouseEvent e) {
|
||||
showHideLog();
|
||||
}
|
||||
});
|
||||
red = new Color(display, new RGB(255, 0, 0));
|
||||
yellow = new Color(Display.getCurrent(), new RGB(255, 255, 0));
|
||||
orange = new Color(display, new RGB(255, 128, 0));
|
||||
black = new Color(display, new RGB(0, 0, 0));
|
||||
|
||||
table.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
int idx = table.getSelectionIndex();
|
||||
StatusMessage sm = null;
|
||||
try {
|
||||
|
||||
StatusMessage sm = SystemStatusHandler.retrieveByPk(idx
|
||||
+ range[0]);
|
||||
sdb.displayDetails(sm);
|
||||
sm = SystemStatusHandler.retrieveByPk(idx + range[0]);
|
||||
} catch (Exception e1) {
|
||||
Container
|
||||
.logInternal(
|
||||
|
@ -227,6 +211,12 @@ public class SimpleLogViewer extends Dialog {
|
|||
"SimpleLogViewer: exception retrieving StatusMessage by key from SystemStatusHandler: "
|
||||
+ (idx + range[0]), e1);
|
||||
}
|
||||
detailsComp.displayDetails(sm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
showHideLog();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -332,19 +322,52 @@ public class SimpleLogViewer extends Dialog {
|
|||
}
|
||||
});
|
||||
|
||||
sdb = new SimpleDetailsComp(shell, SWT.NONE);
|
||||
detailsComp = new SimpleDetailsComp(shell, SWT.NONE);
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
detailsComp.setLayoutData(gd);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void alertArrived(StatusMessage statusMessage,
|
||||
AlertMetadata alertMetadata, Category category,
|
||||
TrayConfiguration globalConfiguration) {
|
||||
|
||||
if (!table.isDisposed()) {
|
||||
int count = table.getItemCount();
|
||||
table.setItemCount(count + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the dialog (makes visible).
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public Object open() {
|
||||
Point minSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
||||
shell.setMinimumSize(minSize);
|
||||
|
||||
Point size = minSize;
|
||||
shell.setSize(size);
|
||||
|
||||
showHideLog();
|
||||
|
||||
AlertvizJob.getInstance().addAlertArrivedCallback(this);
|
||||
|
||||
shell.pack();
|
||||
shell.open();
|
||||
table.showItem(table.getItem(table.getItemCount() - 1));
|
||||
table.select(table.getItemCount() - 1);
|
||||
|
||||
// Wait until the shell is disposed.
|
||||
Display display = parent.getDisplay();
|
||||
Display display = shell.getDisplay();
|
||||
while (!shell.isDisposed()) {
|
||||
if (!display.readAndDispatch()) {
|
||||
display.sleep();
|
||||
}
|
||||
}
|
||||
|
||||
AlertvizJob.getInstance().removeAlertArrivedCallback(this);
|
||||
table.dispose();
|
||||
red.dispose();
|
||||
yellow.dispose();
|
||||
|
@ -358,26 +381,27 @@ public class SimpleLogViewer extends Dialog {
|
|||
*
|
||||
*/
|
||||
private void showHideLog() {
|
||||
int idx = reference.getSelectionIndex();
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
StatusMessage sm = SystemStatusHandler.retrieveByPk(idx + range[0]);
|
||||
if (sdb.isVisible() == false) {
|
||||
sdb.setVisible(true);
|
||||
sdb.displayDetails(sm);
|
||||
showLog.setText("Hide Log...");
|
||||
} else {
|
||||
sdb.setVisible(false);
|
||||
showLog.setText("Show Log...");
|
||||
}
|
||||
} catch (AlertvizException e1) {
|
||||
Container
|
||||
.logInternal(
|
||||
Priority.ERROR,
|
||||
"SimpleLogViewer: exception retrieving StatusMessage by key from SystemStatusHandler: "
|
||||
+ (idx + range[0]), e1);
|
||||
int delta = 0;
|
||||
if (first || detailsComp.isVisible()) {
|
||||
showLog.setText("Show Log...");
|
||||
|
||||
((GridData) detailsComp.getLayoutData()).exclude = true;
|
||||
detailsComp.setVisible(false);
|
||||
delta -= detailsComp.getSize().y;
|
||||
first = false;
|
||||
} else {
|
||||
showLog.setText("Hide Log...");
|
||||
((GridData) detailsComp.getLayoutData()).exclude = false;
|
||||
detailsComp.setVisible(true);
|
||||
delta += detailsComp.getSize().y;
|
||||
}
|
||||
|
||||
Point minSize = shell.getMinimumSize();
|
||||
minSize.y += delta;
|
||||
shell.setMinimumSize(minSize);
|
||||
|
||||
Point size = shell.getSize();
|
||||
size.y += delta;
|
||||
shell.setSize(size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,20 @@
|
|||
<!-- Only define when not wanting to use the UF Standard.
|
||||
<property scope="context" name="log.message.pattern" value="%-5p %d [%t] %c{0}: %m%n"/>
|
||||
-->
|
||||
<timestamp key="startTime" datePattern="yyyyMMdd_HHmmss" />
|
||||
<define name="adminLogFile" class="com.raytheon.uf.common.logback.LogFilePropertyDefiner" >
|
||||
<directory>${LOGDIR}</directory>
|
||||
<name>alertviz_${startTime}_admin.log</name>
|
||||
</define>
|
||||
<define name="consoleLogFile" class="com.raytheon.uf.common.logback.LogFilePropertyDefiner" >
|
||||
<directory>${LOGDIR}</directory>
|
||||
<name>alertviz_${startTime}_console.log</name>
|
||||
</define>
|
||||
|
||||
<!-- general application log -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
<!-- In eclipse InvertedThresholdFilter allows different color display for console and errConsole. -->
|
||||
<filter class="com.raytheon.uf.common.logback.filter.InvertedThresholdFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
|
@ -18,20 +29,16 @@
|
|||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
</appender>
|
||||
|
||||
<appender name="AlertVizAdminLogAppender" class="com.raytheon.uf.common.logback.appender.EnvConfigurableRollingFileAppender">
|
||||
<!-- file and fileNamePattern will be overridden by the env variable if present, but are required by logback -->
|
||||
<file>alertviz-admin.log</file>
|
||||
<envLogVar>LOGFILE_ALERTVIZ</envLogVar>
|
||||
<rollingPolicy class="com.raytheon.uf.common.logback.policy.EnvConfigurableFixedWindowRollingPolicy">
|
||||
<fileNamePattern>alertviz-admin.log%i</fileNamePattern>
|
||||
<envLogVar>LOGFILE_ALERTVIZ</envLogVar>
|
||||
<minIndex>1</minIndex>
|
||||
<maxIndex>5</maxIndex>
|
||||
</rollingPolicy>
|
||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
</triggeringPolicy>
|
||||
<append>true</append>
|
||||
<appender name="consoleLog" class="com.raytheon.uf.common.logback.appender.ConsoleFileAppender">
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
<file>${consoleLogFile}</file>
|
||||
<filter class="com.raytheon.uf.common.logback.filter.InvertedThresholdFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="AlertVizAdminLogAppender" class="ch.qos.logback.core.FileAppender">
|
||||
<file>${adminLogFile}</file>
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
</appender>
|
||||
|
||||
|
@ -71,5 +78,6 @@
|
|||
<level value="INFO"/>
|
||||
<appender-ref ref="console"/>
|
||||
<appender-ref ref="errConsole"/>
|
||||
<appender-ref ref="consoleLog"/>
|
||||
</root>
|
||||
</configuration>
|
||||
|
|
|
@ -75,10 +75,11 @@ import com.raytheon.uf.viz.core.VizApp;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 4, 2008 1433 chammack Initial creation
|
||||
* Jun 3, 2013 2026 randerso Improve error handling
|
||||
* May 5, 2015 4473 mschenke Major refactor
|
||||
* Jun 1, 2015 4473 njensen Major refactor, removed send ability
|
||||
* Sep 04, 2008 1433 chammack Initial creation
|
||||
* Jun 03, 2013 2026 randerso Improve error handling
|
||||
* May 05, 2015 4473 mschenke Major refactor
|
||||
* Jun 01, 2015 4473 njensen Major refactor, removed send ability
|
||||
* Jun 29, 2015 4473 njensen Register notification observer on start
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -178,6 +179,7 @@ public class AlertvizJob extends Job implements AlertService {
|
|||
this.broker.setPersistent(false);
|
||||
this.broker.setUseJmx(false);
|
||||
this.port = port;
|
||||
AlertVizNotificationObserver.registerAlertVizNotificationObserver();
|
||||
|
||||
String localIP = "localhost";
|
||||
try {
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Map;
|
|||
import org.eclipse.jface.viewers.ColumnLabelProvider;
|
||||
import org.eclipse.jface.viewers.ILabelProviderListener;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
|
@ -66,6 +67,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.TreeObjectContainer;
|
|||
* Mar 06, 2014 2848 bclement get venueName directly from session
|
||||
* Jun 12, 2014 3267 bclement fixed missing null-check for outdated UI info
|
||||
* Oct 08, 2014 3705 bclement replaced checks for SessionGroupContainer with TreeObjectContainer
|
||||
* Jun 23, 2015 4563 mapeters bold/color users in contacts list if logged-in
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -86,6 +88,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
return connection.getContactsManager().getPresence(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDisplayName(UserId user) {
|
||||
return getLocalAlias(user);
|
||||
}
|
||||
|
@ -136,7 +139,6 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private List<ILabelProviderListener> listeners;
|
||||
|
@ -159,7 +161,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
if (element instanceof UserId) {
|
||||
return userLabelProvider.getImage(element);
|
||||
} else if (element instanceof RosterEntry) {
|
||||
return userLabelProvider.getImage((RosterEntry) element);
|
||||
return userLabelProvider.getImage(element);
|
||||
} else if (element instanceof RosterGroup) {
|
||||
key = "roster_group";
|
||||
} else if (element instanceof SharedGroup) {
|
||||
|
@ -168,7 +170,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
// key = "session_group";
|
||||
} else if (element instanceof TreeObjectContainer) {
|
||||
key = ((TreeObjectContainer) element).getIcon();
|
||||
}
|
||||
}
|
||||
|
||||
if (imageMap.get(key) == null && !key.equals("")) {
|
||||
imageMap.put(key, CollaborationUtils.getNodeImage(key));
|
||||
|
@ -183,7 +185,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
} else if (element instanceof SharedGroup) {
|
||||
return ((SharedGroup) element).getName();
|
||||
} else if (element instanceof RosterEntry) {
|
||||
return userLabelProvider.getText((RosterEntry) element);
|
||||
return userLabelProvider.getText(element);
|
||||
} else if (element instanceof TreeObjectContainer) {
|
||||
return ((TreeObjectContainer) element).getLabel();
|
||||
} else if (element instanceof UserId) {
|
||||
|
@ -211,10 +213,13 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
|
||||
@Override
|
||||
public Font getFont(Object element) {
|
||||
if (element instanceof RosterGroup || element instanceof SharedGroup
|
||||
|| element instanceof TreeObjectContainer) {
|
||||
// for this case do nothing, as it is not the top level of
|
||||
// session groups
|
||||
boolean isGroupTitle = element instanceof RosterGroup
|
||||
|| element instanceof SharedGroup
|
||||
|| element instanceof TreeObjectContainer;
|
||||
boolean isAvailableUser = element instanceof RosterEntry
|
||||
&& userLabelProvider.getPresence(
|
||||
userLabelProvider.convertObject(element)).isAvailable();
|
||||
if (isGroupTitle || isAvailableUser) {
|
||||
if (boldFont == null) {
|
||||
Font currFont = Display.getCurrent().getSystemFont();
|
||||
boldFont = new Font(Display.getCurrent(), currFont.toString(),
|
||||
|
@ -225,6 +230,17 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getForeground(Object element) {
|
||||
if (element instanceof RosterEntry) {
|
||||
UserId user = userLabelProvider.convertObject(element);
|
||||
if (userLabelProvider.getPresence(user).isAvailable()) {
|
||||
return Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tooltip text on the tree that this is a label provider for
|
||||
*/
|
||||
|
@ -234,7 +250,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
if (element instanceof UserId) {
|
||||
return userLabelProvider.getToolTipText(element);
|
||||
} else if (element instanceof RosterEntry) {
|
||||
return userLabelProvider.getToolTipText((RosterEntry) element);
|
||||
return userLabelProvider.getToolTipText(element);
|
||||
}
|
||||
// builds the tooltip text for the session group
|
||||
// portion of the view
|
||||
|
@ -242,10 +258,8 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
IVenueSession sessGroup = (IVenueSession) element;
|
||||
IVenue venue = sessGroup.getVenue();
|
||||
builder.append("ID: ").append(venue.getId());
|
||||
builder.append("\nName: ").append(venue.getName())
|
||||
.append("\n");
|
||||
builder.append("Subject: ").append(venue.getSubject())
|
||||
.append("\n");
|
||||
builder.append("\nName: ").append(venue.getName()).append("\n");
|
||||
builder.append("Subject: ").append(venue.getSubject()).append("\n");
|
||||
builder.append("Participants: ")
|
||||
.append(venue.getParticipantCount());
|
||||
return builder.toString();
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.core.commands.ExecutionEvent;
|
|||
import org.eclipse.core.commands.ExecutionException;
|
||||
import org.eclipse.ui.handlers.HandlerUtil;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
|
@ -49,6 +50,8 @@ import com.raytheon.viz.ui.dialogs.localization.VizLocalizationFileListDlg.Mode;
|
|||
* Jul 8, 2008 #1183 chammack Migrate to new localization
|
||||
* Oct 16, 2012 #1229 rferrel Changes for non-blocking VizLocalizationFileListDlg.
|
||||
* Jun 02, 2015 #4401 bkowal Updated to use {@link VizLocalizationFileListDlg}.
|
||||
* Jun 30, 2015 #4401 bkowal Specify the localization type when constructing a
|
||||
* {@link VizLocalizationFileListDlg}.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -74,7 +77,8 @@ public class DeleteAWIPSProcedure extends AbstractHandler {
|
|||
|| listDlg.isDisposed()) {
|
||||
listDlg = new VizLocalizationFileListDlg("Delete Procedure",
|
||||
HandlerUtil.getActiveShell(event), Mode.DELETE,
|
||||
ProcedureDlg.PROCEDURES_DIR, "procedures");
|
||||
ProcedureDlg.PROCEDURES_DIR, "procedures",
|
||||
LocalizationType.CAVE_STATIC);
|
||||
listDlg.setCloseCallback(new ICloseCallback() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.core.commands.ExecutionEvent;
|
|||
import org.eclipse.core.commands.ExecutionException;
|
||||
import org.eclipse.ui.handlers.HandlerUtil;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.LocalizationUtil;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
|
@ -35,6 +36,7 @@ import com.raytheon.uf.viz.d2d.ui.dialogs.procedures.ProcedureDlg;
|
|||
import com.raytheon.viz.ui.VizWorkbenchManager;
|
||||
import com.raytheon.viz.ui.actions.LoadPerspectiveHandler;
|
||||
import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
||||
import com.raytheon.viz.ui.dialogs.localization.VizLocalizationFileListDlg;
|
||||
import com.raytheon.viz.ui.dialogs.localization.VizOpenLocalizationFileListDlg;
|
||||
|
||||
/**
|
||||
|
@ -52,6 +54,8 @@ import com.raytheon.viz.ui.dialogs.localization.VizOpenLocalizationFileListDlg;
|
|||
* Jun 07, 2013 2074 mnash Don't open the dialog if no procedures are deserialized
|
||||
* Aug 11, 2014 3480 bclement added logging
|
||||
* Jun 02, 2015 #4401 bkowal Updated to use {@link VizOpenLocalizationFileListDlg}.
|
||||
* Jun 30, 2015 #4401 bkowal Specify the localization type when constructing a
|
||||
* {@link VizOpenLocalizationFileListDlg}.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -76,7 +80,8 @@ public class OpenAWIPSProcedure extends AbstractHandler {
|
|||
if (dialog == null || dialog.getShell() == null || dialog.isDisposed()) {
|
||||
dialog = new VizOpenLocalizationFileListDlg("Open Procedure",
|
||||
HandlerUtil.getActiveShell(event),
|
||||
ProcedureDlg.PROCEDURES_DIR, "procedures");
|
||||
ProcedureDlg.PROCEDURES_DIR, "procedures",
|
||||
LocalizationType.CAVE_STATIC);
|
||||
dialog.setCloseCallback(new ICloseCallback() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.swt.widgets.Button;
|
|||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.viz.ui.dialogs.localization.VizLocalizationFileListDlg;
|
||||
|
||||
/**
|
||||
|
@ -43,6 +44,7 @@ import com.raytheon.viz.ui.dialogs.localization.VizLocalizationFileListDlg;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 2, 2015 4401 bkowal Initial creation
|
||||
* Jun 30, 2015 4401 bkowal Specify the localization level during construction.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -67,7 +69,8 @@ public class ProcedureListFileDlg extends VizLocalizationFileListDlg {
|
|||
*/
|
||||
public ProcedureListFileDlg(String title, Shell parent, Mode mode,
|
||||
String localizationDirectory) {
|
||||
super(title, parent, mode, localizationDirectory, "procedures");
|
||||
super(title, parent, mode, localizationDirectory, "procedures",
|
||||
LocalizationType.CAVE_STATIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
<extension
|
||||
point="com.raytheon.viz.ui.contextualMenu">
|
||||
<contextualMenu
|
||||
actionClass="com.raytheon.uf.viz.damagepath.ImportFromDistanceSpeedAction"
|
||||
actionClass="com.raytheon.uf.viz.damagepath.NewTornadoDamagePathAction"
|
||||
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
|
||||
name="Import from Distance Speed Tool"
|
||||
name="New Tornado Damage Path"
|
||||
sortID="4">
|
||||
</contextualMenu>
|
||||
<contextualMenu
|
||||
|
|
|
@ -83,6 +83,7 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
* initInternal.
|
||||
* Jun 18, 2015 4354 dgilling Allow each polygon to have their own
|
||||
* properties.
|
||||
* Jul 01, 2015 4375 dgilling Fix setDefaultPolygon.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -175,7 +176,7 @@ public class DamagePathLayer<T extends DamagePathResourceData> extends
|
|||
Polygon polygon = PolygonUtil.makeDefaultPolygon(getResourceContainer()
|
||||
.getActiveDisplayPane().getRenderableDisplay());
|
||||
DrawablePolygon drawablePolygon = new DamagePathPolygon(polygon, this);
|
||||
polygons.add(0, drawablePolygon);
|
||||
super.resetPolygons(Arrays.asList(drawablePolygon));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.nio.file.Path;
|
|||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -38,7 +37,6 @@ import org.opengis.feature.simple.SimpleFeatureType;
|
|||
import org.opengis.feature.type.Name;
|
||||
|
||||
import com.raytheon.uf.common.json.JsonException;
|
||||
import com.raytheon.uf.common.json.geo.BasicJsonService;
|
||||
import com.raytheon.uf.common.json.geo.GeoJsonMapUtil;
|
||||
import com.raytheon.uf.common.json.geo.IGeoJsonService;
|
||||
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
|
||||
|
@ -47,7 +45,6 @@ import com.raytheon.uf.common.localization.exception.LocalizationException;
|
|||
import com.raytheon.uf.common.util.Pair;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
import com.vividsolutions.jts.operation.valid.IsValidOp;
|
||||
|
||||
/**
|
||||
* Loads a damage path GeoJSON-formatted file from either local disk or the
|
||||
|
@ -62,6 +59,10 @@ import com.vividsolutions.jts.operation.valid.IsValidOp;
|
|||
* Jun 05, 2015 #4375 dgilling Initial creation
|
||||
* Jun 18, 2015 #4354 dgilling Support FeatureCollections so each polygon
|
||||
* can have its own properties.
|
||||
* Jun 30, 2015 #4354 dgilling Remove unnecessary back compat code for
|
||||
* 15.1 version of damage path tool.
|
||||
* Jul 01, 2015 #4375 dgilling Remove isValid check to imported
|
||||
* polygons.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -71,12 +72,8 @@ import com.vividsolutions.jts.operation.valid.IsValidOp;
|
|||
|
||||
public final class DamagePathLoader {
|
||||
|
||||
private static final String UNSUPPORTED_GEOJSON_TYPE = "Damage path file is unsupported GeoJSON object type %s. This tool only supports Feature and Geometry objects.";
|
||||
|
||||
private static final String UNSUPPORTED_GEOM_TYPE = "Damage path file contains invalid geometry type %s at geometry index %d. Must only contain Polygons.";
|
||||
|
||||
private static final String INVALID_POLYGON = "Damage path file contains an invalid Polyon at index %d: %s";
|
||||
|
||||
private final Collection<Pair<Polygon, Map<String, String>>> damagePathData;
|
||||
|
||||
public DamagePathLoader(LocalizationFile locFile)
|
||||
|
@ -119,85 +116,6 @@ public final class DamagePathLoader {
|
|||
}
|
||||
|
||||
private void loadFromInputStream(final InputStream is) throws JsonException {
|
||||
Geometry deserializedGeom = null;
|
||||
Map<String, String> deserializedProps = Collections.emptyMap();
|
||||
GeoJsonMapUtil geoJsonUtil = new GeoJsonMapUtil();
|
||||
|
||||
/*
|
||||
* For compatibility with any users that may have an autosaved damage
|
||||
* path file from previous builds, we'll support deserializing Geometry,
|
||||
* Feature and FeatureCollection GeoJSON types.
|
||||
*
|
||||
* TODO: remove this code for code that just expects the file to always
|
||||
* be a FeatureCollection.
|
||||
*/
|
||||
Map<String, Object> jsonObject = (Map<String, Object>) new BasicJsonService()
|
||||
.deserialize(is, LinkedHashMap.class);
|
||||
String geoJsonType = jsonObject.get(GeoJsonMapUtil.TYPE_KEY).toString();
|
||||
if (geoJsonType.equals(GeoJsonMapUtil.FEATURE_COLL_TYPE)) {
|
||||
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = geoJsonUtil
|
||||
.populateFeatureCollection(jsonObject);
|
||||
populateDataFromFeatureCollection(featureCollection);
|
||||
return;
|
||||
} else if (geoJsonType.equals(GeoJsonMapUtil.FEATURE_TYPE)) {
|
||||
SimpleFeature feature = geoJsonUtil.populateFeature(jsonObject);
|
||||
deserializedGeom = (Geometry) feature.getDefaultGeometry();
|
||||
|
||||
Name defaultGeomAttrib = feature.getDefaultGeometryProperty()
|
||||
.getName();
|
||||
deserializedProps = new LinkedHashMap<>();
|
||||
deserializedProps.put(GeoJsonMapUtil.ID_KEY, feature.getID());
|
||||
for (Property p : feature.getProperties()) {
|
||||
if (!defaultGeomAttrib.equals(p.getName())) {
|
||||
deserializedProps.put(p.getName().toString(), p.getValue()
|
||||
.toString());
|
||||
}
|
||||
}
|
||||
} else if (isGeometryType(geoJsonType)) {
|
||||
deserializedGeom = geoJsonUtil.populateGeometry(jsonObject);
|
||||
} else {
|
||||
throw new JsonException(String.format(UNSUPPORTED_GEOJSON_TYPE,
|
||||
geoJsonType));
|
||||
}
|
||||
|
||||
int numGeometries = deserializedGeom.getNumGeometries();
|
||||
for (int i = 0; i < numGeometries; i++) {
|
||||
Geometry geomN = deserializedGeom.getGeometryN(i);
|
||||
if (geomN instanceof Polygon) {
|
||||
Polygon newPolygon = (Polygon) geomN;
|
||||
IsValidOp validator = new IsValidOp(newPolygon);
|
||||
if (validator.isValid()) {
|
||||
Pair<Polygon, Map<String, String>> polygonAndProps = new Pair<>(
|
||||
newPolygon, deserializedProps);
|
||||
damagePathData.add(polygonAndProps);
|
||||
} else {
|
||||
throw new JsonException(String.format(INVALID_POLYGON, i,
|
||||
validator.getValidationError()));
|
||||
}
|
||||
} else {
|
||||
throw new JsonException(String.format(UNSUPPORTED_GEOM_TYPE,
|
||||
geomN.getGeometryType(), i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGeometryType(String geoJsonType) {
|
||||
return ((GeoJsonMapUtil.GEOM_COLL_TYPE.equals(geoJsonType))
|
||||
|| (GeoJsonMapUtil.LINE_STR_TYPE.equals(geoJsonType))
|
||||
|| (GeoJsonMapUtil.MULT_LINE_STR_TYPE.equals(geoJsonType))
|
||||
|| (GeoJsonMapUtil.MULT_POINT_TYPE.equals(geoJsonType))
|
||||
|| (GeoJsonMapUtil.MULT_POLY_TYPE.equals(geoJsonType))
|
||||
|| (GeoJsonMapUtil.POINT_TYPE.equals(geoJsonType)) || (GeoJsonMapUtil.POLY_TYPE
|
||||
.equals(geoJsonType)));
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Replace loadFromInputStream with this method when we no longer
|
||||
* desire supporting the version 15.1 GeoJSON formatted damage path files.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void loadFromInputStreamFuture(final InputStream is)
|
||||
throws JsonException {
|
||||
IGeoJsonService json = new SimpleGeoJsonService();
|
||||
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = json
|
||||
.deserializeFeatureCollection(is);
|
||||
|
@ -215,12 +133,6 @@ public final class DamagePathLoader {
|
|||
Geometry geom = (Geometry) feature.getDefaultGeometry();
|
||||
if (geom instanceof Polygon) {
|
||||
Polygon newPolygon = (Polygon) geom;
|
||||
IsValidOp validator = new IsValidOp(newPolygon);
|
||||
if (!validator.isValid()) {
|
||||
throw new JsonException(String.format(INVALID_POLYGON,
|
||||
featureIdx, validator.getValidationError()));
|
||||
}
|
||||
|
||||
Map<String, String> properties = new LinkedHashMap<>();
|
||||
Name defaultGeomAttrib = feature
|
||||
.getDefaultGeometryProperty().getName();
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.util.Collections;
|
|||
import java.util.Map;
|
||||
|
||||
import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon;
|
||||
import com.raytheon.uf.viz.drawing.polygon.PolygonLayer;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
|
@ -37,6 +36,7 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 18, 2015 #4354 dgilling Initial creation
|
||||
* Jun 30, 2015 #4354 dgilling Force setProperties to trigger a save.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -51,23 +51,23 @@ public class DamagePathPolygon extends DrawablePolygon {
|
|||
|
||||
private Map<String, String> properties;
|
||||
|
||||
public DamagePathPolygon(PolygonLayer<?> polygonLayer) {
|
||||
super(polygonLayer);
|
||||
public DamagePathPolygon(DamagePathLayer<?> layer) {
|
||||
super(layer);
|
||||
this.properties = DEFAULT_PROPS;
|
||||
}
|
||||
|
||||
public DamagePathPolygon(Polygon polygon, PolygonLayer<?> polygonLayer) {
|
||||
this(polygon, DEFAULT_PROPS, polygonLayer);
|
||||
public DamagePathPolygon(Polygon polygon, DamagePathLayer<?> layer) {
|
||||
this(polygon, DEFAULT_PROPS, layer);
|
||||
}
|
||||
|
||||
public DamagePathPolygon(Polygon polygon, Map<String, String> properties,
|
||||
PolygonLayer<?> polygonLayer) {
|
||||
super(polygon, polygonLayer);
|
||||
DamagePathLayer<?> layer) {
|
||||
super(polygon, layer);
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public DamagePathPolygon(Coordinate[] coords, PolygonLayer<?> polygonLayer) {
|
||||
super(coords, polygonLayer);
|
||||
public DamagePathPolygon(Coordinate[] coords, DamagePathLayer<?> layer) {
|
||||
super(coords, layer);
|
||||
this.properties = DEFAULT_PROPS;
|
||||
}
|
||||
|
||||
|
@ -87,5 +87,6 @@ public class DamagePathPolygon extends DrawablePolygon {
|
|||
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
((DamagePathLayer<?>) polygonLayer).scheduleSaveJob();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,67 +19,89 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.damagepath;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
import javax.measure.quantity.Length;
|
||||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
import javax.measure.unit.Unit;
|
||||
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.radar.RadarStation;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.AbstractStormTrackResource;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState.StormCoord;
|
||||
import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer.Baseline;
|
||||
import com.raytheon.viz.radar.util.StationUtils;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.Point;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* Utility class for Damage Paths.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 23, 2015 3977 nabowle Initial creation
|
||||
* Mar 26, 2015 3977 nabowle Limit distance to avoid polar errors. Log
|
||||
* skipped points.
|
||||
* Apr 01, 2015 3977 nabowle rename the status handler.
|
||||
*
|
||||
* Jun 18, 2015 3977 nabowle Fix buffering. Renamed mehtods to
|
||||
* specify that they're for Tornados.
|
||||
* Jun 25, 2015 3977 nabowle Redo inner-point buffering for use with
|
||||
* Interactive Baselines.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
public class DamagePathUtils {
|
||||
|
||||
/**
|
||||
* The number of degrees between points at the ends of a Tornado Damage Path
|
||||
* Buffer.
|
||||
*/
|
||||
private static final double END_DEGREE_DIFF = 30.0D;
|
||||
|
||||
/** Upper degree boundary to define a sharp angle. */
|
||||
private static final double SHARP_ANGLE = 100;
|
||||
|
||||
/** Lower degree boundary when a sharp angle straddles 0 degrees. */
|
||||
private static final double SHARP_ANGLE_INV = 360 - SHARP_ANGLE;
|
||||
|
||||
private static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(DamagePathUtils.class);
|
||||
|
||||
/** The unit for the uncertainty algorithm. */
|
||||
private static Unit<Length> TARGET_UNIT = NonSI.MILE;
|
||||
/** Convert miles for the algorithm to meters. */
|
||||
private static UnitConverter TO_METERS = NonSI.MILE
|
||||
.getConverterTo(SI.METER);
|
||||
|
||||
/** Convert meters returned the GeodeticCalculator to the desired unit. */
|
||||
private static UnitConverter METERS_TO = SI.METER
|
||||
.getConverterTo(TARGET_UNIT);
|
||||
/*
|
||||
* Pre-convert algorithm constants to meters to prevent having to convert
|
||||
* back and forth.
|
||||
*/
|
||||
private static final double ONE_TENTH_MILE = TO_METERS.convert(0.1);
|
||||
|
||||
private static final double THREE_TENTHS_MILE = TO_METERS.convert(0.3);
|
||||
|
||||
private static final double FORTY_MILES = TO_METERS.convert(40.0);
|
||||
|
||||
private static final double EIGHTY_MILES = TO_METERS.convert(80.0);
|
||||
|
||||
/**
|
||||
* Maximum distance of a point to the radar station to use when estimating a
|
||||
* damage path polygon. Any farther point will be ignored.
|
||||
* damage path polygon. Any farther point will be ignored. Based on radar
|
||||
* max extent
|
||||
*/
|
||||
private static final double MAX_DISTANCE = NonSI.MILE.getConverterTo(
|
||||
TARGET_UNIT).convert(300.0); // Based on radar max extent
|
||||
private static final double MAX_DISTANCE = TO_METERS.convert(300.0);
|
||||
|
||||
private DamagePathUtils() {
|
||||
super();
|
||||
|
@ -87,129 +109,405 @@ public class DamagePathUtils {
|
|||
|
||||
|
||||
/**
|
||||
* Estimates the damage path polygon for a storm track.
|
||||
* Estimates a Tornado damage path polygon for a baseline.
|
||||
*
|
||||
* @param stormTrack
|
||||
* The storm track to create a damage path for.
|
||||
* @return The estimated damage path polygon for a storm track.
|
||||
* @param baseline
|
||||
* The baseline to create a tornado damage path for.
|
||||
* @return The estimated tornado damage path polygon for a baseline.
|
||||
*/
|
||||
public static Polygon estimateDamagePath(
|
||||
AbstractStormTrackResource stormTrack) {
|
||||
|
||||
StormTrackState stState = stormTrack.getStormTrackState();
|
||||
public static Polygon estimateTornadoDamagePath(Baseline baseline) {
|
||||
|
||||
Coordinate[] coords = baseline.line.getCoordinates();
|
||||
RadarStation station = StationUtils.getInstance().getHomeRadarStation();
|
||||
GeometryFactory gf = new GeometryFactory();
|
||||
|
||||
List<StormTrackState.StormCoord> skippedCoords = new ArrayList<>();
|
||||
Geometry damagePathBuffer = createBuffer(stState.timePoints, station,
|
||||
gf, null, skippedCoords);
|
||||
damagePathBuffer = createBuffer(stState.futurePoints, station, gf,
|
||||
damagePathBuffer, skippedCoords);
|
||||
List<Coordinate> skippedCoords = new ArrayList<>();
|
||||
List<Coordinate> validCoords = new ArrayList<>();
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
filterCoords(coords, station, skippedCoords, validCoords,
|
||||
gc);
|
||||
|
||||
if (!skippedCoords.isEmpty()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Skipped the following Storm Coordinates because they ")
|
||||
sb.append(
|
||||
"Skipped the following Coordinates for Baseline "
|
||||
+ baseline.name + " because they ")
|
||||
.append("are out of range of the radar station. ");
|
||||
for (StormTrackState.StormCoord coord : skippedCoords) {
|
||||
sb.append("(").append(coord.time.toString()).append(", ")
|
||||
.append(coord.coord.x).append(", ")
|
||||
.append(coord.coord.y).append(") ");
|
||||
for (Coordinate coord : skippedCoords) {
|
||||
sb.append("(").append(coord.x).append(", ").append(coord.y)
|
||||
.append(") ");
|
||||
}
|
||||
statusHandler.info(sb.toString());
|
||||
}
|
||||
|
||||
/*
|
||||
* user likely tried to import before creating track or entire track is
|
||||
* outside of the max range.
|
||||
*/
|
||||
if (damagePathBuffer == null) {
|
||||
if (validCoords.isEmpty()) {
|
||||
String suggestion;
|
||||
if (skippedCoords.isEmpty()) {
|
||||
suggestion = "Make sure the storm track is initialized.";
|
||||
suggestion = "Make sure the baseline is initialized.";
|
||||
} else {
|
||||
suggestion = "Make sure the storm track is within range of the radar station.";
|
||||
suggestion = "Make sure the baseline is within range of the radar station.";
|
||||
}
|
||||
statusHandler
|
||||
.warn("Could not create a Damage Path polygon for the storm track. "
|
||||
+ suggestion);
|
||||
.warn("Could not create a Damage Path polygon for Baseline "
|
||||
+ baseline.name + ". " + suggestion);
|
||||
return null;
|
||||
}
|
||||
|
||||
Polygon polygon = gf.createPolygon(damagePathBuffer.convexHull()
|
||||
.getCoordinates());
|
||||
Coordinate[] damagePathCoords = createTornadoBuffer(validCoords, station, gc,
|
||||
gf);
|
||||
|
||||
Polygon polygon = gf.createPolygon(damagePathCoords);
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a buffers a buffer around the storm coordinates. If
|
||||
* damagePathBuffer is non null, the created buffer will be the union of the
|
||||
* two buffers.
|
||||
* Filter the coordinates based on their range to the given radar station.
|
||||
*
|
||||
* @param stormCoords
|
||||
* The storm track coordinates.
|
||||
* The coordinates.
|
||||
* @param station
|
||||
* The station to base distance on.
|
||||
* @param gf
|
||||
* The geometry factory.
|
||||
* @param damagePathBuffer
|
||||
* The current damage path buffer. May be null.
|
||||
* @param farCoords
|
||||
* The list to add any skipped coordinates to.
|
||||
* @return The created buffer. If damagePathBuffer is not null, the created
|
||||
* buffer will included damagePathBuffer.
|
||||
* The radar station.
|
||||
* @param skippedCoords
|
||||
* A list where coordinates that are out of range of the station
|
||||
* will be added to.
|
||||
* @param validCoords
|
||||
* A list where coordinates that are in range of the station will
|
||||
* be added to.
|
||||
* @param gc
|
||||
* A GeodeticCalculator.
|
||||
*/
|
||||
private static Geometry createBuffer(
|
||||
StormTrackState.StormCoord[] stormCoords, RadarStation station,
|
||||
GeometryFactory gf, Geometry damagePathBuffer,
|
||||
List<StormCoord> farCoords) {
|
||||
if (stormCoords == null || stormCoords.length == 0) {
|
||||
return damagePathBuffer;
|
||||
}
|
||||
private static void filterCoords(Coordinate[] stormCoords,
|
||||
RadarStation station, List<Coordinate> skippedCoords,
|
||||
List<Coordinate> validCoords, GeodeticCalculator gc) {
|
||||
Coordinate stormCoord;
|
||||
double distance;
|
||||
if (stormCoords != null) {
|
||||
for (int i = 0; i < stormCoords.length; i++) {
|
||||
stormCoord = stormCoords[i];
|
||||
gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y);
|
||||
gc.setDestinationGeographicPoint(station.getLon(),
|
||||
station.getLat());
|
||||
distance = gc.getOrthodromicDistance();
|
||||
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
Point point;
|
||||
Geometry buffer;
|
||||
double distanceMeters; // distance in meters
|
||||
double distance; // distance in the desired unit
|
||||
if (distance > MAX_DISTANCE) {
|
||||
skippedCoords.add(stormCoords[i]);
|
||||
} else {
|
||||
validCoords.add(stormCoords[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a buffer around the line defined by the storm coordinates using
|
||||
* Doug Speheger's tornado damage path algorithm.
|
||||
*
|
||||
* @param stormCoords
|
||||
* The storm coordinates to create a damage path around.
|
||||
* @param station
|
||||
* The radar station to use.
|
||||
* @param gc
|
||||
* A GeodeticCalculator.
|
||||
* @param gf
|
||||
* A GeometryFactory.
|
||||
* @return A Geometry representing an estimated Tornado Damage Path for the
|
||||
* given storm coordinates. If the no coordinates are provided, null
|
||||
* is returned.
|
||||
*/
|
||||
private static Coordinate[] createTornadoBuffer(List<Coordinate> stormCoords,
|
||||
RadarStation station, GeodeticCalculator gc, GeometryFactory gf) {
|
||||
// left hand side points
|
||||
List<Point2D> lhsPoints = new ArrayList<>();
|
||||
// right hand side points
|
||||
Deque<Point2D> rhsPoints = new ArrayDeque<>();
|
||||
double uncertainty;
|
||||
Coordinate stormCoord;
|
||||
for (int i = 0; i < stormCoords.length; i++) {
|
||||
stormCoord = stormCoords[i].coord;
|
||||
gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y);
|
||||
gc.setDestinationGeographicPoint(station.getLon(), station.getLat());
|
||||
distanceMeters = gc.getOrthodromicDistance();
|
||||
distance = METERS_TO.convert(distanceMeters);
|
||||
/* Create a concave hull for a linear set of coordinates. */
|
||||
for (int i = 0; i < stormCoords.size(); i++) {
|
||||
stormCoord = stormCoords.get(i);
|
||||
uncertainty = calculateUncertainty(station, gc, stormCoord);
|
||||
|
||||
if (distance > MAX_DISTANCE) {
|
||||
farCoords.add(stormCoords[i]);
|
||||
continue;
|
||||
if (stormCoords.size() == 1) {
|
||||
/*
|
||||
* In the case that there's only one coordinate, draw a circle
|
||||
* around the point and break out.
|
||||
*/
|
||||
for (double d = -180; d < 180; d += END_DEGREE_DIFF) {
|
||||
gc.setDirection(d, uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Based off of research done by Doug Speheger comparing surveyed
|
||||
* tornado paths to manually identified radar tornadic vortex
|
||||
* signatures in 2008-2012. In the initial dataset, 87% of tornadoes
|
||||
* were within this range of uncertainty.
|
||||
*/
|
||||
if (distance < 40.0) {
|
||||
uncertainty = 0.3 + distance * 0.005;
|
||||
} else if (distance < 80.0) {
|
||||
uncertainty = 0.1 + distance * 0.01;
|
||||
if (i == 0) {
|
||||
createStartCap(stormCoords, gc, lhsPoints, uncertainty, i);
|
||||
} else if (i < stormCoords.size() - 1) {
|
||||
bufferInnerPoint(stormCoord, stormCoords, gc, lhsPoints,
|
||||
rhsPoints, uncertainty, i, station);
|
||||
} else {
|
||||
uncertainty = distance * 0.015 - 0.3;
|
||||
createEndCap(stormCoords, gc, rhsPoints, uncertainty, i);
|
||||
}
|
||||
|
||||
point = gf.createPoint(stormCoord);
|
||||
buffer = point.buffer(uncertainty);
|
||||
if (damagePathBuffer == null) {
|
||||
damagePathBuffer = buffer;
|
||||
} else {
|
||||
damagePathBuffer = damagePathBuffer.union(buffer);
|
||||
}
|
||||
}
|
||||
return damagePathBuffer;
|
||||
lhsPoints.addAll(rhsPoints);
|
||||
|
||||
Coordinate[] coordinates = new Coordinate[lhsPoints.size() + 1];
|
||||
Point2D point;
|
||||
for (int i = 0; i < lhsPoints.size(); i++) {
|
||||
point = lhsPoints.get(i);
|
||||
coordinates[i] = new Coordinate(point.getX(), point.getY());
|
||||
}
|
||||
coordinates[coordinates.length - 1] = coordinates[0];
|
||||
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Based off of research done by Doug Speheger comparing surveyed tornado
|
||||
* paths to manually identified radar tornadic vortex signatures in
|
||||
* 2008-2012. In the initial dataset, 87% of tornadoes were within this
|
||||
* range of uncertainty.
|
||||
*
|
||||
* Note: All units are in meters. Constants have been pre-converted from
|
||||
* miles to meters.
|
||||
*
|
||||
* @param station
|
||||
* @param gc
|
||||
* @param coord
|
||||
* @return
|
||||
*/
|
||||
private static double calculateUncertainty(RadarStation station,
|
||||
GeodeticCalculator gc, Coordinate coord) {
|
||||
gc.setStartingGeographicPoint(coord.x, coord.y);
|
||||
gc.setDestinationGeographicPoint(station.getLon(), station.getLat());
|
||||
double distance = gc.getOrthodromicDistance();
|
||||
|
||||
double uncertainty;
|
||||
if (distance < FORTY_MILES) {
|
||||
uncertainty = THREE_TENTHS_MILE + distance * 0.005;
|
||||
} else if (distance < EIGHTY_MILES) {
|
||||
uncertainty = ONE_TENTH_MILE + distance * 0.01;
|
||||
} else {
|
||||
uncertainty = distance * 0.015 - THREE_TENTHS_MILE;
|
||||
}
|
||||
return uncertainty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a buffer around a non-end point. If the path is on a generally
|
||||
* straight path, just create two points on opposite sides of the path
|
||||
* point. If the path coordinate is the vertex of an angle is sharp, create
|
||||
* a couple points around the outside of the angle and create a single point
|
||||
* on the inside that's uncertainty-meters from the point and both lines
|
||||
* creating the angle.
|
||||
*
|
||||
* @param stormCoord
|
||||
* @param stormCoords
|
||||
* @param gc
|
||||
* @param lhsPoints
|
||||
* @param rhsPoints
|
||||
* @param uncertainty
|
||||
* @param i
|
||||
* @param station
|
||||
*/
|
||||
private static void bufferInnerPoint(Coordinate stormCoord,
|
||||
List<Coordinate> stormCoords, GeodeticCalculator gc,
|
||||
List<Point2D> lhsPoints, Deque<Point2D> rhsPoints,
|
||||
double uncertainty, int i, RadarStation station) {
|
||||
gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y);
|
||||
|
||||
Coordinate nextCoord = stormCoords.get(i + 1);
|
||||
gc.setDestinationGeographicPoint(nextCoord.x, nextCoord.y);
|
||||
double azimuthToNext = nonNegativeAzimuth(gc.getAzimuth());
|
||||
|
||||
Coordinate prevCoord = stormCoords.get(i - 1);
|
||||
gc.setDestinationGeographicPoint(prevCoord.x, prevCoord.y);
|
||||
double azimuthToPrev = nonNegativeAzimuth(gc.getAzimuth());
|
||||
|
||||
double angle = Math.abs(azimuthToPrev - azimuthToNext);
|
||||
boolean sharpAngle = (angle <= SHARP_ANGLE && angle > 0)
|
||||
|| (angle >= SHARP_ANGLE_INV && angle < 360);
|
||||
|
||||
if (sharpAngle) {
|
||||
boolean rhsOnInside = angle <= SHARP_ANGLE ? azimuthToNext < azimuthToPrev
|
||||
: azimuthToPrev < azimuthToNext;
|
||||
double bisectionAngle = Math
|
||||
.toRadians(angle >= SHARP_ANGLE_INV ? (360.0 - angle) / 2
|
||||
: angle / 2);
|
||||
|
||||
gc.setDirection(geodeticAzimuth(azimuthToNext + 180), uncertainty);
|
||||
if (rhsOnInside) {
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
|
||||
createOpposingPoints(stormCoord, gc, lhsPoints,
|
||||
new ArrayDeque<Point2D>(), uncertainty, azimuthToNext,
|
||||
azimuthToPrev);
|
||||
double innerUncertainty = Math.abs(uncertainty
|
||||
/ Math.sin(bisectionAngle));
|
||||
if (innerUncertainty < uncertainty) {
|
||||
innerUncertainty = uncertainty;
|
||||
}
|
||||
createOpposingPoints(stormCoord, gc, new ArrayList<Point2D>(),
|
||||
rhsPoints, innerUncertainty, azimuthToNext,
|
||||
azimuthToPrev);
|
||||
|
||||
gc.setDirection(geodeticAzimuth(azimuthToPrev + 180),
|
||||
uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
|
||||
} else {
|
||||
rhsPoints.push(gc.getDestinationGeographicPoint());
|
||||
|
||||
createOpposingPoints(stormCoord, gc, new ArrayList<Point2D>(),
|
||||
rhsPoints, uncertainty, azimuthToNext, azimuthToPrev);
|
||||
double innerUncertainty = Math.abs(uncertainty
|
||||
/ Math.sin(bisectionAngle));
|
||||
if (innerUncertainty < uncertainty) {
|
||||
innerUncertainty = uncertainty;
|
||||
}
|
||||
createOpposingPoints(stormCoord, gc, lhsPoints,
|
||||
new ArrayDeque<Point2D>(), innerUncertainty,
|
||||
azimuthToNext, azimuthToPrev);
|
||||
|
||||
gc.setDirection(geodeticAzimuth(azimuthToPrev + 180),
|
||||
uncertainty);
|
||||
rhsPoints.push(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
} else {
|
||||
createOpposingPoints(stormCoord, gc, lhsPoints, rhsPoints, uncertainty,
|
||||
azimuthToNext, azimuthToPrev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create two points at 180 degrees from each other on the imaginary line
|
||||
* that bisects the angle created at this point.
|
||||
*
|
||||
* @param coord
|
||||
* @param gc
|
||||
* @param lhsPoints
|
||||
* @param rhsPoints
|
||||
* @param uncertainty
|
||||
* @param azimuthToNext
|
||||
* @param azimuthToPrev
|
||||
*/
|
||||
private static void createOpposingPoints(Coordinate coord,
|
||||
GeodeticCalculator gc,
|
||||
List<Point2D> lhsPoints, Deque<Point2D> rhsPoints,
|
||||
double uncertainty, double azimuthToNext, double azimuthToPrev) {
|
||||
gc.setStartingGeographicPoint(coord.x, coord.y);
|
||||
double pointAzimuth = geodeticAzimuth(Math.min(azimuthToNext,
|
||||
azimuthToPrev)
|
||||
+ Math.abs(azimuthToPrev - azimuthToNext) / 2);
|
||||
|
||||
if (azimuthToNext <= azimuthToPrev) {
|
||||
pointAzimuth = geodeticAzimuth(pointAzimuth + 180);
|
||||
}
|
||||
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
|
||||
pointAzimuth = geodeticAzimuth(pointAzimuth + 180);
|
||||
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
rhsPoints.push(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create's a curved half-circle buffer around the starting coordinate.
|
||||
*
|
||||
* @param stormCoords
|
||||
* @param gc
|
||||
* @param lhsPoints
|
||||
* @param uncertainty
|
||||
* @param i
|
||||
*/
|
||||
private static void createStartCap(List<Coordinate> stormCoords,
|
||||
GeodeticCalculator gc, List<Point2D> lhsPoints, double uncertainty,
|
||||
int i) {
|
||||
Coordinate nextCoord = stormCoords.get(i + 1);
|
||||
gc.setDestinationGeographicPoint(nextCoord.x, nextCoord.y);
|
||||
double azimuthToNext = gc.getAzimuth();
|
||||
|
||||
double pointAzimuth = geodeticAzimuth(azimuthToNext + 90);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
|
||||
for (double d = END_DEGREE_DIFF; d <= 180; d += END_DEGREE_DIFF) {
|
||||
pointAzimuth = geodeticAzimuth(pointAzimuth + END_DEGREE_DIFF);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create's a curved half-circle buffer around the ending coordinate.
|
||||
*
|
||||
* @param stormCoords
|
||||
* @param gc
|
||||
* @param rhsPoints
|
||||
* @param uncertainty
|
||||
* @param i
|
||||
*/
|
||||
private static void createEndCap(List<Coordinate> stormCoords,
|
||||
GeodeticCalculator gc, Deque<Point2D> rhsPoints,
|
||||
double uncertainty, int i) {
|
||||
Coordinate prevCoord = stormCoords.get(i - 1);
|
||||
gc.setDestinationGeographicPoint(prevCoord.x, prevCoord.y);
|
||||
double azimuthToPrev = gc.getAzimuth();
|
||||
|
||||
double pointAzimuth = geodeticAzimuth(azimuthToPrev - 90);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
rhsPoints.push(gc.getDestinationGeographicPoint());
|
||||
|
||||
for (double d = END_DEGREE_DIFF; d <= 180; d += END_DEGREE_DIFF) {
|
||||
pointAzimuth = geodeticAzimuth(pointAzimuth - END_DEGREE_DIFF);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
rhsPoints.push(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps the azimuth to [-180, 180] for use with the GeodeticCalculator.
|
||||
*
|
||||
* @param azimuth
|
||||
* The azimuth.
|
||||
* @return An equivalent azimuth in [-180, 180].
|
||||
*/
|
||||
private static double geodeticAzimuth(double azimuth) {
|
||||
double az = azimuth;
|
||||
while (az < -180.0) {
|
||||
az += 360.0;
|
||||
}
|
||||
|
||||
while (az > 180.0) {
|
||||
az -= 360.0;
|
||||
}
|
||||
|
||||
return az;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps the azimuth to [0, 360] to simplify the azimath.
|
||||
*
|
||||
* @param azimuth
|
||||
* The azimuth.
|
||||
* @return An equivalent azimuth in [0, 360].
|
||||
*/
|
||||
private static double nonNegativeAzimuth(double azimuth) {
|
||||
double az = azimuth;
|
||||
while (az < 0) {
|
||||
az += 360.0;
|
||||
}
|
||||
|
||||
while (az > 360.0) {
|
||||
az -= 360.0;
|
||||
}
|
||||
|
||||
return az;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.damagepath;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
|
||||
import com.raytheon.viz.awipstools.ui.layer.DistanceSpeedLayer;
|
||||
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* Action to create a damage path from a DistanceSpeedLayer.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 23, 2015 3977 nabowle Initial creation
|
||||
* Jun 01, 2015 3975 dgilling Update for DamageLayer changes for
|
||||
* multiple polygon support.
|
||||
* Jun 18, 2015 4354 dgilling Update isEnabled to consider editable
|
||||
* capability.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ImportFromDistanceSpeedAction extends AbstractRightClickAction {
|
||||
|
||||
protected static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ImportFromDistanceSpeedAction.class);
|
||||
|
||||
public ImportFromDistanceSpeedAction() {
|
||||
super("New from Distance Speed Tool");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
VizApp.runSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
||||
DistanceSpeedLayer dsLayer = findImportLayer(layer);
|
||||
|
||||
// The Distance Speed tool has not been loaded.
|
||||
if (dsLayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon polygon = DamagePathUtils.estimateDamagePath(dsLayer);
|
||||
|
||||
if (polygon != null) {
|
||||
layer.addPolygon(polygon.getExteriorRing().getCoordinates());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff super.isEnabled() is true and the DistanceSpeed tool is
|
||||
* loaded, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
AbstractVizResource<?, ?> rsc = getSelectedRsc();
|
||||
boolean enabled = rsc.getCapability(EditableCapability.class)
|
||||
.isEditable();
|
||||
if (enabled) {
|
||||
if (rsc != null) {
|
||||
enabled = findImportLayer(rsc) != null;
|
||||
}
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the DistanceSpeedLayer.
|
||||
*
|
||||
* @param rsc
|
||||
* The current resource
|
||||
* @return The found DistanceSpeedLayer, or null if the tool is not loaded.
|
||||
*/
|
||||
private DistanceSpeedLayer findImportLayer(AbstractVizResource<?, ?> rsc) {
|
||||
ResourceList resources = rsc.getDescriptor().getResourceList();
|
||||
for (ResourcePair rp : resources) {
|
||||
if (rp.getResource() instanceof DistanceSpeedLayer) {
|
||||
return (DistanceSpeedLayer) rp.getResource();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.damagepath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.action.ActionContributionItem;
|
||||
import org.eclipse.jface.action.IMenuCreator;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
|
||||
import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer;
|
||||
import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer.Baseline;
|
||||
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* Action to create a tornado damage path from an InteractiveBaselineLayer.
|
||||
*
|
||||
* Adds a menu item to the DamagePath's legend right-click menu which has a
|
||||
* submenu to select one of the available baselines.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 23, 2015 3977 nabowle Initial creation
|
||||
* Jun 01, 2015 3975 dgilling Update for DamageLayer changes for
|
||||
* multiple polygon support.
|
||||
* Jun 18, 2015 4354 dgilling Update isEnabled to consider editable
|
||||
* capability.
|
||||
* Jun 19, 2015 3977 nabowle Specify Tornado Path.
|
||||
* Jun 23, 2015 3977 nabowle Switch to InteractiveBaselineLayer.
|
||||
* Renamed from ImportFromDistanceSpeedAction.
|
||||
* </pre>
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class NewTornadoDamagePathAction extends AbstractRightClickAction
|
||||
implements IMenuCreator {
|
||||
|
||||
protected static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(NewTornadoDamagePathAction.class);
|
||||
|
||||
private Menu menu;
|
||||
|
||||
public NewTornadoDamagePathAction() {
|
||||
super("New Tornado Path from Baseline", SWT.DROP_DOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(Control parent) {
|
||||
if (menu != null) {
|
||||
menu.dispose();
|
||||
}
|
||||
|
||||
menu = new Menu(parent);
|
||||
createMenu(menu);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (menu != null) {
|
||||
menu.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menu getMenu(Menu parent) {
|
||||
if (menu != null) {
|
||||
menu.dispose();
|
||||
}
|
||||
|
||||
createMenu(parent);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMenuCreator getMenuCreator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a submenu with every displayed baseline, listed in alphabetical
|
||||
* order.
|
||||
*
|
||||
* @param parent
|
||||
*/
|
||||
private void createMenu(Menu parent) {
|
||||
menu = new Menu(parent);
|
||||
InteractiveBaselinesLayer ibl = findImportLayer(getSelectedRsc());
|
||||
if (ibl == null || ibl.getCurrentBaselines() == null) {
|
||||
return;
|
||||
}
|
||||
List<Baseline> baselines = new ArrayList<>(Arrays.asList(ibl
|
||||
.getCurrentBaselines()));
|
||||
Collections.sort(baselines, new Comparator<Baseline>() {
|
||||
@Override
|
||||
public int compare(Baseline b1, Baseline b2) {
|
||||
return b1.name.compareTo(b2.name);
|
||||
}
|
||||
});
|
||||
|
||||
for (Baseline baseline : baselines) {
|
||||
ActionContributionItem aci = new ActionContributionItem(
|
||||
new ImportFromBaselineInternalAction(baseline));
|
||||
aci.fill(menu, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
AbstractVizResource<?, ?> rsc = getSelectedRsc();
|
||||
boolean enabled = rsc.getCapability(EditableCapability.class)
|
||||
.isEditable();
|
||||
if (enabled) {
|
||||
if (rsc != null) {
|
||||
enabled = findImportLayer(rsc) != null;
|
||||
}
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the import layer.
|
||||
*
|
||||
* @param rsc
|
||||
* The current resource
|
||||
* @return The found import layer, or null if the tool is not loaded.
|
||||
*/
|
||||
private InteractiveBaselinesLayer findImportLayer(
|
||||
AbstractVizResource<?, ?> rsc) {
|
||||
ResourceList resources = rsc.getDescriptor().getResourceList();
|
||||
for (ResourcePair rp : resources) {
|
||||
if (rp.getResource() instanceof InteractiveBaselinesLayer) {
|
||||
return (InteractiveBaselinesLayer) rp.getResource();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submenu actions for each available baseline.
|
||||
*
|
||||
* Each action is created with one of the available baselines, which when
|
||||
* run will generate a Tornado damage path for that baseline.
|
||||
*/
|
||||
private class ImportFromBaselineInternalAction extends Action {
|
||||
final Baseline baseline;
|
||||
|
||||
public ImportFromBaselineInternalAction(Baseline line) {
|
||||
super(line.name, Action.AS_PUSH_BUTTON);
|
||||
this.baseline = line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
VizApp.runSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
||||
|
||||
Polygon polygon = DamagePathUtils
|
||||
.estimateTornadoDamagePath(baseline);
|
||||
|
||||
if (polygon != null) {
|
||||
layer.addPolygon(polygon.getExteriorRing()
|
||||
.getCoordinates());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getContainer().refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return baseline.name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -41,6 +41,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
|||
* Jun 09, 2015 #4355 dgilling Rename action for UI.
|
||||
* Jun 18, 2015 #4354 dgilling Allow individual properties object for
|
||||
* each polygon.
|
||||
* Jun 30, 2015 #4354 dgilling Fix NullPointerException.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -65,7 +66,6 @@ public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction {
|
|||
Shell shell = VizWorkbenchManager.getInstance()
|
||||
.getCurrentWindow().getShell();
|
||||
|
||||
final DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
||||
final Map<String, String> geoJsonProps = damagePath
|
||||
.getProperties();
|
||||
EditGeoJsonPropertiesDlg dlg = new EditGeoJsonPropertiesDlg(
|
||||
|
@ -78,7 +78,6 @@ public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction {
|
|||
&& (!geoJsonProps.equals(returnValue))) {
|
||||
Map<String, String> updatedProperties = (Map<String, String>) returnValue;
|
||||
damagePath.setProperties(updatedProperties);
|
||||
layer.scheduleSaveJob();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
|
||||
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
|
||||
|
||||
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
|
||||
This_software_product_contains_export-restricted_data_whose
|
||||
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
|
||||
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
|
||||
an_export_license_or_other_authorization.
|
||||
|
||||
Contractor_Name:________Raytheon_Company
|
||||
Contractor_Address:_____6825_Pine_Street,_Suite_340
|
||||
________________________Mail_Stop_B8
|
||||
________________________Omaha,_NE_68106
|
||||
________________________402.291.0100
|
||||
|
||||
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
|
||||
further_licensing_information.
|
||||
-->
|
||||
<DerivedParameter abbreviation="DIRC" name="Current Direction"
|
||||
unit="°"
|
||||
>
|
||||
<Method name="Direction">
|
||||
<Field abbreviation="UOGRD" />
|
||||
<Field abbreviation="VOGRD" />
|
||||
</Method>
|
||||
<Method name="Direction">
|
||||
<Field abbreviation="OGRD" />
|
||||
</Method>
|
||||
</DerivedParameter>
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
|
||||
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
|
||||
|
||||
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
|
||||
This_software_product_contains_export-restricted_data_whose
|
||||
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
|
||||
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
|
||||
an_export_license_or_other_authorization.
|
||||
|
||||
Contractor_Name:________Raytheon_Company
|
||||
Contractor_Address:_____6825_Pine_Street,_Suite_340
|
||||
________________________Mail_Stop_B8
|
||||
________________________Omaha,_NE_68106
|
||||
________________________402.291.0100
|
||||
|
||||
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
|
||||
further_licensing_information.
|
||||
-->
|
||||
<DerivedParameter unit="" name="Max 1hr Lightning Threat (flashes/km^2)" abbreviation="LTNG">
|
||||
<Method name="Alias">
|
||||
<Field abbreviation="LTNG1hr"/>
|
||||
</Method>
|
||||
</DerivedParameter>
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
|
||||
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
|
||||
|
||||
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
|
||||
This_software_product_contains_export-restricted_data_whose
|
||||
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
|
||||
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
|
||||
an_export_license_or_other_authorization.
|
||||
|
||||
Contractor_Name:________Raytheon_Company
|
||||
Contractor_Address:_____6825_Pine_Street,_Suite_340
|
||||
________________________Mail_Stop_B8
|
||||
________________________Omaha,_NE_68106
|
||||
________________________402.291.0100
|
||||
|
||||
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
|
||||
further_licensing_information.
|
||||
-->
|
||||
<DerivedParameter abbreviation="MXDVV" name="Max 1hr Downdraft Vertical Velocity" unit="m/s" >
|
||||
<Method name="Alias">
|
||||
<Field abbreviation="MAXDVV1hr"/>
|
||||
</Method>
|
||||
</DerivedParameter>
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue